Black Friday 2025 starts at midnight tonight. Cyber Monday is December 1. We have spent the last three weeks running a 6-point stack audit on 11 Razorpay-powered Indian SMB clients — Tier-1 D2C brands, Tier-2 sarees retailers, a Pune logistics aggregator, and three SaaS shops with international BFCM exposure. This post is the audit checklist itself, the failure modes we caught (28 across the 11 clients), and the exact fixes we shipped before the deadline. If you have a Razorpay checkout going live tomorrow, run this list tonight.
TL;DR — the 6 checks in 60 words
(1) API rate-limit headroom: confirm Razorpay's 100 req/min default does not throttle your peak. (2) Retry budgets: bounded retries with idempotency keys, no infinite loops. (3) COD throttling: OTP + per-IP rate limit + refundable deposit on orders >₹2,500. (4) Abandoned-cart hooks: 1h, 4h, 18h WhatsApp + email triggers. (5) Fraud rules: velocity, geography, BIN-list filters. (6) Support routing: tiered queue, auto-escalation, war-room channel.
Why this matters now — November 27, 2025
BFCM 2025 is the first festive window where most Indian SMB stacks are running on the post-IMS, post-MFA, post-30-day-IRP regulatory regime. Diwali 2025 was the load test for the gateway and the inventory layer. BFCM is the test for the international-card layer (NRI buyers spike), the abandoned-cart conversion engine, and the support team's stamina. The patterns differ from Diwali in three specific ways:
We crosschecked our audit against the Triple Whale BFCM 2025 checklist and the Shopify India BFCM prep — both recommend testing every payment method twice and confirming webhook stability under load. Most SMBs we audit have done it once on a Tuesday morning.
The 6 checks, in priority order
Check 1: rate-limit headroom (this kills first)
Razorpay's standard rate limit is 100 requests per minute per merchant on the standard plan. A cart-to-payment flow typically uses 3-5 calls (order_create, order_fetch, payment_capture, webhook ack). At BFCM peak, an SMB doing 1,200 orders/hour needs ~100 calls/min just for the happy path — leaving zero headroom for retries, status checks, and admin queries.
- The audit:
- Pull the last 7 days of Razorpay API calls from your monitoring (or count from the dashboard's Insights).
- Identify peak 60-second windows.
- If peak is >60 calls/min, you are at risk of being throttled during BFCM.
- The fix:
- Email Razorpay support at care@razorpay.com 7+ days ahead requesting a temporary rate-limit bump for "Black Friday-Cyber Monday traffic." They typically grant 3-5x the default for the BFCM week if you ask before November 21. After Nov 24, the response time is variable.
- In parallel, batch where possible: instead of one order_fetch per webhook receive, batch every 5 webhooks into a single fetch. Razorpay supports the bulk fetch endpoint for this.
A Pune client of ours hit the rate limit at 2:14 pm on Cyber Monday 2024 — Razorpay throttled them for 22 minutes, during which conversions dropped from 9.4% to 1.2%. We had asked them to email Razorpay on Nov 19 — they did not. The lost revenue: ~₹1.8 lakh. The cost of the email: 4 minutes.
Check 2: bounded retry budgets and circuit breakers
This is the audit that catches the most failure-mode debt. We see it in 7 of 11 stacks.
The pattern that fails: a try-catch wrapping a Razorpay API call, with retry logic that does for (let i = 0; i < Infinity; i++) or while (true) until success. When Razorpay returns 503 for 9 minutes (which it did during one of our simulated load tests), the retry queue grows unboundedly. Every request thread is now blocked. New requests fail immediately because the thread pool is exhausted. The SMB looks down even after Razorpay recovers.
The fix is the circuit breaker pattern:
// Pseudo-code: a simple circuit breaker for Razorpay calls
class RazorpayCircuitBreaker {
constructor({ failureThreshold = 5, resetTimeoutMs = 30000 }) {
this.failureCount = 0;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.lastFailureTime = null;
this.threshold = failureThreshold;
this.resetMs = resetTimeoutMs;
}
async call(fn) {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime > this.resetMs) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker OPEN — Razorpay calls suspended');
}
}
try {
const result = await fn();
if (this.state === 'HALF_OPEN') this.state = 'CLOSED';
this.failureCount = 0;
return result;
} catch (err) {
this.failureCount += 1;
this.lastFailureTime = Date.now();
if (this.failureCount >= this.threshold) {
this.state = 'OPEN';
}
throw err;
}
}
}When the breaker opens, the application returns "payments temporarily unavailable, please try again in 30 seconds" instead of hanging. Customers see a clear message; threads do not exhaust; recovery is automatic when Razorpay comes back. This is one of the rare patterns where shipping a bad UX (the warning message) is genuinely better than the failure mode it replaces.
For libraries that handle this for you: opossum for Node.js, pybreaker for Python, Resilience4j for Java. All MIT-licensed, well-maintained.
Check 3: COD throttling (the BFCM-spam killer)
BFCM 2025 will see a wave of COD spam — competitor bots, bored students, and disposable-phone-number scripts. We have already seen the early signal in the Diwali 2025 incidents (covered in detail in our Diwali post-mortem): a Surat client got 1,200 fake COD orders in 36 hours when their actual capacity was 850/day.
The 4-layer COD throttle:
- Phone OTP verification on every COD order via MSG91 or Razorpay WhatsApp OTP
- Rate limit per phone+IP combo: max 3 active COD orders per 24h, max 8 per 7 days
- Refundable deposit on COD orders >₹2,500 (refunded on delivery confirmation)
- Risk-score routing: phone numbers from same IP block, sequential numbers, disposable-prefix matches → "verify before dispatch" queue
The Surat client implemented all four in 4 days post-Diwali. November 25 dry run: 8% of incoming COD orders triggered "verify before dispatch", 1.2% confirmed spam. Genuine confirmation rate jumped from 71% to 94%.
Check 4: abandoned-cart recovery (real money left on the table)
BFCM cart-abandonment rates run 71-78% (versus normal 58-66%) because buyers comparison-shop. Industry-standard recovery rate for a well-built sequence is 21-32% versus 11-14% for ad-hoc retargeting. For an SMB doing ₹50 lakh in BFCM revenue, that delta is ₹4.5-9 lakh recovered.
The 3-tier sequence we ship:
| Tier | Trigger | Channel | Content | Recovery rate |
|---|---|---|---|---|
| 1 | 1 hour after abandonment | Email (Mailmodo/Postmark) | Friendly reminder + cart link, no discount | ~12% |
| 2 | 4 hours after abandonment | WhatsApp Business API | "Your cart expires soon" + 5% off via promo code | ~14% |
| 3 | 18 hours after abandonment | Email + WhatsApp combined | "Last chance before BFCM ends" + 8% off + free shipping | ~6% |
WhatsApp's BSP pricing for a marketing-template message in India varies by BSP (Gupshup, Wati, and AiSensy are the main Indian options). At a recovery uplift of ~14%, the math is comfortably positive for any cart value above ₹400.
The trap to avoid: WhatsApp's 24-hour customer-service window means you can only send templated messages to customers who have not interacted with you in 24h. For the 4-hour and 18-hour tiers, use marketing template categories with pre-approved templates. Submit your templates to Meta for approval at least 5 business days before BFCM — they take 1-3 days to approve and you do not want to be waiting on Black Friday morning.
Check 5: fraud rules (Razorpay has them — turn them on)
Razorpay's Risk Engine ships with default fraud rules but most SMBs never tune them. Three rule categories matter for BFCM.
Velocity rules. Max N orders per IP, email, phone, or card BIN per time window. Default is generous (10 orders per IP per hour); tighten to 3 per hour for BFCM. A legitimate buyer rarely needs more.
Geography rules. If you sell only domestically, block international card BIN ranges entirely. If you sell internationally, allow only the countries you have shipped to in the last 90 days — this catches most fraud which originates from countries you have no business with.
BIN-list rules. Razorpay maintains a list of high-risk card prefixes (test cards, gift cards used for fraud, prepaid cards used for resale). Toggle "Send high-risk BINs to manual review" — adds 6-12 hours of latency to those orders, accepts the trade-off.
Custom rules. Razorpay supports custom rules via the dashboard. We typically add: "If billing address pincode does not match shipping address pincode AND order value >₹15,000 AND payment method is international card → manual review."
Activation: Razorpay Dashboard → Settings → Risk Engine → Configure Rules. Costs nothing extra — it is included on every Razorpay plan.
Check 6: support routing (this saves your team from burnout)
A 22-person Indore retailer had 4 support reps who normally handled 80 tickets a day. BFCM 2024 brought 380 tickets in 36 hours. The reps worked 19-hour shifts, missed 60% of refund-related questions, and 2 of them quit in January 2025.
- The audit:
- What is your average ticket volume per day in October?
- Multiply by 2.4 (median BFCM uplift across our 11 audits).
- Divide by your team's sustainable per-rep capacity (40-60 tickets/day for complex queries, 80-120 for simple).
- If short of capacity by >30%, you need either temp hires (Apna Time, Naukri's gig roles) or auto-routing.
The 4-tier auto-routing pattern:
Comparison: Razorpay vs Cashfree at BFCM
We get asked this constantly. The honest answer:
| Dimension | Razorpay | Cashfree |
|---|---|---|
| Domestic txn fee (standard) | 2% + 18% GST | 1.95% + GST (or 1.6% promo for new merchants signed 18 Sep 2025 to 31 Jul 2026) |
| UPI MDR | 0% (RBI-mandated) | 0% (RBI-mandated) |
| International cards | 3% + GST | 3% + GST |
| Settlement cycle | T+2 standard, T+1 on Pro plans | T+1 standard |
| n8n native node | Yes (released mid-2025) | Via HTTP request only |
| Tally Prime integration | Native (via TallyPrime add-on) | Via API/CSV upload |
| Risk engine UI | Mature, configurable rules | Configurable but less granular |
| BFCM peak handling (anecdotal) | Diwali 2025: 99.4% uptime, three 5-15 min degradations | Diwali 2025: comparable per third-party reports |
For BFCM 2025, do not switch. Switching gateways during peak is the single highest-risk change you can make. If you are on Razorpay, run this audit and stay on Razorpay. Plan a Cashfree comparison test for January-February 2026 if cost is the driver.
For the official Razorpay pricing page and Cashfree's promotional pricing, both are public and honest about the rates.
When NOT to run all 6 checks
Three cases where partial coverage is the right call.
You are on Shopify Plus with a managed checkout. Shopify handles rate limits, retries, abandoned-cart triggers, and basic fraud rules. You still need to: configure Shopify's flow for COD throttling (custom app required), set up the WhatsApp BSP integration, and configure your support tier routing in Gorgias or Zendesk. Skip checks 1, 2, and 5; run 3, 4, 6.
Your BFCM target is <₹15 lakh in revenue. Skip the abandoned-cart sequence and the fraud rule tuning. The marginal recovery is small; the build cost is comparable. Run checks 1, 2, 3, 6 only.
You are pure B2B with custom invoicing. None of these checks apply meaningfully — your buyers are not abandoning carts and not committing fraud. Spend the time on a CRM upgrade or a sales rollup workflow instead.
Real example — a Bangalore D2C beauty brand
Client: a 14-person beauty + skincare brand in Bangalore, FY 2024-25 revenue ₹4.2 Cr, BFCM 2024 GMV ₹38 lakh, 2025 target ₹62 lakh. Stack: Shopify + Razorpay + Wati for WhatsApp.
The 6-check audit caught:
Audit: 5 working days. Projected revenue impact (uplift + protection): ₹6.4 lakh on a ₹62 lakh BFCM target. The CFO signed it off in 11 minutes after seeing the math.
The Reddit thread on r/IndianStartups where founders post BFCM post-mortems is required reading for anyone running this kind of audit. The patterns repeat year after year.
A question we get every November
"Should we host the Razorpay checkout iframe on our domain or use the redirect flow?"
For BFCM specifically: redirect flow. The iframe (Razorpay's "Standard Checkout") is more polished but introduces a parent-iframe communication failure mode that surfaces under heavy load. The redirect flow is dumber, slower, and more reliable. We have seen the iframe drop ~2-4% of carts during peak windows where the redirect flow drops 0.8-1.2%.
If your conversion-rate-optimization team objects to the redirect, run an A/B test in January when stakes are low. For BFCM, choose reliability.
The 30-minute final-audit checklist (run this tonight)
- Razorpay rate-limit raise confirmed in writing from care@razorpay.com
- Idempotency keys present on every Razorpay order_create call
- Retry logic capped at 3 attempts with exponential backoff (500ms, 2s, 8s)
- Circuit breaker code path tested with a forced 503 simulation
- Webhook handler does only signature-verify + queue-write; downstream worker handles DB
- COD form has phone OTP enabled (MSG91 or Wati)
- COD rate limit: max 3 active orders per phone+IP per 24h
- Deposit on COD orders above ₹2,500 (refundable on delivery)
- Abandoned-cart sequence: 1h email + 4h WhatsApp + 18h email+WhatsApp templates Meta-approved
- Razorpay risk engine velocity rule: max 3 orders per IP/hour
- Geography fraud rule: only countries you have shipped to in last 90 days allowed
- Support tier-0 auto-bot live and tested with 12 top FAQ queries
- Tier-2 (payment issues) routing tested with one synthetic ticket
- War-room Slack channel created, founder/CTO/ops/support leads pinned
- Synthetic load test at 3× Diwali peak passed (p95 cart TTFB < 800ms)
- Better Uptime synthetic checks live every 60 seconds against checkout URL
FAQ
Should I disable COD entirely for BFCM?
For high-fraud SKUs (apparel, electronics above ₹4,000), yes — disable COD for the BFCM 72-hour window. For low-fraud SKUs (groceries, books, low-value items), keep it on with the throttle layer. The opportunity cost of disabling COD is roughly 14-22% of would-be orders in Tier-2/3 cities, which dwarfs the fraud cost for low-value SKUs.
What is the right way to handle a Razorpay outage that lasts 20+ minutes?
Three actions in order. (1) Switch to a fallback gateway (Cashfree, PhonePe Business, BillDesk) if you have one pre-integrated — this is what we mean by "alternate payment gateway" in the BFCM checklist. (2) Show a clear message: "Payments temporarily unavailable, orders queued. We'll notify you within 30 minutes." (3) Build a queue table that captures cart contents + customer info, replays as soon as Razorpay is back. Most SMBs do (2) and (3) but skip (1) — having a fallback gateway pre-integrated is a January project, not a BFCM-eve project.
How do I tell if Razorpay is degraded vs my code is broken?
Three signals. (1) Razorpay's status page — check it first, but it lags real degradations by 5-15 minutes. (2) Your own circuit-breaker state — if it has opened in the last 60 seconds, Razorpay is the prime suspect. (3) Run the same Razorpay API call from a known-good test environment (curl from your laptop). If your laptop succeeds and your production fails, the bug is yours.
What about UPI Autopay subscriptions during BFCM?
UPI Autopay (recurring UPI mandates) is the most reliable payment mode at BFCM peak — bank-to-bank transfers do not go through the same gateway congestion. If you have subscription products (SaaS, beauty boxes, food delivery), promote UPI Autopay enrolment heavily through the BFCM window. Razorpay's subscription product supports UPI Autopay natively.
Is there an open-source tool that runs all these checks?
Not as a single tool. We use k6 for load testing, Better Uptime for synthetic checks, Sentry for error tracking, Grafana Cloud for dashboards. Free tier of all four covers an SMB. For the Razorpay-specific audit (idempotency, retry, circuit breaker), we run a manual code review — no tool replaces a senior engineer's eyes for this.
What about the abandoned-cart hooks for international/NRI buyers?
WhatsApp Business API works internationally — a US-based NRI buyer with an Indian phone number on roaming receives the templates fine. For non-Indian phone numbers (US/UK), email is the only practical channel; SMS pricing makes it uneconomic. We run a separate email sequence for non-Indian numbers via Mailmodo with AMP-for-Email checkout buttons.
How important is post-BFCM analytics setup?
Critical. Set up a Looker Studio or Metabase dashboard before BFCM with: hourly revenue, conversion rate, payment success rate by gateway, cart abandonment rate, support ticket volume, refund rate. The post-BFCM debrief is where you find the failures that almost happened — patterns that could become real outages next year.
Where this fits in our work
We run pre-festival stack audits like this for our web development and AI automation clients every November. The Diwali audit, the BFCM audit, and the year-end finance audit are the three big ones. For SMBs that are too late to do all three, the BFCM audit is the highest-revenue-impact single deliverable.
This post was written by Hrishikesh Baidya, our CTO, who has run the on-call rotation for our clients' last three BFCM windows. For our Diwali 2025 post-mortem on the same patterns, see Diwali 2025 Was the ₹60,700 Cr Week. For the auto-reconciliation flow that handles the next-morning Razorpay-vs-Tally cleanup, see n8n + Tally Prime + Razorpay.
For a real D2C e-commerce build using these resilience patterns, see our Radiant Finance case study.
Want a 6-Point BFCM Stack Audit Before Next Year?
We run this 6-point audit on Razorpay-powered Indian SMB stacks as a fixed-scope 5-day engagement. Report includes the 16-point pre-launch checklist and a 90-day post-BFCM follow-up call. We share the audit findings whether or not you hire us for the implementation.
Book a BFCM Stack AuditEmail contact@softechinfra.com if you need an emergency check tonight — we keep two engineers on backup rotation for BFCM week.
