Wallet Disputes
Review the disputes your wallet holders open, talk to them, decide each case, and carry out the outcome.
A holder can dispute an entry on their wallet: a card load that went wrong, or a charge you made. You are the first to decide the case. This page walks through the lifecycle, from the holder filing a dispute to the money moving.
Before you start
- You run a wallet program, and your credential has the Wallet Management permission. See Access to wallets and payment requests.
- Register the dispute webhooks with Add Webhook:
wallet-dispute-opened,wallet-dispute-status-changedandwallet-dispute-message-added.
How a dispute starts
The holder files a dispute from their wallet against one entry, with a reason (unauthorized, duplicate-charge, incorrect-amount, not-credited or other), the amount they claim, and an optional statement. A holder can only have one live dispute per entry, and only within the dispute window of your program. Disputes have IDs starting with DS-.
Payment Labs then sends wallet-dispute-opened. The webhook's data is the dispute as it is at delivery time.
Statuses
status | Meaning | Final? |
|---|---|---|
open | Filed, nobody is reviewing it yet. | No |
under-review | You picked it up. | No |
needs-more-info | You asked the holder for information. They have 7 days to reply. | No |
accepted | You agreed an outcome and amount. The money moves when you resolve it. | Final decision |
declined | You declined it, with a reason the holder reads. | Yes |
withdrawn | The holder cancelled it. | Yes |
expired | The holder did not reply to your request for information within 7 days. | Yes |
superseded-by-chargeback | The holder's bank took the money back through a card chargeback first. | Yes |
open ──pick up──► under-review ◄──holder replies── needs-more-info
│ │ └──request information──────────►│
│ │ └──no reply in 7 days──► expired
└───────────────────┴──► accepted ──resolve──► money moves
└──► declined
Every status change sends wallet-dispute-status-changed.
Step 1: Find and read disputes
- Search with Search Wallet Disputes. Filter on
statusGroupto build a work queue:open(statusesopenandneeds-more-info),under-review, orresolved(every final status). You can also filter ondisputeId,holderId,subjectEntryId,statusandcreatedAt. - Read one with Get Wallet Dispute. Besides the dispute it returns
holderIdandtakenOver. - Find the disputed entry with Search Wallet Entries, filtering
entryIdon the dispute'ssubjectEntryId.
Step 2: Pick it up
Pick Up Wallet Dispute moves an open (or needs-more-info) dispute to under-review, so the holder sees that someone is looking at it. It has no body.
Step 3: Talk to the holder
The dispute has one conversation that you and the holder both read.
- Read it: List Wallet Dispute Messages. Each message has an
authorRole(holderorpayor) and its attachments. - Write: Create Wallet Dispute Message with a
body(up to 2,000 characters) and up to 5attachments(JPEG, PNG or PDF, up to 6 MB each).
{
"body": "Please send the card statement that shows this load.",
"attachments": [{ "mimeType": "application/pdf", "fileName": "load-receipt.pdf", "size": 48213 }]
}The response is 201 with one upload per declared file. Send each file with a PUT to its uploadUrl, with the uploadHeaders exactly as given and Content-Type set to the file's mimeType. The file must be exactly the declared size. Upload and download links last one hour.
Your messages never change the status. To require an answer, use the next step.
- Ask for information: Request Wallet Dispute Information moves an
openorunder-reviewdispute toneeds-more-infoand setsresponseDueAtto 7 days from now. Send a message first that says what you need. When the holder replies, the dispute returns tounder-review. If they do not, it becomesexpired.
Every new message sends wallet-dispute-message-added, with the dispute and the new messageId.
Step 4: Decide
Before you accept, call Get Wallet Dispute Resolution Options. It lists the outcomes the disputed entry allows and the most each can pay:
| Disputed entry | Outcomes you can choose |
|---|---|
| One of your charges | wallet-credit |
| A card load that was credited to the wallet | card-refund, wallet-credit |
| A card load that was never credited to the wallet | complete-credit, card-refund |
| Outcome | What resolving it does |
|---|---|
card-refund | Refunds the amount to the holder's card, out of the load. |
wallet-credit | Credits the amount to the holder's wallet from your funds. Needs a batch when you resolve. |
complete-credit | Books the credit that the load never received. |
Then either:
-
Accept: Accept Wallet Dispute with the outcome and the agreed amount, in minor units of the dispute's currency (
1500= $15.00), at least 1 and no more than the claim.{ "outcome": "card-refund", "amount": 1500 }Accepting records your decision and moves the dispute to
accepted. It does not move money. The outcome is checked only when you resolve, so choose it from the resolution options. -
Decline: Decline Wallet Dispute with a
reason(up to 2,000 characters) that the holder reads. The dispute moves todeclined.
You can accept or decline from open, under-review or needs-more-info.
Step 5: Resolve
Resolve Wallet Dispute carries out the accepted outcome and moves the money.
{ "batchId": "B-01JDA1B2C3D4E5F6G7H8J9K0M1" }batchIdis required forwallet-credit(the credit is paid as a virtual payment in that batch) and ignored otherwise. Send an empty body for the other outcomes.- Retrying is safe: a
card-refundorwallet-creditretry returns the same result and never moves money twice. A repeatedcomplete-creditis refused with409 DISPUTE_OUTCOME_NOT_PERMITTED, because the load is already credited. - If the load can no longer pay for the outcome, for example because the holder spent it, the call returns
409 DISPUTE_RESOLUTION_ESCALATED. The dispute staysacceptedand Payment Labs takes it from there.
When Payment Labs takes over
Payment Labs can take over a live dispute. takenOver is then true on Get Wallet Dispute, and pick-up, request information, accept and decline return 409 DISPUTE_NOT_ADJUDICABLE. You can still read the dispute and its messages.
Errors and edge cases
| Error | Operation | Meaning |
|---|---|---|
404 NOT_FOUND | All | The dispute does not exist or is not in your program. |
409 DISPUTE_NOT_ADJUDICABLE | Pick up, request information, accept, decline | The dispute is in a status that does not allow this, or Payment Labs has taken it over. |
400 VALIDATION_ERROR | Accept | outcome is unknown, or amount is not a whole number of at least 1. |
400 DISPUTE_EXCEEDS_CLAIM | Accept | amount is more than the holder claimed. |
400 VALIDATION_ERROR | Decline, message | reason or body is missing, blank, or over 2,000 characters; or an attachment is invalid, too large, or one too many. |
409 DISPUTE_NOT_RESOLVABLE | Resolve | The dispute has not been accepted. |
409 DISPUTE_OUTCOME_NOT_PERMITTED | Resolve | The disputed entry cannot take the accepted outcome. |
400 CREDIT_BATCH_REQUIRED, 400 CREDIT_BATCH_INVALID | Resolve | A wallet-credit needs a usable batch. |
409 HOLDER_NOT_PAYABLE | Resolve | A wallet-credit cannot be made until the holder finishes onboarding. Retry later. |
409 CUSTOMER_FROZEN | Resolve | Your wallet program is frozen. Contact Payment Labs support. |
Webhook payloads carry the dispute as it is when the webhook is delivered. If deliveries arrive late, trust the latest status, or read the dispute.
Next steps
Updated 1 day ago
What’s Next
Next: Payins Overview.
