Payments Lite

Payments Lite is a new way of defining and managing your game's in-app purchases. This new feature allows you to develop a serverless payments solution.

If you have your own server, you might want to define and host your own payment products under Payments (server required).

Overview

Payments Lite is a new way of defining your game's in-app purchases as products directly in the App Dashboard, assigning an ID, name, description, price, currency and image. The product ID is then passed in the JavaScript call to start the payments flow instead of the OG Object URL required by the regular payments flow. This allows for a streamlined flow of creating and modifying products without the need of doing a server push.

Creating Products

To create a product, you need to navigate to Canvas Payments in the App Dashboard to reveal the Products subsection.

To create a product, click the Create New Product button at the top right. In the Product Details dialog, enter the Product ID, Title, Description, and Price, select a currency from the drop-down menu, and upload a 50 px by 50 px image that will represent your product.

Payments Lite will only allow you invoke the Payment Dialog for one product, so if you're planning on selling an in-game currency, your products should reflect a currency bundle.

Product List API

After you have defined the products that will be available for sale in your game, you should build your in-game store. This will allow players to select the product that they are interested in buying. To make sure that you're using the correct information for the products that you wish to sell, you can use the Product List API to get information about the products. To get a list of products, you should call the following endpoint:

GET https://graph.facebook.com/APP_ID/products

With the following parameters:

Parameter Name Type Value Required

product_id

String

Comma separated list of the app's product IDs

Yes

Example call and response:

FB.api(
  '/app/products', 
  'get', 
  function(response) {
    console.log(response);
  }
);
FB.API(
  "app/products",
  HttpMethod.GET,
  this.productCallback // callback that receives a IGraphResult
);
{
  "data": [
    {
      "title": "100 coins lite package",
      "product_id": "payments_lite_test_01",
      "product_type": "managed",
      "description": "Package of 100 coins to test Payments Lite",
      "price": "$1.00",
      "price_amount_cents": 100,
      "price_currency_code": "USD"
    },
    {
      "title": "Friend Smash!",
      "product_id": "480369938658210_premium",
      "product_type": "managed",
      "description": "One time purchase to play game",
      "price": "$0.01",
      "price_amount_cents": 1,
      "price_currency_code": "USD"
    }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIUlg1cXRqcnVad05taFRVRlZAZAU2tQdWNSd0FKRDh1TTJMdGd3azVTZA3ZAZAOFgzcXZAaZAlQ1N1VMMmRmZAXpUNG9KX2tsSWhYVlB6Yko2cEotUXZAiRGgzQkFKc0lJLUQzVlJxbHVPampZAS19SWEQ4",
      "after": "QVFIUmRiSGltU1BKQnRqWTRxNkd1WktUTHFKMmxvaEwtV2dSYUtpeDJxQnN0Ri1mZAnF0TG1Ub3oyWnphSExqZAU5qQzNNZAmFrejVnSTlaRVVGMXdSSlNsNE13"
    }
  }
}

If you have configured more than 25 products, the response will return only the first 25. You can refer to https://developers.facebook.com/docs/graph-api/using-graph-api#paging for information on how to fetch the rest.

Invoking the UI

Once the user has selected a product, you should prompt them to complete the purchase by invoking the Payment dialog. This can be achieved via the ui function of the Facebook Javascript SDK FB object.

To invoke the Payment dialog, you should provide a JSON object as the first parameter with the following keys:

Parameter Name Type Value Required

method

String

pay

Yes

action

String

purchaseiap

Yes

product_id

String

Your product ID

Yes

developer_payload

String

String defining a payload that should be used to verify that the transaction was originated by the developer.

No

quantity

Int

If defined, should always be 1.

No

Example code to invoke the dialog:

