Applies to: Disputes API | Payments API
Use the Disputes API to programmatically complete the dispute process.
To test your application without creating actual payment disputes with a bank, make calls to the Disputes API using the Square Sandbox. This topic walks through the following steps:
- Trigger a dispute in the Sandbox.
- Get new disputes.
- Respond by accepting or challenging the dispute.
- Verify the state of the dispute.
Important
Test disputes you create in the Square Sandbox aren't visible in the Developer Dashboard or Seller Dashboard. You can only access and manage them through the Disputes API. Actual payment disputes initiated by customers are visible to sellers in the Seller Dashboard.
The following flowchart outlines the steps of the dispute process and possible outcomes, beginning with the customer's initial chargeback request. For more information about the seller’s role in the dispute process and details about the use of each Disputes API endpoint in a production application, see Process Disputes.
To trigger a test dispute in the Square Sandbox, send a CreatePayment request with one of the following charge amounts. The Sandbox creates a Dispute
object whose reason
corresponds to the charge amount set.
Charge amount | Dispute reason |
---|---|
8801 | AMOUNT_DIFFERS |
8802 | CANCELLED |
8803 | DUPLICATE |
8804 | NO_KNOWLEDGE |
8805 | NOT_AS_DESCRIBED |
8806 | NOT_RECEIVED |
8807 | PAID_BY_OTHER_MEANS |
8808 | CUSTOMER_REQUESTS_CREDIT |
8809 | EMV_LIABILITY_SHIFT |
Note
The amounts shown are in the lowest denomination of the currency provided in the request. For example, USD is in cents.
The following Sandbox request creates a payment for the amount of $88.03 USD. This generates a Dispute
with the reason of DUPLICATE
. When testing payments in the Sandbox, you can use one of the test payment tokens as the source_id
in the request.
Create payment
The following is an example response:
{
"payment": {
"id": "BqzL87eLnz9gJRuoiIYSY44p9ORZY",
"created_at": "2022-05-02T15:08:42.217Z",
"updated_at": "2022-05-02T15:08:42.481Z",
"amount_money": {
"amount": 8803,
"currency": "USD"
},
"status": "COMPLETED",
"delay_duration": "PT168H",
"source_type": "CARD",
"card_details": {
"status": "CAPTURED",
"card": {
"card_brand": "VISA",
"last_4": "5858",
"exp_month": 5,
"exp_year": 2024,
"fingerprint": "sq-1-il5Ik5fUhNr9fTjLEWcZWaLpV0Ozij13Sry1jvqRiybpgAgbv4rOT3DPxVjs_tJOzQ",
"card_type": "CREDIT",
"prepaid_type": "NOT_PREPAID",
"bin": "453275"
},
"entry_method": "KEYED",
"cvv_status": "CVV_ACCEPTED",
"avs_status": "AVS_ACCEPTED",
"statement_description": "SQ *DEFAULT TEST ACCOUNT",
"card_payment_timeline": {
"authorized_at": "2022-05-02T15:08:42.327Z",
"captured_at": "2022-05-02T15:08:42.482Z"
}
},
"location_id": "L1HN3ZMTZEB87",
"order_id": "QKE7BmUeP58xIxdVeL4ps2CQ5c4F",
"risk_evaluation": {
"created_at": "2022-05-02T15:08:42.327Z",
"risk_level": "NORMAL"
},
"total_money": {
"amount": 8803,
"currency": "USD"
},
"approved_money": {
"amount": 8803,
"currency": "USD"
},
"receipt_number": "7tMe",
"receipt_url": "https://squareupsandbox.com/receipt/preview/7tMeeuCCMOF3Xh1iRyGmdd1MuSBZY",
"delay_action": "CANCEL",
"delayed_until": "2022-05-09T15:08:42.217Z",
"application_details": {
"square_product": "ECOMMERCE_API",
"application_id": "sandbox-sq0idb-TINhb_yF4yhyks_OiADYzA"
},
"version_token": "iI6Z7ot8md2wc9V6Xp0sF2hBdiKzT4f2LxcANqA86yw6o"
}
}
Your application receives new Dispute
objects by listening for the dispute.created webhook or by calling the ListDisputes endpoint.
If you set up a subscription for disputes webhooks, your listening endpoint receives a dispute.created
notification whenever a new dispute is created. The body of the notification contains the new Dispute
object.
{
"merchant_id": "MGYG72TMMXMCQ",
"location_id": "L1HN3ZMTZEB87",
"type": "dispute.created",
"event_id": "4f5cf45b-ff26-4ec1-b720-4d4e934883f9",
"created_at": "2022-05-02T15:08:42.217Z",
"data": {
"type": "dispute",
"id": "OWo09e15R49UrfXjG5Bod",
"object": {
"dispute": {
"amount_money": {
"amount": 8803,
"currency": "USD"
},
"brand_dispute_id": "P9td9draSX6ACrUO3KEI6Q",
"card_brand": "VISA",
"created_at": "2022-05-02T15:08:42.217Z",
"disputed_payment": {
"payment_id": "BqzL87eLnz9gJRuoiIYSY44p9ORZY"
},
"due_at": "2022-05-16T00:00:00.000Z",
"id": "OWo09e15R49UrfXjG5Bod",
"location_id": "L1HN3ZMTZEB87",
"reason": "DUPLICATE",
"reported_at": "2022-05-02T15:08:42.217Z",
"state": "EVIDENCE_REQUIRED",
"updated_at": "2022-05-02T15:40:42.978Z"
}
}
}
}
If you don't want to use webhook notifications, you can make periodic calls to ListDisputes. An unfiltered request returns all disputes, so it might be helpful to filter the request to only return disputes awaiting seller action.
Important
A seller typically has 14 days or less to respond to a new dispute. Depending on how often your application calls ListDisputes
, information about disputes might be delayed getting to sellers. Consider implementing webhook notifications to receive dispute data as it is created.
The following ListDisputes request is filtered to return only open disputes in the EVIDENCE_REQUIRED
state (that is, awaiting seller action):
List disputes
The following sample response shows two disputes: the DUPLICATE
dispute created in the previous step and a dispute with the reason
of NOT_RECEIVED
. Both are awaiting action.
{
"disputes": [
{
"amount_money": {
"amount": 8803,
"currency": "USD"
},
"reason": "DUPLICATE",
"state": "EVIDENCE_REQUIRED",
"due_at": "2022-05-16T00:00:00.000Z",
"disputed_payment": {
"payment_id": "BqzL87eLnz9gJRuoiIYSY44p9ORZY"
},
"card_brand": "VISA",
"created_at": "2022-05-02T15:08:42.217Z",
"updated_at": "2022-05-02T15:08:42.481Z",
"brand_dispute_id": "P9td9draSX6ACrUO3KEI6Q",
"location_id": "L1HN3ZMTZEB87",
"id": "OWo09e15R49UrfXjG5Bod",
"reported_at": "2022-05-02T00:00:00.000Z"
},
{
"amount_money": {
"amount": 8806,
"currency": "USD"
},
"reason": "NOT_RECEIVED",
"state": "EVIDENCE_REQUIRED",
"due_at": "2022-06-16T00:00:00.000Z",
"disputed_payment": {
"payment_id": "rRozdpYme93hXWPPUIXEjvB8kdVZY"
},
"card_brand": "VISA",
"created_at": "2022-06-02T15:46:06.585Z",
"updated_at": "2022-06-02T15:52:28.759Z",
"brand_dispute_id": "PGAM7Z22So2Y5kZVYCEbQA",
"version": 2,
"location_id": "L1HN3ZMTZEB87",
"id": "yVD4obqS9rn7Zrr9MIS3P",
"reported_at": "2022-06-02T00:00:00.000Z"
}
]
}
Important
- If the
due_at
deadline passes with no action from the seller, Square automatically challenges the dispute on the seller’s behalf. - If a seller takes an initial action on a dispute by using the Disputes Dashboard, the dispute state changes to
PROCESSING
and your application cannot take further action.
Sellers respond by either accepting or challenging the dispute.
To accept the dispute on behalf of a seller, have your application call AcceptDispute. This isn't reversible. If a dispute is accepted, it cannot be challenged later.
Accept dispute
The following response shows that the state
of the test dispute has changed to ACCEPTED
:
{
"dispute":{
"amount_money": {
"amount": 8803,
"currency": "USD"
},
"reason": "DUPLICATE",
"state": "ACCEPTED",
"due_at": "2022-05-16T00:00:00.000Z",
"disputed_payment": {
"payment_id": "BqzL87eLnz9gJRuoiIYSY44p9ORZY"
},
"card_brand": "VISA",
"created_at": "2022-05-02T15:46:06.585Z",
"updated_at": "2022-05-02T15:52:28.759Z",
"brand_dispute_id": "PGAM7Z22So2Y5kZVYCEbQA",
"version": 2,
"location_id": "L1HN3ZMTZEB87",
"id": "OWo09e15R49UrfXjG5Bod",
"reported_at": "2022-05-02T00:00:00.000Z"
}
}
Challenging a dispute using the Disputes API is a two-step process:
- Upload evidence - Your application provides one or more pieces of evidence related to the payment. These can be images, PDFs, or text. For more information about the requirements and best practices for uploading evidence, see Uploading evidence.
- Submit the evidence - Your application calls the SubmitEvidence endpoint to submit the provided evidence to the bank.
For testing purposes, disputes managed in the Square Sandbox can be WON
or LOST
by submitting a piece of evidence with the name evidence_won or evidence_lost. Submitting any of the allowed file types with either of these names causes an automatic WON
or LOST
state change.
Suppose you're testing a sample dispute in the Sandbox with the reason
of NOT_RECEIVED
. The following example call to CreateDisputeEvidenceFile uploads an image delivery-confirmation.png as PROOF_OF_DELIVERY_DOCUMENTATION
.
Create dispute evidence file
To complete testing and trigger an automatic WON
or LOST
state for the dispute, make another call to CreateDisputeEvidenceFile
and include a file of the application/pdf
type named evidence_won.pdf (to test a winning dispute state) or evidence_lost.pdf (to test a losing dispute state).
Create dispute evidence file
Finally, submit the evidence using the SubmitEvidence endpoint. Don't call SubmitEvidence
for each piece of uploaded evidence. Call the endpoint after the complete body of evidence has been uploaded to Square. By calling SubmitEvidence
, the challenge process starts and you can no longer add or remove evidence.
Submit evidence
The following is an example response:
{
"dispute": {
"amount_money": {
"amount": 8806,
"currency": "USD"
},
"reason": "NOT_RECEIVED",
"state": "PROCESSING",
"due_at": "2022-06-16T00:00:00.000Z",
"disputed_payment": {
"payment_id": "rRozdpYme93hXWPPUIXEjvB8kdVZY"
},
"card_brand": "VISA",
"created_at": "2022-06-02T16:38:37.460Z",
"updated_at": "2022-06-03T15:36:53.297Z",
"brand_dispute_id": "P9td9draSX6ACrUO3KEI6Q",
"version": 5,
"location_id": "L1HN3ZMTZEB87",
"id": "yVD4obqS9rn7Zrr9MIS3P",
"reported_at": "2022-06-02T00:00:00.000Z"
}
}
After a seller submits evidence to challenge a dispute, the state
changes to PROCESSING
while the bank deliberates. Your application can listen for the dispute.state.updated
webhook notification to receive the most timely notification when a bank responds to the dispute challenge.
When testing the Disputes API in the Square Sandbox, you can cause a dispute state change to WON
or LOST
by submitting a piece of evidence named evidence_won or evidence_lost, respectively. Because there is no bank involved in Sandbox disputes, if you submit a dispute without any evidence with these names, the state changes to PROCESSING
, but doesn't resolve.
In the previous step, delivery-confirmation.png and evidence_won.pdf were submitted as evidence for a dispute. The state
changes to WON
, and the webhook notification contains the following data:
{
"merchant_id": "MGYG72TMMXMCQ",
"location_id": "L1HN3ZMTZEB87",
"type": "dispute.state.updated",
"event_id": "a6c77a1e-d426-4659-a585-db13fbd76c12",
"created_at": "2022-06-02T14:55:09.831Z",
"data": {
"type": "dispute",
"id": "yVD4obqS9rn7Zrr9MIS3P",
"object": {
"dispute": {
"amount_money": {
"amount": 8806,
"currency": "USD"
},
"brand_dispute_id": "P9td9draSX6ACrUO3KEI6Q",
"card_brand": "VISA",
"created_at": "2022-06-02T16:38:37.460Z",
"disputed_payment": {
"payment_id": "rRozdpYme93hXWPPUIXEjvB8kdVZY"
},
"due_at": "2022-06-16T00:00:00.000Z",
"id": "yVD4obqS9rn7Zrr9MIS3P",
"location_id": "L1HN3ZMTZEB87",
"reason": "NOT_RECEIVED",
"reported_at": "2022-06-02T00:00:00.000Z",
"state": "WON",
"updated_at": "2022-06-02T14:55:09.831Z",
"version": 6
}
}
}
}
Another way to receive information about a dispute is to call RetrieveDispute with a dispute ID. Note that it might take a bank several days or more to respond to a dispute challenge. Therefore, if your application regularly queries for information about open disputes, it might take time to receive new information.
Retrieve dispute
The following is an example response:
{
"dispute": {
"amount_money": {
"amount": 8806,
"currency": "USD"
},
"reason": "NOT_RECEIVED",
"state": "WON",
"due_at": "2022-06-16T00:00:00.000Z",
"disputed_payment": {
"payment_id": "rRozdpYme93hXWPPUIXEjvB8kdVZY"
},
"card_brand": "VISA",
"created_at": "2022-06-02T16:38:37.460Z",
"updated_at": "2022-06-03T15:36:53.297Z",
"brand_dispute_id": "PGAM7Z22So2Y5kZVYCEbQA",
"version": 6,
"location_id": "L1HN3ZMTZEB87",
"id": "yVD4obqS9rn7Zrr9MIS3P",
"reported_at": "2022-06-02T00:00:00.000Z"
}
}