Facebook Developers
DocsToolsSupportNewsApps
Log In
  • Social Plugins
  • Facebook Login
  • Open Graph
  • Facebook APIs
  • Games
  • Payments
  • App Center
  • Promote Your App
  • iOS
  • Android
  • JavaScript
  • PHP
  • More SDKs
  • Getting Started
    • Payments Tutorial
    • Register your Company
    • Payments Callback
    • Payments Reports
  • Core APIs
    • Pay Dialog
    • Order API
    • Error Codes
    • In-App Currency Orders
    • Payment Subscriptions
    • Payer Promotions
  • Local currency payments
    • Local currency payments
    • How-to: Local currency payments
    • 1. Company Registration
    • 2. Defining Products
    • 3. User Payment Flow
    • 4. Order Fulfillment
    • 5. Handling Disputes and refunds
    • 6. Testing Payments
    • Product Object
    • Pay with Mobile APIs for local currency
    • Payment Price Floors
    • Local currency FAQ
  • How-Tos
    • Display prices in user's currency
    • Pay with Mobile APIs
  • Advanced
    • Payments payout FAQ
    • Disputes & Chargebacks
    • Offers with Payments
    • Payment Methods

Payments Callback

Overview

Facebook issues two types of HTTP POST requests to the URL specified at Payments Callback URL. To configure the app's Payments Callback URL, visit this documentation. The two types of app server requests compliment the Pay Dialog by:

  • Getting item information for display in the Pay Dialog.

  • Notifying the app of Facebook order status updates.

In both cases, the developer will need to parse the signed request to authenticate and process Facebook's requests.

In addition to standard signed_request fields, the developer is required to process an additional field named credits whose value is an array. The contents of the array will depend on the Facebook request type.

Not all Pay Dialogs result in both types of app sever requests. The following table articulates the relationship.

Pay Dialog action valueFacebook sends
payments_get_items request?
Facebook sends
payments_status_update request?
buy_itemYes.
When a user buys an item from the developer, Facebook needs the developer to provide the order information. As a result, Facebook sends a payments_get_items request to the developer's Credits Callback URL containing the Pay Dialog's order_info value. The developer's response must contain the order information because this information is then displayed in the Pay Dialog. Details on this request can be found here.
Yes.
After a user places an order and Facebook reserves the user's funds to purchase this order, Facebook sends a payments_status_update request to the developer's Credits Callback URL. Assuming the developer fulfills the order based on the order_details value, the developer should settle the order by responding so that Facebook can transfer the funds from the user to the developer. Details on this request can be found here.
earn_currencyNo.
Facebook does not send a payments_get_items request because the order information is calculated based on the Pay Dialog's product value which is an app's currency OG object URL.
Yes.
After a user completes an offer, an item order for the app's currency is placed, and Facebook reserves the user's funds to purchase this order. Then Facebook sends a payments_status_update request to the developer's Credits Callback URL to inform the developer that the user has placed an order. Assuming the developer fulfills the order based on the modified value, the developer should settle the order by responding so that Facebook can transfer the funds from the user to the developer. Details on this request can be found here.
buy_credits No.
Since the user purchases credits and Facebook understands credits' orders, Facebook does not send a payments_get_items request to the developer's Credits Callback URL.
No.
Since the user is purchasing credits from Facebook and Facebook is responsible for fulfilling orders for credits, Facebook does not send a payments_status_update to the developer's Credits Callback URL indicating that orders for credits have been placed.

A PHP example can be found here.

 

Get Item Information

To open an item order in the Pay Dialog, Facebook issues an app server request for the item information. Facebook uses the developers response to this request to populate the Pay Dialog.

Note that Facebook considers app currencies orders (e.g. Fred's App's Cash) as item orders.

Facebook Request

To identify the type of request, inspect the POST parameter method for the value payments_get_items.

An example POST request body,

signed_request=rb6-VQP3uFb8y3rAgOuVR9SiOMUaWqk1NJGt...&
buyer=409697&
receiver=409697&
order_id=9006597900959&
order_info={"item_id":"1a"}&
method=payments_get_items

After parsing the POST parameter signed_request value, the credits field contains an array with the following fields.

NameTypeValue
buyerIntegerThe UID of the buyer.
receiverIntegerThe UID of the order recipient.
order_idInteger64-bit Facebook order id. If the app server is not configured for 64-bit integers, the value can be cast into a string.
order_infoStringThe order information passed when the FB.ui is invoked

An example parsed and JSON decoded signed_request,

Array(
  [algorithm] => HMAC-SHA256
  [credits] => Array(
                 [buyer] => 409697
                 [receiver] => 409697
                 [order_id] => 9006597900959
                 [order_info] => {"item_id":"1a"}
  )
  [expires] => 1325210400
  [issued_at] => 1325203762
  [oauth_token] => AAABhWGUwIE8BABlFo...
  [user] => Array(
              [country] => us
              [locale] => en_US
              [age] => Array(
                        [min] => 21
                       )

            )
  [user_id] => 409697
)

Developer Response

Developers should use the order_info passed from FB.ui and parsed from the signed_request value to determine the actual item information.

Since invoking FB.ui occurs on the client, anyone with access to the client can mutate order_info.

As a result, Facebook issues this request to the developer's app server so that the developer can validate and utilize order_info to determine the actual item information.

After validating the order_info and using it to lookup the actual item information, the developer should respond with the following information.

NameTypeDescriptionRequired
methodStringThe value payments_get_items.Yes
titleStringThe name of the product. String length must be <= 50 characters.Yes
descriptionString A description of the product. String length must be <= 175 characters.Yes
image_urlStringThe URL for the image to display to the user.Yes
product_urlStringA permalink to the product's URL.Yes
priceIntegerThe product cost based in credits. All product costs must be based in credits. Integer value must be > 0.Yes
item_idStringA developer specific id for the product. Not used by Facebook.No
dataarrayJSON encoded array containing the order information.No

The structure of the response is a JSON string whose contents contain an object with two fields.

  • The content field contains all of the above attributes except method and is represented as the 0th property of an object.

  • The method field contains the string payments_get_items.

An example developer JSON string response,

{
  "content":[
              {
                "title":"BFF Locket",
                "description":"Best friend locket",
                "price":1,
                "image_url":"http:\/\/www.facebook.com\/images\/gifts\/21.png"
              }
            ],
  "method":"payments_get_items"
}

After receiving the developer's response containing the item information, Facebook opens the Pay Dialog displaying the provided item information.

 

Order Status Updates

Facebook issues order status update requests under the following circumstances:

  • A user places an item order.

  • A user earns app currency.

  • A user disputes an item order.

  • Facebook refunds an item order.

Note: Facebook sometimes issues a second payments_status_update request with the settled status. Developers should ignore this request. Facebook will be removing this second request on March 1, 2012 so developers should not depend on it.

 

Order Status Update - Placed Item Order

Facebook issues an order status update request after the user confirms the item order in from the Pay Dialog.

This notifies the app that a user's order is ready to be processed.

Facebook Request

To identify the type of request, inspect the POST parameter method for the value payments_status_update.

An example POST request body,

signed_request=IdUotyZ7b-bT1gCJx8ClnCIPx742ldxUtlvZ...&
order_details={"order_id":9007076736544,"buyer":409697,
  "app":107032282669135,"receiver":409697,"amount":1,
  "time_placed":1329243276,"update_time":1329243277,
  "data":"","items":[{"item_id":"0","title":"100 FredCoins",
    "description":"Spend FredCoins for all things in FredLand.",
    "image_url":"http:\/\/www.inexpensivegold.com\/wp-content\/uploads\/2009\/12\/20-liberty-double-eagle.jpg",
    "product_url":"","price":1,"data":""}],
  "status":"placed"}&
status=placed&
order_id=9007076736544&
method=payments_status_update

After parsing the POST parameter signed_request value, the credits field contains an array with the following fields.

NameTypeValue
order_detailsJSON stringContains the developer's payments_get_items response information. See below for an example.
statusStringThe value placed. This indicates that the user has placed the order and that Facebook has reserved the funds from the user for this order.
order_idInteger64-bit Facebook order id. Parsing the signed_request can garble this value. Use the order_id in the above order_details field.

An example parsed and JSON decoded signed_request,

Array(
  [algorithm] => HMAC-SHA256
  [credits] => Array(
                 [order_details] => {"order_id":9007076736544,"buyer":409697,"app":107032282669135,"receiver":409697,"amount":1,"time_placed":1329243276,"update_time":1329243277,"data":"","items":[{"item_id":"0","title":"100 FredCoins","description":"Spend FredCoins for all things in FredLand.","image_url":"http:\/\/www.inexpensivegold.com\/wp-content\/uploads\/2009\/12\/20-liberty-double-eagle.jpg","product_url":"","price":1,"data":""}],"status":"placed"}
                 [status] => placed
                 [order_id] => 9007076736544
               )
  [expires] => 1329249600
  [issued_at] => 1329243278
  [oauth_token] => AAABhWGUwIE8BALBqO...
  [user] => Array(
              [country] => us
              [locale] => en_US
              [age] => Array(
                         [min] => 21
                       )

            )
  [user_id] => 409697
)

JSON decoding the above example order_details value yields:

Array(
  [order_id] => 9007076736544
  [buyer] => 409697
  [app] => 107032282669135
  [receiver] => 409697
  [amount] => 1
  [time_placed] => 1329243276
  [update_time] => 1329243277
  [data] => 
  [items] => Array(
               [0] => Array(
                        [item_id] => 0
                        [title] => 100 FredCoins
                        [description] => Spend FredCoins for all things in FredLand.
                        [image_url] => http://www.inexpensivegold.com/wp-content/uploads/2009/12/20-liberty-double-eagle.jpg
                        [product_url] => 
                        [price] => 1
                        [data] => 
                      )

             )
  [status] => placed
)

Developer Response

Developers should respond with the following information.

NameTypeDescriptionRequired
methodStringThe value payments_status_update.Yes
order_idStringThe order id for the order which was placed by the user.Yes
statusStringThe value settled or canceled. See below for details.Yes

The structure of the response is a JSON string whose contents contain an object with two fields.

  • The content field contains all of the above attributes except method and is represented as the 0th element of an array.

  • The method field contains the string payments_get_items.

More specifically, developers have two options:

1. Settle the placed order by:

  • Fulfilling the order by depositing the appropriate amount of virtual currency or item. Developers can use the order_details to determine what goods to deliver.

  • Responding to this payments_status_update with settled. An example developer settled JSON string response,

{
  "content":{
              "status":"settled",
              "order_id":9006195253076
            },
  "method":"payments_status_update"
}
  • The developer is paid the price for the order and these transactions are represented as type S in the developer payout reports.

2. Or cancel the placed order by:

  • Responding to this payments_status_update with canceled. An example developer canceled JSON string response,
{
  "content":{
              "status":"canceled",
              "order_id":9006203669116
            },
  "method":"payments_status_update"
}
  • If the order is cancelled, Facebook releases the user's reserved funds for this order.

If the developer settles the order, Facebook will open an appropriate order confirmation dialog.

For both the settled and canceled response options, Facebook will return data to the client.

 

Order Status Update - Earned App Currency

Facebook issues an order status update request after the user completes an In-app Currency Offer.

This notifies the app that a user's order is ready to be processed.

Facebook Request

To identify the type of request, inspect the POST parameter method for the value payments_status_update.

An example POST request body,

signed_request=lqk6mXAGGhmUvsZ_jbKezG1bGq7whh7Ecmvj...&
order_details={"order_id":9007080443022,"buyer":409697,
  "app":107032282669135,"receiver":409697,"amount":1,
  "time_placed":1329408828,"update_time":1329408830,
  "data":"","items":[{"item_id":"0","title":"3 Fred Currency",
    "description":"Make it rain!",
    "image_url":"URL_TO_SOME_IMAGE",
    "product_url":"","price":1,
    "data":"{\"modified\":{\"product\":\"URL_TO_APP_CURR_WEBPAGE\",
      \"product_title\":\"Fred Currency\",\"product_amount\":3,\"credits_amount\":1}}"}],
  "status":"placed"}&
status=placed&
order_id=9007080443022&
method=payments_status_update

After parsing the POST parameter signed_request value, the credits field contains an array with the following fields.

NameTypeValue
order_detailsJSON stringContains the developer's payments_get_items response information. See below for an example.
statusStringThe value placed. This indicates that the user has placed the order and that Facebook has reserved the funds from the user for this order.
order_idInteger64-bit Facebook order id. Parsing the signed_request can garble this value. Use the order_id in the above order_details field.

An example parsed and JSON decoded signed_request,

Array(
  [algorithm] => HMAC-SHA256
  [credits] => Array(
                 [order_details] => {"order_id":9007080443022,"buyer":409697,"app":107032282669135,"receiver":409697,"amount":1,"time_placed":1329408828,"update_time":1329408830,"data":"","items":[{"item_id":"0","title":"3 Fred Currency","description":"Make it rain!","image_url":"URL_TO_SOME_IMAGE","product_url":"","price":1,"data":"{\"modified\":{\"product\":\"URL_TO_APP_CURR_WEBPAGE\",\"product_title\":\"Fred Currency\",\"product_amount\":3,\"credits_amount\":1}}"}],"status":"placed"}
                 [status] => placed
                 [order_id] => 534023310
               )
  [expires] => 1329415200
  [issued_at] => 1329408831
  [oauth_token] => AAABhWGUwIE8BAAB6g...
  [user] => Array(
              [country] => us
              [locale] => en_US
              [age] => Array(
                         [min] => 21
                       )

            )
  [user_id] => 409697
)

JSON decoding the above example order_details value yields:

Array(
  [order_id] => 9007080443022
  [buyer] => 409697
  [app] => 107032282669135
  [receiver] => 409697
  [amount] => 1
  [time_placed] => 1329408828
  [update_time] => 1329408830
  [data] => 
  [items] => Array(
               [0] => Array(
                        [item_id] => 0
                        [title] => 3 Fred Currency
                        [description] => Make it rain!
                        [image_url] => URL_TO_SOME_IMAGE
                        [product_url] => 
                        [price] => 1
                        [data] => {"modified":{"product":"URL_TO_APP_CURR_WEBPAGE","product_title":"Fred Currency","product_amount":3,"credits_amount":1}}
                      )

             )
  [status] => placed
)

Unlike payments_status_update for placed item orders which have a preceding payments_get_items for the developer's item information, payments_status_update for earned app currency does not have a preceding payments_get_items.

As a result, the developer must JSON decode the order_details' items' 0th element's data field's value to understand the contents of the order.

JSON decoding the data value yields an array with the modified element.

The modified element contains an array following information:

  • product: A URL to app's currency object instance. The user is purchasing this app currency.

  • product_title: The title of app's currency.

  • product_amount: The integer amount of app currency to deposit into the user’s balance.

  • credits_amount: The integer credits amount which will be paid to the developer for fulfilling and settling the order.

JSON decoding the above example data value yields:

Array(
  [modified] => Array(
                  [product] => URL_TO_APP_CURR_WEBPAGE
                  [product_title] => Fred Currency
                  [product_amount] => 3
                  [credits_amount] => 1
                )
)

Developer Response

Developers should respond with the following information.

NameTypeDescriptionRequired
methodStringThe value payments_status_update.Yes
order_idStringThe order id for the order which was placed by the user.Yes
statusStringThe value settled or canceled. See below for details.Yes

The structure of the response is a JSON string whose contents contain an object with two fields.

  • The content field contains all of the above attributes except method and is represented as the 0th element of an array.

  • The method field contains the string payments_get_items.

Developers have two options:

1. Settle the placed order by:

  • Depositing the product_amount of the product into the user’s app currency balance.

  • Responding to this payments_status_update with settled. An example developer settled JSON string response,

{
  "content":{
    "status":"settled",
    "order_id":9006195253076
  },
  "method":"payments_status_update"
}
  • The developer is paid the credits_amount for the order and these transactions are represented as type S in the developer payout reports.

  • Facebook then makes a confirmation request to the callback, passing in the same data as in the previous (placed) request, except that the status will be settled. To confirm that you've fulfilled the order, respond with the precise same content that you returned for the previous (placed) call.

2. Or cancel the placed order by:

  • If the order is cancelled because of the order’s implicit exchange rate, developer are required to pass the parameter code and the value 131. An example developer canceled JSON string response,
{
  "content":{
              "status":"canceled",
              "code":131,
              "order_id":9006203669116
            },
  "method":"payments_status_update"
}
  • The user’s Facebook balance is credited with the credits_amount for the canceled order.

For both the settled and canceled response options, Facebook will return data to the client.

It’s possible for a user to complete multiple offers in a single Facebook offerwall dialog. Facebook only returns the last completed order_id to the client.

 

Order Status Update - Disputed Item Order

Facebook issues an order status update request after the user disputes an item order. An illustration describing the user dispute experience can be found here.

This notifies the app that a user's disputed item order is ready to be processed.

Facebook Request

To identify the type of request, inspect the POST parameter method for the value payments_status_update.

An example POST request body,

signed_request=qxvRyt82FDTSipYTu0CEnYp4aNDDGAci4jmQ...&
order_details={"order_id":9007249182704,"buyer":409697,
  "app":107032282669135,"receiver":409697,"amount":1,
  "time_placed":1330641001,"update_time":1330646619,
  "data":"","items":[{"item_id":"0","title":"100 FredCoins",
    "description":"Spend FredCoins for all things in FredLand.",
    "image_url":"http:\/\/www.inexpensivegold.com\/wp-content\/uploads\/2009\/12\/20-liberty-double-eagle.jpg",
    "product_url":"","price":1,"data":""}],
    "status":"disputed"}&
status=disputed&
order_id=9007249182704&
method=payments_status_update

After parsing the POST parameter signed_request value, the credits field contains an array with the following fields.

NameTypeValue
order_detailsJSON stringContains the developer's payments_get_items response information. See below for an example.
statusStringThe value disputed. This indicates that the user has disputed the order and that Facebook has reserved the funds from the user for this order.
order_idInteger64-bit Facebook order id. Parsing the signed_request can garble this value. Use the order_id in the above order_details field.

An example parsed and JSON decoded signed_request,

Array(
  [algorithm] => HMAC-SHA256
  [credits] => Array(
                 [order_details] => {"order_id":9007249182704,"buyer":409697,"app":107032282669135,"receiver":409697,"amount":1,"time_placed":1330641001,"update_time":1330646619,"data":"","items":[{"item_id":"0","title":"100 FredCoins","description":"Spend FredCoins for all things in FredLand.","image_url":"http:\/\/www.inexpensivegold.com\/wp-content\/uploads\/2009\/12\/20-liberty-double-eagle.jpg","product_url":"","price":1,"data":""}],"status":"disputed"}
                 [status] => disputed
                 [order_id] => 9007249182704
               )
  [expires] => 1330653600
  [issued_at] => 1330646620
  [oauth_token] => AAABhWGUwIE8BAH8cd...
  [user] => Array(
              [country] => us
              [locale] => en_US
              [age] => Array(
                         [min] => 21
                       )
            )
  [user_id] => 409697
)

JSON decoding the above example order_details value yields:

Array(
  [order_id] => 9007249182704
  [buyer] => 409697
  [app] => 107032282669135
  [receiver] => 409697
  [amount] => 1
  [time_placed] => 1330641001
  [update_time] => 1330646619
  [data] => 
  [items] => Array(
               [0] => Array(
                        [item_id] => 0
                        [title] => 100 FredCoins
                        [description] => Spend FredCoins for all things in FredLand.
                        [image_url] => http://www.inexpensivegold.com/wp-content/uploads/2009/12/20-liberty-double-eagle.jpg
                        [product_url] => 
                        [price] => 1
                        [data] => 
                      )
             )
  [status] => disputed
)

Developer Response

Developers cannot synchronously respond to payments_status_update requests with disputed status.

Developers must investigate the user's item order dispute and respond asynchronously using the Graph API.

