We’ve built our own subscription app using Shopify’s Subscriptions API, and we’re seeing unexpected behaviour when a customer updates their payment method on a paused subscription contract.
Expected behaviour: When a customer updates their payment method, Shopify’s dunning retries the original overdue billing cycle (e.g., one that failed on April 23), marks it as BILLED, and resumes the contract.
Actual behaviour: Shopify’s dunning creates a billing attempt via subscriptionBillingAttemptCreate, which starts a new billing cycle from today’s date (e.g., April 30) rather than targeting the existing UNBILLED cycle. The original April 23 cycle remains UNBILLED + HAS_ATTEMPT indefinitely.
Evidence from our contract history:
- April 23: Billing attempt created → FAILED
- April 24–26: Further retries → all FAILED → contract PAUSED
- April 30 19:34: Customer updates payment method
- April 30 19:36: Billing attempt SUCCEEDS (triggered by Shopify’s native dunning) → contract ACTIVE, billing date advanced to May 30 (i.e., a new 30-day cycle was created from April 30)
- April 23 billing cycle: still shows as UNBILLED in the billing cycles list
Because the April 23 cycle is still UNBILLED + HAS_ATTEMPT, our retry jobs (using subscriptionBillingCycleBulkCharge) pick it up days later and charge the customer again — a double charge.
Questions:
- Is this intentional behaviour — that dunning on payment method update always starts a fresh cycle from today rather than retrying the overdue cycle?
- Is there a way to configure dunning to retry the specific UNBILLED cycle rather than creating a new one?
We’re on API version 2026-01. Happy to provide more details if helpful.