Dispute
The Dispute entity in Payments.
A Dispute is an issuer- or buyer-initiated chargeback against a Transfer: the buyer's bank pulls the funds back into their account and asks Easy Labs (and you, the merchant) to either accept the loss or contest it with evidence. Disputes are read-mostly from the SDK's perspective — they are created by the network, not by you, and the work you do is responding to them with evidence and tracking the outcome. The Dispute object is the durable record of that exchange.
Lifecycle
- Created — a
dispute.createdwebhook fires when the network notifies Easy Labs of a chargeback. The disputed amount has already been pulled from the merchant settlement. A separate Transfer withtype: "DISPUTE"holds the funds in flight. - Under review — you have a fixed evidence window (network-dependent; typically 7–21 days) to upload supporting documentation through the dashboard or by attaching it via your account team.
- Decision — the issuer decides. A
dispute.updatedwebhook fires when the status changes. Outcomes are typicallyWON(funds returned to merchant),LOST(funds stay with buyer), orACCEPTED(you chose not to contest). - Tagged — at any point you can call
client.updateDispute(disputeId, { internalCaseId: "…" })to attach your own metadata. Tags are the only mutable surface on a Dispute.
Relationships
Every Dispute references the Transfer it is contesting. From the Transfer you can resolve back to the Order (if the charge originated from a checkout flow), the Customer that owns the funding source, and the Payment Instrument that was charged.
Fields that matter
The Dispute schema is processor-specific and the API exposes it as a permissive object; the fields you can rely on are:
id(string) — the canonical Dispute ID. Use withgetDispute,updateDispute.amount(number) — disputed amount in the smallest currency unit.currency(string) — ISO-4217.state/status(string) — current dispute status as reported by the network (e.g.PENDING,WON,LOST).transfer(string) — the Transfer ID this Dispute is contesting.reason_code(string) — network-supplied reason (fraud,product_not_received,duplicate, etc.). Drives what evidence you should provide.respond_by(string) — ISO deadline for submitting evidence.tags(Record<string, unknown>) — your own metadata. Mutable.
For end-to-end response workflow, the Easy Labs dashboard is the primary surface — programmatic evidence upload is on the roadmap and not yet exposed via the public SDK.