# Payments Lite
## Overview {#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 {#creating}
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.
**Note:** 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 {#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_ids` | String | Comma separated list of the app's product IDs | No |
Example call and response:
### JavaScript SDK
```
FB.api(
'/app/products',
'get',
function(response) {
console.log(response);
}
);
```
### Unity SDK
```
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"
}
}
}
```
**Note:** If you have configured more than 25 products, the response will return only the first 25. You can refer to [/docs/graph-api/using-graph-api#paging](https://developers.facebook.com/docs/graph-api/using-graph-api#paging) for information on how to fetch the rest.
## Invoking the UI {#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:
### JavaScript SDK
```
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
);
```
### Unity SDK
```
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 {#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:
### JavaScript SDK
```
FB.api(
'/app/purchases',
'get',
{access_token: 'ACCESS_TOKEN'}, // user access token
payload => { // callback function
console.log('purchases payload:');
console.log(payload);
}
);
```
### Unity SDK
```
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...",
}
}
}
```
For more information for the signed_request returned from this response, please see [this section](https://developers.facebook.com/docs/games/monetization/in-app-purchases/instant-games#verification).
**Note:** If you have more than 25 purchases, the response will return only the first 25. You can refer to [/docs/graph-api/using-graph-api#paging](https://developers.facebook.com/docs/graph-api/using-graph-api#paging) for information on how to fetch the rest.
**Warning:** Starting with Graph API v11.0, the `consumed` field is renamed to `is_consumed`.
## Consuming a purchase {#consuming}
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:
### 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);
}
);
```
### Unity SDK
```
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,
}
```
## Disputes {#disputes}
Disputes can occur much later after the original payment was completed, so to handle a dispute server component is required for the developer to be able to get notified when a player initiates a dispute process. In Payments Lite which is a serverless payments system, all disputes are automatically refunded and closed. For details on how to implement Payments and handle disputes with a server component see [Taking Payments](https://developers.facebook.com/documentation/games_payments/taking-payments) and [Disputes](https://developers.facebook.com/docs/games_payments/fulfillment/disputes).