PaymentsPayment operationsDisputes

Disputes

Respond to chargebacks and manage evidence.

View as MarkdownInstall skills

When a cardholder asks their bank to reverse a payment, the issuer opens a chargeback and VINR creates a dispute object on the affected payment. You then have a fixed window to submit evidence proving the charge was legitimate. This page covers the full lifecycle, how to respond, and how to keep your dispute rate low.

Dispute lifecycleAsk

A dispute moves through a small set of states. Each transition fires a webhook so you can automate responses instead of polling.

StatusMeaningYour action
needs_responseIssuer opened the chargeback; funds are heldGather and submit evidence before the deadline
under_reviewEvidence submitted; the issuer is decidingWait — no action possible
wonIssuer ruled in your favor; funds returnedNone
lostIssuer ruled for the cardholder; funds reversedReview reason, prevent recurrence
warning_needs_responseEarly fraud alert (pre-chargeback)Refund proactively to avoid a formal dispute
payment.completed
   └─ cardholder disputes
        └─ dispute.created (needs_response)   ← funds held + fee debited
             └─ you submit evidence
                  └─ dispute.under_review
                       ├─ dispute.won   → funds + fee returned
                       └─ dispute.lost  → funds stay reversed

The moment a dispute opens, VINR debits the disputed amount plus a dispute fee from your balance. If you win, the amount is returned; the fee may or may not be, depending on the network. See Fees & reversals.

Reacting to the webhookAsk

Subscribe to dispute.* events so your team is alerted the instant a chargeback lands. Always verify the signature before trusting the payload.

import { Vinr } from '@vinr/sdk';

const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });

export async function handler(req: Request) {
  const payload = await req.text();
  const signature = req.headers.get('x-vinr-signature') ?? '';

  const event = vinr.webhooks.verify(payload, signature);

  if (event.type === 'dispute.created') {
    const dispute = event.data; // dp_...
    await alertOpsTeam({
      disputeId: dispute.id,
      paymentId: dispute.payment,
      reason: dispute.reason,        // e.g. "fraudulent", "product_not_received"
      amount: dispute.amount,        // minor units, e.g. 1000 = €10.00
      respondBy: dispute.evidenceDueBy, // ISO-8601 deadline
    });
  }

  return new Response('ok', { status: 200 });
}

Submitting evidenceAsk

Evidence is a structured bundle of fields and file uploads. Tailor what you send to the dispute reason — a "product not received" claim needs shipping proof, while a "fraudulent" claim needs identity and device data.

Inspect the dispute

Retrieve the dispute to read its reason and evidenceDueBy. The reason determines which fields the issuer weighs most heavily.

const dispute = await vinr.disputes.retrieve('dp_3Nf8x2a...');
console.log(dispute.reason, dispute.evidenceDueBy);

Upload supporting files

Receipts, shipping labels, and signed contracts are uploaded first and referenced by ID.

const receipt = await vinr.files.create({
  purpose: 'dispute_evidence',
  file: fs.createReadStream('./receipt.pdf'),
});
// receipt.id → "file_8Hk2..."

Attach and submit evidence

Send the fields plus file references. Submitting moves the dispute to under_review and locks further edits.

await vinr.disputes.update('dp_3Nf8x2a...', {
  evidence: {
    customerName: 'Jordan Rivera',
    customerEmail: 'jordan@example.com',
    billingAddress: 'Keizersgracht 100, 1015 CW Amsterdam, NL',
    receipt: 'file_8Hk2...',
    shippingCarrier: 'PostNL',
    shippingTrackingNumber: '3SABC1234567890',
    serviceDate: '2026-05-12',
    productDescription: 'Annual Pro plan — order #1234',
    customerCommunication: 'file_9Lm3...', // email thread
  },
  submit: true,
});

You can save evidence without submitting by omitting submit (or setting it to false). VINR keeps a draft so multiple team members can contribute before the final submission.

Deadlines & outcomesAsk

The evidenceDueBy timestamp is set by the issuing bank, typically 7 to 21 days after the dispute opens. Missing it counts as conceding the dispute.

  • Submit at least 24 hours early — issuers occasionally close windows before the displayed time.
  • Once submitted, decisions usually arrive in 60 to 75 days. This is set by card-network rules, not VINR.
  • Outcomes are final at the network level. A lost dispute cannot be appealed through VINR, though some networks allow a separate arbitration process for large amounts — contact support before pursuing it.

Prop

Type

Fees & reversalsAsk

When a dispute opens, two things leave your VINR balance immediately:

  1. The disputed amount, held until the outcome.
  2. A dispute fee (network-dependent, shown on each dispute object).

If you win, the disputed amount is credited back to your balance and appears as a dispute.won adjustment in reconciliation. If you lose, the amount stays reversed and the original payment is marked disputed. Either way the debit and any reversal show up on your settlement report, so reconcile against the dp_ IDs rather than the original pay_ IDs.

Refunding a payment that is already disputed does not resolve the dispute and can result in the customer being paid twice. Respond to the dispute instead; only issue a refund if you intend to concede.

Preventing disputesAsk

Most disputes are avoidable. The highest-leverage controls:

  • Clear billing descriptors — set a recognizable statement descriptor so customers recognize the charge. "Unrecognized" disputes are the most common and the most preventable.
  • 3D Secure — authenticating cardholders shifts fraud liability to the issuer for many disputes. See 3D Secure.
  • Respond to fraud warningswarning_needs_response events arrive before a formal chargeback. Refunding then avoids the fee and the dispute-rate hit entirely.
  • Prompt fulfillment + tracking — capture shipping and delivery data so "product not received" claims are easy to rebut.
  • Easy cancellation — for subscriptions, make cancelling self-serve; friction drives subscription_canceled disputes.

A dispute rate above roughly 0.9% risks card-network monitoring programs. Track yours in the dashboard and treat sustained spikes as an incident.

Next stepsAsk

Was this page helpful?
Edit on GitHub

Last updated on

On this page