Handling Disputes and Refunds

There are occasional times when a user will wish to revoke a payment made in your app. As a developer, you are responsible for efficiently responding to such requests, providing a trustworthy and fair service to your customers. Facebook offers a mechanism for being alerted when a user disputes a transaction and suggests best practices for handling such disputes.

Facebook User Dispute Philosophy

Facebook's philosophy regarding payment disputes is that we will provide primary support for cases in which the user requests a full refund of the payment or the user contends a transaction directly with their funding provider (i.e. a credit card company or Paypal). However, when a user has an in-app purchasing issue, or does not receive a purchased item or currency, they should be routed directly to the developer. In the latter case, the developer is best equipped to satisfy the dispute, typically by issuing more or replacement in-app items, refunding the payment, or providing clarification on a delay to item delivery.

How Users Dispute a Transaction

The dispute resolution process is designed to provide the user and the developer with an easy way to communicate regarding a contended payment made using Facebook Payments.
The user is provided with links to dispute a transaction in multiple places across Facebook, all of which link to the Facebook Payments Support area of the Facebook Help Center. The payment dispute flow is either presented as a standalone web page, or as an overlay on top of your canvas app, depending on how the flow was invoked by the user.
The methods of invoking the dispute flow are enumerated below:
1. In-App Dispute Flow
2. User Payment Settings on Facebook.com
3. User Payment Settings via Receipt Email
Regardless of how the Facebook Payments Support flow is initiated, users are prompted to identify their issue by answering a series of multiple choice questions. Depending on the user's selections, they are directed to the appropriate contact, either Facebook or the developer.
As mentioned earlier on this page, Facebook's philosophy regarding payment disputes is that we will handle all disputes that imply that the user is requesting a full refund of the transaction (i.e. the "I accidentally purchased an item I do not want" option). On the other hand, if the user request is aimed at receiving the item or in-app currency that they've purchased, we will route the dispute to the developer (i.e. the "I didn't receive the game item(s) I purchased" option).
An example of this form is illustrated below. Here, the user has selected an issue best handled by the developer.
After the user has initiated a dispute, a realtime update is sent to the developer with the correspondingpayment_id for the disputed transaction. The developer can then query the Graph API to retrieve additional information regarding the transaction, including the user's email address, and their specified reason for initiating the dispute. It is then the developer's responsibility to use this information to communicate with the user and reach an agreed solution. This process is illustrated below:

Subscribing to Disputes

In an effort to provide the best payments experience possible for people on Facebook, after May 13, 2014, developers that accept payments in their apps will be required to subscribe and honor Realtime Updates for the payments object.
In order to receive updates when a user disputes a transaction in your app, you must first subscribe to the Payments Object for the Realtime Updates and supply a callback URL. This process is key to your ability to handle disputes and offer good customer service. By subscribing to this object, you will be sent an update to your callback along with the associated payment_id of the transaction whenever a user disputes a purchase.
2013-11-19 22:31:41 {"object":"payments","entry":[{"id":"471516296294882","time":1384900300,"changed_fields":["disputes"]}]}
You can then use the payment_id provided to query the Graph API for additional details regarding the dispute, from which you can communicate with the user to resolve the transaction.

Resolving a Dispute

As described above, when a user disputes an order, a realtime update is sent to the developer specified URL with the associated payment_id.
Additionally, as illustrated in the diagram above, once a dispute has been created by the user, Facebook will add additional information to the Graph API return data associated with the disputedpayment_id. These additional fields are combined under a disputes array as follows:
ParameterDescription
disputes/user_commentThe free text reason for the dispute entered by the user.
disputes/time_createdThe time in PST at which the user created the dispute.
disputes/user_emailThe user's preferred email address.
disputes/statusThe current status of the dispute.
disputes/reasonDispute resolution outcome’ (pendingrefunded_in_cash,granted_replacement_itemdenied_refundbanned_user)
These additional parameters give you the means to review the dispute, and optionally contact the user in order to resolve their issue.
A full sample response from the Graph API for a disputed transaction is below:
{
  "id": "519180411528475", 
  "user": {
    "name": "Marco Alvarez", 
    "id": "500535225"
  }, 
  "application": {
    "name": "Friend Smash", 
    "namespace": "friendsmashsample", 
    "id": "241431489326925"
  }, 
  "actions": [
    {
      "type": "charge", 
      "status": "completed", 
      "currency": "EUR", 
      "amount": "0.80", 
      "time_created": "2014-02-12T00:49:38+0000", 
      "time_updated": "2014-02-12T00:49:38+0000"
    }
  ], 
  "refundable_amount": {
    "currency": "EUR", 
    "amount": "0.80"
  }, 
  "items": [
    {
      "type": "IN_APP_PURCHASE", 
      "product": "https://ancient-savannah-6416.herokuapp.com/opengraph/coin.html", 
      "quantity": 10
    }
  ], 
  "country": "US", 
  "request_id": "ISgQj4vGrrnmhGyABL5IaRmeUAoYlL2BrMoMOnmbsFj7AxrNurHej3jeZZS3710k", 
  "created_time": "2014-02-12T00:49:38+0000", 
  "payout_foreign_exchange_rate": 1.343826, 
  "disputes": [
    {
      "user_comment": "I didn't get my Friend Smash coin! Please help!", 
      "time_created": "2014-02-12T01:37:27+0000", 
      "user_email": "email@domain.com", 
      "status": "pending", 
      "reason": "pending"
    }
  ]
}
After reviewing the user-provided reason for the dispute and optionally their transaction history and any additional correspondence, you may choose to settle the dispute by issuing a complete or partial refundor by updating the dispute status.
After a dispute is settled, Facebook recommends as a best practice, to communicate with the user the outcome of the dispute and any associated actions taken. You can choose to do this via the provided user email address and/or in-app messaging. This will ensure the best experience for people using your application.

Refunding a Payment

You may refund the user any amount less than or equal to the refundable_amount returned by the Graph API for a given payment_id. You can also issue additional refunds, as long as therefundable_amount remains greater than zero. Facebook does not offer the functionality to refund an amount greater than the purchase amount.
In order to issue a refund, make an HTTP POST call to the Graph API endpoint /PAYMENT_ID/refundswith an app access token, and the following parameters:
Parameters
NameDescriptionType
currencyThe three-letter ISO code of the currency in which the refund amount is specified; it must be the same as the currency in which the original purchase was denominated.string
amountThe amount to refundstring
reasonThe reason you are refunding this order. This is optional but if specified must be one of the following: MALICIOUS_FRAUDFRIENDLY_FRAUD,CUSTOMER_SERVICE. Providing any value other than those enumerated here will result in an error.string
Response
The response from Facebook will be true on success, or an error code otherwise. The payment object is then updated, with its actions field set to include details of the refund. The dispute status will automatically be set to resolved with the refunded_in_cash reason.
If the response from Facebook is true, the refund will be issued immediately. Different banks will vary in the time taken to settle the refund, typically a couple of days.
For complete details on how the payment object is changed after a refund is issued, please refer to thePayment Graph API reference doc.

Updating a Dispute's Status

