SELECT razorpay_event_id, COUNT(*) AS hits
FROM webhook_audit
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY razorpay_event_id
HAVING COUNT(*) > 1;
Anything in the result? That is your leak.
## Check 3: Month-to-Date Reconciliation (DB Vs Razorpay Dashboard)
The discipline: every morning at 9 am, your team should compare:
- Total Captured This Month from your DB (sum of order amounts where status = paid AND payment_date this month)
- Total Captured This Month from Razorpay Dashboard > Reports
These two numbers should match within ₹0. If they drift, you have an unreconciled gap somewhere — usually refunds, partial captures, or a webhook that failed.
The "8 of 11 had a leak" finding from our recent audits was driven mostly by this check. A typical pattern: a refund processed in Razorpay was not webhook-acknowledged because the handler 500'd that day. The order shows status = paid in your DB; Razorpay shows it as refunded. Net cash impact: missing ₹2,400 to ₹14,000 across 8-30 such transactions per month.
The fix is procedural plus technical:
- A daily cron at 8 am pulls Razorpay's Settlement API for the previous day, compares against your DB, writes any mismatches to a reconciliation_queue table.
- A 9 am email to the finance lead with the queue contents (typically empty; alarming when not).
- A weekly review with the founder of any aged-over-7-day items.
This pattern catches the leak. Without it, the leak only surfaces at month-end when the bank deposit number does not match the dashboard.
## Check 4: SMS Rate-Limit Tuning
Order-confirmation SMS during a sale spike sits in a queue. If your SMS provider (Twilio, MSG91, Gupshup) has a per-second rate cap, queue depth grows, latency creeps up, and order-confirms arrive 4 hours late. Customers panic. Support tickets pile up.
What to check:
- Your SMS provider's dashboard > rate-limit graph for the sale period (Aug 1-7). Did your queue depth exceed 60 seconds at any point?
- Default rate limits: Twilio India long codes ~3 SMS/second; MSG91 transactional ~10/second on the basic plan; Gupshup transactional ~25/second.
- Festive D2C peaks can hit 80+ SMS/second on a popular drop.
The fixes:
- Per-route prioritisation. Order-confirmation SMS goes ahead of marketing SMS. Use separate provider sender IDs.
- Provider-side rate increase. A 1-line email to your provider asking for a temporary rate bump — most will lift to 50-100/sec for a day with 24 hours notice.
- Batched WhatsApp templates as fallback. WhatsApp Business API is rarely the rate-limit bottleneck. Set up an order-confirm template and route to WhatsApp first, SMS as fallback. ~88% of Indian D2C buyers have WhatsApp; better delivery, lower cost.
## Check 5: GA4 Event Drift Caused by Checkout-Page A/B Tests
Most D2C teams run a checkout-page A/B test in the lead-up to a sale. The test changes button text, repositions the trust badges, swaps the upsell offer. The team forgets to update the GA4 event names accordingly.
Result: by August 14, your GA4 conversion-funnel report shows mysterious gaps because the new variant fires begin_checkout_v2 while the old fires begin_checkout, and your funnel report aggregates only the latter.
What to check:
- GA4 > Configure > Events. Look for any event with a v2, _new, _test suffix that has fired > 1,000 times this month.
- GA4 > Reports > Conversions. Are your funnel-step counts on the day-after-sale dramatically lower than the cart-add count?
- Tag Manager > Versions. Was a new version published in the last 30 days?
The fix is usually a 5-minute Tag Manager change to consolidate event names, plus a manual GA4 conversion-event re-mapping. The damage is to your post-sale analysis — you cannot make rational decisions about the next sale if your funnel data is broken.
cart_id cookie on product pages.
- Webhook handler had no idempotency. Found 14 double-processed payment.captured events in the last 30 days, ₹4,200 in over-credited customer wallets.
- Reconciliation drift of ₹6,800/month from refunds processed in Razorpay but not webhook-acknowledged.
- SMS queue depth peaked at 380 seconds during their July 25 launch — they switched to WhatsApp-first templates with SMS fallback; queue dropped to under 10 seconds during August 5 sale.
- GA4 was tracking a deprecated add_to_cart_v3 event; funnel report was 38% under-counted.
Total cleanup time: 4.2 hours of our engineering. Estimated annual saving: ₹2.8 lakh on hosting + reconciliation + lost-conversion analytics. ROI on the audit: ~5 weeks.
## A Note on the Razorpay Side
[Razorpay's documentation has gotten a lot better in 2024-25](https://razorpay.com/docs/). The webhooks-best-practices page is now the first thing they link to; their settlement API is well-documented; their dashboard shows webhook delivery history. Our typical recommendation: read the docs once carefully when you set up; bookmark the best-practices and settlement pages; run this 5-point check quarterly.
## FAQ
### How often should I run this audit?
Quarterly minimum. Monthly during festive season (Aug-Nov). Plus immediately after any deploy that touches the checkout, the webhook handler, or the SMS pipeline.
### Does this audit apply to Stripe or PayU sites?
Yes — checks 1, 3, 4, 5 are gateway-agnostic. Check 2 is gateway-specific in the implementation but the principle (idempotent webhook handlers) applies to every gateway. Stripe's docs are explicit on this; PayU's are less so but the same discipline matters.
### What about UPI Autopay subscriptions?
Subscriptions add a 6th check we did not include here: the recurring-payment failure rate. Subscriptions on Razorpay can fail for AFA (Additional Factor of Authentication) reasons specific to the buyer's bank. Track the failure rate weekly and alert if it exceeds 8%.
### How do I prevent webhook handler 500s during a peak?
Three things. Respond 200 immediately, queue the work asynchronously. Make the handler stateless and horizontally scalable. Set up an alert on handler error rate > 1% so you catch issues before they pile up.
### Can the cache-rule fix break my checkout?
No, if you scope the cache rule to /product/* explicitly. Your /cart, /checkout, and /api routes should remain uncached. Test the rule on a staging-mirror first if your site has unusual URL patterns.
### Why do you care about GA4 event drift this much?
Because it determines your next-sale planning. If you cannot trust your funnel data, every decision (creative spend, discount depth, inventory positioning) is based on noise. Bad analytics is worse than no analytics — it gives false confidence.
### Do you offer this audit as a service?
Yes. Same-day for ₹14,000 fixed. We send the findings as a written report plus a Loom walk-through. If we find nothing, you pay half. The full pricing and process is on our [services page](/services/web-development).
## Related Reading
If you found this useful
- Snapdragon Summit + Amazon Great Indian Festival Day-1 Audit — sister post for the September festive surge
- FMCG Marketplace Stack with Razorpay Route — settlement-engine deep dive
- Our AI Automation Service — for reconciliation cron automation
- Founder commentary on D2C operations from Vivek Singh
Need a Same-Day BFCM-Style Stack Audit?
We run this 5-point health check on your Razorpay + Shopify or Razorpay + custom stack the same day. ₹14,000 fixed. Written report + Loom walk-through. If we find nothing actionable, you pay half. Suitable for D2C sites doing ₹3 lakh+ monthly GMV. Email contact@softechinfra.com or book direct below.
Book a Same-Day Stack Audit
