Setting up billing for your public Shopify app can be a daunting task. To give you a head start when building apps for the Shopify App Store, we’re releasing additional forkable apps with Shopify billing built-in.
To make sure that we captured the nitty-gritty details that go into working with the Shopify Billing API, we worked with the Optiz.io team, who have released both public and custom apps, to build a series of forkable sample apps that incorporate usage-based billing into different subscription models.
The first of these app templates can be forked here: https://app.gadget.dev/auth/fork?domain=shopify-billing-recurring-usage-v2--development.gadget.app
Included in this app:
All you need to do to get started is set up a Shopify Partners connection in Gadget and install your app on a development store.
There are two steps you want to make sure you take when setting up the connection:
The app’s Home page, powered by the Readme.md file in the project root, has step-by-step instructions for setting up the connection. Check out the following “Under the hood” section for more details on implementation and the billing flow.
Join our developer Discord to chat with the Gadget team and the community!
A Plan model has been added to keep track of the available payment plans. Two pricing values need to be stored for this app: monthly fees and a percentage of each order, both of which are stored in Plan. There are also fields for storing information about the remaining trial days, and the remaining cap on the usage plan. Each shop can have a single active plan, defined through a relationship field.
The following diagram shows how app subscription works. This is a typical flow for Shopify billing and shows where requests are handled in Gadget. Most notably, the shopifyShop/subscribe/onSubscribe.js and routes/GET-finished-subscription.js files are used to make the initial subscription and handle the redirection back to the admin app’s billing page.
In this sample, when orders are created a new usage charge is made against the shop on which the app is installed. This is done in the shopifyOrder/create/onCreate.js file, which is triggered by Shopify Order webhooks.
When creating the charge, the orderId becomes the usage record’s idempotencyKey. This is to prevent duplicate charging of an order.
Once usage charges have been made the remaining balance on the account can be calculated. This is done via a Shopify Sync success effect and is only kicked off once every five minutes, at max. A sync is required to get all of the latest usage charges and app subscription info so that the remaining cap balance can be updated.
You may want to use this value to prompt merchants to upgrade plans in the admin UI or send a friendly email to let them know that they are close to their spending limit.
The usedTrialDaysUpdatedAt and possibly existing usedTrialDays are used to update the new usedTrialDays value when a merchant has upgraded or downgraded a plan. When a merchant uninstalls the application, usedTrialDays is again updated, and the usedTrialDaysUpdatedAt is reset.
The subscribe action looks at the plan's default trialDays and deducts the usedTrialDays to calculate the allowed trialDays to add to the subscription.
This approach prevents merchants from abusing free trials by continuously changing plans or continuously reinstalling the application.
The trial is not currently incorporated into the frontend of this template. Check out Gadget’s Shopify billing docs for an example of how to implement advanced free trial features.
With this template, Gadget will handle all of the connections and boilerplate code, and now billing too. If you have any questions or just want to connect with other Shopify app developers, join our Discord.