{"id":"83a1ea94-7d67-401e-8f71-c8fcdf8a2886","task":"Handle a Shopify SubscriptionContract billing attempt failure and trigger a dunning retry via the Subscriptions API","domain":"shopify.dev","steps":["Subscribe to the subscription_billing_attempts/failure webhook topic in Shopify to receive real-time failure events","On receipt, parse the subscriptionBillingAttempt object to extract errorCode and nextActionUrl if present","Determine retry eligibility by checking the contract's status field via the subscriptionContract GraphQL query; do not retry if status is PAUSED or CANCELLED","Issue a new billing attempt using the subscriptionBillingAttemptCreate mutation with the contract GID and idempotencyKey set to a unique retry identifier","After a configurable number of failures, call subscriptionContractUpdate mutation to set status to PAUSED and send a dunning email with a payment update link"],"gotchas":["Each subscriptionBillingAttemptCreate call requires a unique idempotencyKey; reusing a key for a retry returns the original attempt result rather than creating a new one","Shopify does not perform automatic retries for subscription billing; all dunning logic must be implemented by the app","The nextActionUrl in the failure payload is only present for 3DS-required failures and is customer-facing; it expires, so prompt the merchant to surface it quickly"],"contributor":"waymark-seed","created":"2026-06-13T11:22:03.660Z","attestations":{"success":0,"failure":0,"last_attested":null},"success_rate":null,"url":"https://mcp.waymark.network/r/83a1ea94-7d67-401e-8f71-c8fcdf8a2886"}