How the diagnoser is tested

60 payment decline scenarios across card, UPI, UPI Autopay and NACH. Each one has a hand-written correct answer: the root cause, whether to retry, when, and what to tell the customer. Every version of the diagnoser is scored against this set.

50

Development scenarios

10

Held-out scenarios

18

Root causes

200

Codes in the reference

How I built it

  1. 1

    I started from the codes, not the model. I researched ~200 decline codes from NPCI, ISO 8583, Razorpay, Cashfree and Stripe, grouped them into 18 root causes, and defined the right merchant action for each.

  2. 2

    I designed scenarios around real failure modes. I covered different rails, repeated failures, retry timing, advice codes, customer-reported debits, and deliberately unknown codes to test hallucination.

  3. 3

    I wrote the expected answer for every scenario myself. For each case, I determined the correct root cause, merchant action and retry recommendation using the source documentation and transaction context. I used AI occasionally to help draft or sanity-check answers, but reviewed and finalized every label myself.

  4. 4

    I kept 10 scenarios completely separate from prompt tuning. These are my holdout set. I don't use them while improving the prompt, so I can use their final score to see whether the model actually generalizes.

  5. 5

    I validated the final labels against the source documentation. I rechecked the cases where the answer depended on rail-specific or provider-specific rules, and documented any changes to the expected answers.

BY SCENARIO TYPE

clear30
ambiguous8
unrecognised5
trap7

BY RAIL

Card21
UPI Autopay16
NACH12
UPI1

Scenarios

S01
clear
Tests: Baseline card decline

Card · code 51 · ₹799 · recurring · attempt 1

Reason: Insufficient funds

Context: Monthly OTT subscription renewal, debit card on file

EXPECTED ROOT CAUSE

Insufficient funds

RETRY VERDICT

Retry: yes

TIMING

Retry after 3 days; if that fails, retry around the 1st–7th (likely salary credit)

WHY

First failure, specific code, small amount — soft decline. Card retry is simple.

S02
clear
Tests: Baseline card decline

Card · code 54 · ₹2,499 · recurring · attempt 1

Reason: Expired card

Context: Annual SaaS renewal; card saved three years ago

EXPECTED ROOT CAUSE

Card expired

RETRY VERDICT

Retry: conditional

TIMING

Never retry on the expired card; retry after customer updates card details

WHY

Preventable — expiry date is known; send reminder ~30 days before (grace period for annual plan)

S03
clear
Tests: Baseline hard decline; also check the customer message

Card · code 41 · ₹4,999 · one-off · attempt 1

Reason: Lost card

Context: Online electronics accessory purchase

EXPECTED ROOT CAUSE

Card lost stolen

RETRY VERDICT

Retry: no

TIMING

Never retry on this card

WHY

Hard decline + fraud signal: person at checkout may not be the cardholder; Merchant: flag session for review. Generic message only — safe for both a genuine customer and a fraudster. Fails if model retries or names the reason.

S04
clear
Tests: Baseline technical decline

Card · code 91 · ₹1,299 · one-off · attempt 1

Reason: Issuer or switch inoperative

Context: Food delivery order at 11:45pm

EXPECTED ROOT CAUSE

Bank or network downtime

RETRY VERDICT

Retry: conditional

TIMING

Immediately, but only when customer retries with a different method; no scheduled retry

WHY

"retry in 1–4h" is useless for a food order at 11:45pm — order is lost and the same card likely fails while issuer is down.

S05
clear
Tests: Baseline data-entry decline

Card · code 82 · ₹3,450 · one-off · attempt 1

Reason: CVV mismatch

Context: First purchase on a D2C apparel site

EXPECTED ROOT CAUSE

Payment details invalid

RETRY VERDICT

Retry: conditional

TIMING

Customer retries immediately with corrected details; never resubmit same details

WHY

Usually a typo — field-level error message recovers the sale. Merchant: don't clear the form; cap attempts at 2–3, since repeated CVV failures on a first purchase are a card-testing pattern. The model should give the specific fix, and ideally mention an attempt cap.

S06
clear
Tests: Authentication on a high-value card payment

Card · code 1A · ₹8,999 · one-off · attempt 1

Reason: Additional customer authentication required

Context: Flight booking checkout

EXPECTED ROOT CAUSE

Auth not completed

RETRY VERDICT

Retry: conditional

TIMING

Retry immediately through the authentication flow while customer is at checkout

WHY

Card is fine; issuer wants authentication the request lacked. Merchant fix: resubmit with 3DS/AFA; hold fare during verification. In India, 1A suggests a flow that skipped AFA (e.g. international acquirer). Time pressure: fare may expire. Fails if model says "use another card".

S07
clear
Tests: Gateway reason string instead of ISO code

Card · code card_disabled_for_online_payments · ₹1,899 · one-off · attempt 1

Context: Customer's first online purchase with a new debit card (Razorpay)

EXPECTED ROOT CAUSE

Instrument restricted

RETRY VERDICT

Retry: conditional

TIMING

Customer retries immediately after enabling online payments or switching method; no scheduled retry

WHY

New Indian cards often have online use off by default. Fixable in seconds: a specific checkout message saves the sale. Tests whether model gives a concrete fix instead of generic "contact your bank".

S08
clear
Tests: Gateway code; recurring with no customer present

Card · code authentication_required · ₹1,199 · recurring · attempt 1

Context: Off-session monthly renewal of a design tool (Stripe)

EXPECTED ROOT CAUSE

Auth not completed

RETRY VERDICT

Retry: conditional

TIMING

No automatic retry (off-session retry fails again); retry only after customer authenticates

WHY

Customer isn't present — model must recommend bringing them back, not a timed retry. If every renewal hits this, it's a setup problem: check the card was registered with an RBI-compliant e-mandate (verify rule before freezing). Common for global SaaS billing Indian cards.

S09
clear
Tests: Duplicate handling

Card · code 94 · ₹649 · one-off · attempt 2

Reason: Duplicate transmission

Context: Grocery order; customer double-tapped Pay

EXPECTED ROOT CAUSE

Duplicate or already collected

RETRY VERDICT

Retry: no

TIMING

Never retry; check status of attempt 1 first

WHY

Decline is the system correctly blocking a double-tap. Merchant: reconcile — confirm order if attempt 1 succeeded, refund if both went through. Worst response is "payment failed, try again". Root fix: disable Pay after first tap + idempotency keys.

S10
clear
Tests: Customer-initiated stop on a card mandate

Card · code R1 · ₹999 · recurring · attempt 1

Reason: Revocation of authorization

Context: Monthly fitness app subscription

EXPECTED ROOT CAUSE

Mandate revoked or stopped

RETRY VERDICT

Retry: no

TIMING

Never retry; any new charge needs fresh customer consent

WHY

The customer went to their bank rather than just tapping a button in an app, which is about as clear as cancellation intent gets. High R1 rates often mean the merchant's cancel flow is hard to find.

Showing 110 of 50
10 held-out scenarios are hidden until the current version has been scored on them, so nobody tunes the diagnoser to the test.