When a renewal fails, the most dangerous response is also the easiest to automate: keep submitting the same charge until something changes. That can recover a temporary decline, but it can also repeat an impossible payment, conflict with a gateway-owned recovery flow, or charge an order that already succeeded remotely.
Good automatic retry does not repeat every failed charge on a fixed loop. It identifies who owns collection, separates retryable failures from customer-action and stop conditions, verifies that the order was not already paid, spaces a limited number of attempts inside the grace window, communicates clearly, and reconciles the order, subscription, gateway, and access state after recovery.
Key takeaways
- Decide ownership, eligibility, safety, and policy before every retry.
- Route failures by the required remedy, not by a simplistic hard-versus-soft label.
- Treat idempotency and payment reconciliation as separate protections.
- Align retry timing with grace, access, fulfillment, and customer messages.
- Measure paid recoveries in closed cohorts, not retry jobs or open failures.
An initial attempt is the first collection attempt for a renewal that has become due. An automatic retry is a later system-triggered attempt against that same unresolved obligation. Reconciliation means making the gateway payment, WooCommerce renewal order, subscription status, next renewal date, scheduled jobs, and customer access agree with the verified outcome.
What should happen before an automatic retry?
A safe retry policy is a four-gate decision. If a renewal cannot pass all four gates, the system should reconcile, request customer action, wait for a remote provider, or stop—not charge again.

- Ownership: Is this a locally collected automatic renewal, a customer-paid manual renewal, or a remotely collected PayPal or Paddle subscription?
- Eligibility: Does current provider evidence permit another attempt with the same payment method and context?
- Safety: Is the exact renewal still unpaid, due, active enough to process, and protected against concurrency or a missed webhook?
- Policy: Does the attempt fit the disclosed retry limit, grace period, access policy, fulfillment cutoff, and communication plan?
This is the difference between a retry engine and a timer. A timer asks whether enough time has passed. A retry engine asks whether another charge is still the correct next action.
When does retry help, and when does it make things worse?
Automatic retry helps when the cause may resolve without changing the payment context. A temporary processing problem or permitted insufficient-funds decline may succeed later. It hurts when the customer must update a card, authenticate, replace a revoked credential, or when another system already owns collection.
Stripe exposes decline information and network advice such as try_again_later, do_not_try_again, and confirm_card_data; it also warns that excessive reattempts can increase declines or appear fraudulent (Stripe card declines, Stripe decline codes). Provider advice is more useful than assuming every “soft” decline deserves another attempt.
| Evidence or failure | Same-context retry | Required next action | Stop or escalate when |
|---|---|---|---|
| Processing or network error with retry advice | Use a bounded delayed retry | Monitor gateway health; offer another method if repeated | Outage continues or provider says stop |
| Insufficient funds with retry permission | A later bounded retry may fit | Customer adds funds or changes method | Attempt limit or network stop is reached |
| Expired or invalid card | Do not blindly retry | Customer securely updates the method | No replacement before the policy deadline |
| Incorrect CVC or card data | Wait for corrected data | Customer re-enters details | Invalid data repeats |
| Authentication required | Do not loop off-session attempts | Customer completes the hosted authentication or payment flow | Action expires, fails, or is declined |
| Lost, stolen, revoked, or stop-recurring advice | Never retry unchanged context | New method, issuer contact, or risk review | Stop immediately for that credential |
| PayPal or Paddle reports past due | Do not start a second local charge loop | Follow provider recovery and reconcile webhooks | Provider exhausts recovery or states disagree |
| Gateway payment already succeeded | Never charge again | Reconcile the local order and subscription | Investigate webhook or mapping failure |
| Unknown evidence | Review conservatively | Provide a safe pay, update, or support route | Escalate instead of repeatedly charging |

The phrase “hard decline” is useful shorthand, but it is not a portable rulebook. Gateways and card networks expose different evidence, and the same broad category can require different action. Preserve the raw provider code and advice for operations while showing customers a safe, plain-language explanation.
Who owns retries in WooCommerce, Stripe, PayPal, and Paddle?
Ownership is the first operational decision because two collection engines can create duplicate attempts, contradictory notices, and mismatched access states.
WooCommerce Subscriptions has its own optional failed-payment retry engine. Its current documentation describes rule-based intervals, emails, order statuses, and subscription statuses, with five default rules across seven days. It applies when automatic recurring payments use a gateway that does not control the billing schedule (WooCommerce failed recurring payment retry system). Those rules describe WooCommerce Subscriptions, not ArraySubs.
| Billing path | Collection and retry owner | Correct operating rule |
|---|---|---|
| ArraySubs with local Stripe renewal | ArraySubs creates the renewal order; its Stripe integration attempts collection | Use the local retry and reconciliation pipeline |
| Manual or offline renewal | Customer or administrator completes payment | Send an invoice or Pay Now path; do not pretend it is an automatic retry |
| PayPal subscription | PayPal owns the remote billing schedule and recovery | Reconcile remote webhooks and state; do not add a second local charge engine |
| Paddle subscription | Paddle owns the remote transaction and recovery | Align local access and grace with remote past_due handling |
| Stripe Billing subscription | Stripe Billing owns invoices and Smart Retries | Do not confuse this with WooCommerce renewal orders collected through PaymentIntents |

PayPal documents provider-owned retries every five days, up to twice per billing cycle, plus outstanding-balance and failure-threshold behavior (PayPal payment failures). Paddle marks a subscription with an unpaid transaction past_due, applies its configured payment recovery, restores active on success, and can cancel after recovery is exhausted (Paddle subscription.past_due). These are provider behaviors, not recommended ArraySubs intervals.
Stripe Billing Smart Retries also belongs to a specific architecture: Stripe selects retry times for Stripe Billing invoices within a configured count and duration (Stripe Smart Retries). It does not control the current ArraySubs flow in which WooCommerce renewal orders are collected through the ArraySubs Pro Stripe integration.
How many retry attempts should a subscription use?
There is no universal best number. “Three retries” is not a strategy until the merchant can explain why each attempt is permitted, when it runs, and what happens around it.
Choose the attempt count and delays inside these constraints:
- provider and card-network advice;
- whether the failure can succeed without customer action;
- local, manual, or remote collection ownership;
- time required to update a method or authenticate;
- active and on-hold grace boundaries;
- product marginal cost and physical fulfillment cutoff;
- billing cadence, amount, and customer expectations;
- message frequency and support capacity;
- contract and legal notice requirements reviewed for the business.
retry 1 time = first-failure time + delay 1
retry N time = retry-(N−1)-failure time + delay N
latest eligible retry
= minimum of provider stop, local lifecycle stop, and merchant policy stop
local cancellation threshold
= due time + active grace + on-hold grace
For a remote gateway, compare the local access deadline with the provider recovery deadline. If local access ends first, a customer may still be charged later by the provider. If local grace lasts longer, access may continue after the provider has stopped trying. Either can be intentional; an undocumented mismatch is the problem.
Current ArraySubs Stripe boundary example
Current source inspection for ArraySubs 1.8.11 and ArraySubs Pro 1.1.2 found a Stripe retry configuration of up to three automatic retries at 24-hour intervals after the initial failure. Current default lifecycle settings keep an ordinary overdue subscription active for three days, and the overdue checker runs hourly.
Illustrative schedule, not a recommendation:
initial failure July 16, 09:00 UTC
retry 1 July 17, around 09:00
retry 2 July 18, around 09:00
retry 3 July 19, around 09:00
on-hold cutoff July 19, checked hourly

The third retry and active-to-on-hold transition can meet at the same scheduler boundary. Exact Action Scheduler ordering may determine whether that attempt runs while the subscription remains eligible. Say “up to three retries,” test the boundary in the deployed environment, and do not infer behavior from timestamps alone.
How do idempotency and reconciliation prevent duplicate charges?
Idempotency protects a repeated API operation. Stripe, for example, lets a client send an idempotency key so a repeated request returns the first result instead of creating another operation (Stripe idempotent requests). That is important, but it does not prove the local order and remote payment agree.
Consider this failure: Stripe successfully charges a PaymentIntent, but the response or webhook never updates WooCommerce. The local renewal still looks failed. A new request with a different key can be technically idempotent and still charge the same business obligation again unless the retry first checks the remote payment.
| Safety layer | Protects against | Does not prove |
|---|---|---|
| Scheduler lock and status gates | Overlapping local workers and ineligible states | Whether the gateway already charged |
| API idempotency key | Re-executing the same API request | Whether a later request represents the same renewal |
| Order and payment metadata | Correlating the local renewal with a remote payment | Whether local lifecycle state reflects success |
| Pre-retry gateway verification | Missing a successful remote charge before another attempt | Safety for a gateway without an implemented lookup |
| Webhook reconciliation | Applying remote events and restoring state | Correctness when signatures, mapping, or delivery are broken |
Current ArraySubs Stripe source checks the PaymentIntent stored on the order and can search recent customer PaymentIntents for exact order and subscription metadata. If it finds a succeeded payment, it marks the renewal order paid and clears retry state rather than charging again. A supported manual retry forces this verification path even when no automatic retry was previously scheduled.

The correct missed-webhook outcome is:
retrieve the exact remote payment
→ verify amount, currency, order, and subscription context
→ mark the renewal order paid with its transaction reference
→ clear failure and retry state
→ confirm subscription status, access, and next renewal
→ send the recovery confirmation
→ do not submit another charge
What should customers see after a failed payment?
Every message should reduce uncertainty and provide one safe next action. It should state:
- the affected subscription and renewal amount;
- a customer-safe reason, when known;
- whether the customer should pay, update the method, authenticate, contact the issuer, or wait;
- the next attempt or deadline with date, time, and timezone;
- the effect on access, shipment, or service if unresolved;
- a support route that never asks for card details by email.

Use an authenticated first-party account or hosted gateway route. Never include raw processor payloads, a full primary account number, or CVC in an email, screenshot, note, or support transcript. PCI Security Standards Council guidance prohibits storing sensitive authentication data such as CVC after authorization, even when encrypted (PCI SSC FAQ 1533).
An authentication_required result needs a hosted customer action; repeating the same off-session attempt cannot complete 3D Secure. An expired card needs a secure update path. A processing error with explicit retry permission may need only a calm notice and a later attempt. Stop the failure sequence immediately after payment is verified.
How should teams monitor and test automatic retries?
WooCommerce recommends understanding the subscription anatomy, determining expected behavior, and then reconstructing the actual timeline when troubleshooting (WooCommerce troubleshooting framework). Apply that model before manually changing any order or subscription status.
Record enough evidence to explain one renewal from due time to final outcome:
- subscription ID, status, next date, auto-renew state, and pending-cancellation state;
- renewal order ID, status, amount, currency, method, and transaction ID;
- first-failure time, raw provider code/advice, and normalized category;
- retry count, last/next retry time, and scheduled-action status;
- remote payment object or subscription status plus webhook events;
- customer email, method-update, payment, and authentication events;
- access and fulfillment state;
- final paid, cancelled, or fallback outcome and recovery time.
Minimum pre-launch test matrix
- Retry-permitted temporary decline.
- Provider stop advice.
- Expired or invalid payment method.
- Authentication required.
- Method updated before the next retry.
- Successful remote payment with a missed webhook.
- Webhook and retry worker overlap.
- Two workers reaching the same retry action.
- Customer and administrator manual retry.
- Pending cancellation during recovery.
- Auto-renew disabled during recovery.
- Retry limit reached.
- The day-three retry/on-hold boundary.
- PayPal remote recovery without local duplicate collection.
- Paddle remote recovery without local duplicate collection.
- Success restores the order, subscription, access, next date, jobs, and messages.
Use gateway sandboxes and disposable test subscriptions. Save timestamps, action IDs, order notes, gateway object IDs, and before/after screenshots, but redact sensitive payment information. A passing charge is not enough; the lifecycle is correct only when every dependent state agrees.

How should automatic-retry recovery be measured?
Use a closed observation window. A failure that is still inside its configured grace period is unresolved, not unrecovered.
first-attempt failure rate
= failed initial renewal attempts ÷ eligible renewal attempts
customer recovery rate
= customers whose renewal later paid
÷ affected customers whose recovery window closed
value recovery rate
= amount collected against affected renewals
÷ amount originally due in closed affected renewals
recovery by attempt N
= renewals first recovered on attempt N
÷ affected renewals eligible to reach attempt N
time to recovery = paid time − first-failure time
Suppose an illustrative closed cohort contains 100 eligible renewals. Twelve initial attempts fail, seven later pay, $1,600 was originally due across the failed group, and $900 is recovered.
failure rate = 12 ÷ 100 = 12%
customer recovery rate = 7 ÷ 12 = 58.3%
value recovery rate = $900 ÷ $1,600 = 56.25%

