Chargebacks
A chargeback (dispute) is the buyer's bank reversing a payment — usually because the cardholder claims fraud, non-delivery or a billing error. The chargeback API gives you a full case-management workflow for each dispute: record it, assign an owner, keep notes, track the documents the scheme requests, upload evidence, fight it with a representment, and close it with an outcome.
When a chargeback lands, a payment.disputed webhook fires (carrying chargebackId, disputeState and the disputed amount) — so your systems learn about it the moment it happens, not when someone checks a bank portal. The payment's financial status (CAPTURED/REFUNDED) is not overwritten by the dispute.
All chargeback endpoints use plain Bearer authentication (an at_live_… access token); they manage a case record, not money movement.
All amounts are minor-unit (kuruş): the chargeback body carries "amountMinor": "10050" (₺100,50) as a string.
Lifecycle
A dispute case moves through a simple lifecycle:
- Received — the case is created (
POST /chargebacks) and linked to the payment (case statusRECEIVED). - In progress — your team works the case: assignment, notes, document requests, evidence (
UNDER_REVIEW). - Represented (optional) — you formally challenge the chargeback by submitting a representment with your evidence (
REPRESENTMENT_SUBMITTED). - Resolved — the case closes with one of three outcomes:
| Outcome | Meaning |
|---|---|
WON | The representment succeeded — the funds come back to you |
LOST | The dispute was decided in the cardholder's favour — the funds stay reversed |
ACCEPTED | You chose not to fight the chargeback and accepted the reversal |
Endpoints
| Method | Path | What it does |
|---|---|---|
| POST | /chargebacks | Record a new dispute case against a payment |
| GET | /chargebacks | List dispute cases |
| GET | /chargebacks/:id | Full case detail |
| PATCH | /chargebacks/:id/status | Update the case's lifecycle status |
| POST | /chargebacks/:id/assign | Assign the case to a team member |
| POST | /chargebacks/:id/notes | Add an internal note to the case timeline |
| POST | /chargebacks/:id/document-requests | Track a document the scheme/bank has requested |
| POST | /chargebacks/:id/evidence | Upload an evidence document to the case |
| POST | /chargebacks/:id/representment | Submit the representment (formally challenge the chargeback) |
| POST | /chargebacks/:id/resolve | Close the case with an outcome: WON, LOST or ACCEPTED |
Working a dispute
Learn about the dispute
Your payment.disputed webhook fires with the chargebackId and disputeState. Record the case (amount is a minor-unit string here):
curl -X POST https://api-gateway.lunixi.com/api/v1/chargebacks \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{
"paymentId": "pay_9f3a1c",
"amountMinor": "10050",
"currency": "TRY",
"networkReasonCode": "13.1",
"reasonCategory": "product_not_received"
}'Optional fields include provider, providerCaseId, cycleCount, representmentDeadline (ISO date) and fee fields. Cases are deduplicated on provider + providerCaseId + cycle (or paymentId + cycle for manual entries) — re-posting the same dispute returns the existing case with created: false.
Assign an owner and investigate
Give the case to whoever will work it, and keep the investigation on the record:
curl -X POST https://api-gateway.lunixi.com/api/v1/chargebacks/cb_5d21e0/assign \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{ "assignedUserId": "usr_ops_17", "priority": "HIGH" }'
curl -X POST https://api-gateway.lunixi.com/api/v1/chargebacks/cb_5d21e0/notes \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{ "note": "Order shipped 2026-06-28, tracking shows delivered. Pulling courier proof." }'Collect what the scheme asks for
If the bank or scheme requests specific documents, track each one with POST /chargebacks/:id/document-requests ({ "requestType": "…", "description": "…", "dueDate": "…" }), then satisfy them by attaching evidence. Evidence is a JSON record referencing an already-uploaded file (fileRef), typed so re-uploads of the same type are versioned:
curl -X POST https://api-gateway.lunixi.com/api/v1/chargebacks/cb_5d21e0/evidence \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{
"type": "DELIVERY",
"fileRef": "media/disputes/cb_5d21e0/delivery-proof.pdf",
"fileName": "delivery-proof.pdf",
"mimeType": "application/pdf",
"note": "Courier delivery confirmation with signature"
}'Fight it — or accept it
To challenge the chargeback, submit the representment (no body — the case's current evidence set is what gets represented):
curl -X POST https://api-gateway.lunixi.com/api/v1/chargebacks/cb_5d21e0/representment \
-H "Authorization: Bearer at_live_5f3e2b1a..."If the dispute is legitimate (or not worth fighting), skip this step and resolve as ACCEPTED.
Resolve the case
When the scheme's decision arrives, close the case:
curl -X POST https://api-gateway.lunixi.com/api/v1/chargebacks/cb_5d21e0/resolve \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{ "outcome": "WON", "reason": "Delivery proof accepted" }'Response shape
Mutating calls answer with a compact case reference:
{
"id": "cb_5d21e0",
"caseNumber": "CB-000123",
"status": "UNDER_REVIEW",
"created": false
}GET /chargebacks/:id returns the full case detail — the case record (payment link, amountMinor, reason codes, assignment, priority, deadlines) plus its timeline, checklist, evidence, notes and tasks. Case status values: RECEIVED, UNDER_REVIEW, REPRESENTMENT_SUBMITTED, WON, LOST, ACCEPTED, CLOSED.
Use PATCH /chargebacks/:id/status with { "toStatus": "UNDER_REVIEW" } (or "REPRESENTMENT_SUBMITTED") when your workflow requires an explicit stage change, and GET /chargebacks (Bearer, paginated) to build your dispute queue.
Errors
| Situation | What happens / what to do |
|---|---|
| Unknown chargeback or payment id | 404 — check the id; cases are merchant-scoped. |
| Resolving an already-resolved case | State-conflict error — a case takes exactly one final outcome. |
Invalid outcome value | Validation error — use WON, LOST or ACCEPTED exactly. |
| Evidence upload rejected | Check file size/format and retry; keep one document per upload call. |
| Missing or invalid API key | 401 — chargeback endpoints require your server-side Bearer key. |
Webhooks
| Event | Fired when |
|---|---|
payment.disputed | A chargeback is opened against a payment or changes phase — carries chargebackId, disputeState, disputedAmountMinor, openChargebackCount |
React to payment.disputed by opening your internal case immediately: dispute windows are short, and evidence assembled early wins cases.
Next steps
- Webhooks — the delivery model behind
payment.disputed - Listing Payments — find the disputed payment and its history
- Refunds — refunding proactively can prevent a dispute from being raised