Skip to content

Repository files navigation

Recoup — Autonomous AI Revenue Recovery Agent for Razorpay

Razorpay AI Buildathon · Track 03: Revenue Recovery
Failed payments are not a support ticket. They are a queue of decisions.

Next.js 16.3.4 React 19 TypeScript 5.9 Tailwind CSS v4 Drizzle ORM Inngest Google Gemini


⚡ Executive Summary

Indian digital businesses lose between 5% to 18% of monthly recurring revenue to failed payments. When payments fail, merchants typically react in two flawed ways:

  1. Blind brute-force retries (which destroy customer goodwill, incur gateway fees, and can trigger fraud blocks).
  2. Manual customer support tickets (which are slow, expensive, and result in churn before an agent ever reaches out).

Recoup is an autonomous revenue recovery agent built directly on top of Razorpay. It watches one-time checkout failures and failing subscription mandates in real time, diagnoses root causes, and executes bounded, omnichannel recovery playbooks (SMS, Email, Payment Links) — all constrained by an impenetrable, compliance-first Policy Gate.


🏛️ Core Architectural Principles

Recoup is engineered around five fundamental principles of financial systems engineering:

1. Rules First, Model Second (Cost & Latency Optimization)

  • Unambiguous Razorpay error codes (GATEWAY_ERROR, BAD_REQUEST_ERROR, INSUFFICIENT_FUNDS, etc.) resolve through a deterministic triage matrix with 0ms latency and $0 token cost.
  • The LLM (Google Gemini Flash Lite) is treated as an escalation tier — invoked only when error codes are contradictory, missing, or vendor-mangled.
  • When invoked, Gemini returns strictly validated JSON (Zod-enforced schema). If the model times out, degrades, or violates schema, the system gracefully falls back to conservative rules without crashing.

2. Bounded Policy Gate (Separation of Diagnosis vs. Execution)

In automated financial systems, an AI model must never be allowed to execute actions directly. Recoup decouples diagnosis from execution:

  • The Thinker (Triage + Gemini LLM) proposes an action.
  • The Gatekeeper (Policy Gate) evaluates non-negotiable business rules:
    • Quiet Hours: Respects Indian Standard Time (IST); no customer contact between 9:00 PM and 9:00 AM IST.
    • Value Floor: Refuses to contact customers for amounts under the merchant's configured floor (e.g., ₹200), preventing communications that cost more than the fee recovered.
    • Contact Frequency: Caps customer contact intervals (e.g., minimum 24h between messages across all cases).
    • Daily Send Caps: Hard limit on merchant-wide daily outbound notifications.
    • Kill Switch: Instant merchant-wide pause that freezes execution while keeping cases queued.

3. Non-Negotiable Hard Stops

  • If an event is diagnosed as fraud, stolen card, account frozen, or revoked customer mandate, Recoup executes a Hard Stop.
  • Hard stops cannot be overridden by the LLM, the merchant, or any human operator. The refusal itself is permanently written to the audit log.

4. Append-Only Compliance Audit Trail

  • Designed for fintech auditability: there are no UPDATE or DELETE procedures in the audit log.
  • Every case records a full chronological trail of decision nodes: ingesttriagediagnosepolicyactoutcome.
  • Human overrides do not overwrite machine decisions; they are appended alongside the machine decision with timestamp, actor ID, and rationale.

