Selling plans vs subscription contracts

A selling plan is the template — "monthly, 10% off, billed and delivered every 30 days." A subscription contract is an instance of that template attached to a specific customer with a specific payment method, address, and line items. The contract is what actually renews. Apps create the selling plan once and create a contract every time a customer subscribes. Both objects are queryable via Shopify's GraphQL Admin API.

How third-party apps drive renewals

Shopify doesn't auto-renew contracts on a schedule for you. Apps run their own cron jobs, query upcoming renewals, and call the subscriptionBillingAttempt mutation to charge the stored payment method and create the next order. This is where app quality varies wildly. A well-built app handles failed payments with a dunning sequence, retries on a sensible schedule, and updates the contract status. A badly built one charges once, fails, and silently stops.

  • subscriptionBillingAttemptCreate is the mutation that triggers a renewal charge
  • Failed attempts surface error codes — your app needs to interpret and react
  • Idempotency matters: replaying a billing attempt should not double-charge

Webhooks you actually need

Subscription apps subscribe to a handful of webhook topics to stay in sync with Shopify. The important ones are subscription_contracts/create, subscription_contracts/update, subscription_billing_attempts/success, and subscription_billing_attempts/failure. Miss a webhook and your app's view of the contract drifts from Shopify's truth.

  • Verify HMAC signatures on every webhook — not optional
  • Make webhook handlers idempotent; Shopify retries on non-2xx responses
  • Subscribe to customer/payment_method updates if you want proactive failure handling

API-based vs legacy billing

"Legacy billing" refers to the old ScriptTag approach where apps ran their own checkout and stored cards in their own vault, bypassing Shopify checkout. It's deprecated and being removed. Modern apps use Shopify's native checkout, which means cards are vaulted by Shopify Payments (or the gateway), 3DS works automatically, and customers see a normal Shopify checkout. SimpleSubscription is API-native.

What to ask before trusting an app with your billing

If you're evaluating a subscription app, the questions that matter are technical. Does it use subscription contracts or a custom database? Does it pass selling plan IDs through to Shopify checkout? Does it handle dunning, and how many retries with what backoff? Can you export contract data if you leave? Apps that answer these confidently are the ones running on Shopify's native rails.

  • Ask for the GraphQL queries the app makes — a serious vendor will share them
  • Confirm renewals create real Shopify orders, not external invoices
  • Check what happens to active contracts if you uninstall (they pause, not disappear)