Subscriptions Tutorial

Subscriptions helps you establish a recurring revenue stream and offer updated content or premium experiences for a fee on a weekly or monthly basis. The subscriptions feature allows you to set prices based on local currency (ex: Japanese yen, British pound, etc.) and offer different levels of subscriptions. Additionally, you can choose whether to offer a free trial and for how long.
People can pay for subscriptions with a credit card or PayPal account, and they can cancel from their Facebook payment settings. We also recommend that you provide a cancel option from within your app.
If you're offering both subscriptions and in-app payments, make sure it's clear to users why you have both. For example, you might offer a monthly subscription for energy or supplies and sell vanity items through in-app purchases.
An example subscription: Playdom's [Gardens of Time](https://apps.facebook.com/gardensoftime/) offers premium currency, exclusive items and more for $15 a month.

Subscription API

Defining a subscription object for your application

A subscription object is an fbpayment:subscription Open Graph object that describes the details of a subscription offered by your application. Details about how Open Graph works can be found in ourOG documentation. An fbpayment:subscription object requires the following metadata tags:
  1. og:title – The title for your subscription
  2. og:image – A image that Facebook can associate with your subscription
  3. og:description – The description of your subscription
  4. og:type – The object type, which for subscriptions is always “fbpayment:subscription”
  5. fb:app_id – The application id that this subscription will be used in.
  6. fbpayment:price – The monthly price for this subscription, specified as a string consisting of a numeric price and an ISO-3 currency code, separated by a space, in either order
  7. fbpayment:alternate_price – (optional, multiple allowed) Similar to price; this allows for pricing in additional currencies
  8. fbpayment:trial_duration – (optional) the amount of time (in days, weeks, or months) that a user can use this subscription before the first billing period will begin
  9. fbpayment:billing_period - (optional) how frequently we charge for the subscription in weeks or months. Valid values include "1 week" or "2 months". The default is "1 month".

Notes

  • There may be zero or more alternate_price properties, to allow the application to price subscriptions differently for different currencies.
  • For users whose preferred currencies are not explicitly listed among the subscription object'sprice/alternate_price properties, Facebook will determine a price based on the price at our exchange rates, which are updated daily.
  • Developers can supply a trial_duration which allows the user to get a free trial for the specified period. A given user can enjoy a free trial for a particular application, for any subscription, only once.
  • If a price field is malformed (e.g. 'US$ 5.00', rather than the correctly-formed '5.00 USD'), Facebook can't catch it until a transaction is attempted. If, in your testing, you get a "null" value passed to your client-side callback, it may be for this reason.
  • Discounted trials are not available for V1 - only free trials. We will update this document if and when that changes.
  • An app can define multiple subscriptions associated with the app. However, a user can have only one active subscription at any time for that app (this does not apply to test users and users listed as Payments Testers, who can purchase multiple subscriptions for the same app).
  • Also a user can only get a free trial for any subscription for that app only once.

Example Object Markup

<html>
    <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# fbpayment: http://ogp.me/ns/fb/fbpayment#">        
        <meta property="og:title" content="Abhi's Bronze Subscription" />
        <meta property="og:image" content="https://s-static.ak.fbcdn.net/images/devsite/attachment_blank.png" />
        <meta property="og:description" content="The Best bronze subscription around!" />
        <meta property="fbpayment:price" content="5.99 USD" />
        <meta property="fbpayment:alternate_price" content="3.99 EUR" />
        <meta property="fbpayment:alternate_price" content="3.99 GBP" />
        <meta property="fbpayment:trial_duration" content="7 days" />
        <meta property="fbpayment:billing_period" content="1 week" />
        <meta property="fb:app_id" content="214417841952278" />
        <meta property="og:url" content="http://samples.ogp.me/231899796870749" />
        <meta property="og:type" content="fbpayment:subscription" />
</html>

Client-side API

Prompting a User to Purchase a Subscription

