AI-Powered Financial Remediation Engine
Policy-bounded LLM agent that recovers failed payments through negotiation, not just retries.
Follow @Razorpay Β· @RazorpayDevs Β· #RazorpayBuildathon #Track03 #AIRevenueRecovery
remediate is a Policy-Bounded Conversational Financial Concierge - an LLM agent that recovers high-value, complex payment failures that standard retry-and-notify systems cannot handle.
It doesn't compete with Razorpay's Smart Retries or Agent Studio. It specialises in cases where the root cause is financial friction - cash flow issues, sticker shock, B2B billing delays - requiring negotiation and restructuring, not just another payment link blast.
Built for Razorpay AI Buildathon 2026 - Track 03: AI Revenue Recovery
flowchart TD
A[π‘ Razorpay Webhooks\npayment.failed\ncheckout.abandoned\ninvoice.expired] --> B
B[π Event Normalizer\nevent_normalizer.py\nWebhook β RecoveryEvent\n+ Fraud & Late-Auth Flags] --> C
C[π§ Context Aggregator\ncontext_aggregator.py\nRecovery Probability\nPolicy Constraint Checks\nLLM Context Block] --> D
D{π Fast-Path\nStopping Rules}
D -->|Fraud Flag| E1[π« do_nothing\nFraud]
D -->|Late Auth Risk| E2[βΈοΈ do_nothing\nLate Auth]
D -->|Budget Exceeded| E3[β do_nothing\nBudget]
D -->|Pass| F
F[π€ AI Decision Engine\ndecision_engine.py\nGemini 2.5 Flash\nFunction Calling\nOR Heuristic Fallback] --> G
G{6 Policy-Bounded Tools}
G --> T1[π³ create_payment_link\n55% simulated recovery]
G --> T2[π
convert_to_emi\n60% simulated recovery]
G --> T3[π·οΈ apply_discount\n65% simulated recovery\nmax 15% per policy]
G --> T4[π€ schedule_promise_to_pay\n50% simulated recovery]
G --> T5[β¬οΈ downgrade_subscription\n75% simulated retention]
G --> T6[π« do_nothing\nExplicit stop]
T1 & T2 & T3 & T4 & T5 & T6 --> H
H[βοΈ Remediation Executor\nremediation_executor.py\nMock Razorpay API\nIdempotency + Retry] --> I
I[π Audit Logger\naudit_logger.py\nSQLite DB + JSONL\nHTTP Broadcast] --> J
I --> K[π FastAPI + WebSocket\napi/index.py]
J[π Evaluation Engine\nscripts/evaluator.py\nAI vs Baseline\nRecovery Report]
K --> L[π» React Dashboard\nReal-time UI]
style A fill:#072654,color:#fff
style F fill:#4285F4,color:#fff
style G fill:#1a1f2e,color:#fff
style I fill:#059669,color:#fff
style D fill:#dc2626,color:#fff
style K fill:#009688,color:#fff
style L fill:#61dafb,color:#000
| Capability | How It Works | Razorpay API Used |
|---|---|---|
| Dynamic EMI Conversion | Restructures high-value failures into 2β6 monthly instalments | Payment Links (series) |
| Promise-to-Pay Tracker | Parses natural language date, pauses retries, schedules link delivery | Notifications + Scheduler |
| Anti-Churn Downgrades | Switches subscription to lower tier or temporary pause | Subscriptions API |
| Smart Discounts | Bounded by max_discount_pct: 15% - cooldown enforced |
Payment Links |
| Fraud Hard Stop | card_stolen / customer_fraud_risk β immediate do_nothing |
None (policy override) |
| Late-Auth Safety | Razorpay timeout β hold, no duplicate link created | None (wait) |
| Intervention Budget | Customer with β₯3 interventions in 30 days β auto-skip | Policy enforcement |
The following metrics are from an actual run of 500 synthetic revenue-at-risk events. No fake data.
| Metric | Baseline (Naive Retry) | remediate (AI Engine) | Lift |
|---|---|---|---|
| Events Processed | 500 | 500 | - |
| Revenue at Risk (Rs) | 2,21,72,623 | 2,21,72,623 | - |
| Revenue Recovered (Rs) | 88,69,049 | 92,71,323 | +Rs 4,02,274 |
| Recovery Rate | 40.0% | 41.8% | +1.8 pp |
| Brand Damage Cost (Rs) | 1,215 | 0 | Eliminated |
| Fraud Events Stopped | 0 / 59 | 59 / 59 | 100% |
| Late-Auth Double-Charges | 22 sent | 0 sent | Prevented |
| Do-Nothing Decisions | 0 | 99 | Policy-compliant |
| Net Recovery Lift | - | - | +4.6% |
| Processing Time | - | 4.6 seconds | - |
| Tool | Events | Revenue Recovered (Rs) | Avg / Event (Rs) |
|---|---|---|---|
create_payment_link |
278 | 55,09,364 | 19,818 |
do_nothing |
99 | 0 | 0 |
convert_to_emi |
79 | 19,88,968 | 25,177 |
schedule_promise_to_pay |
30 | 17,55,000 | 58,500 |
apply_discount |
14 | 17,991 | 1,285 |
| Failure Reason | Events | Recovery Rate |
|---|---|---|
do_not_honor |
41 | 77.1% |
card_expired |
36 | 61.8% |
cart_abandoned |
28 | 60.9% |
invoice_overdue_b2b |
18 | 53.8% |
invoice_overdue_b2b_long |
15 | 50.0% |
invalid_otp |
89 | 50.6% |
insufficient_funds |
75 | 42.9% |
subscription_renewal_failed |
62 | 43.7% |
card_stolen |
39 | 0.0% β (fraud halted) |
timeout |
22 | 0.0% β (late-auth held) |
remediate/
βββ batch_runner.py # π Entry point - run this
β
βββ config/
β βββ merchant_policy.json # π All AI bounds defined here
β
βββ engine/ # π§ Core package
β βββ __init__.py
β βββ event_normalizer.py # Webhook β RecoveryEvent
β βββ context_aggregator.py# Enrichment + policy pre-check
β βββ decision_engine.py # Gemini function calling + fallback
β βββ razorpay_mock.py # Mock Razorpay API layer
β βββ remediation_executor.py # Tool execution + idempotency
β βββ orchestrator.py # Pipeline connector
β βββ audit_logger.py # Structured JSONL audit trail
β
βββ scripts/
β βββ generate_events.py # Generates 500 synthetic events
β βββ evaluator.py # AI vs baseline comparison
β
βββ api/
β βββ index.py # π FastAPI Server (REST + WebSocket)
β
βββ dashboard-app/ # π» React + Vite Frontend
β βββ src/ # Modern UI with Tailwind CSS v4
β βββ package.json # Node dependencies
β
βββ data/ # Generated (not committed)
β βββ synthetic_events.jsonl
β
βββ outputs/ # Generated (not committed)
βββ audit_log.jsonl
βββ batch_outcomes.jsonl
βββ evaluation_report.md
All AI decisions are strictly bounded by config/merchant_policy.json. The LLM cannot exceed these limits:
{
"discount_policy": { "max_discount_pct": 15, "discount_cooldown_days": 90 },
"emi_policy": { "allow_emi_conversion": true, "max_emi_months": 6, "min_order_value_inr": 3000 },
"promise_to_pay_policy": { "max_deferral_days": 30, "max_promise_attempts_per_invoice": 2 },
"intervention_budget": { "max_interventions_per_customer_per_30d": 3 },
"stopping_rules": { "stop_on_recovery_probability_below_pct": 5 },
"human_escalation": { "escalate_on_amount_above_inr": 50000, "escalate_on_b2b_invoice_overdue_days": 14 }
}git clone https://github.com/x2ankit/remediate.git
cd remediate
# Create conda environment (Python 3.11)
conda create -n remediate python=3.11 -y
conda activate remediate
# Install dependencies
pip install -r requirements.txtpython scripts/generate_events.py
# Output: data/synthetic_events.jsonl (500 events)python batch_runner.py# Windows (PowerShell)
$env:GEMINI_API_KEY = "your-api-key-here"
python batch_runner.pypython scripts/evaluator.py
# Output: outputs/evaluation_report.mdStart the backend API server:
uvicorn api.index:app --reload --port 8000Start the React frontend:
cd dashboard-app
npm install
npm run dev
# Open: http://localhost:5174flowchart LR
A[Raw Event] --> B{Fraud Flag?}
B -->|Yes| Z1[do_nothing\nfraud_flag]
B -->|No| C{Late Auth Risk?}
C -->|Yes| Z2[do_nothing\nlate_authorization_risk]
C -->|No| D{Intervention\nBudget Exceeded?}
D -->|Yes| Z3[do_nothing\nbudget_exceeded]
D -->|No| E{Recovery\nProb < 5%?}
E -->|Yes| Z4[do_nothing\nprob_too_low]
E -->|No| F[Gemini\nFunction Calling]
F --> G{Select Tool}
G -->|B2B Invoice| T1[schedule_promise_to_pay]
G -->|Insufficient Funds\n+ High Value| T2[convert_to_emi]
G -->|Subscription Failure| T3[downgrade_subscription]
G -->|Cart Abandon\n+ Discount OK| T4[apply_discount]
G -->|Default| T5[create_payment_link]
style F fill:#4285F4,color:#fff
style Z1,Z2,Z3,Z4 fill:#dc2626,color:#fff
| Problem with Naive Retry | How remediate Solves It |
|---|---|
| Blasts fraud victims with payment links | Hard stop on card_stolen / customer_fraud_risk |
| Creates duplicate links after Razorpay timeout | Late-auth detection β do_nothing |
| Annoying customers who already said "I'll pay Friday" | Promise-to-Pay tracker pauses all retries |
| Rs 30,000 invoice fails β send Rs 30,000 link | Splits into 3x Rs 10,000 EMI links |
| Repeats discounts to same customer every week | 90-day discount cooldown enforced |
| No audit trail | Full JSONL record: reason β decision β outcome |
| Package | Version | Purpose |
|---|---|---|
google-generativeai |
β₯ 0.8.0 | Gemini function calling (optional) |
python-dateutil |
β₯ 2.9.0 | Date parsing for Promise-to-Pay |
No API key needed - the engine runs in heuristic mode with zero external dependencies.
This project was built for the Razorpay AI Buildathon 2026. PRs, issues, and forks are welcome.
Engineered for the Razorpay Ecosystem
@Razorpay Β· @RazorpayDevs
#RazorpayBuildathon #Track03 #AIRevenueRecovery #FinTech #GenerativeAI