5. Closed-Loop Real-World Execution

  • When an action is permitted, Recoup calls the Razorpay API to mint a unique, trackable Payment Link with custom case metadata.
  • Outbound copy is delivered via Resend (Email) and Razorpay (SMS notifications directly to the customer's phone).
  • When the customer completes the payment, Razorpay emits a payment_link.paid or payment.captured webhook. Recoup captures it, matches the case, flips the status to RECOVERED, and credits the recovered rupees to the merchant's dashboard.

🔄 The 6-Stage Pipeline

graph TD
    A[Razorpay Webhook / Synthetic Event] --> B[Stage 1: Ingestion & Deduplication]
    B --> C[Stage 2: Deterministic Triage]
    C -->|Unambiguous Code| E[Triage Decision]
    C -->|Ambiguous / Mangled| D[Stage 3: Gemini AI Diagnosis]
    D --> E
    E --> F[Stage 4: Bounded Policy Gate]
    F -->|Hard Stop / Opt-out| G[Blocked / Hard Refusal]
    F -->|Quiet Hours / Value Floor / Low Conf| H[Held / Escalated to Human]
    F -->|Allow Verdict| I[Stage 5: Execution Engine]
    I --> J[Mint Razorpay Payment Link]
    I --> K[Dispatch Email Resend + SMS Razorpay]
    I --> L[Stage 6: Outcome & Closed-Loop Capture]
    L -->|Customer Pays Link| M[Case RECOVERED]
Loading
  1. Stage 1: Ingest & Deduplication:
    • Validates webhook HMAC-SHA256 signature against the merchant's encrypted secret.
    • Enforces idempotency on razorpay_entity_id (pay_...), acknowledging duplicate deliveries within 50ms to prevent gateway retry storms.
  2. Stage 2: Triage:
    • Pure rules engine. Evaluates lane (one_time vs subscription), error codes, and customer history.
  3. Stage 3: Diagnose:
    • Only invoked if needsDiagnosis is true. Calls Gemini Flash Lite to extract root cause, customer sentiment, transient vs. permanent failure, and recommended action.
  4. Stage 4: Policy Gate:
    • Evaluates autonomy mode (auto, approve, suggest), quiet hours, attempt caps, frequency floors, and confidence bars.
  5. Stage 5: Act:
    • Mints live test payment links via Razorpay API and dispatches personalized recovery messages.
  6. Stage 6: Outcome:
    • Listens for downstream recovery payments to verify actual rupees recovered.

??? Tech Stack

Layer Technology Purpose
Framework Next.js 16.3.4 (App Router) Latest React Server Components, Turbopack, and network proxy.ts boundary
Frontend React 19, Tailwind CSS v4, Motion Responsive, high-density fintech dashboard inspired by Bloomberg/Linear
Icons & UI Lucide React, Radix UI, Sonner Accessible primitives, clean toasts, and iconography
Database Neon Serverless PostgreSQL Cloud-native serverless Postgres with instant branching
ORM Drizzle ORM Type-safe SQL schema, relationships, and ultra-fast migrations
API & RPC tRPC v11 + TanStack Query v5 End-to-end type safety between server routers and client queries
Auth Better Auth Multi-tenant auth supporting Email/Password and Google OAuth
Background Jobs Inngest Event-driven, durable workflow orchestration with automatic retries
AI / LLM Google Gemini (gemini-flash-lite-latest) Fast, structured JSON diagnosis of ambiguous payment failures
Payment Gateway Razorpay REST API & Webhooks Payment link generation, test-mode payment capture, customer notification
Email Delivery Resend Transactional omnichannel recovery emails
Runtime Bun v1.3+ / Node.js 20+ High-performance JavaScript package manager and runtime

?? Project Structure

recoup-next/
+-- AGENTS.md                  # Next.js 16 AI agent guide
+-- next.config.ts             # Next.js 16 config (allowedDevOrigins, transpilePackages)
+-- package.json               # Dependencies and maintenance scripts
+-- drizzle.config.ts          # Drizzle kit configuration for Neon PostgreSQL
+-- src/
¦   +-- proxy.ts               # Next.js 16 network-boundary proxy (supersedes middleware.ts)
¦   +-- app/
¦   ¦   +-- layout.tsx         # Root HTML layout with Sora & IBM Plex typography
¦   ¦   +-- page.tsx           # Public landing page explaining core pillars
¦   ¦   +-- login/             # Better Auth sign-in / sign-up page
¦   ¦   +-- api/
¦   ¦   ¦   +-- auth/[...all]/ # Better Auth API route handler
¦   ¦   ¦   +-- inngest/       # Inngest serverless endpoint (GET, POST, PUT)
¦   ¦   ¦   +-- trpc/[trpc]/   # tRPC fetch request handler
¦   ¦   ¦   +-- webhooks/
¦   ¦   ¦       +-- razorpay/[merchantId]/ # Webhook ingestion with deduplication
¦   ¦   +-- app/               # Authenticated Merchant Portal
¦   ¦       +-- layout.tsx     # Session gatekeeper & auth protection
¦   ¦       +-- page.tsx       # Command Centre (At-risk vs Recovered, Feed, Attention)
¦   ¦       +-- cases/         # Cases explorer & interactive decision tree
¦   ¦       ¦   +-- [id]/      # Detailed case view, audit chain & human controls
¦   ¦       +-- batch/         # Synthetic benchmark generator & model scorecard
¦   ¦       +-- guardrails/    # Policy gate configuration & emergency kill switch
¦   ¦       +-- audit/         # Compliance audit log with search, filters & CSV export
¦   ¦       +-- setup/         # Razorpay credentials & webhook endpoint setup
¦   +-- components/            # Shell layout, decision chain, UI kit primitives
¦   +-- lib/                   # tRPC client, Better Auth client, formatting utilities
¦   +-- queries/               # TanStack query hooks with stale-time caching
¦   +-- server/
¦       +-- auth/              # Better Auth server configuration with Drizzle adapter
¦       +-- db/                # Neon PostgreSQL connection & full Drizzle schema
¦       +-- inngest/           # Inngest client, events, and durable workflow functions
¦       +-- lib/               # Crypto (AES-256), Razorpay API client, audit logging
¦       +-- pipeline/          # Core recovery engine
¦       ¦   +-- run.ts         # Pipeline orchestration (Stages 1–6)
¦       ¦   +-- triage.ts      # Deterministic rules classification
¦       ¦   +-- diagnose.ts    # Gemini LLM diagnosis & copy drafting
¦       ¦   +-- policy-gate.ts # Guardrail checks, channel picker, quiet hours
¦       ¦   +-- executor.ts    # Razorpay link minting & Resend email delivery
¦       ¦   +-- taxonomy.ts    # Failure taxonomy (16 failure classes & playbooks)
¦       ¦   +-- synthetic.ts   # Synthetic batch engine & ground-truth simulator
¦       +-- trpc/              # tRPC routers (dashboard, cases, policy, merchant, audit)
+-- scripts/
    +-- clean-db.ts            # Safe database truncate script for demo resets

?? Getting Started

Prerequisites

  • Bun (v1.2+) or Node.js (v20.9+)
  • A Neon Serverless Postgres database
  • A Razorpay account (Test mode API keys)
  • A Google AI Studio API Key (GEMINI_API_KEY)
  • An Inngest account (for production durable workflows)
  • A Resend API key (for live email delivery)

1. Clone & Install Dependencies

git clone https://github.com/TheRealShreyash/recoup.git
cd recoup/recoup-next
bun install

2. Configure Environment Variables

Create a .env.local file in recoup-next/:

# Database (Neon PostgreSQL)
DATABASE_URL="postgresql://user:password@ep-xyz.aws.neon.tech/neondb?sslmode=require"

# Application URL
NEXT_PUBLIC_APP_URL="http://localhost:3000"
BETTER_AUTH_URL="http://localhost:3000"
BETTER_AUTH_SECRET="your-32-char-random-secret"

# LLM Diagnosis (Google Gemini)
GEMINI_API_KEY="AIzaSy..."
GEMINI_MODEL="gemini-flash-lite-latest"

# Email Delivery (Resend)
RESEND_API_KEY="re_..."

# Durable Background Workflows (Inngest)
INNGEST_EVENT_KEY="your-inngest-event-key"
INNGEST_SIGNING_KEY="signkey-prod-..."

# Optional: Google OAuth
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""

3. Push Database Schema

bun run db:push

4. Run Development Server

# In one terminal, start the Next.js app:
bun run dev

# In a second terminal (optional, for local Inngest dev server):
npx inngest-cli@latest dev

Visit http://localhost:3000 to create your merchant account and access the dashboard.


?? Testing the Live Recovery Flow

  1. Connect Razorpay: Navigate to /app/setup and input your Razorpay Test Key ID & Secret.
  2. Expose Localhost via ngrok:
    ngrok http 3000
  3. Register Webhook: In your Razorpay Dashboard, set the webhook URL to:
    https://<your-ngrok-id>.ngrok-free.app/api/webhooks/razorpay/<your-merchant-id>
    
    Select events: payment.failed, payment_link.paid, payment.captured.
  4. Trigger a Payment Failure: Use Razorpay test checkout and trigger a failure (e.g. Netbanking ? Failure).
  5. Watch Recoup Act:
    • The failure is ingested and triaged.
    • If held for review, approve it from the Cases screen.
    • Razorpay will automatically create a payment link and send an SMS to the customer's phone!
    • Click the link in the SMS, complete the payment (Netbanking ? Success), and watch the case automatically flip to Recovered on your dashboard!

??? Security & Guardrails

  • Enforced Test Mode: Recoup deliberately refuses live Razorpay API keys (rzp_live_...). Money-moving requests cannot be sent to production banks.
  • AES-256 Key Encryption: Merchant webhook secrets and API keys are encrypted at rest using AES-256-GCM before being stored in the database.
  • Webhook Signature Verification: Every incoming webhook payload is cryptographically validated using HMAC-SHA256 signatures.

?? License

Built for the Razorpay GenAI Cohort Hackathon (Track 03). MIT License.

About

Recoup is an autonomous revenue recovery agent built directly on top of Razorpay. It watches one-time checkout failures and failing subscription mandates in real time, diagnoses root causes, and executes bounded, omnichannel recovery playbooks (SMS, Email, Payment Links), all constrained by an impenetrable, compliance-first Policy Gate.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages