Shopify Subscriptions Demystified: A Developer's Guide to Billing, Webhooks & Testing

Hey everyone, I was just browsing the community forums and came across an excellent set of questions from Navin3 about building a custom subscription (membership) app using Shopify’s Selling Plans and the Subscriptions API. It really hit on some core areas that a lot of developers and store owners wonder about when diving into recurring revenue models on Shopify. So, I thought I'd share some insights, drawing from how these systems generally work and what we often see in the community.

Navin3 was looking for clarification on recurring billing, webhooks, and testing, aiming to build an app that integrates seamlessly without duplicating effort. Let's break down these points, because getting this right is crucial for a smooth subscription experience for both you and your customers.

Who Handles the Recurring Billing? Shopify or Your App?

This is probably one of the most common questions, and it’s a good one to start with because it clarifies where your app's responsibilities end and Shopify's begin. Navin3 asked if recurring charges are automatically handled by Shopify or if the app needs to manage billing logic externally.

Here’s the deal: once you've successfully created a subscription contract using the Subscriptions API and linked it to a selling plan, Shopify takes over the recurring billing. This is fantastic news because it means you don't need to build out complex cron jobs or external payment capture systems for each billing cycle. Shopify manages the billing attempts through Shopify Payments or whatever payment gateway the customer initially used for their purchase.

Your app's role is primarily to:

  • Create and manage the subscription contract: This includes setting up the initial contract, updating it (e.g., changing a plan), or canceling it.
  • Respond to contract events: This is where webhooks come in, which we'll discuss next!

So, to directly answer Navin3's question: No, manual intervention from the app side for the actual recurring payment processing is generally NOT required. Shopify handles the heavy lifting of charging the customer's card on file according to the contract's billing cycle. Your app just needs to be aware of what’s happening.

Navigating Subscription Webhooks: What to Listen For

Knowing when things happen is just as important as knowing who does what. Navin3 was looking for a clear list of reliable webhooks to track the subscription billing lifecycle – successful billing, failed payments, retries, and contract updates. This is where you connect your app to Shopify's pulse.

For selling plan-based subscriptions, you'll primarily be interested in a few key webhook topics:

1. For Subscription Contract Lifecycle Events:

  • subscription_contracts/create: Fired when a new subscription contract is successfully created. This is your cue that a customer has subscribed!
  • subscription_contracts/update: Triggered when a contract is modified (e.g., plan change, address update, pause).
  • subscription_contracts/cancel: Notifies you when a subscription contract has been canceled.

These are your go-to for managing the state of the subscription itself within your app.

2. For Recurring Billing & Order Creation:

  • orders/create: This is absolutely critical for tracking recurring charges. When Shopify successfully processes a recurring payment for a subscription renewal, it generates a new order in your Shopify Admin. This webhook will fire for that new order, just like it would for any other order placed in your store.

This means that each renewal isn't just a charge; it's a full-fledged order, complete with line items, shipping details (if applicable), and payment information. You'll process these just like any other order for fulfillment, inventory updates, etc.

3. For Payment Status (Success/Failure/Retries):

While orders/create tells you when a renewal order is made, you'll want more granular detail on the payment itself. This is typically handled within the context of the order:

  • order_transactions/create: This webhook is incredibly useful. It fires when a transaction is created for an order, including successful payments, failed attempts, and sometimes even authorizations. You can inspect the transaction object to see its status (e.g., 'success', 'failure', 'pending').

Shopify's internal retry logic for failed subscription payments usually happens behind the scenes, and the status updates would flow through subsequent order_transactions/create events (if a new transaction attempt is made) or an orders/update webhook if the order's payment status changes without a new transaction being created (e.g., from 'pending' to 'paid'). You might also see specific payment gateway events if your app integrates very deeply, but for most subscription needs, order_transactions/create within the context of the renewal order is sufficient.

So, to sum up the webhooks: focus on subscription_contracts/* for contract state, orders/create for renewals, and order_transactions/create for payment outcomes on those renewal orders.

Tracking Your Test Subscriptions in the Admin

Navin3 also asked about viewing transactions for test payments. This is straightforward once you understand how Shopify handles renewals.

Since each successful recurring charge generates a new order, you will see all these renewal orders directly in your Shopify Admin under 'Orders'. They'll look just like any other order, but often with an indicator that they originated from a subscription (depending on your theme/app setup, or by inspecting the order's metadata or associated subscription contract ID).

Within each of these renewal orders, you can click into the order details to see the payment attempts and their status (success/failure) in the 'Timeline' or 'Payments' section. So, yes, the Shopify Admin is your central hub for viewing all transactions triggered by recurring billing cycles, both orders and payment attempts.

The Best Strategy for Testing Your Subscription Flow

Testing is where the rubber meets the road, especially for a multi-stage process like a subscription lifecycle. Navin3 asked whether to use Bogus Gateway or Shopify Payments (test mode) and which supports full lifecycle testing.

While the Bogus Gateway is quick for basic payment flow testing, for anything involving recurring payments and simulating real-world scenarios like failures and retries, you absolutely want to use Shopify Payments in test mode. Here’s why:

  1. Realistic Simulation: Shopify Payments test mode uses specific test card numbers that simulate various outcomes – successful charges, failures due to insufficient funds, declined payments, etc. This is crucial for testing your app's error handling and how it reacts to different payment statuses.
  2. Subscription Contract Renewals: Shopify Payments test mode fully supports the creation and renewal of subscription contracts, allowing you to test the automatic recurring charges just as they would happen in a live environment.
  3. Full Lifecycle Testing: You can truly test the entire subscription lifecycle: creating a subscription, waiting for a renewal (or fast-forwarding time in a development store if possible, though usually you'd simulate renewal events via API or wait for the actual cycle), simulating a failed payment, observing retry attempts, and then a successful payment or eventual cancellation.

To use Shopify Payments in test mode:

  1. Go to your Shopify Admin > Settings > Payments.
  2. If Shopify Payments is already active, you'll see a 'Manage' button. Click it.
  3. Scroll down to 'Test mode' and ensure it's enabled.
  4. Use the Shopify test card numbers for different scenarios when making test purchases.

This approach gives you a robust way to ensure your app correctly integrates with Shopify’s subscription infrastructure, handles various billing outcomes, and doesn't miss any critical webhook events. It’s all about building confidence that your app will perform flawlessly when real customers start signing up for your fantastic subscription offerings!

So, there you have it! Navin3's questions really opened up a great discussion point for anyone looking to build or integrate with Shopify's subscription capabilities. By understanding these core mechanics – who handles billing, which webhooks to listen for, and how to thoroughly test – you're well on your way to a robust and reliable subscription service. Happy building!

Share:

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools