Respond To Disputes
The Disputes resources represent chargebacks and inquiries.At a high level, disputes occur when a payer disputes a charge with their credit card issuer. When the payer takes this action, the dispute process begins and:
- The credit card issuer notifies us, and we debit the merchant account for the amount.
- Your platform then receives a Notification, which contains the Dispute ID, merchant information, and the reason for a dispute. You consume the amount and inform your merchant. Find out more about differing amounts here.
- Your platform provides UI for merchants to upload documentation.
- When merchants upload a document, you call the WePay Javascript library to process and store the documents.
- We back-end store the document, and return the ID of the document.
- You call the disputes endpoint, with the IDs, and the merchant's explanation for the dispute.
- We return a notification to your platform at a point later in time, informing you if the dispute has been won or lost.
- You communicate to your merchant with the status of the dispute.
disputes.created
notification (assuming you've subscribed). In most cases, the disputes.created
notification will be immediately followed by the disputes.funds_withdrawn
notification.Note
When a Payment using a card from a different currency from the merchant's currency (i.e. a card in the UK paying a merchant in the United States) receives a Dispute, exchange rates will come in to play. At the time of initial payment, the exchange rate at that time is applied. When a Dispute occurs, the exchange rate might be different and that exchange rate will be applied to the Dispute. As such, the disputed amount may be greater or less than the initial amount paid.
Chargebacks
A chargeback (also known as a reversal) is a form of consumer protection where card holders may file a complaint with their card issuer about a specific transaction on their statement. Once the card holder files a complaint, the issuing bank starts an investigation which includes crediting the funds back to the card holder's account. Once the credit is requested, we debit the merchant account for the required amount.
Essentially, the chargeback life cycle looks like this:
When a chargeback for a WePay payment occurs:
- We will send a
disputes.created
and adisputes.funds_withdrawn
notification (be sure to subscribe).- If you have taken ownership of end user emails, then you, the platform, are responsible for the required communications about the chargeback with the merchant and payer, per the Send End User Emails guide.
- All fees are reversed (identical to a full refund).
- A $15 non-refundable chargeback fee is applied.
- The chargeback net (full amount minus fees) and chargeback fee are deducted from the merchant account.
Inquiries
An inquiry is a pre-chargeback phase specific to AmericanExpress. This phase allows AmericanExpress to investigate prior to crediting the card holder. That said, we preemptively debit the merchant until the inquiry is resolved. The inquiry life cycle is the same as the chargeback life cycle.
Inquiries should be responded to just like chargebacks; this is a chance for the merchant to explain the charge before AmericanExpress requires a credit, and the process of returning inquiry funds to a merchant is much smoother.
If AmericanExpress determines that the payment should be credited back to the payer, then the inquiry will be closed and a dispute with"type": "chargeback"
will be issued. When an inquiry rolls into a chargeback, it goes through the chargeback life cycle again.When a merchant receives a dispute, they can respond to it in one of two ways:
You must build out UIs enabling your merchants to respond to disputes.
Challenge a Dispute
A merchant will challenge a dispute when they feel the payment should not be credited back to the payer. This process requires supporting documentation, and acceptable forms are listed here and explained below:Documentation Type | Notes |
---|---|
cancelation_request | Evidence that the payer requested a cancellation, and the outcome of that request. |
contract | The contract between the merchant and payer showing the agreed-upon amount of payment and services/goods. |
correspondence | Communication between the merchant and payer. |
item_description | The public item description which was available prior to purchase. |
itemized_receipt | An itemized receipt showing the components of the total purchase amount. |
invoice | The invoice sent to the payer describing services/goods and the total payment amount and date. |
ip_logins | Logs with the payer's IP to determine whether an account takeover occurred. |
proof_of_credit | If a refund/credit was already provided to the payer, provide credit documentation. |
return_policy | A copy of the merchant's return policy which must be presented prior to purchase and publicly available. |
refund_policy | A copy of the merchant's refund policy which must be presented prior to purchase and publicly available. |
signed_contract | The contract between the merchant and payer showing the agreed-upon amount of payment and services/goods, signed by the payer. |
tracking | For shipped goods, provide the tracking number. |
written_rebuttal |
Important
The supporting documentation for a challenge must be submitted to us for review within 5 days of the chargeback.
Step 1: Gather Information
Create a WePay document object for each document the merchant wishes to submit. Load the WePay Helper JavaScript Library on the page where you present your document upload UI to the merchant. CallWePay.documents.create
for each .jpg, .jpeg, .png, or .pdf file being uploaded. Note that each file has a size limit of 10MB, and a null
file cannot be created.Note
Documents have a time-to-live (TTL) of 24 hours, after which, the document's ID will become invalid, and the merchant will have to re-upload their documentation.
WePay.documents.create
request should look like this:WePay.documents.create(body, headers
,function(response){
console.log(response); // You can see response in the console
});
The console response will contain document IDs to use in the next step.
At some point in your chargeback challenge UI, provide a text input for the merchant to submit their written statement explaining the challenge.
Step 2: Submit Information
To challenge a dispute, update the dispute by sending aPOST /disputes/id
request with an array of document IDs and the merchant's written statement:curl -X POST \
/disputes/47521346-c054-11e7-abc4-cec278b6b50a \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
-d '{
"documentation": {
"documents": ["docu-abc123", "docu-efg456", "docu-hij789"],
"explanation": "lorem ipsum dolores umbridge"
}
}'
status
will return as pending_wepay_review
.Typically, reviews will be completed within 10 days at which point we will either fight the chargeback or close it for the payer.
- If we fight the chargeback, evidence will be forwarded to back-end processors and the card networks. The dispute
status
will becomeawaiting_chargeback_decision
. - If we decide to close the chargeback for the payer, the dispute
status
will becomeresolved
with aresolution.type
oflost
.
Once we submit evidence to fight a dispute, issuers have 30-45 days to make a decision -- although some cases may take as long as 120 days to resolve.
Concede to a Dispute
A merchant will concede a dispute when they feel it is warranted. Once a dispute has been conceded, it cannot be challenged. Experienced merchants will already know about the chargeback process and will most likely understand the terminology, but it's important to offer education and ask for confirmations in your UI when a merchant requests to concede a chargeback.
The concede API request does not require documentation or explanation, and will look like this:curl -X POST \
/disputes/47521346-c054-11e7-abc4-cec278b6b50a/concede \
-H "App-Id: 121212" \
-H "App-Token: prod_MTAwXzk5OWIwZT666LWYwNWItNDU4MS1iZjBiL" \
-H "Api-Version: 3.0" \
-H "Content-Type: application/json" \
status
of resolved
and a resolution
structure like this:{
"resolution": {
"resolution_time": 1566932448, // Unix timestamp of resolution
"type": "lost"
}
}