RAZORPAY AI BUILDATHON 2026 · TRACK 3 · REVENUE RECOVERY
Hey, I'm

What happens after a payment fails?

UPI timed out Card declined Cart abandoned Invoice overdue Insufficient funds Gateway error Bank downtime Subscription lapsed UPI timed out Card declined Cart abandoned Invoice overdue Insufficient funds Gateway error Bank downtime Subscription lapsed
Vulcan routes payments. Recovery Router routes failures.

A fully autonomous recovery engine — it classifies every revenue leak, decides the recovery action, and executes through the right channel. Merchants configure credentials and deploy — the pipeline handles classification, routing, and messaging autonomously from there.

Why This Track Exists

Indian merchants lose revenue from three separate holes. Current recovery tools handle them separately with no shared intelligence about why the payment failed.

68–74%
D2C Success Rate
Razorpay, 2026 ↗
40%
Won't Return After Decline
Razorpay, 2026 ↗
15–20%
Retry Recovery Rate
Razorpay, 2026 ↗
47.6%
Industry Median Recovery
Digital Applied ↗

The Gap in Razorpay's Ecosystem

BEFORE PAYMENT
Magic Checkout ↗
UX optimization
DURING PAYMENT
Vulcan (AI Routing) ↗
8-10% success improvement
AFTER FAILURE
Recovery Router
Classify · Route · Act · Measure

How the World Handles It

CompetitorApproachLimitation
Stripe ↗Smart Retries + card updates (55% recovery)Email-only dunning, retry and dunning independent
Adyen ↗Multi-armed bandits for retry timingRetry-only, no customer communication
Cashfree ↗"Relay" AI agent for failed payments + cartsSingle-agent, not a pipeline
Recurly ↗Intelligent Dunning ML (70-80% recovery)Subscriptions only
Chargebee ↗Pre-dunning workflows (30-40% + 15-22%)Subscriptions only
Most othersFixed retry schedules, email-onlyNo multi-channel, no classification

Everyone focuses on retry mechanics. Nobody combines diagnostic intelligence with personalized multi-channel recovery across all three leak types in a single engine.

Why I Built It This Way

Every decision here was deliberate. Let me walk you through how I see this.

"If it doesn't recover revenue, I didn't build it"
I rejected features that look impressive but don't improve recovery. No Promise-to-Pay, no complex ML that can't be explained, no vanity metrics. Every line of code has to justify its existence with ROI.
I designed it like I already work at Razorpay
I cloned Razorpay's actual UI — their design tokens, SVG icons, color system. Not because it looks pretty — because Recovery Router should feel like it already lives inside Razorpay's product suite. If this shipped as a native feature tomorrow, the UI wouldn't need redesigning.
I chose honest metrics over impressive numbers
If no outreach was sent, I mark it organic_recovery, not recovered. I track "sent" not "delivered" because I haven't built delivery receipts yet. I'd rather be honest than inflate.
I treat this like financial software, not a hackathon project
HMAC-SHA256 webhooks, XSS prevention, AI input sanitization, distributed locks, action reservation with idempotency keys, 3-layer give-up prevention, delivery failure detection, database-level trigger as my last line of defense. 18 defense layers deep. Because this handles real money.
I built production patterns, not demo patterns
acks_late=True, reject_on_worker_lost=True, exponential backoff, distributed locks, conditional DB updates, and a reserve-before-send pattern with idempotency keys that prevents double-sends on worker crashes. If Razorpay shipped this tomorrow, the architecture wouldn't need rewriting.

One Engine, Three Leak Types

I built one autonomous engine that handles all three. Same pipeline, every time. Zero manual intervention.

Payment Failures
Razorpay payment.failed webhook
I classify these into 12 categories. My AI picks the optimal recovery path based on failure type, amount, and customer context.
Cart Abandonment
Merchant POST to /webhook/recovery-router
I classify by intent - high-value carts get outreach, browse-only carts get zero attempts. I respect the customer's signal.
Overdue Invoices
My invoice scanner polls Razorpay API every 6 hours
I classify by days overdue. The escalation tone matches urgency - friendly for recently overdue, formal for 30+ days.

How My Pipeline Works

01
CLASSIFY
AI Classification
  • 3-model fallback chain via OpenRouter
  • Claude Haiku 4.5 → Gemini 3.7 Flash → GPT-4o-mini
  • Rule-based fallback if all AI fails
  • System never blocks on AI
02
ROUTE
Dynamic Budgets
  • max_attempts computed per event
  • High-value UPI timeout → 5 attempts
  • Browse-only cart → 0 attempts
  • User-cancelled → 2 attempts
03
ACT
Multi-Channel Send
  • WhatsApp: Green API → Twilio → Email
  • SMS: Twilio → WhatsApp → Email
  • Email: Resend AI-generated HTML
  • Every attempt logged in degradation_path
04
MEASURE
Honest Metrics
  • 4-strategy reconciliation matching
  • No outreach sent? → marked organic, not recovered
  • No double-attribution
  • Currency match with 1% tolerance

I Mapped Every Failure to a Category

Each one gets different treatment - different channel, different timing, different attempt budget.

CategoryProbabilityChannelTimingMax Attempts
UPI Timeout75–85%WhatsAppImmediate3–5
Bank Downtime70–85%WhatsApp30 min delay3–5
Gateway Error80–90%WhatsApp5 min3–5
Card Expired40–60%EmailImmediate3–4
Insufficient Funds30–50%SMS4 hour delay3
User Cancelled20–40%WhatsApp1 hour2
Unrecoverable Decline0%None-0
High Intent Abandonment30–50%WhatsApp1 hour3
Browse Only Abandonment5–10%None-0
Recently Overdue (1-7d)60–80%WhatsAppImmediate3–5
Moderately Overdue (8-30d)30–50%EmailImmediate3–4
Long Overdue (30d+)10–20%Email-2

Six-Component Production Architecture

I wired up FastAPI + Celery Worker + Celery Beat + React Frontend + Redis + Supabase. Every operation runs through my real async pipeline.

Recovery Router System Architecture - webhook ingestion, AI classification, multi-channel recovery, escalation loop, and feedback tracking

Tech Stack

ComponentTechnologyWhy
APIFastAPIAsync, auto-docs (Swagger), Pydantic validation
Task QueueCelery + RedisLate ACK, crash recovery, periodic scheduling (Beat)
DatabaseSupabase (PostgreSQL)RLS, REST API, PostgreSQL triggers
AI GatewayOpenRouterMulti-model, no vendor lock-in, single API
AI ModelsClaude Haiku 4.5 → Gemini 3.7 Flash → GPT-4o-miniSpeed-first fallback: fastest first, cheapest last
PaymentsRazorpay Orders APIUnlimited orders (vs 30-link Payment Links limit)
WhatsAppGreen API + TwilioGreen API for personalized text, Twilio as template fallback
SMSTwilioIndustry standard, trial limits restrict testing
EmailResendAI-personalized HTML with branded template
FrontendReact 19 + Vite 8 + Tailwind 4Fast HMR, Razorpay UI clone
Live UpdatesREST API pollingDashboard auto-refreshes every 15-30s via backend API
Cache/LocksRedis (6 roles)Broker, cache, dedup, rate limit, locks, PII store

Security Architecture - 18 Defense Layers

Webhook HMAC-SHA256
Timing-safe hmac.compare_digest()
Body Size Limit
256 KB max payload
Two-Level Dedup
Redis SET NX (1h TTL) + PostgreSQL unique indexes
Rate Limiting
Sliding window per-endpoint via Redis sorted sets
AI Input Sanitization
200-char truncation + control character stripping
XSS Prevention
Regex-validated order IDs + json.dumps escaping
Server-Side PII
Redis with 24h-TTL token - never in URLs
Distributed Locks
Per-event Redis NX locks (300s TTL)
3-Layer Give-Up Prevention
Schema default → AI override → hard guard
Database Trigger
PostgreSQL blocks premature exhaustion from ANY writer
Race-Safe State
Conditional .eq("status","pending") on every update
Delivery Failure Detection
Separate delivery_failure_count stops infinite retries on unreachable contacts

From Prototype to Production in 4 Days

I did the research before writing a single line of code. Here's how it played out.

Before Aug 28 - Research Phase
I Studied Razorpay Like I Was Joining the Team
I went through their full product ecosystem: Vulcan, Agent Studio, Magic Checkout, Smart Collect. Analyzed 13 competitors globally to understand the recovery landscape. That's when I found my core insight: "Vulcan routes payments. Recovery Router routes failures."
Before Aug 28 - n8n Prototype
I Built 5 Workflows to Prove the Logic
Recovery Router, Invoice Scanner, Recovery Tracker, Escalation Agent, Analytics API. I proved the classify-route-act-measure pipeline worked - but n8n lacked distributed locking, dedup, and race condition handling. These prototypes would later come back to haunt me as the Ghost Writer bug.
Aug 28, 4:06 PM IST - Day 1
I Rebuilt Everything From Scratch
First commit: full 6-component architecture. FastAPI + Celery + Redis + Supabase + React. My rule was simple - "Everything will be async. Use Celery, workers, everything - no tricks."
Aug 30, 8:37 AM – 5:50 PM - The Marathon
Everything Came Together and Nearly Fell Apart
8:47 AM - Premature Give-Up bug discovered → 3-layer defense built.
10:59 AM - Ghost recovery prevention, honest metrics system born.
12:57 PM - TOCTOU race condition → distributed locks + conditional updates.
5:42 PM - Ghost Writer bug: n8n workflows still writing to DB → PostgreSQL trigger.
5:45–5:50 PM -3 Railway build failures in 8 minutes.
Aug 31, 7:34 AM - Final
I Ran a Full Security Audit on My Own Code
Found 6 security issues, fixed all of them in one commit. If this handles real money, I need to trust it myself first.

What Broke & How I Fixed It

These are the bugs that almost took me down. I'm sharing them because this is what separates production systems from demos.

01
The Premature Give-Up
Events exhausted after 1 attempt when budget was 5
What broke
  • AI schema defaulted action to "give_up" instead of "send"
  • Partial AI JSON inherited the destructive default
How I fixed it
  • Changed schema default to "send"
  • Added AI override checking for untried channels
  • Added hard guard blocking give-up when attempt_count < max_attempts
02
The Race Condition
Two Celery tasks processing the same event at the same time
What broke
  • _send_delayed and Beat escalation both picked up the same event
  • Task A reads "pending", Task B reads "pending" - one sets exhausted before the other finishes
How I fixed it
  • Conditional DB updates with .eq("status", "pending")
  • Per-event Redis distributed locks (300s TTL)
  • Atomic exhaustion check in a single write
03
The Ghost Writer Mystery
Event #18 was in an impossible state
What broke
  • Event marked exhausted with skip_reason=null - my code never does that
  • Checked every code path, git history, Celery tasks - everything was correct
  • Found my old n8n workflow was still writing directly to Supabase, bypassing my backend
How I fixed it
  • Unpublished all n8n workflows
  • Added PostgreSQL trigger - blocks ANY writer from premature exhaustion
  • Database-level defense, no matter what writes to it
04
The Budget Problem
Every event showing 1/5 attempts - "why is everyone the same?"
What broke
  • Hardcoded max_attempts = 5 for every event
  • A ₹50 browse-only cart got the same budget as a ₹30,000 failed invoice
How I fixed it
  • Built dynamic compute_max_attempts()
  • Budget based on amount, recovery probability, and category
  • Range: 0 (unrecoverable) to 5 (high-value)
05
The WhatsApp Problem
Messages sending generic templates instead of AI-personalized text
What broke
  • Twilio WhatsApp requires pre-approved content_sid templates
  • Couldn't send custom AI-generated text through it
How I fixed it
  • Prioritized Green API (free-form text) over Twilio
  • Twilio becomes the template-based fallback
06
The Infinite Retry Loop
Event #36 had fake contact info — the system kept retrying forever with no way to stop
What broke
  • A test event had invalid phone/email — every send attempt was rejected by the provider
  • attempt_count only increments on successful sends — provider rejections left it at 0
  • The safety guard (attempt_count < max_attempts) always passed — the event could never exhaust
  • Deadlock: the counter that stops retries only moves when you succeed, but you can never succeed
How I fixed it
  • Added delivery_failure_count — a separate counter for hard provider rejections
  • Doesn't count cooldowns or quiet hours — only real failures (provider says "this contact is unreachable")
  • Gate: delivery_failure_count > max_attempts → mark exhausted with skip_reason
  • Bypass: if any past attempt ever succeeded (has_any_sent), skip the gate — the contact works
  • Wired into all 3 send paths: initial, delayed, and escalation

The Numbers Behind Recovery Router

~₹0.65
Cost per recovery attempt
AI classification + message send via the cheapest model in my fallback chain
0.5%
Break-even recovery rate
If even 1 in 200 messages recovers a payment, the system pays for itself
47.6%
Industry recovery rate
Median across existing tools - that's the bar I'm building toward

What changes for a Razorpay merchant

ScenarioTodayWith Recovery Router
Payment failsMerchant follows up manually, or doesn'tAI classifies the failure and sends a personalized message within seconds
Cart abandonedNo recovery - lost revenueHigh-intent carts get recovery; browse-only ones get zero attempts (saves cost)
Invoice overdueManual reminders, takes weeksAutomated within hours - tone escalates with urgency
Customer ghosts40% never come backMulti-channel outreach (email → SMS → WhatsApp) within the optimal window
Honest note: These numbers are from my test-mode data with simulated scenarios. I track whether the message was accepted by the provider ("sent"), not whether the customer actually paid. Real recovery rates depend on merchant volume, payment mix, and customer behavior.

Full System Walkthrough

I walk you through the architecture, live demos with dynamic budgets, safety mechanisms, the Ghost Writer bug story, honest metrics, the test suite, and the future of agent-to-agent recovery.

Demo Video
Coming soon

What the Demo Covers

SectionWhat's Shown
OpeningPersonal intro — why I picked Track 3, the insight behind Recovery Router
ArchitectureSix-component architecture with decision reasons for each technology choice
Live DemoSimulator scenarios showing dynamic budgets, then real Razorpay test-mode checkout
DashboardEvents page walkthrough — different classifications, budgets, and AI reasoning
Safety18 defense layers, 3-layer give-up prevention, then the Ghost Writer bug story
AnalyticsHonest metrics — organic vs recovered, code overlay for ghost recovery prevention
Testing397-test suite run + CI pipeline + bug war stories
EcosystemWhere Recovery Router fits in Razorpay's product suite + the build journey
FutureAgent-to-agent recovery — why traditional channels fail when the payer is an AI agent

397 Tests. Four Tiers. Every Function Covered.

Split into unit (247 offline, no credentials), live (92 integration, real services), e2e (31 standalone flows), and frontend (27 component tests). Unit tests verify every backend function anywhere. Live tests hit real Redis, real Supabase, real AI. CI runs 274 tests on every push.

