Fintech
Key points

Key points

  1. 1An LLM should extract and organize facts from order, shipping and chat records into a structured evidence table, and draft the rebuttal only from verified fields.
  2. 2The model must never produce amounts, dates, tracking numbers, addresses or transaction IDs that do not appear verbatim in the source documents.
  3. 3Automated checks for missing fields, contradictions and unsupported numbers catch most errors before a human ever reads the draft.
  4. 4A named human signs off on every claim against the source documents before the pack goes to the acquirer.

Start from the reason code, not from the documents

The single biggest mistake in LLM-assisted dispute work is asking the model to read everything and write a rebuttal. A rebuttal is only persuasive if it answers the specific claim the cardholder made, and that claim arrives as a reason code. Visa organizes its codes into four categories (Fraud, Authorization, Processing Errors, Consumer Disputes), and Mastercard uses an equivalent four-category structure with four-digit codes such as 4837 for no cardholder authorization and 4853 for a cardholder dispute, as catalogued in this guide to chargeback reason codes. Each code also dictates the evidence the issuer expects and the deadline attached to it.

This gives you your first design decision: the reason code is the agent's input, and it selects the evidence checklist before any document is read. Stripe's dispute documentation groups hundreds of payment-method-specific codes into eight categories based on the type of claim and the evidence required to challenge it, which is a useful mental model even if you do not process on Stripe. The categories collapse into a small number of evidence shapes:

Dispute shapeTypical claimEvidence the pack must lead with
Fraud, card absentI did not authorize thisAuthentication results, AVS/CVV match, IP and device data, prior undisputed orders
Merchandise not receivedIt never arrivedCarrier tracking, delivery confirmation, address match to billing
Not as describedIt is not what I orderedProduct page as shown at purchase, policy screenshots, chat records
Credit not processedI returned it and got no refundReturn receipt, refund transaction record, correspondence
Processing errorI was charged twiceAuthorization log, settlement records, duplicate detection

A checklist from Chargeblast makes the same point from the merchant side: evidence must match the reason code, and the wrong evidence for the code loses automatically. Your agent should treat a mismatch between the pack and the reason code as a hard failure, not a quality nudge.

There is one more decision rule worth encoding early. If the dispute is fraud-coded and the transaction was fully authenticated with 3D Secure, liability generally shifts to the issuer, and you are representing with authentication artifacts rather than arguing about delivery. Stripe's support notes are explicit that liability shift applies to fraudulent-type disputes only, and that bank-approved exemptions do not move liability. A US-focused breakdown of 3DS liability adds the detail that matters for the pack: you need the ECI, the CAVV/AAV and the ACS transaction identifiers, and Data-Only 3DS grants no shift at all. So the first branch in your workflow is not what the chat logs say but whether this is a fraud-coded, authenticated transaction, and if it is, whether you hold the artifacts.

Connect the sources before you prompt anything

Before a model sees a single record, the agent needs a join key. In practice the transaction ID or order ID is the spine, and everything else hangs off it: the payment authorization, the fulfillment record, the carrier tracking events, and the support conversations. Chargeback Gurus describes representment as a package containing a rebuttal letter plus compelling evidence, and notes the fee is not refunded even when you win, which is why assembling the package correctly the first time matters more than assembling it fast.

Build a collector that pulls, for one dispute:

  • The original transaction record: amount, currency, timestamp, authorization result, AVS and CVV responses.
  • The order record: line items, shipping address, billing address, email, account creation date.
  • Fulfillment and carrier events: dispatch time, scan events, delivery confirmation type, signature or photo availability.
  • Every support message touching the order, including pre-purchase and post-purchase, in timestamp order.
  • Prior order history for the same customer, which is strong context for a claim of unauthorized use.
  • Policy and product-page snapshots as they appeared at purchase time.

Store each item with an immutable reference (document ID, URL, export timestamp). The model will later cite these references, and your checks will verify the citations resolve. If a source system cannot be reached, the agent should mark the pack incomplete rather than proceed. A partial pack that looks complete is the worst outcome in this workflow.

Extract into a fixed evidence table, then draft from the table

The core insight is to split the job in two. The model's first task is extraction into a schema you control; its second task is drafting prose from that schema. Prose generated directly from raw logs is where invented tracking numbers and paraphrased amounts come from. Prose generated from a validated table can be checked line by line.

Define the schema explicitly and ask for JSON. A minimal version:

{
  "dispute_id": "string",
  "reason_code": "string",
  "claimed_amount": {"value": "string", "source_ref": "string"},
  "transaction": {
    "timestamp": {"value": "string", "source_ref": "string"},
    "amount": {"value": "string", "source_ref": "string"},
    "avs_result": {"value": "string", "source_ref": "string"},
    "cvv_result": {"value": "string", "source_ref": "string"}
  },
  "authentication": {
    "eci": {"value": "string|null", "source_ref": "string|null"},
    "cavv_present": {"value": "boolean", "source_ref": "string|null"}
  },
  "fulfillment": [
    {"event": "string", "timestamp": "string", "source_ref": "string"}
  ],
  "delivery_confirmation": {"type": "string|null", "source_ref": "string|null"},
  "customer_messages": [
    {"timestamp": "string", "author": "customer|merchant", "summary": "string", "source_ref": "string"}
  ],
  "evidence_gaps": ["string"]
}