Once an application has created at least one subscription Open Graph object, prompting a user to purchase a subscription requires using the Facebook Pay Dialog, as described in the core Payments documentation. Please note that information in that document regarding server-side callbacks is not applicable here; instead, please use the server-side logic described below to query a user's subscription status.
Subscription dialog
The following JS snippet can be used to start a subscription purchase dialog:
  var obj = {
    method: 'pay',
    action: 'create_subscription',
    product: 'URL_TO_SUBSCRIPTION_OBJECT'
     };
  FB.ui(obj, js_callback);
  • product: The url that hosts the application’s subscription open graph object.
On completion or cancellation of the subscription purchase dialog, the Javascript callback will be called. In case of success, the callback's argument will be an object containing the keys:
  • subscription_id: the unique identifier that represents the user’s active subscription
  • status: “active”
In the case where the user cancels the subscription purchase dialog, or if there is an error, the object will contain the keys:
  • error_code: integer identifier for the error
  • error_message: explanation of the error

Prompting a User to Modify the Payment Method for a Subscription

Once a user already has purchased a subscription it's possible for the application to prompt the user to change the payment method currently being used to pay for the service. For example, a user who has a credit card on file that he or she knows to be expiring soon can update the payment method from within the application with this functionality.
Change Payment Method Dialog
This subscription modification dialog can be invoked with the following js snippet:
var obj = {
     method: 'pay',
     action: 'modify_subscription',
     subscription_id: USER_SUBSCRIPTION_ID,
  };
  FB.ui(obj, js_callback);
  • subscription_id: user to subscription identifier returned when the user purchased this subscription
On success, Facebook will invoke the application-specified “js_callback” with an object containing:
  • subscription_id: the unique identifier that represents the user’s subscription. (Note that this is the same subscription_id as was provided when invoking this API)
  • status: “active” – indicates the modified subscription is active.
In the case where the user cancels the subscription modification dialog, or if there is an error, the object will instead contain:
  • error_code: integer identifier for the error
  • error_message: explanation of the error

Prompting a User to Upgrade/Downgrade a Subscription

Once a user already has purchased a subscription, the application can prompt the user to change his/her subscription. For example, a user may want to upgrade from a “Bronze” subscription to a “Silver” one or downgrade from a “Silver” subscription to a “Bronze” one.
Subscription upgrades (defined as ones costing the same as, or more than, the existing subscription) take effect immediately and the user is charged a pro-rated amount for the rest of the current billing cycle. Subscription downgrades (those costing less than the existing subscription) take effect at the start of the subsequent billing cycle.
Upgrade Dialog
This subscription change dialog can be invoked with the following js snippet:
var obj = {
     method: 'pay',
     action: 'change_subscription',
     subscription_id: USER_SUBSCRIPTION_ID,
     product: 'URL_TO_SUBSCRIPTION_ WEBPAGE'
  };
  FB.ui(obj, js_callback);
  • subscription_id: user-subscription unique identifier returned when the user purchased this subscription
  • product: URL of the application’s subscription open graph object that the user is switching to
As above, on success, Facebook will invoke the “js_callback” with an object containing:
  • subscription_id: the unique identifier that represents the user’s subscription. (Note that this is the same subscription_id as was provided when invoking this API)
  • status: “active” – indicates the changed subscription is active. For upgrades this means the user is now subscribed to the service determined by the provided product parameter. For downgrades, this means that the user’s subscription will change to the service determined by the provided product parameter at the start of the subsequent billing cycle.
In case of an error, or if the user cancels the dialog, the object passed to the callback will contain:
  • error_code: integer identifier for the error
  • error_message: explanation of the error

Prompting a User to Cancel a Subscription

You may use this functionality to allow a user to cancel his or her existing subscription.
After a user takes the action to cancel a subscription, it will be in the “pending cancellation” state, and will actually be canceled at the end of the current billing cycle. This means that the user should continue to receive all the benefits from the subscription until then. Also, note that a user can reactivate a subscription that is in a “pending cancellation” state, as described below.
Cancel Dialog
This subscription cancel dialog can be invoked with the following js snippet:
  var obj = {
    method: 'pay',
    action: 'cancel_subscription',
    subscription_id: USER_SUBSCRIPTION_ID
  };
  FB.ui(obj, js_callback);
  • subscription_id: user to subscription identifier returned when the user purchased this subscription
On success, the callback will be passed an object containing:
  • subscription_id: the unique identifier that represents the user’s subscription
  • status: “active” – as described above, cancellation does not happen immediately, so this indicates that the user’s subscription is still active, but that she/he has decided to cancel his subscription, and that change will take effect at the end of the current billing cycle
In the case where the user cancels the subscription cancellation dialog, or if there is an error, the object will contain:
  • error_code: integer identifier for the error
  • error_message: explanation of the error

Prompting a User to Reactivate a Subscription

Once a user has decided to cancel a subscription, but before the cancellation actually takes place, a developer can re-engage the user via the reactivation flow. Note that if the cancellation is initiated by the app, this reactivation flow will not succeed.
After a user takes the action to cancel a subscription it will be placed in a “pending cancellation” state, to be actually canceled at the end of the current billing cycle. Before the end of the current billing cycle, the user can reactivate the subscription and it will become active again. (The next charge will occur at the start of the next billing cycle.)
Reactivation Dialog
This subscription reactivation dialog can be invoked with the following js snippet:
  var obj = {
    method: 'pay',
    action: 'reactivate_subscription',
    subscription_id: USER_SUBSCRIPTION_ID
  };
  FB.ui(obj, js_callback);
  • subscription_id: user-subscription unique identifier returned when the user purchased this subscription
On success, the callback will be passed an object containing:
  • subscription_id: the unique identifier that represents the user’s subscription
  • status: “active” – Indicates that the user has reactivated the subscription
In the case where the user cancels the subscription reactivation dialog, or on error, the object will contain the following two keys:
  • error_code: integer identifier for the error
  • error_message: explanation of the error

Prompting a user to settle after payment failure

If a payment cannot be processed to fund a user's subscription, the payment_status flag in his or her subscription object will be false. In that case, the app can request that the user settle that payment using the pay dialog as illustrated in this snippet:
Settlement dialog
var obj = {
     method: 'pay',
     action: 'settle_subscription',
     subscription_id: USER_SUBSCRIPTION_ID,
  };
  FB.ui(obj, js_callback);
  • subscription_id: the user-specific subscription ID number
On success, the callback will be passed an object containing:
  • subscription_id: the unique identifier that represents the user’s subscription
  • statusactive to indicate that the user has reactivated the subscription
In the case where the user cancels out of the dialog, or on an error, the object will contain:
  • error_code: integer identifier for the error
  • error_message: explanation of the error
If the subscription is already settled (i.e. the subscription object's payment_status is success) when the dialog is invoked, the user will see an exception. It is the application's responsibility to verify the user's settlement status before proceeding.

Server-side API

Querying for a User’s Subscriptions

Developers can use the Graph API end point GEThttps://graph.facebook.com/USER_ID/payment.subscriptions with an app access_token to access a user's subscriptions associated with that application. By default, just those in an active status will be returned; pass in a status=canceled parameter if you also want canceled subscriptions.

GET https://graph.facebook.com/USER_ID/payment.subscriptions

Response Values * A json encoded string that represents an array of subscription identifiers and their details.

Sample Response

{1234: {
  id: 1234,
  user: {
      "name": "Bikash Agarwalla",
      "id": "1245537185"
  },
  application: {
      "name": "Application",
      "id": "10245213"
  },
  status: "active",
  created_time: "2012-03-16T20:10:34+0000",
  updated_time: "2012-03-16T20:10:34+0000",
  amount: "10.00",
  currency: "USD",
  product: "http://current_item",
  period_start_time: "2012-03-16T20:10:34+0000",
  next_bill_time: "2012-04-16T20:10:34+0000",
  next_period_product: "http://next_item",
  next_period_amount:: "20.00",
  next_period_currency: "USD",
  billing_period: "1 month",
  payment_status: "success", 
  last_payment: {
    "id": 3566,
    "actions": [
      {
        "type": "charge",
        "status": "completed",
        "amount": "10.00",  
        "currency: "USD",
        "time_created": "2012-03-16T20:10:34+0000",
        "time_updated": "2012-03-16T20:10:34+0000",
    },
    "refundable_amount": {
        "currency": "USD",
        "amount": "10.00"
    },
    "country": "US",  
  }
}

Querying for the Details of a Specific Subscription

Calling the Graph API end point GET https://graph.facebook.com/SUBSCRIPTION_ID/ with an app access_token returns details about a specific subscription, as long as it belongs to the application.

GET https://graph.facebook.com/SUBSCRIPTION_ID/

Response Values * A json-encoded string containing: * id: the id of the subscription * user: array containing user who is subscribed (name, id) * application: array containing application info (name, id) * status: current status of the subscription [active, canceled] * product: the url that defines the subscription open graph object for the user in the current billing cycle * amount: the amount the user is currently subscribed for in the current billing period * currency: ISO-3 currency code for the current period amount. * period_start_time: date that the current billing cycle began * created_time: date on which subscription was created * updated_time: date on which subscription was last updated *next_period_product: the url that defines the subscription open graph object for the user in the next billing cycle * next_period_amount: the amount that the user will pay in the next billing period *next_period_currency: ISO-3 currency code for the next period amount. * billing_period: how often we bill the users. Formatted like '1 month'. The valid periods are 'month' and 'week'. *next_bill_time: date that the next billing cycle will begin * trial_expiry_time: date on which any promotion (if provided) expires or expired for this subscription * trial_amount: amount that applies during promotion period * trial_currency: ISO-3 currency code corresponding to promotion amount *pending_cancel: Boolean indicating whether or not the user has decided to cancel the subscription at the end of the current billing cycle. (NOTE: this will only be true when a user has taken explicit action to cancel his subscription. In other words, a subscription for which a payment has failed will not have this flag set to true.) * canceled_reason: flag indicating why a subscription has been canceled [user_decision, app_decision, failed_payment, none] * payment_status: string indicating the status of the payment for the current billing cycle [success, failed, not_billed]. It will be "success" if last payment for the user succeeded. It will be "failed" if last payment for the user failed. If the user hasn't been billed (for example, if the user is in free trial), this will be set to "not_billed". (NOTE: more detailed reasons for failed status to be added; this document will be updated to reflect those changes) * last_payment: details for the last payment, an object with fields 'id', 'actions', 'refundable_amount', and 'country'

Sample Response

  • In this example, we have a user who signed up for a 9.99 USD “gold” subscription service on 03/01/2012 and received a 2 week free trial. Sometime after 04/14/2012 and before 05/14/2012, the user decided to downgrade to the “bronze” subscription that costs only 5.99 USD. Assume the current date is 05/03/2012.
{id: "122119087921267",
 user: {
      "name": "Bikash Agarwalla",
      "id": "1245537185"
 },
 application: {
      "name": "Application",
      "id": "10245213"
 },
 status: "active",
 created_time: "2012-04-01",
 updated_time: "2012-04-17",
 amount: "9.99",
 currency: "USD",
 product: "www.application.com/gold_subscription.html",
 period_start_time: "2012-04-14",
 next_bill_time: "2012-05-14",
 next_period_product: "www.application.com/bronze_subscription.html",
 next_period_amount:: "5.99",
 next_period_currency: "USD",
 billing_period: "1 month",
 trial_amount: "0",
 trial_currency: "USD",
 trial_expiry_time: "2012-04-14",
 payment_status: "success",
 last_payment: {
    "id": 3566,
    "actions": [
      {
        "type": "charge",
        "status": "completed",
        "amount": "9.99",  
        "currency: "USD",
        "time_created": "2012-04-14T20:00:00+0000",
        "time_updated": "2012-04-14T20:00:00+0000",
    },
    "refundable_amount": {
        "currency": "USD",
        "amount": "9.99"
    },
    "country": "US",  
  }
}

Additional example response

{id: "122119087921265",
 user: {
      "name": "Bikash Agarwalla",
      "id": "1245537185"
 },
 application: {
      "name": "Application",
      "id": "10245213"
 },
 status: "active",
 created_time: "2012-04-16T20:10:34+0000",
 updated_time: "2012-04-17T20:10:34+0000",
 amount: "10.00",
 currency: "USD",
 product: "http://current_item",
 period_start_time: "2012-04-16T20:10:34+0000",
 next_bill_time: "2012-05-17T20:10:34+0000",
 next_period_product: "http://next_item",
 next_period_amount:: "20.00",
 next_period_currency: "USD",
 billing_period: "1 month",
 trial_amount: "0",
 trial_currency: "USD",
 trial_expiry_time: "2012-04-17T20:10:34+0000",
 pending_cancel: true,
 canceled_reason: "user_decision",
 payment_status: "not_billed"
}

Updating a Specific Subscription Programmatically

Certain properties of a subscription can be updated by the application.
  • Developers can choose to push the next billing date out in case they wish to give users free usage time, most often as a compensation for poor delivery of service or other dissatisfaction.
  • Developers can choose to discount the subscription for a given user, by updating the price of the subscription for that user to a value lower than the user's current price. An app might do this to (e.g.) avoid punishing early adopters if it later lowers the price of a subscription.
  • Developers can cancel the subscription for a particular user at any time, without their explicit consent. They can choose to do so either immediately or at the end of a billing cycle. Subscriptions that are canceled directly by the developer cannot be re-activated with the client-side flow. This might be done when a user's payment fails, for instance.
To do any of these things, invoke the Graph API endpoint POSThttps://graph.facebook.com/SUBSCRIPTION_ID/ with an app access_token and the appropriate parameter(s) from the list below.

POST https://graph.facebook.com/SUBSCRIPTION_ID/

Parameters * next_bill_time (optional): string timestamp for when the next billing date should be (i.e 2013-01-11T10:40:40+0000) * amount (optional): string that includes the amount (i.e 5.99) - note that without explicit user consent, the amount must be lower, denominated in the same currency, than the amount specified by the user's existing billing agreement * currency (optional - required if amount is specified): ISO-3 currency code (i.e. USD) * status (optional): the status that the subscription is in (the application can cancel a subscription) * canceled indicates that the subscription should be canceled. *cancel_type (optional) parameter with values either: * immediate (default) indicates that the subscription should be canceled now. * pending indicates that the subscription should be canceled at the end of current billing cycle.

Response Values

  • Boolean indicating success, or error on failure

Query for the details of any Payment

Developers can use the Graph API end point GET https://graph.facebook.com/PAYMENT_ID/ with an app access token to get the details of a specific payment, provided the payment is related to this application.

GET https://graph.facebook.com/PAYMENT_ID/

Response Values * A json-encoded string of data containing: * id: the id of the payment * user: array containing id and name for the user who made the payment * application: array containing application info (name, id) * actions: an array of actions associated with the payment (type, status, amount, currency, time_created, time_updated) * type: "charge", "refund", "chargeback", "chargeback reversal" * status: "inited", "processing", "completed", "failed" * item: the item associated with the payment (type, id and more details based on item type) * refundable_amount: the amount that are still refundable by the app. * request_id : // this is always empty for subscription, should we remove it for now?, * country" : the user's country for tax purposes.

Example Response

{
  "payment_id": 90010000008188,
  user: {
    "name": "Bikash Agarwalla",
    "id": "1245537185"
  },
  "application": {
    "name": "FBCredits Demo",
    "namespace": "credits_demo",
    "id": 81947918671,
  },
  "actions": [
    {
      "type": "charge",
      "status": "completed",
      "amount": "1.00",  
      "currency: "USD",
      "time_created": "2012-04-16T20:10:34+0000",
      "time_updated": "2012-04-16T20:10:34+0000",
    },
    {
      "type": "refund",
      "status": "completed",
      "amount": "0.20",
      "currency": "USD",
      "time_created": "2012-04-18T10:10:34+0000",
      "time_updated": "2012-04-18T10:10:34+0000",
    },
    {
      "type": "refund",
      "status": "processing",
      "amount": "0.30",
      "currency": "USD",
      "time_created": "2012-04-20T10:10:34+0000",
      "time_updated": "2012-04-20T10:10:34+0000",
    },
  ],
  "refundable_amount": {
    "amount": "0.50",
    "currency": "USD",
  }

  "items": [{
    "type": "SUBSCRIPTION",
    "id": 376537519748,
    "product": "http://test.com/test_subscription",
    "period_start_time": "2012-03-16T10:10:34+0000",
    "period_end_time" : "2012-04-16T10:10:34+0000",
    "amount": "10.10"
    "currency": USD
  }],

  "request_id": "app_request_id_test_12345",
  "country": "US",   
}

Consuming Updates in Real-time

Developers who prefer real time server-server updates when a particular subscription or payment changes can optionally register a callback url via the “Real-time Updates” Graph API. Details of how to register your callback url for specific updates can be found in the Realtime API docs. The Realtime Update API has retry logic built into it and will retry approximately five times, with exponential backoff, over the course of 24 hours.

Subscription Updates

Real-time updates for a specific subscription are provided by consuming updates for the “subscription” object. Once signed up for these updates, you will receive notifications when:
  • A new subscription becomes active
  • An existing subscription gets upgraded or downgraded
  • User decides to cancel their subscription and its pending_cancel becomes true
  • User decides to cancel their subscription and the subscription gets cancelled at the end of the current billing cycle.
  • A payment is processed for this subscription
Apps can call POST /<app_id>/subscriptions to register for realtime notifications with the following parameters.

POST https://graph.facebook.com/APP_ID/subscriptions

Parameters * objectpayment_subscriptions * fields: Supported fields will be status,canceled_reasonpending_cancelnext_period_amountnext_period_currency,next_bill_timenext_period_productproductpayment_statuslast_payment *callback_url - A callback URL to which Facebook will post subscription updates. * verify_token - A subscriber-provided opaque token that will be echoed back in the verification request to assist the subscriber in identifying which subscription request is being verified.

Subscriptions realtime notification sample

{"object":"payment_subscriptions",
 "entry":[{"id":"SUBSCRIPTION_ID","time":1336431497,"changed_fields":[...]}]} 

Payment Updates

Real time updates for a specific payment (e.g did a payment get refunded or charged-back?) are provided by consuming updates for the “payment” object, using the endpoint POST /APP_ID/subscriptions. Apps consuming these receive real time updates when:
  • A new payment has failed
  • A new payment has succeeded
  • An existing payment has been refunded
  • An existing payment has been charged-back

POST /APP_ID/subscriptions

Parameters * objectpayments * fields: the only supported fields will be actions * callback_url - A callback URL to which Facebook will post subscription updates * verify_token - A subscriber-provided opaque token that will be echoed back in the verification request to assist the subscriber in identifying which subscription request is being verified

Payment realtime notification sample

{"object":"payments",
   "entry":[{"id":"PAYMENT_ID","time":1336431497,"changed_fields":["actions"]}]}

Query for or create a refund for a payment

Developers can use the Graph API endpoint GEThttps://graph.facebook.com/PAYMENT_ID/refunds with an app access token to read a list of refunds for a given payment, and POST https://graph.facebook.com/PAYMENT_ID/refunds to initiate a new refund.

GET https://graph.facebook.com/PAYMENT_ID/refunds

Response * type : with value refund * status : status of the refund "initiated", "processing", "completed", "failed" * currency : currency in which the amount was refunded * amount : amount refunded * time_created: when the action (refund) was first initiated * time_updated: when the refund was last changed, for instance, if a refund is to a pending method like direct debit, time_updated will change every time the status changed.

POST https://graph.facebook.com/PAYMENT_ID/refunds

Parameters * amount : amount to refund * currency : currency in which to refund
Sample Response
{
   "90810000015396": [
      {
         "type": "refund",
         "status": "completed",
         "currency": "USD",
         "amount": "0.25",
         "time_created": "2012-05-04T19:54:00+0000",
         "time_updated": "2012-05-04T19:54:06+0000"
      },
      {
         "type": "refund",
         "status": "completed",
         "currency": "USD",
         "amount": "0.25",
         "time_created": "2012-05-04T19:56:44+0000",
         "time_updated": "2012-05-04T19:56:50+0000"
      },
      {
         "type": "refund",
         "status": "completed",
         "currency": "USD",
         "amount": "0.50",
         "time_created": "2012-05-04T19:57:08+0000",
         "time_updated": "2012-05-04T19:57:14+0000"
      }
   ]
}

Payment and Billing

Subscriptions are pre-paid and the user has to pay at the beginning of the pay cycle. The pay cycle length can only be one month.
When a payment is due on a subscription, we update the subscription object's values for the next bill time and current period start time, reflecting the passage of a subscription period. We then attempt to process the payment in a smart queue that manages retries; in most cases, processing will occur within 20 minutes of payment creation.

Handling Chargebacks

Developers can find out when there has been a chargeback by either querying for the payment objects for each user at regular intervals or by registering a real-time update for the payment object.
Note: Facebook does not directly take any action when there is a chargeback. Developers can choose to cancel the subscription at this point if they deem it the right action for the user and their application.

Payment Failure Retry Logic

When a user’s payment for a subscription fails Facebook will attempt several automated retries to collect funds from the existing funding source. (Each attempt will have a unique payment identifier.) In addition to retries, we will also notify the user of the failed payment, and provide her or him the opportunity to repay for the subscription with a new funding source.
There are four payment failure scenarios, all of which apply to both credit card and PayPal:
  • Situations where we deem the payment instrument to be "non-chargeable" e.g. Blacklisted card => we disable the payment instrument and do not retry (although we do still email the user, asking them to update the instrument)
  • Situations where we deem the payment instrument to be "chargeable" e.g. Reason codes like Insufficient funds (NSF), Credit Limit Hit => retry every 24 hours, up to a maximum of 3 times
  • Other, Facebook-internal errors (e.g. database error, system unavailable) => retry every 6 hours, for up to a maximum of 4 times
  • Other, payment provider-side errors (e.g. Paypal unavailable) => retry every 12 hours, for up to a maximum of 4 times
This logic reflects feedback from partners who claim that this captures and fixes about 75% of instrument declines.
Note: A failed payment does not immediately affect the subscription. In fact, the subscription will remain active for the remainder of the billing cycle, unless you, the developer, explicitly cancel it. We recommend that you not cancel immediately, but rather suspend fulfillment until the payment issue is addressed. Regardless of how you choose to handle the payment failure, Facebook will cancel a subscription if it ends a billing cycle in an unpaid state, so users will get at most one month of unpaid subscription, even absent developer intervention.

Other Cancellation Scenarios

If a user with an active subscription uninstalls the app, then the subscription will be put into thepending_cancel state, and will be terminated at the end of the billing cycle. This way, if a user re-installs the app, the developer can choose to prompt them to re-activate via the client-side flow.
If a user with an active subscription deletes their Facebook account, their subscription will be cancelled immediately.

Emails to users

We will send emails to users on the following events
  • Subscription created
  • Subscription canceled
  • Subscription reactivated
  • Payment successful
  • Payment declined (even on retries)

Subscription Management

Facebook provides a settings page to enable users to manage all their subscriptions in one place.
Users will be able to either change their payment instrument, or cancel their subscriptions, here.
Was this document helpful?