Last month, reviewing a Razorpay dashboard with a Bangalore founder, one number looked calm.
Cancellations were low. Active subscriptions were climbing. New signups were still coming in. On the surface, nothing looked broken — and yet MRR had barely moved in eight weeks. ₹3.1L in expected subscription revenue was sitting in retry logs, expired mandates, and unrecovered payment attempts. The subscriptions were active. The customers were still in the product. The money was not in the bank.
We had stopped looking at cancellations and started looking at payment attempts. That is where the real leak appeared.
The separation Razorpay doesn't show you upfront
Razorpay Subscriptions tracks two things in parallel: subscription state and payment state. The default dashboard view surfaces subscription state.
A subscription marked "Active" means the mandate exists and the billing schedule is running. It does not mean the last invoice cleared. A mandate with confirmed status means the customer agreed to recurring debit at setup. It does not mean the next debit will succeed.
A cancellation is explicit. A failed payment is often invisible — until enough failed invoices collect behind it. The customer may still want the product. The mandate may still exist. The subscription may still appear recoverable. But the money has not reached the bank.
This is the gap most Razorpay dashboards don't close on their own. And in India, the gap is wider than it looks — because the payment rail itself introduces failure modes that Western card-first billing doesn't have.
Why India's payment rails add layers to this problem
A card mandate in India may need to be set up against RBI's tokenization requirement. Any transaction above ₹15,000 requires Additional Factor Authentication — which means retrying a ₹20,000 annual plan charge without customer action will fail again, every time. Banks must send pre-debit notifications before UPI Autopay debits, and customers can withdraw e-mandates without warning.
Each payment rail creates a different failure mode and a different recovery path:
Payment rail | How it fails | What the dashboard shows |
|---|---|---|
UPI Autopay | Revoked mandate, insufficient funds, pre-debit notification not sent | Subscription stays "Active" until retry window exhausts |
eNACH / card mandate | Bank-side decline, tokenization failure, expired card |
|
Card recurring (tokenized) | Soft decline vs hard decline — each requires a different response | Failure code ( |
The failure code is the routing input for recovery. Most founders never look at it — not because they don't care, but because nothing in the standard dashboard asks them to.
What a healthy collection view actually measures
A cancellation report tells you who chose to leave. It cannot tell you how much committed MRR was attempted, how much failed, which failures were retryable, and how much was recovered before it was counted as lost.
For every billing cycle, six questions tell the real story:
Question | Why it matters |
|---|---|
How much MRR was scheduled for collection? | Sets the real collection base — not plan pricing, but actual attempt volume |
How much cleared on first attempt? | Shows baseline payment health across your mandate mix |
How much failed? | Identifies the recovery pool — this number should sit next to cancellation MRR |
Which failures were retryable without customer action? | Prevents exhausting retries on hard declines or revoked mandates |
Which failures needed customer action? | Separates gateway retry from WhatsApp message from payment update link |
How much was recovered before the billing cycle closed? | Shows whether your recovery flow is working or just logging |
The dashboard question shouldn't be "how many customers cancelled?" It should be "how much committed MRR was attempted, how much was collected, how much failed, and how much of the failed amount was recovered?"
A retry is not just a retry
When a payment fails inside Razorpay, the next action is not always to retry.
It may be a bank-side failure that clears on retry. It may be an expired mandate that needs re-registration. It may be a pre-debit notification issue specific to UPI Autopay. It may be a customer who never saw the email but would have responded to a WhatsApp message. It may be a ₹20,000 annual charge where the customer needs to authenticate again because of AFA threshold rules.
India's involuntary churn has sub-categories that each require a different recovery response:
Churn type | What it means | Correct next action |
|---|---|---|
Mandate churn | UPI Autopay mandate revoked or expired after bank account change | Re-registration link, not a retry |
Payment-state churn | Subscription is | WhatsApp nudge or payment update before retry window closes |
Delinquent churn | Retry window exhausted, customer never reached | Re-engagement sequence before counting as lost |
Treating all three the same way — another retry, another email — is why recovery rates stay low even when the infrastructure is in place.
Where SubsShield fits
SubsShield sits between the Razorpay webhook and the customer communication layer. When payment.failed fires, SubsShield reads the failure code and mandate state, routes the event to the right recovery path — retry, WhatsApp action, email, or mandate re-registration — and tracks whether the payment cleared.
It is not a replacement for Razorpay. It is the layer that handles what happens after the gateway reports a failure, because the gateway's job ends there.
If you pulled your Razorpay failed payment log for the last 30 days and separated mandate failures from gateway declines from retry exhaustion — how many of those failure states currently have a distinct recovery action in your stack, and how many are being retried the same way regardless of why they failed?