There are several cases where settling a dispute does not require the developer to issue a monetary refund to the customer. For these special cases, Facebook provides a Disputes API, for settling a dispute and communicating the outcome with both the customer and Facebook. It also acts as a historical log of actions taken on each disputed transaction..
As mentioned earlier in this doc, the process of updating a dispute status is key to your ability to offer good customer service and keep your users satisfied.
As part of Facebook’s commitment to ensuring a positive experience for players of games on Canvas, developers that accept payments will be required to offer timely responses to any disputed transactions within their apps. From May 13th 2014, it will therefore be mandatory that developers make use of the Disputes API to inform Facebook of the outcome of each dispute that occurs within their product. After this date, Facebook will reserve the right to auto-refund any dispute not handled by the developer in a timely manner.
The status field of a dispute has two states: pending, after the consumer has disputed the transaction and is waiting on the developer to resolve it and resolved, after Facebook or the developer have settled the dispute.
After resolving a dispute, in order to update the status of a dispute, make an HTTP POST call to the Graph API endpoint /PAYMENT_ID/dispute with an app access token, and the following parameters:
NameDescriptionType
reasonThe reason you are settling this dispute. This is a required parameter and must be one of the following constants: GRANTED_REPLACEMENT_ITEM,DENIED_REFUNDBANNED_USER. Providing any value other than those enumerated here will result in an error.string
Response
The response from Facebook will be true on success, or an error code otherwise. The payment object is then updated, with its latest disputes status set to resolved with the specified reason.
The developer is allowed to update this field after it has been settled if they need to change the resolution reason.
After you've updated the dispute's status you can verify it by querying the Graph API on the/payment_id endpoint. Below is an example Graph API response for a payment transaction that has been resolved by the developer with a GRANTED_REPLACEMENT_ITEM reason:
{
  "id": "519180411528475", 
  "user": {
    "name": "Marco Alvarez", 
    "id": "500535225"
  }, 
  "application": {
    "name": "Friend Smash! Dev", 
    "namespace": "fsmashdev", 
    "id": "241431489326925"
  }, 
  "actions": [
    {
      "type": "charge", 
      "status": "completed", 
      "currency": "EUR", 
      "amount": "0.80", 
      "time_created": "2014-02-12T00:49:38+0000", 
      "time_updated": "2014-02-12T00:49:38+0000"
    }
  ], 
  "refundable_amount": {
    "currency": "EUR", 
    "amount": "0.80"
  }, 
  "items": [
    {
      "type": "IN_APP_PURCHASE", 
      "product": "https://ancient-savannah-6416.herokuapp.com/opengraph/coin.html", 
      "quantity": 10
    }
  ], 
  "country": "US", 
  "request_id": "ISgQj4vGrrnmhGyABL5IaRmeUAoYlL2BrMoMOnmbsFj7AxrNurHej3jeZZS3710k", 
  "created_time": "2014-02-12T00:49:38+0000", 
  "payout_foreign_exchange_rate": 1.343826, 
  "disputes": [
    {
      "user_comment": "I didn't get my Friend Smash coin! Please help!", 
      "time_created": "2014-02-12T01:37:27+0000", 
      "user_email": "mail@domain.com", 
      "status": "resolved", 
      "reason": "granted_replacement_item"
    }
  ]
}
For complete details on how the payment object is changed after a dispute is updated, please refer to the Payment Graph API reference doc.

Facebook-Initiated Refunds and Effect on Developer Revenue

In the examples above, the developer has been primarily responsible for handling a user dispute. There are however, circumstances in which Facebook will assume the primary point of contact for the user, typically in the case of user-confusion or fraud complaints.
Below is a simple description of how we classify refunds:
  • Non-fraud dispute: User request for monetary refund related to mistaken purchase or misuse of financial instrument by family or friend.
  • Malicious fraud charge dispute: Unauthorized purchase associated with a stolen financial instrument or compromised account.
For all non-fraud disputes, Facebook reviews a user's refund request on a case-by-case basis. Typically, non-fraud refund requests are as a result of user confusion, where the purchase was made accidentally due to a misunderstanding of the purchase flow. Our qualitative investigation examines factors including previous orders, spending frequency, and account level details. Facebook will refund the charges only if the user's reason for the dispute is deemed appropriate to receive a full reversal. Facebook monitors refund rates to protect against users who might attempt to defraud developers or Facebook by abusing the dispute resolution process.
For fraudulent charges made using a user's payment instrument brought to the attention of Facebook, we will always seek to fully refund a user as quickly as possible. Doing so prevents a user having to resort to a chargeback, and builds trust with honest users who may fall victim to fraud. If Facebook determines that the dispute is valid and that the user should be refunded, we will recover the cost of such a provision from the developer. Facebook does this by deducting the refunded amount from the next payout made to the developer at the end of the twice-monthly payout cycle. We will only do this for transactions disputed within 90 days of the the original transaction date.
As with disputes, you will be notified via a realtime update when Facebook refunds an order. Also, as before, additional information will be added to the Graph API return data for the payment. Rather than an additional disputes array, there will be a refund object added to the actions array, signifying the payment has been refunded.
Below is an example Graph API response for a payment transaction refunded by Facebook:
{
   "id": "3603105474213890",
   "user": {
      "name": "Daniel Schultz",
      "id": "221159"
   },
   "application": {
      "name": "Friend Smash",
      "namespace": "friendsmashsample",
      "id": "241431489326925"
   },
   "actions": [
      {
         "type": "charge",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-03-22T21:18:54+0000",
         "time_updated": "2013-03-22T21:18:55+0000"
      },
      {
         "type": "refund",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-03-23T21:18:54+0000",
         "time_updated": "2013-03-23T21:18:55+0000"
      }
   ],
   "refundable_amount": {
      "currency": "USD",
      "amount": "0.00"
   },
   "items": [
      {
         "type": "IN_APP_PURCHASE",
         "product": "http://www.friendsmash.com/og/friend_smash_bomb.html",
         "quantity": 1
      }
   ],
   "country": "US",
   "created_time": "2013-03-22T21:18:54+0000",
   "payout_foreign_exchange_rate": 1,
}

Chargebacks

A chargeback occurs when a user of your app contacts their payment provider directly (e.g., credit card company or PayPal) to dispute a charge. A chargeback can happen for a variety of reasons, including unauthorized use of a financial instrument, double billing, or non-receipt of a virtual good.
If the payment provider issues a refund, Facebook will recover the cost of the chargeback from the developer. Facebook does this by deducting the charged-back amount from the next payout made to the developer at the end of the twice-monthly payout cycle. Facebook will only do this if the chargeback occurs within 90 days of the original transaction. Beyond 90 days, Facebook will be responsible for the cost of the chargebacks unless:
  1. We determine you accepted the payment after breaching Facebook rules or policies.
  2. Your chargeback rate for any one of the prior three months exceeds 5% of your total transaction volume for that month.
As with refunds, you will also be notified via realtime update when a chargeback has been issued. There will additionally be a chargeback object added to the actions array of the Graph API return data for the payment, signifying the payment has been charged-back.
Below is an example of the Graph API return data for a payment that has been charged-back:
{
   "id": "3603105474213890",
   "user": {
      "name": "Daniel Schultz",
      "id": "221159"
   },
   "application": {
      "name": "Friend Smash",
      "namespace": "friendsmashsample",
      "id": "241431489326925"
   },
   "actions": [
      {
         "type": "charge",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-03-22T21:18:54+0000",
         "time_updated": "2013-03-22T21:18:55+0000"
      },
      {
         "type": "chargeback",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-05-20T21:18:54+0000",
         "time_updated": "2013-05-20T21:18:55+0000"
      }
   ],
   "refundable_amount": {
      "currency": "USD",
      "amount": "0.00"
   },
   "items": [
      {
         "type": "IN_APP_PURCHASE",
         "product": "http://www.friendsmash.com/og/friend_smash_bomb.html",
         "quantity": 1
      }
   ],
   "country": "US",
   "created_time": "2013-03-22T21:18:54+0000",
   "payout_foreign_exchange_rate": 1,
}

Declines

In certain cases Facebook will group small transactions into transaction bundles that will be captured and processed together. For these transactions, the bundle is processed when the user reaches a certain price threshold, after a set period of time or after a given number of transactions have been added to the bundle. Facebook retains control of these heuristics and will take steps to maximize the efficiency of the system across different currencies and markets. Larger transactions will continue to be processed and captured independently.
There is no additional work required to enable your application to start receiving bundled transactions. These types of transactions are handled automatically by Facebook and developers will continue to receive individual updates (via JavaScript and Realtime Updates) for each individual transaction. Bundled transactions are not exposed via the Graph API, but users can see bundled transactions on their payments history and on the transaction receipt.
A decline occurs when Facebook is unable to capture a bundled payment. Like a chargeback, if a transaction bundle is not able to be captured, Facebook will recover the cost of the declined payment from the developer. It will be at the developer's discretion as to how they want to handle the declined payment with customers.
Below is an example of the Graph API return data for a payment that has been declined:
{
   "id": "3603105474213890",
   "user": {
      "name": "Marco Alvarez",
      "id": "500535225"
   },
   "application": {
      "name": "Friend Smash",
      "namespace": "friendsmashsample",
      "id": "241431489326925"
   },
   "actions": [
      {
         "type": "charge",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2014-01-15T21:14:23+0000",
         "time_updated": "2014-01-15T21:14:24+0000"
      },
      {
         "type": "decline",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2014-01-22T21:12:28+0000",
         "time_updated": "2014-01-22T21:12:28+0000"
      }
   ],
   "refundable_amount": {
      "currency": "USD",
      "amount": "0.00"
   },
   "items": [
      {
         "type": "IN_APP_PURCHASE",
         "product": "http://www.friendsmash.com/og/friend_smash_coin.php",
         "quantity": 1
      }
   ],
   "country": "US",
   "created_time": "2014-01-15T21:14:23+0000",
   "payout_foreign_exchange_rate": 1,
}

Tracking Chargebacks, Refunds and Declines

By logging the realtime updates sent to your specified callback URL by Facebook, you can keep track of the disputes, chargebacks and declines for which you are responsible. Additionally we offer daily reports of payment activity through our Reporting API.
Additionally, at all times you can query the Graph API for Payments, which for a given transaction will return the latest action taken on the order, such as refundchargeback and decline.
Typically, a user will resort to a chargeback after they have requested a refund from the developer, and have not received a response in a timely manner. To limit chargebacks of this type and to be able to issue refunds accurately and with confidence, we recommend that you log detailed information regarding each transaction. This enables you to easily investigate user disputes as they arise and communicate detailed information with the user about their payment activity within your app.
Incurring chargebacks, refunds and declines is a normal part of operating any online business. Handling disputed transactions in an accurate, fair and timely manner is a responsibility of the developer as part of providing good customer service and maintaing user trust.
If there is reason for concern, please reach out to us via our Help Center and we will work with you to investigate your individual app or use-case.

Best Practices

Facebook allows developers to subscribe to realtime updates and call the graph API to get the latest status of transactions within their app. It is recommended that developers monitor, log and respond to these updates so that they can provide the best user experience possible.
If a transaction is declined, refunded or charge backed, it is up to the developer to decide how they want to handle these situations with their users. Some developers may choose to retract in-app purchases for users who end up not paying for they item. It may be appropriate to take different actions depending on the history and status of each transaction.
We recommend that if a developer decides to retract an in-app purchase from a user, that they inform the user of their action via an in-app message or through email. A declined, refunded, chargeback or dispute can be the result of insufficient funds, misunderstanding or miscommunication and many of these users may intend to keep using and purchasing from the app.

Fraud

Facebook takes fraudulent activity seriously and strives to minimize fraud with minimal impact to developer revenue. With high precision, we employ proactive methods to block fraudulent transactions, manually review potentially fraudulent cases and provide responsive, reactive support to users who have unauthorized charges made on their account.
Furthermore, we take steps to help honest users quickly regain access to their accounts, keeping them active on the Facebook platform, and by quickly refunding purchases made with suspected stolen funding sources. Conversely, we endeavour to eliminate malicious users by disabling payment functionality for those who commit fraudulent transactions via stolen funding sources or have excessive chargebacks or refund requests.

Next Steps

Your payment implementation should now be complete and working, with the ability to handle refunds and disputes within your system. Before taking your solution live, it's important that you performthorough testing of your user experience.
Was this document helpful?