Every scalar is wrapped with a source reference, which forces the model to point at the document it read. Fields it cannot populate must be null plus listed in evidence_gaps. Tell the model in the system prompt that null is the correct answer for anything absent, and that inventing a value is the only unacceptable failure. Structured-output modes make the schema enforceable; this benchmark write-up on structured outputs shows the failure mode you are guarding against, where a model returned a valid-looking JSON object with a subtly wrong amount and an impossible date, and argues that per-field trust scoring lets reviewers focus on the small fraction of fields that warrant attention.

Then draft. The drafting prompt receives only the evidence table, the reason code, and a template. Its instruction set has three rules: every sentence containing a fact must cite at least one source_ref; no number may appear that is not in the table; and the letter opens by naming the specific claim and closes with a list of attachments matching the table's source references.

The fields the model must never invent

This is the part most teams under-specify. Some values are verifiable in a millisecond and some are catastrophically wrong if wrong, so treat the second group as locked fields. The agent may copy them; it may never compute, infer or complete them.

Locked fieldWhy it cannot be inferredCheck
Transaction and dispute amountsA transposed digit misstates the claimExact string match against payment record
Transaction timestamp and timezoneAn off-by-one-day shift breaks the timelineExact match including offset
Tracking number and carrierA fabricated tracking number destroys credibilityExact match against carrier export
Delivery date and confirmation typeDelivered versus left at door are different claimsMatch against carrier event
Shipping and billing addressesInferred addresses cannot be defendedExact match against order record
Card last four and networkWrong identifiers misroute the responseExact match
Reason code and its wordingParaphrasing changes the claim you answerMatch against the dispute notification
Customer message quotesQuoted text must be verbatimSubstring match against transcript
Policy terms citedStating a policy you do not have is a misrepresentationMatch against archived policy snapshot
Prior order counts and datesA claimed count of three prior orders must actually be threeRow count against order history

Two adjacent rules save a lot of grief. First, the model may summarize a customer message, but any text in quotation marks must be a verbatim substring of the transcript; your checker can test this mechanically. Second, the model may not state a conclusion about the cardholder's intent. A sentence such as the cardholder appears to have forgotten the purchase is an argument the human reviewer makes, not one the model asserts.

Delivery evidence deserves its own caution. A basic delivered scan does not establish where a package was left or who received it, and delivery confirmation does not guarantee a reversal; it works as part of a package alongside order records, invoices and communications, as this guide to delivery confirmation in disputes explains. Instruct the model to describe exactly what the carrier recorded and nothing more. If the scan says left at front door, the letter says left at front door, not signed for by the recipient.

The checks that run before a human sees the draft

Automation should catch the cheap errors so reviewers spend their attention on judgment calls. Run these in order and block on failure:

  1. Schema validation. All required fields present or explicitly null with a gap entry.
  2. Reference resolution. Every source_ref resolves to a stored document.
  3. Locked-field exactness. Every locked field matches its source byte for byte.
  4. Numeric containment. Every number in the draft appears in the evidence table.
  5. Quote verification. Every quoted string is a substring of a source transcript.
  6. Timeline sanity. No event precedes the order, and no date is impossible.
  7. Address consistency. Billing and shipping are stated accurately and the discrepancy, if any, is described rather than smoothed over.
  8. Evidence coverage. The reason code's required evidence types are all present or listed as gaps.

The timeline and address checks catch a specific, common hallucination: a model that produces a tidy narrative by quietly reconciling a shipping address that does not match the billing address. That discrepancy is often the most important fact in a not-received dispute, in either direction, and it must survive into the letter. Chargeback Gurus on compelling evidence frames the standard as documentation that directly contradicts the claim, which means discrepancies are evidence, not noise to be cleaned up.

Track your checks. Two numbers tell you whether the system is working: the rate at which drafts fail numeric containment (high early, falling as prompts tighten) and the rate at which human reviewers still correct a factual error that passed all checks. The second number is your real error rate and should drive prompt and schema changes.

The human review gate, and when to drop the case

The gate is not a rubber stamp. Give the reviewer a side-by-side view: the draft on the left, the evidence table with resolved source links on the right, and every locked field highlighted. The reviewer's job is to confirm four things and nothing else: the letter answers the reason code, every claim traces to a source, nothing is overstated, and nothing is missing that would strengthen the case.

