Recover failed WooCommerce Subscriptions payments
WooCommerce runs on your own WordPress install, so the failure signal comes from the store rather than a hosted platform. The advantage is a direct, tokenised pay-for-order URL you can put straight into a recovery message.
The WooCommerce Subscriptions events recovery depends on
- order.updated → status: failed
- A renewal order failed payment — open a recovery case.
- order.updated → status: processing/completed
- The renewal was paid. Close the case.
- subscription status: on-hold
- Woo suspended the subscription after the retry rule ran out.
Verifying WooCommerce Subscriptions webhooks
- Scheme
- HMAC-SHA256 over the raw body, base64-encoded
- Signature location
- X-WC-Webhook-Signature
Set the webhook secret in WooCommerce settings. Because the store is self-hosted, also restrict the endpoint by store domain.
import { createHmac, timingSafeEqual } from "crypto";
const digest = createHmac("sha256", process.env.WOO_WEBHOOK_SECRET!)
.update(rawBody, "utf8")
.digest("base64");
const sig = req.headers["x-wc-webhook-signature"] as string;
if (!timingSafeEqual(Buffer.from(digest), Buffer.from(sig))) {
return new Response("Invalid signature", { status: 401 });
}
const order = JSON.parse(rawBody); // topic: order.updated
if (order.status === "failed") {
await rrlabs.enqueueRecovery({
provider: "woocommerce",
externalId: String(order.id),
payUrl: order.payment_url, // tokenised pay-for-order link
});
}Decline playbook for WooCommerce Subscriptions
| Failure signal | Recovery action |
|---|---|
| Gateway declined the stored token | Send the pay-for-order URL so the customer can complete payment with any method. |
| Token expired | Ask for a new payment method through the My Account page before the subscription moves to on-hold. |
| Automatic retry rule exhausted | Escalate the channel — this is the last window before the subscription is suspended. |
What happens after a payment fails
T+0s
Payment failed
Provider webhook received and verified
T+2s
AI analysis
Decline reason classified, amount at risk scored
T+5s
Dynamic email
Copy generated for that decline code and customer
Day 2
Smart retry
Retry scheduled only when the decline code is retryable
Day 2
WhatsApp push
Second channel used when the email went unanswered
On success
Recovered
Counted only when the provider confirms the charge
Timings describe the configured workflow, not a guaranteed outcome. Every step is skipped when the decline reason makes it counter-productive.
Frequently asked questions
- Does RRLabs need WordPress admin access?
- No. It needs a webhook pointed at its endpoint and, optionally, read access to order data. It does not install plugins or modify the store.
- What is the strongest WooCommerce recovery link?
- The tokenised pay-for-order URL on the failed renewal order — it lets the customer pay without logging in or re-entering the cart.
Connect WooCommerce Subscriptions with read-only credentials
RRLabs reads failure events and orchestrates recovery. It never holds card data and never becomes the merchant of record.
Get early access