Clicks & Carts

Shopify Billing API: charging for your app

Charging through Shopify puts your fee on the merchant's Shopify invoice. The implementation is small; the pricing decisions are not.

7 min read · Apps & checkout ·

Public Shopify apps charge through Shopify's Billing API. The merchant approves a charge, it appears on their regular Shopify invoice alongside their plan, and Shopify handles collection, dunning, currency and tax. In exchange, Shopify takes a revenue share.

For custom apps built for one client you usually bill outside Shopify entirely — an invoice, like any other work.

The charge types

Recurring subscription. The standard model. A monthly or annual fee, optionally with a trial and optionally with capped usage on top.

Usage charges. Metered billing on top of a subscription, within a cap the merchant approved. Right when your cost scales with their volume — orders processed, records synced, documents generated.

One-time charge. A single fee. Rare as a primary model; useful for setup fees or add-ons.

App credits. Refunds and goodwill, applied against future charges.

The flow

  1. Your app creates a charge with a mutation and gets back a confirmation URL.
  2. You redirect the merchant to it.
  3. They approve or decline in Shopify's UI.
  4. Shopify redirects back to your return URL.
  5. You verify the charge status through the API before unlocking anything.

Step five is the one people skip. Never trust the redirect alone — check the subscription's actual status server-side. And check it on an ongoing basis, because a charge can be cancelled or fail later.

``graphql mutation { appSubscriptionCreate( name: "Pro plan" returnUrl: "https://your-app.example.com/billing/callback" trialDays: 14 lineItems: [{ plan: { appRecurringPricingDetails: { price: { amount: 29.0, currencyCode: USD }, interval: EVERY_30_DAYS } } }] ) { confirmationUrl userErrors { field message } } } ``

Select userErrors, as with every Admin API mutation.

Trials and plan changes

Trials are a parameter on the subscription, so Shopify handles the free period — you don't track it yourself.

Plan changes replace the subscription rather than editing it. Create the new one, the merchant approves, the old one is cancelled. Handle the gap: if they approve the upgrade and your code cancels the old plan before the new one is confirmed, they briefly have no plan and your app locks them out of something they just paid more for.

Cancellations happen without warning — the merchant can cancel from their admin, and uninstalling cancels everything. Listen for app_subscriptions/update and app/uninstalled and degrade gracefully rather than erroring.

The pricing decisions that matter more

The implementation is a day. The pricing is the product.

  • Charge for the value, not the feature count. Tiers based on order volume or store size track the value merchants get. Tiers based on "number of widgets enabled" invite them to work around you.
  • Make the free tier genuinely useful or don't have one. A free tier that does nothing produces installs, no revenue, and support load.
  • Trials should be long enough to see value. If your app's value shows up at month-end, a seven-day trial is worthless.
  • Usage caps need headroom. A merchant hitting a cap during Black Friday and having the app stop is a churn event you built yourself.
  • Annual billing at a discount improves retention markedly.

What you must handle

  • Failed charges. Shopify retries; you decide what your app does in the meantime. Cutting access instantly on a first failure is aggressive; never cutting it is a business model problem.
  • Uninstall during a billing period. The subscription cancels; your obligation to delete their data begins — the mandatory privacy webhooks.
  • Currency. Shopify handles conversion, but your reporting needs to know what you actually received.
  • Test mode. Charges can be created as test charges on development stores. Use it, and make sure test charges can never be created in production — a real error that has shipped in real apps.

Review requirements

Shopify checks that pricing in your listing matches what the app charges, that trials work as described, and that the app doesn't lock a merchant out of their own data when a subscription ends. Listing requirements covers the rest.

The Billing API is the easy part. Deciding what to charge, and what happens when someone stops paying, is where app businesses are actually made or lost.

Is this the problem you’re looking at?

Send me the link to your store and a line about what is going wrong. You get a straight answer within one business day — no pitch, no obligation.

mario@clicksandcarts.co

Or see what I do around Shopify: services, work beyond the theme, selected work.

Keep reading

← All articles