A decision rule worth stating plainly: do not fight disputes where the available evidence does not actually disprove the claim. Chargeback Gurus on representment makes the same point, that merchants should assess whether the dispute is valid and whether escalation makes financial sense, and a dispute package checklist stresses that all dates, transaction IDs and names must match across documents, because a mismatch causes confusion or delay. An LLM makes it cheap to draft a letter for every dispute; resist that. A weak, well-formatted argument costs you reviewer time and does nothing for your win rate. Route cases with unresolved evidence gaps to accept-or-refund instead.

Friendly fraud context matters for that routing decision. Visa's material on friendly fraud notes it represents around 20% of fraudulent disputes globally and up to 30% for high-volume online merchants, while a BBC report on chargeback scams describes a restaurant owner who found chargebacks arriving after card payments taken over the phone, with a fixed fee on top of the lost sale. Both point to the same operational conclusion: the evidence pack wins when it shows participation and delivery, so keep the artifacts as a matter of routine rather than reconstructing them under deadline.

One more structural point: a soft chargeback, also called a retrieval request, arrives before a formal dispute and asks for more information about a transaction. Shift4's overview of chargebacks notes that responding without delay is advisable because a retrieval request is a chance to avoid a chargeback entirely. Your agent should handle retrieval requests with the same collector and checks, because the evidence assembled there is reused if the dispute follows.

Common hallucinations to catch, and the sign-off

Keep a standing list, because models fail in recognizable patterns:

  • A tracking number with a plausible carrier prefix that matches no shipment in your export.
  • A delivery date one day off the carrier's scan, or in the wrong timezone.
  • A paraphrased policy line that softens or hardens the actual terms.
  • A prior-order count that rounds up.
  • A quoted customer message with tidied grammar.
  • A summary of a chat thread that omits the message where the customer asked to cancel.
  • An inferred discount, partial refund or adjustment the payment record does not show.
  • A confident statement that authentication succeeded when the ECI is absent.
  • A named recipient for a signature that was never collected.
  • A currency symbol applied to an amount from a different currency.

When you route this through one API, keep extraction and drafting as separate model calls with separate prompts, even if both hit the same endpoint. Mixing them reintroduces the failure mode you just removed. Quanta Inference serves text, image and embedding models through one OpenAI-compatible key, which keeps the extractor, the drafter and any classifier you add on the same billing and auth path.

The sign-off itself should be a named person, a timestamp, and a checklist of confirmations recorded against the draft version. That record is what you show internally when a letter goes wrong, and it is what keeps the model where it belongs: assembling and drafting, never deciding.

FAQ

FAQ

Do I need the reason code before the model reads any documents?

Yes. The reason code determines which evidence the pack must lead with and how the letter frames the claim. Feeding it in first lets the agent select the checklist and flag gaps before extraction, which is far cheaper than discovering a missing evidence type after drafting. This reason code reference shows how deadlines and evidence requirements vary by code.

Should the model write the rebuttal letter directly from the raw chat and shipping logs?

No. Extract into a structured evidence table first, validate it, then draft only from the table. Direct drafting from raw logs is where invented tracking numbers, shifted dates and tidied quotes originate. The two-stage split also makes automated checking possible, since every fact in the letter can be traced to a table row or field.

What is the fastest check that catches the most hallucinations?

Numeric containment: confirm every number in the draft appears verbatim in the evidence table. Amounts, dates, tracking numbers, counts and card digits all fall under it, and it runs without any model call. Pair it with quote verification, which tests quoted text as a substring of the source transcript, and you cover the majority of fabrication risk cheaply.

How do I keep reviewers from rubber-stamping drafts?

Limit the review to four explicit confirmations, show every locked field with its source link side by side, and record the reviewer's name and timestamp against the draft version. Also route cases with unresolved evidence gaps to accept-or-refund instead of review, so reviewers only see disputes worth arguing. A gate that is asked to judge everything judges nothing.

Does 3D Secure authentication always mean we win the fraud dispute?

No. Liability shift applies to fraudulent-type disputes when authentication succeeded and the artifacts are transmitted, and it does not cover non-fraud claims such as goods not received or not as described. It also does not apply to Data-Only 3DS or to approved exemptions, per Visa's own guidance and this US liability shift breakdown.

Sources

Sources

  1. The complete guide to chargeback reason codes for card ...
  2. Dispute reason code categories
  3. Building a Winning Chargeback Evidence Packet
  4. Liability shift with frictionless flow for 3D Secure v2 (3DS2) - Stripe Support
  5. What the 3D Secure Liability Shift Means for US Businesses
  6. What Is Chargeback Representment?
  7. Real-Time Error Detection for LLM Structured Outputs
  8. Fighting Chargebacks with Delivery Confirmation
  9. Win Chargeback Disputes with Compelling Evidence
  10. Dispute Package Checklist: What to Submit to Win
  11. Friendly fraud explained: prevention and solutions | Visa
  12. Friendly fraud: The new scam causing harm to businesses - BBC
  13. Chargebacks in a Nutshell: A Guide for Merchants - Shift4
  14. 3D Secure: your guide to safer transactions | Visa
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles