How the diagnoser is tested

60 payment decline scenarios across card, UPI, UPI Autopay and NACH. Each one has a hand-written correct answer: why it failed, 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

Reasons payments fail

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 payment methods, 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 payment-method-specific or provider-specific rules, and documented any changes to the expected answers.

BY SCENARIO TYPE

Straightforward30
Unclear8
Unknown code5
Trick case7

BY PAYMENT METHOD

Card21
UPI Autopay16
NACH12
UPI1

Scenarios

S01
Straightforward
Tests: Baseline card decline

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

Reason: Insufficient funds

Context: Monthly OTT subscription renewal, debit card on file

EXPECTED REASON

Not enough balance

RETRY DECISION

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
Straightforward
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 REASON

Card expired

RETRY DECISION

Retry: After an action

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
Straightforward
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 REASON

Card reported lost or stolen

RETRY DECISION

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
Straightforward
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 REASON

Bank or network was down

RETRY DECISION

Retry: After an action

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
Straightforward
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 REASON

Wrong or outdated payment details

RETRY DECISION

Retry: After an action

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
Straightforward
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 REASON

Customer didn't complete verification

RETRY DECISION

Retry: After an action

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
Straightforward
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 REASON

Card or account is restricted

RETRY DECISION

Retry: After an action

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
Straightforward
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 REASON

Customer didn't complete verification

RETRY DECISION

Retry: After an action

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
Straightforward
Tests: Duplicate handling

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

Reason: Duplicate transmission

Context: Grocery order; customer double-tapped Pay

EXPECTED REASON

Already paid or a duplicate

RETRY DECISION

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
Straightforward
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 REASON

Customer cancelled autopay

RETRY DECISION

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 1–10 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.