Unit Tests - 247 offline tests
  • Classifier orchestration - 29 tests (AI orchestration + all 12 fallback categories)
  • Escalation helpers - 28 tests (channel rotation, AI decisions, state updates)
  • Messenger - 27 tests (3 degradation chains, 4 provider guards)
  • Models - 21 tests (all 10 Pydantic models validated)
  • Message generator - 18 tests (AI fallback, XSS prevention)
  • Router logic - 15 tests for budgets + channel routing
  • Dedup - 15 tests (hash determinism, identifier priority)
  • Recovery task - 13 tests (durable dedup, quiet hours)
  • Classifier logic - 13 tests (category mapping, probability)
  • Reconciliation - 12 tests (amount, currency, duplicates)
  • Quiet hours - 10 tests (IST boundary conditions)
  • Idempotency keys - 9 tests (format, uniqueness)
  • Invoice scanner - 8 tests, escalation logic - 8 tests
  • Rate limiter - 6, payment links - 6, stale reservations - 5, delivery failure gate - 4
Security - 20 live tests
  • SQL injection - 3 attack vectors
  • XSS - 3 attack vectors
  • CORS - 3 origin checks
  • Webhook signature verification
  • Input validation - 5 edge cases
  • Path traversal - 2 vectors
Pipeline - 15 live tests
  • All 10 failure scenarios classified correctly
  • AI fallback chain (Haiku → Gemini → GPT)
  • Dynamic budget assignment
  • Ghost recovery prevention
  • Race condition guards
API, E2E, Load & Frontend - 115 tests
  • 38 endpoint tests across all routes
  • 13 error scenarios - timeouts, bad input, server faults
  • 31 standalone end-to-end flows
  • 6 concurrency and load tests
  • 27 frontend component tests (Vitest + React Testing Library)

What I Haven't Done Yet

I'd rather tell you what's missing than pretend it's all done.

  • Test-mode only - all Razorpay calls use test keys, no real merchant data yet
  • I track "sent", not "delivered" - I know the provider accepted the message, but I can't confirm the customer actually read it
  • Single shared password for the dashboard - works for a demo, but production needs per-user auth with JWT
  • Supabase service key in the backend - bypasses row-level security, production would use scoped tokens
  • One Celery worker - handles current load fine, but would bottleneck at scale (architecture already supports horizontal scaling though)
  • Quiet hours are IST-only - everyone gets 9 PM – 9 AM Indian time, no per-customer timezone support

I Built This to Plug Into Razorpay

Recovery Router isn't a standalone tool - it's designed to sit inside Razorpay's existing ecosystem and fill the gap after a payment fails.

VULCAN
Optimizes routing to prevent failures - my system picks up when prevention wasn't enough
PAYMENT GATEWAY
Fires payment.failed webhooks - that's my primary entry point
MAGIC CHECKOUT
Tracks checkout behavior - I use that data to pick better recovery channels for returning customers
AGENT STUDIO
Could serve as execution endpoints - my pipeline dispatches, their agents deliver
SUBSCRIPTIONS
Does mechanical T+1/T+2/T+3 retries - I add contextual intelligence on top
SMART COLLECT
Creates virtual accounts - useful as B2B invoice recovery endpoints

When the Payer Isn't Human

Razorpay's Agent Studio launched AI agents that initiate payments. When the payer is also an agent, who do you send the WhatsApp to?

The Problem
AI agents handling procurement, subscriptions, and automated purchasing don't check inboxes. They don't read SMS. Traditional recovery channels — WhatsApp, email, SMS — are fundamentally incompatible with agent-initiated payments. When an agent's payment fails, sending a recovery link to a human who didn't initiate the purchase makes no sense.
The Architecture Is Ready
Recovery Router's classify-route-act pipeline is channel-agnostic. Today the channels are WhatsApp, SMS, and email. Tomorrow, the channel could be an API callback to the paying agent. The pipeline doesn't change — only the last mile does. Agent-to-agent recovery: machines resolving payment failures in seconds, not hours.
Agentic Recovery Demo
The dashboard includes an Agentic Recovery page that demonstrates agent-initiated payment failure scenarios — expired authorization mandates, delegation limit exceeded, consumed payment credentials. It visualizes the animated recovery pipeline and shows how traditional channels fail when the payer is an AI agent, pointing toward API-based agent-to-agent recovery as the next evolution.

The Developer

Albert Abishek I
Albert Abishek I
Chennai, Tamil Nadu, India
B.E. Computer Science & Engineering (2023–2027)
Thanthai Periyar Govt. Institute of Technology, Vellore

Experience

AI Automation Developer
Funnel Truffle · Mumbai (Remote)
June 2026 – Present
Building full-stack AI products - social listening tools, multi-model LLM platforms, and audience intelligence systems using FastAPI, Next.js, Celery, Redis, and PostgreSQL. Also designing automation workflows (n8n, Make, Zapier) for marketing and CRM pipelines.
AI Automation
CSTE Group · Delhi (Remote)
November 2025 – May 2026
Built internal dashboards and tools using React, Streamlit, Flask, and Supabase. Integrated third-party APIs (YouTube, Google Sheets, Shopify, CRM platforms).
Web Development & SEO
AdventX · England, UK (Remote)
August 2025 – November 2025
Redesigned website pages with React.js + TypeScript. Integrated Prisma ORM and Stripe payment gateway. Contributed to internal SaaS product.
Automation Engineer
CodeSA Technologies · Adelaide, Australia (Remote)
June 2025 – August 2025
Designed automation workflows in n8n, Zapier, and Make. Integrated APIs connecting Google Workspace, Notion, Slack, and CRM systems.

Technical Skills

Languages & Backend
PythonJavaScriptTypeScript SQLFastAPIFlask DjangoNode.js
AI & Automation
OpenAI APIRAGQdrant n8nMake.comCelery Prompt Engineering
Frontend & Cloud
ReactTailwind CSSVite SupabaseRedisRailway Vercel
Integrations
Razorpay APITwilioStripe Google APIsSlack APIShopify

"I didn't build a hackathon project. I built what I would build if I were a Razorpay engineer assigned to solve this problem on Day 1."

You're Probably Wondering

Doesn't Razorpay already have a failed payment recovery product?
Yes, but it's focused on subscription payments - basically WhatsApp reminders on a schedule. What I built handles all three revenue leaks (failed payments, abandoned carts, overdue invoices) through one AI pipeline. It decides how many attempts each event deserves, picks the right channel, and tracks whether recovery was actually caused by outreach or happened on its own.
Why didn't you use Agent Studio for this?
Agent Studio gives you individual agents for specific tasks - great building blocks. But I needed the full pipeline: classify the failure, decide the budget, pick the channel, send the message, handle crashes, prevent race conditions, and measure honestly. That's an orchestration layer, not a single agent. Though Agent Studio agents could plug in as execution endpoints later.
So what's the actual recovery rate?
Honestly? I don't know yet. This runs on test-mode data with simulated scenarios. I can tell you the pipeline works end-to-end, and I can tell you the message was accepted by the provider - but I can't tell you the customer actually paid. Real numbers need real merchants, real volume, and delivery receipt integration I haven't built yet.
Can this handle scale?
Right now it runs on one Celery worker, which handles my test load fine. But each recovery event is an independent task with its own distributed lock, so scaling is just adding more workers - no code changes needed. Redis handles the queue, Supabase handles persistence.
Won't this spam customers?
That was one of my biggest concerns. So I built guards: 5-minute cooldowns per phone/email, quiet hours (no messages between 9 PM – 9 AM), dynamic budgets that cap total attempts, and browse-only carts get zero attempts. If someone cancelled on purpose, they get at most 2 gentle nudges. The goal is to recover revenue without annoying people.
Why three AI models?
Because any single API can go down. If Haiku is unavailable, Gemini takes over. If both are down, GPT-4o-mini. And if all three fail, rule-based classification keeps the system running (with a confidence penalty). In payment recovery, you can't just stop and wait - the timing window matters.
What would you build next?
Delivery receipts - so I can track if someone actually opened the message, not just that it was sent. Hinglish voice recovery for regional users. A/B testing different recovery messages. And plugging into Magic Checkout so I can prevent some failures before they happen.