We are transitioning all canvas game developers away from Facebook Credits to local currency payments by September 12, 2013, 90 days after breaking change announcement. The new payments system simplifies the purchase experience for users, improves the performance of the payment flow, and makes it easier for developers to price virtual goods for a global audience. For more information, please see our local currency payments overview.
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.

This document walks through
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 our OG documentation. An fbpayment:subscription object requires the following metadata tags:
og:title – The title for your subscription og:image – A image that Facebook can associate with your subscriptionog:description – The description of your subscriptionog:type – The object type, which for subscriptions is always “fbpayment:subscription”fb:app_id – The application id that this subscription will be used in.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 orderfbpayment:alternate_price – (optional, multiple allowed) Similar to price; this allows for pricing in additional currencies 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 beginfbpayment: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".alternate_price properties, to allow the application to price subscriptions differently for different currencies. price/alternate_price properties, Facebook will determine a price based on the price at our exchange rates, which are updated daily. 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. 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.<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>
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 subscriptionstatus: “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 errorerror_message: explanation of the errorOnce 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 subscriptionOn 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 errorerror_message: explanation of the errorOnce 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 subscriptionproduct: URL of the application’s subscription open graph object that the user is switching toAs 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 errorerror_message: explanation of the errorYou 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 subscriptionOn success, the callback will be passed an object containing:
subscription_id: the unique identifier that represents the user’s subscriptionstatus: “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 cycleIn 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 errorerror_message: explanation of the errorOnce 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 subscriptionOn success, the callback will be passed an object containing:
subscription_id: the unique identifier that represents the user’s subscriptionstatus: “active” – Indicates that the user has reactivated the subscriptionIn 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 errorerror_message: explanation of the errorIf 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 numberOn success, the callback will be passed an object containing:
subscription_id: the unique identifier that represents the user’s subscriptionstatus: active to indicate that the user has reactivated the subscriptionIn the case where the user cancels out of the dialog, or on an error, the object will contain:
error_code: integer identifier for the errorerror_message: explanation of the errorIf 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.
Developers can use the Graph API end point GET https://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{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",
}
}
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/id: the id of the subscriptionuser: 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 cycleamount: the amount the user is currently subscribed for in the current billing periodcurrency: ISO-3 currency code for the current period amount.period_start_time: date that the current billing cycle begancreated_time: date on which subscription was createdupdated_time: date on which subscription was last updatednext_period_product: the url that defines the subscription open graph object for the user in the next billing cyclenext_period_amount: the amount that the user will pay in the next billing periodnext_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 begintrial_expiry_time: date on which any promotion (if provided) expires or expired for this subscriptiontrial_amount: amount that applies during promotion periodtrial_currency: ISO-3 currency code corresponding to promotion amountpending_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'{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",
}
}
{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"
}
Certain properties of a subscription can be updated by the application.
To do any of these things, invoke the Graph API endpoint POST https://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/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 agreementcurrency (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. 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/id: the id of the paymentuser: array containing id and name for the user who made the paymentapplication: array containing application info (name, id)actions: an array of actions associated with the payment (type, status, amount, currency, time_created, time_updated)
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.{
"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",
}
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.
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:
Apps can call POST /<app_id>/subscriptions to register for realtime notifications with the following parameters.
POST https://graph.facebook.com/APP_ID/subscriptionsobject: payment_subscriptionsfields: Supported fields will be status, canceled_reason, pending_cancel, next_period_amount, next_period_currency ,next_bill_time, next_period_product, product, payment_status, last_paymentcallback_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. {"object":"payment_subscriptions",
"entry":[{"id":"SUBSCRIPTION_ID","time":1336431497,"changed_fields":[...]}]}
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:
POST /APP_ID/subscriptionsobject: payments fields: the only supported fields will be actionscallback_url - A callback URL to which Facebook will post subscription updatesverify_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{"object":"payments",
"entry":[{"id":"PAYMENT_ID","time":1336431497,"changed_fields":["actions"]}]}
Developers can use the Graph API endpoint GET https://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/refundstype : with value refundstatus : status of the refund "initiated", "processing", "completed", "failed"currency : currency in which the amount was refundedamount : amount refundedtime_created: when the action (refund) was first initiatedtime_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/refundsamount : amount to refundcurrency : currency in which to refund{
"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"
}
]
}
There is no way to undo a given user's "using up" of his or her free trial. To test your trial functionality repeatedly, you'll need a steady supply of new users; the only way to get them is by using the "test user" functionality, which allows you to create a special kind of user, isolated from "real" users but otherwise perfectly normal. We expose an API to create test users programmatically, as well as a convenient web interface on the Roles page of your app's settings.
Users whose IDs appear in the "Payments Testers" list in your app's settings will be set up to quickly and efficiently test subscription payments with two mocked-up financial instruments, one that always succeeds (without charging the user real money) and one that always fails. Add users to the Testers list here:

When one of these users attempts to purchase a subscription, the payment dialog will look like this:

This will allow you to quickly test your workflows for both valid and invalid payment instruments. Note: Subscriptions that have been created with the mock financial instruments will not be displayed with the Subscription management interface, under Account Settings > Payments. This is reserved only for legitimate subscriptions.
It is important to test your system's ability to handle the ending of a billing period, and the beginning of a new one. To do it, use the server-side API's subscription management interface to set the next_bill_time property to a date and time near the current time.
Subscriptions re-use most of the error codes for Payments listed in the core Payments documentation. In addition, there are several Subscriptions-specific codes, as described below.
| Error code | Error Message | Description |
|---|---|---|
| 1179 | API_EC_PAYMENTS_INVALID_AMOUNT |
The amount you specified is invalid. Please verify that the amount is positive and is an allowed amount for the specific payment. |
| 1180 | API_EC_PAYMENTS_CREDENTIAL_INVALID |
The payment credential is not valid. |
| 1181 | API_EC_PAYMENTS_BA_NOT_ACTIVE |
Subscription is not active. |
| 1182 | API_EC_PAYMENTS_BA_PENDING_CANCEL |
Subscription is currently pending cancellation. |
| 1183 | API_EC_PAYMENTS_BA_NOT_PENDING_CANCEL |
Subscription is not pending cancellation. |
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. Users cannot use their credits balance towards payment of subscription fees.
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.
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.
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:
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.
If a user with an active subscription uninstalls the app, then the subscription will be put into the pending_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.
We will send emails to users on the following events
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.


