Disputes and Chargebacks
A disputed payment is money you booked that is now contested — a card chargeback, or a B2B buyer refusing a Net-N invoice. Throttle surfaces both through the same three fields on the payment, written either by your own call or by the processor.
disputed, disputeReason, and disputeOpenedAt on the payment, plus disputeOutcome and disputeClosedAt once a card chargeback is
decided. There is no evidence submission, no due date, and no dispute id on
the payment. The fields exist so a contested payment stops
looking like clean revenue in your reporting and your AR views — contest the
chargeback in your processor's dashboard.
Two ways a payment gets flagged
- You flag it.
POST /api/v1/payments/{id}/dispute— mainly for Net-N receivables, where the dispute arrives as an email from a buyer rather than a processor event. - The processor flags it. Inbound
dispute.*andchargeback.*webhooks are matched to the payment by processor transaction id and write the same three fields. No configuration needed.
Because both paths converge on the same columns, a consumer of payment.disputed does not need to care
which one fired.
Flagging a payment
Scope payment_disputes:write. reason is required, 1–500 characters.
disputeOpenedAt is stamped server-side.
curl -X POST https://api.usethrottle.dev/api/v1/payments/pay_88ce.../dispute \
-H "X-API-Key: $THROTTLE_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Buyer claims the invoice was already settled by wire" }' {
"data": {
"id": "pay_88ce...",
"disputed": true,
"disputeReason": "Buyer claims the invoice was already settled by wire",
"disputeOpenedAt": "2026-08-09T14:41:02.000Z"
}
}
Flagging an already-flagged payment is a 409 already_disputed rather than a silent
overwrite, so you cannot lose the original reason by retrying.
Clearing a dispute
curl -X POST https://api.usethrottle.dev/api/v1/payments/pay_88ce.../dispute/clear \
-H "X-API-Key: $THROTTLE_SECRET_KEY"
Clearing sets disputed: false but deliberately leaves disputeReason and disputeOpenedAt in place, so the history
of the dispute survives on the payment. It takes no body, and clearing a
payment that was never disputed succeeds without emitting an event.
How processor events are classified
Inbound dispute events are classified from the event suffix and the target's status:
| Processor signal | Outcome | Effect |
|---|---|---|
Status won or reversed | Clear | Sets disputed: false and disputeOutcome: "won", emits payment.dispute_cleared |
Status lost | Lost | Sets disputed: false and disputeOutcome: "lost", emits payment.dispute_lost once; the order reads charged_back |
| Anything else | Open | Sets disputed: true and clears any earlier outcome, emits payment.disputed once |
disputed: true means a dispute is open
right now — build your worklist from it. Once the processor decides a card
chargeback, disputed goes back to false and disputeOutcome records won or lost, with disputeClosedAt. A lost chargeback rolls
the order's paymentStatus up to charged_back. Net-N invoice disputes you
clear by hand don't set an outcome.
A resolution event for a payment that is not currently flagged is a no-op,
and redeliveries of an open event will not re-fire payment.disputed — it is emitted only on
the first transition into the disputed state.
Webhooks
{
"type": "payment.disputed",
"data": {
"paymentId": "pay_88ce...",
"reason": "fraudulent",
"openedAt": "2026-08-09T14:41:02.000Z"
}
} payment.dispute_cleared carries only paymentId. payment.dispute_lost carries paymentId, reason, amount (minor units), currency, and closedAt, and fires once per loss.
Subscribing to any of the three requires payment_disputes:read. Both are worth
routing to a human — a chargeback is one of the few events where nobody
finds out until a payout is short. See Webhooks.
Error codes
| Code | HTTP | Meaning |
|---|---|---|
already_disputed | 409 | The payment is already flagged. Clear it first. |
invalid_status | 409 | The payment is voided or refunded; there is nothing to dispute. |
not_found | 404 | No payment with that id in this workspace environment. |