Use this guide to learn more about commons uses and relative best practices for managing your orders.
Facebook works with payment processors (such as PayPal) who act as merchant of record.
The merchant of record is responsible for any outstanding credits or debits from your buyer payment credentials. This means that at any time, no order payment details will be available in your ecommerce system. Your order management system should assume that acknowledged orders are prepaid by the seller and process it accordingly in your back office. Most order management systems have a payment flow to support prepaid orders.
Prepaid orders may behave differently in your order management system. As such, we highly recommend to:
Orders that can’t be cleared from buyer risk/sanctions potentially remain for a longer time in the FB_PROCESSING state
and cannot be acknowledged. These orders can be canceled after 24 hours.
You can acknowledge orders individually or in batches.
If you expect a high volume of orders, we recommend that you acknowledge them in batches. If you acknowledge them individually, you might exceed our Page rate limits. If you go over the rate limits, your API calls will be throttled.
To process orders in batches, use our bulk acknowledgement method.
No order payment details will be available in your ecommerce system or OMS. Consider which payment method to use (example: pre-paid order
) and what payment method name (example: Paid on Instagram
) will be displayed in your systems and on order invoices.
Consider how often new orders are pulled from the API. A typical frequency is every 5-15 minutes.
Decide when to create orders in your system and manage state accordingly. Orders typically flow through the following workflow:
PENDING
state in your ecommerce platform or OMS.PROCESSING
state in your system. Do not attempt to move state on an order without successful acknowledgement.
Facebook orders are of variant length. Use an appropriate data type in your ecommerce platform, OMS, and any other downstream order fulfillment system. The recommended data type is string (varchar).
Implement a retry and error handling strategy for order updates.
To avoid duplicates, ensure that an order with the given Facebook ID does not exist in your system before creating a new order. As a best practice, use a secondary lookup column for Facebook IDs.
Define whether a self-serve shop UI will be used to manage orders.
Define how order transactional emails will be suppressed in your ecommerce platform or OMS, as Instagram will be sending transactional updates to the buyers on your behalf.
Define how to handle marketing opt-in flag and integrate with your CRM. Customers should not receive any marketing emails unless explicitly opted-in.
Inventory can change very quickly, especially for highly sought items. To ensure that buyers have a good checkout experience, we recommend to allocate inventory early to avoid overselling, which can lead to canceled orders.
When an order is first created, it is in the FB_PROCESSING state
. Between the FB_PROCESSING
to CREATED
state, it can generally take up to 30 minutes to complete the transition and inventory can change during this period.
You can pull the order details during FB_PROCESSING
to lock the inventory first. The buyer information is not shared during this state, but product details are available. Sellers can request for such information and reserve the products in their order management system early to avoid overselling.
Distributed systems required methods to confirm completed and retry methods for uncompleted transactions without side effects. The idempotency key is the identifier used to provide this capability in the Commerce Platform.
Requests that change the state of your shop requires an idempotency key. Examples of such requests are acknowledge/fulfill an order, send a refund, and any other POST
/PUT
/DELETE
request. This key should be a globally unique identifier, a simple way to achieve this uniqueness is using a version 4, pseudo-random identifier (see RFC 4122) and supported by most programming languages:
By not using a globally unique identifier as your idempotency key, you can expect the following side effects:
idempotency_key
have the same effect as making a single request; for example, they will not be executed again and will return the exactly same response as the original request.idempotency_key
will throw an error. For more information, see Design with Fault Tolerance.
merchant_order_reference
ImmutabilityWhen acknowledging orders, you have the option to add the merchant_order_reference
field, which represents the order ID in your order management system.
In some order management systems, this ID may change as the order transitions from the created to a fulfilled state. You should enforce either:
Distributed systems required methods to confirm completed and retry methods for uncompleted transactions without side effects.
The Commerce Platform acts as an idempotent receiver where messages have the same effect whether it is received once or multiple times if they share the idempotency key. This means that a message can safely be resent without causing any problems even if the Commerce Platform receives duplicates of the same message.
For example, a message can receive a timeout, be lost, or a failure in the Requestor-side may happen before it can store the response. In these examples, the Requestor cannot distinguish this scenario from one where the message got lost and can only resend the message. On the other hand, the Commerce platform may receive the same request which was already processed before.
To address these challenges, the system consuming the Commerce Platform should make use of the idempotency key, where each new request should use a globally unique identifier and any retry requests should use the same idempotency key used in the original request. See Enforce Global Idempotency Key uniqueness.
Use a max retry count to avoid flooding the Commerce Platform with failing requests. Not doing so may cause your application to eventually hit the rate limit for your application and be blocked to send new requests. After a message hits the max retry count, it could trigger a notification to your operations team to review the Requestor’s and Commerce Platform’s health.
Use an exponential backoff where retry attempts have a waiting time and timeout increasing by a factor; for example, requests have a 10-second timeout the first attempt, and a 20-second timeout in the next attempt. The first retry happens 10 minutes after the original request; the second retry happens 20 minutes later.
Use a circuit-break behavior where if a given rate of messages fails when calling the Commerce Platform, it will trigger a notification to your operations team. Queue these messages for future processing as the health of the Requestor and/or Commerce Platform are restored.
If your application is subscribing to webhooks, prepare your application to handle duplicate messages sent by the Commerce Platform.
Given the payload in the following example, your application should use the id
field to validate if the message was processed before (for example, likely the idempotency key). You can also use the time
field to track when the webhook notification was first sent.
Example
{ entry:[ { id: 1942543229149327, // unique webhook id time: 1566839325, // time when this webhook notification was first sent changes:[ { // suppressed for readability } ] } ] }
All text exposed by the Commerce Platform is Unicode.
Some legacy systems may not have full Unicode support. Some examples can include legacy systems that are able to only handle ASCII characters or locale specific encodings (for example, ISO/IEC 8859-1, supporting only Latin characters).
To provide the best buyer experience, you should handle these fields as Unicode. Failing to do could result in interacting with the buyer using a name they had not consented to.
If this is not possible, the best alternative is use the equivalent library in your dev environment to PHP/*nix
iconv
, which transliterates strings to the desired target encoding:
<?php //some German $utf8_sentence = 'Weiß, Goldmann, Göbel, Weiss, Göthe, Goethe und Götz'; //US setlocale(LC_ALL, 'en_US'); //transliterate $trans_sentence = iconv('UTF-8', 'ASCII//TRANSLIT', $utf8_sentence); //gives [Weiss, Goldmann, Gobel, Weiss, Gothe, Goethe und Gotz] //which is our original string flattened into 7-bit ASCII as //an English speaker would do it (ie. simply remove the umlauts) echo $trans_sentence . PHP_EOL; ?>
Learn more about Order Management, Commerce Platform.
If you're an API seller who has lost access to your API connection and want to manually process the orders from Commerce Manager, you need to first delete the existing API connection using the DELETE
request to the https://graph.facebook.com/{cms-id}/order_management_apps
endpoint.
Example
{ "error": { "message": "(#803) Some of the aliases you requested do not exist: {cms-id}", "type": "OAuthException", "code": 803, "fbtrace_id": "AXDusJwgK_--o5FnIZkGBu8" } }