FB.ui(
  {
    method: 'pay',
    action: 'purchaseiap',
    product_id: 'com.fb.friendsmash.coins.10',
    developer_payload: 'this_is_a_test_payload'
  },
  response => (console.log(response)) // Callback function
);
FB.PayWithProductId(
  "com.fb.friendsmash.coins.10",
  "purchaseiap",
  1,
  null, null, null, null, null,
  this.payCallback  // Callback function that receives an IPayResult
);

After the flow has been completed, you can verify the outcome of the transaction by providing a callback function as the second parameter of the invoke call. This function will be called with either an object containing information about the transaction or an error code and message:

Example successful response:

{
  app_id: 241431489326925,
  developer_payload: "this_is_a_test_payload",
  payment_id: 860496004080598,
  product_id: "com.fb.friendsmash.coins.10",
  purchase_time: 1473719771,
  purchase_token: "10157567446205226",
  signed_request: "M3fQFj6MlK7WJi597QgCvMlMLh7fl_...",
}

Example transaction with an error:

{
  error_code: 1383010, 
  error_message: "User canceled the order."
}

Listing the player's purchases

Payments Lite allows purchases to be listed and consumed as a form of verification and purchase managing. This means that players are prevented from buying non-consumable products in your game. As a best practice, we recommend checking the current player's purchases after the game has loaded to verify that there aren't any purchases waiting to be consumed.

To list the current player's purchases, you can use the /APP_ID/purchases endpoint of your application along with a user access token. This call will return a list all non-consumed purchases for the current player, with their corresponding purchase information.

For example, using the following calls:

FB.api(
  '/app/purchases',
  'get',
  {access_token: 'ACCESS_TOKEN'},      // user access token
   payload => {        // callback function
     console.log('purchases payload:');
     console.log(payload);
   }
);
FB.API(
  "/app/purchases?access_token=YOUR_ACCESS_TOKEN",
  HttpMethod.GET,
  this.purchasesCallback // callback that receives a IGraphResult
);

Example response:

{
  data: [
    {
      app_id: 241431489326925,
      developer_payload: "this_is_a_test_payload",
      payment_id: 860496004080598,
      product_id: "com.fb.friendsmash.coin",
      purchase_time: 1473719771,
      purchase_token: "10157567446205226",
      signed_request: "M3fQFj6MlK7WJi597QgCvMlMLh7fl_...",
    },
    {
      ...
    }
  ],
  paging: {
    cursors: {
      after: "M3fQFj6MlK7WJi597QgCvMlMLh7fl...",
      before: "M3fQFj6MlK7WJi597QgCvMlMLh7...",
    }
  }
}

If you have more than 25 purchases, the response will return only the first 25. You can refer to https://developers.facebook.com/docs/graph-api/using-graph-api#paging for information on how to fetch the rest.

Consuming a purchase

After a product has been purchased and you've verified that it is a legitimate purchase using the signed request and your developer payload, you must award the purchased item or currency to the player. At this point, if the product purchased is consumable (i.e., currency, one time use items, etc.) you must mark this purchase as consumed to enable the user to purchase another copy of the same item. Products that are not consumable (i.e., special functionality unlock, special VIP programs, etc.) should not be consumed to prevent users from buying the same item more than once.

To consume a purchase, you must use the purchase_token provided in the JavaScript callback or in the players' purchase list discussed on the last section. To consume the purchase, you should call the following Graph API endpoint:

POST	https://graph.facebook.com/PURCHASE_TOKEN/consume

For example, using the Facebook JavaScript SDK:

FB.api(
  '/' + PURCHASE_TOKEN + '/consume',    // Replace the PURCHASE_TOKEN
  'post',
  {access_token: access_token},         // Replace with a user access token
  result => {
    console.log('consuming product', productId, 'with purchase token', purchaseToken);
    console.log('Result:');
    console.log(result);
  }
);
FB.API(
  "/YOUR_PURCHASE_TOKEN/consume?access_token=YOUR_ACCESS_TOKEN",
  HttpMethod.POST,
  this.consumeCallback // callback that receives a IGraphResult
);

Example successful response:

{
  success: true,
}