These numbers demonstrate arithmetic only; they are not ArraySubs, WooCommerce, gateway, or industry benchmarks. Segment real results by gateway, decline evidence, attempt number, customer action, renewal cadence, value band, product, and tenure. Track duplicate charges, complaints, refunds, disputes, support contacts, access mistakes, and fulfillment errors beside recovered value.
What does current ArraySubs actually do?
Current source observations, verified July 16, 2026:
- ArraySubs core creates or finds the renewal order, records failure evidence, owns shared retry state and scheduling, applies eligibility checks, exposes supported manual retries, and coordinates grace, status, emails, notes, and next-renewal scheduling.
- Automatic off-session card collection requires a supported ArraySubs Pro gateway implementation. The public feature catalog lists automatic failed-payment retry as Pro.
- The inspected ArraySubs Pro Stripe delegate currently publishes a fixed maximum of three retries at 24-hour intervals. The current source did not show merchant fields for retry count or interval described by an older architecture note.
- The current normalized failure category helps customer-safe copy, but retry timing is not dynamically selected from every Stripe advice code.
- PayPal and Paddle collection remains remotely owned; their webhooks and synchronization should reconcile local WooCommerce state.
- Pre-retry verification is implemented for the inspected Stripe path. Do not generalize that lookup to every gateway.
This is a source review, not a live decline, webhook-loss, concurrency, or scheduler-boundary test. Verify the packaged versions, payment-gateway versions, settings, sandbox behavior, cron reliability, and access integration on the actual store before relying on the workflow.
ArraySubs is a practical fit when WooCommerce should own local Stripe renewal orders and the merchant wants retry, grace, notes, emails, manual recovery, and portal actions in one lifecycle. It is not automatically the best fit when Stripe Billing invoices and Smart Retries are the real source of truth, when fully decline-adaptive optimization is required, or when the business cannot test webhooks, scheduler reliability, duplicate-charge safety, and access restoration.
For store-level timing and communication policy, read Subscription Dunning Strategy. For the complete operating runbook, use Failed Subscription Payment Recovery. When implementing ArraySubs, choose a documented lenient dunning and grace recipe or strict dunning and grace recipe rather than duplicating setup steps here.
Final recommendation
Treat every automatic retry as a new payment decision. Verify who owns collection, route the failure by remedy, confirm the renewal is still unpaid and eligible, then attempt only within an explicit grace and communication policy. Reconcile every successful payment across the gateway, order, subscription, access, next date, scheduled jobs, and customer message.
Once those controls are tested, review ArraySubs Pro pricing for the supported automatic-payment and recovery workflow.
Frequently asked questions
How many times should a failed subscription payment be retried?
There is no universal number. Base the limit on provider advice, whether customer action is required, grace and fulfillment deadlines, billing cadence, and first-party results. Current inspected ArraySubs Pro Stripe behavior supports up to three retries at 24-hour intervals after the initial failure.
Which failed payments should never be blindly retried?
Do not repeat an unchanged payment context after provider stop advice, a lost or stolen card signal, revoked authorization, invalid credentials, an expired card, or a requirement for customer authentication. Also do not charge locally when PayPal or Paddle owns the unresolved obligation.
What is the difference between idempotency and reconciliation?
Idempotency prevents the same API operation from executing twice. Reconciliation verifies whether the business obligation was already paid and then aligns the gateway payment, renewal order, subscription status, access, next renewal date, and scheduled jobs.
Can an automatic retry charge a customer twice after a missed webhook?
It can if the system trusts stale local state and charges again without checking the gateway. The inspected ArraySubs Stripe path performs a pre-retry PaymentIntent lookup and reconciles verified success, but every deployed integration still needs a missed-webhook and concurrency test.
Does Stripe Smart Retries control ArraySubs renewals?
No. Stripe Smart Retries applies to Stripe Billing invoices. Current ArraySubs renewals are WooCommerce renewal orders collected through the ArraySubs Pro Stripe integration, so the local ArraySubs retry pipeline controls that path.
What happens after ArraySubs reaches its retry limit?
No further automatic retry is scheduled by the current local pipeline. The subscription continues through the configured grace and lifecycle policy, while a supported customer or administrator manual retry can still be available if the renewal remains eligible.
Does a late successful retry change the next renewal date?
Do not assume it does. Verify that the paid order, subscription status, next payment date, and scheduled renewal actions all reflect the store's intended schedule basis after recovery.
Author, technical review, and test environment
Author: Emran, ArrayHash — product and editorial work across WooCommerce subscription operations.
Technical reviewer: ArraySubs Engineering Team — review scope includes ArraySubs core/Pro retry contracts, Stripe payment reconciliation, gateway ownership, lifecycle scheduling, and access recovery.
Verification environment: Source review of ArraySubs 1.8.11 and ArraySubs Pro 1.1.2 on July 16, 2026, plus current official WooCommerce, Stripe, PayPal, Paddle, and PCI SSC documentation. No live decline or scheduler-race test was performed for this article.
Disclosure, limitations, and update log
- Commercial disclosure: ArraySubs is an ArrayHash product. The strategy and provider comparisons above are educational; product limitations are stated explicitly.
- Limitations: Gateway and network behavior changes. Provider timing is not an endorsement, and illustrative cohort numbers are not performance benchmarks.
- July 16, 2026: First publication. Verified the current local Stripe retry count/interval, core/Pro ownership, pre-retry reconciliation, PayPal/Paddle remote ownership, and retry/grace boundary caveat.
Continue from strategy to setup
Use a recipe when the model is settled
These articles own the decision and operating model. The ArraySubs feature map and recipes cover the exact product, billing, and customer-workflow configuration.
Written by
Emran // ArrayHash
Research and practical guidance for WooCommerce subscription operators and implementation teams.
Technical review
ArraySubs Engineering Team
Reviewed against current ArraySubs code, product documentation, and the linked primary platform sources.