After investigating a user's dispute, developers have two options:

1. Settle the disputed order after the developer has satisfactorily resolved the user's dispute.

To update the order status, developers should issue a POST request to the Graph API order id payments endpoint [order_id]/payments with the following parameters.

NameTypeValue
statusStringsettled.
messageStringThe reason for settling a user's disputed order.
accees_tokenStringAn app access token.

For example,

curl -F 'status=settled' -F 'message=the reason for settling a disputed order' 
  'https://graph.facebook.com/[order_id]?access_token=[app_access_token]'

These transactions are represented as type S in the developer payout reports.

2. Or refund the disputed order. The user cannot be made whole so refund the credits spent.

To update the order status, developers should issue a POST request to the Graph API order id payments endpoint [order_id]/payments with the following parameters.

NameTypeValue
statusStringrefunded.
messageStringThe reason for refunding a user's disputed order.
accees_tokenStringAn app access token.

For example,

curl -F 'status=refunded' -F 'message=the reason for refunding a disputed order'
  'https://graph.facebook.com/[order_id]?access_token=[app_access_token]'

These transactions are represented as type R in the developer payout reports.

 

Order Status Update - Refunded Item Order

Facebook occasionally refunds item orders. The disputes and chargebacks documentation describes the circumstances of Facebook initiated refunds.

This request notifies the developer that Facebook has refunded a user's item order and is purely for notification purposes. No developer response is required.

Facebook Request

To identify the type of request, inspect the POST parameter method for the value payments_status_update.

An example POST request body,

signed_request=JKGO2cquBoKG-ZPt_P5EEqrI8wUGgPmZUdcM...&
order_details={"order_id":9007142886185,"buyer":409697,
  "app":107032282669135,"receiver":409697,"amount":1,
  "time_placed":1329866240,"update_time":1329868837,
  "data":"","items":[{"item_id":"0","title":"100 FredCoins",
    "description":"Spend FredCoins for all things in FredLand.",
    "image_url":"http:\/\/www.inexpensivegold.com\/wp-content\/uploads\/2009\/12\/20-liberty-double-eagle.jpg",
    "product_url":"","price":1,"data":""}],
  "status":"refunded"}&
status=refunded&
order_id=9007142886185&
method=payments_status_update

After parsing the POST parameter signed_request value, the credits field contains an array with the following fields.

NameTypeValue
order_detailsJSON stringContains the developer's payments_get_items response information. See below for an example.
statusStringThe value refunded. This indicates that the order has been refunded.
order_idInteger64-bit Facebook order id. Parsing the signed_request can garble this value. Use the order_id in the above order_details field.

An example parsed and JSON decoded signed_request,

Array(
  [algorithm] => HMAC-SHA256
  [credits] => Array(
                 [order_details] => {"order_id":9007142886185,"buyer":409697,"app":107032282669135,"receiver":409697,"amount":1,"time_placed":1329866240,"update_time":1329868837,"data":"","items":[{"item_id":"0","title":"100 FredCoins","description":"Spend FredCoins for all things in FredLand.","image_url":"http:\/\/www.inexpensivegold.com\/wp-content\/uploads\/2009\/12\/20-liberty-double-eagle.jpg","product_url":"","price":1,"data":""}],"status":"refunded"}
                 [status] => refunded
                 [order_id] => 9007142886185
               )
  [expires] => 1329876000
  [issued_at] => 1329868837
  [oauth_token] => AAABhWGUwIE8BAKGqI...
  [user] => Array(
              [country] => us
              [locale] => en_US
              [age] => Array(
                         [min] => 21
                       )

            )
  [user_id] => 409697
)

JSON decoding the above example order_details value yields:

Array(
  [order_id] => 9007142886185
  [buyer] => 409697
  [app] => 107032282669135
  [receiver] => 409697
  [amount] => 1
  [time_placed] => 1329866240
  [update_time] => 1329868837
  [data] => 
  [items] => Array(
               [0] => Array(
                        [item_id] => 0
                        [title] => 100 FredCoins
                        [description] => Spend FredCoins for all things in FredLand.
                        [image_url] => http://www.inexpensivegold.com/wp-content/uploads/2009/12/20-liberty-double-eagle.jpg
                        [product_url] => 
                        [price] => 1
                        [data] => 
                      )

             )
  [status] => refunded
)

Developer Response

A payments_status_update with refunded status is purely for developer notification purposes. No developer response is required.

Developers may use these notifications to inform their internal representation of the order status.

 

PHP Example

<?php

$app_secret = 'APP_SECRET';

// Validate request is from Facebook and parse contents for use.
$request = parse_signed_request($_POST['signed_request'], $app_secret);

// Get request type.
// Two types:
//   1. payments_get_items.
//   2. payments_status_update.
$request_type = $_POST['method'];

// Setup response.
$response = '';

if ($request_type == 'payments_get_items') {
  // Get order info from Pay Dialog's order_info.
  // Assumes order_info is a JSON encoded string.
  $order_info = json_decode($request['credits']['order_info'], true);

  // Get item id.
  $item_id = $order_info['item_id'];

  // Simulutates item lookup based on Pay Dialog's order_info.
  if ($item_id == '1a') {
    $item = array(
      'title' => '100 some game cash',
      'description' => 'Spend cash in some game.',
      // Price must be denominated in credits.
      'price' => 1,
      'image_url' => 'http://some_image_url/coin.jpg',
    );

    // Construct response.
    $response = array(
                  'content' => array(
                                 0 => $item,
                               ),
                  'method' => $request_type,
                );
    // Response must be JSON encoded.
    $response = json_encode($response);
  }

} else if ($request_type == "payments_status_update") {
  // Get order details.
  $order_details = json_decode($request['credits']['order_details'], true);

  // Determine if this is an earned currency order.
  $item_data = json_decode($order_details['items'][0]['data'], true);
  $earned_currency_order = (isset($item_data['modified'])) ?
                             $item_data['modified'] : null;

  // Get order status.
  $current_order_status = $order_details['status'];

  if ($current_order_status == 'placed') {
    // Fulfill order based on $order_details unless...

    if ($earned_currency_order) {
      // Fulfill order based on the information below...
      // URL to the application's currency webpage.
      $product = $earned_currency_order['product'];
      // Title of the application currency webpage.
      $product_title = $earned_currency_order['product_title'];
      // Amount of application currency to deposit.
      $product_amount = $earned_currency_order['product_amount'];
      // If the order is settled, the developer will receive this
      // amount of credits as payment.
      $credits_amount = $earned_currency_order['credits_amount'];
    }

    $next_order_status = 'settled';

    // Construct response.
    $response = array(
                  'content' => array(
                                 'status' => $next_order_status,
                                 'order_id' => $order_details['order_id'],
                               ),
                  'method' => $request_type,
                );
    // Response must be JSON encoded.
    $response = json_encode($response);

  } else if ($current_order_status == 'disputed') {
    // 1. Track disputed item orders.
    // 2. Investigate user's dispute and resolve by settling or refunding the order.
    // 3. Update the order status asychronously using Graph API.

  } else if ($current_order_status == 'refunded') {
    // Track refunded item orders initiated by Facebook. No need to respond.

  } else if ($current_order_status == 'settled') {
    
    // Verify that the order ID corresponds to a purchase you've fulfilled, then…
    
    // Get order details.
    $order_details = json_decode($request['credits']['order_details'], true);

    // Construct response.
    $response = array(
                  'content' => array(
                                 'status' => 'settled',
                                 'order_id' => $order_details['order_id'],
                               ),
                  'method' => $request_type,
                );
    // Response must be JSON encoded.
    $response = json_encode($response);
    
  } else {
    // Track other order statuses.

  }
}

// Send response.
echo $response;

// These methods are documented here:
// https://developers.facebook.com/docs/authentication/signed_request/
function parse_signed_request($signed_request, $secret) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2);

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // check sig
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

function base64_url_decode($input) {
  return base64_decode(strtr($input, '-_', '+/'));
}
Updated about a month ago
Facebook © 2013 · English (US)
AboutAdvertisingCareersPlatform PoliciesPrivacy Policy