Choosing between a recurring subscription model and a one-time charge is one of the highest-leverage decisions you'll make for a Shopify app — it affects your revenue predictability, your LTV calculations, how merchants perceive your pricing, and which Shopify Billing API calls you need to implement. In 2026, the vast majority of successful App Store apps use subscriptions, but one-time charges remain the right choice in specific scenarios. Here's a direct comparison with guidance on which to pick.
| Feature | Recurring Subscription (AppSubscription) Monthly or annual recurring charge, cancelable at any time | One-Time Charge (ApplicationCharge) Single payment, permanent access, no recurring billing |
|---|---|---|
| Revenue predictability | High — MRR compounds predictably | Low — lumpy, project-based revenue |
| Merchant commitment barrier | Low — easy to start, easy to cancel | Higher — feels like a bigger purchase decision |
| Implementation API | appSubscriptionCreate mutation | applicationChargeCreate mutation |
| Test mode support | Yes — test: true in mutation | Yes — test: true in mutation |
| Free trial support | Yes — trialDays field on plan | No native trial concept |
| Annual billing discount | Yes — create with interval: ANNUAL at a discounted price | N/A — no recurring component |
| Usage-based billing add-on | Yes — pair with appUsageRecordCreate | No |
| Merchant refund pathway | Cancels future charges; partial refunds via Shopify Partner support | Shopify handles chargebacks; refunds via support |
| App Store revenue share | Same 0% for first $1M revenue, then 15% | Same 0% for first $1M revenue, then 15% |
| Best for | Ongoing services, SaaS features, tools requiring maintenance | One-time tools, theme customizations, data migrations |
Choose recurring subscriptions for any app that requires ongoing infrastructure, maintenance, or ongoing feature development. This is the right model for review apps, loyalty program apps, email marketing integrations, inventory management tools, analytics dashboards, and anything with a server component that costs you money to run. The market expectation is subscription for these categories — one-time pricing in a category dominated by subscriptions signals to merchants that your app might not be maintained.
Choose one-time charges for apps that provide a discrete, complete deliverable: a data migration tool that imports historical orders from another platform, a theme feature extension that adds specific functionality to a Shopify theme and then requires no server, or a one-time setup service. If your app genuinely requires no ongoing hosting and no updates, a one-time charge is honest pricing and merchants will appreciate it.
Implementing AppSubscription in Remix
The appSubscriptionCreate GraphQL mutation creates a recurring charge and returns a confirmationUrl. Redirect the merchant to this URL to complete the charge approval on Shopify's side. After approval, Shopify redirects them back to your returnUrl with a charge_id query parameter. Verify the charge status with an appSubscription query and unlock the relevant features.
const CREATE_SUBSCRIPTION = `#graphql
mutation CreateSubscription($returnUrl: URL!) {
appSubscriptionCreate(
name: "Pro Plan"
returnUrl: $returnUrl
test: true
lineItems: [
{
plan: {
appRecurringPricingDetails: {
price: { amount: 29.00, currencyCode: USD }
interval: EVERY_30_DAYS
}
}
}
]
) {
appSubscription { id status }
confirmationUrl
userErrors { field message }
}
}
` as const;
export async function action({ request }: ActionFunctionArgs) {
const { admin, session } = await authenticate.admin(request);
const returnUrl = `https://${session.shop}/admin/apps/${process.env.SHOPIFY_API_KEY}/billing/callback`;
const response = await admin.graphql(CREATE_SUBSCRIPTION, {
variables: { returnUrl },
});
const { data } = await response.json();
if (data.appSubscriptionCreate.userErrors.length > 0) {
return json({ error: data.appSubscriptionCreate.userErrors[0].message }, { status: 400 });
}
return redirect(data.appSubscriptionCreate.confirmationUrl);
}Usage-based billing: the third option
Shopify's Billing API supports a third model: usage-based billing, layered on top of a subscription. You create an AppSubscription with a base monthly fee and add a usageLine component with a cappedAmount and terms string. Then, as the merchant uses metered features — sending SMS messages, generating AI content, or processing orders — you call appUsageRecordCreate to increment their usage. Shopify aggregates usage records and charges the merchant at the end of each billing cycle, up to the capped amount.
Usage-based billing is particularly valuable for apps with unpredictable merchant usage patterns. A merchant who sends 10 SMS messages a month should pay far less than one who sends 10,000. The usage model aligns your revenue directly with the value you deliver — which also improves retention, because merchants don't feel they're paying for something they're not using.
# Creating a subscription with a usage component
mutation CreateUsageSubscription($returnUrl: URL!) {
appSubscriptionCreate(
name: "Growth Plan"
returnUrl: $returnUrl
lineItems: [
{
plan: {
appRecurringPricingDetails: {
price: { amount: 9.00, currencyCode: USD }
interval: EVERY_30_DAYS
}
}
},
{
plan: {
appUsagePricingDetails: {
terms: "$0.01 per SMS message sent"
cappedAmount: { amount: 50.00, currencyCode: USD }
}
}
}
]
) {
appSubscription { id status }
confirmationUrl
userErrors { field message }
}
}
# Recording a usage event
mutation RecordSmsUsage($subscriptionLineItemId: ID!, $description: String!) {
appUsageRecordCreate(
subscriptionLineItemId: $subscriptionLineItemId
price: { amount: 0.01, currencyCode: USD }
description: $description
) {
appUsageRecord { id }
userErrors { field message }
}
}Handling cancellations and downgrades
When a merchant cancels an AppSubscription — either by uninstalling your app or by canceling the charge directly — Shopify sends an app_subscriptions/update webhook with the subscription status set to CANCELLED or EXPIRED. Subscribe to this webhook and update your database to reflect the merchant's changed plan. Disabling features immediately upon cancellation is acceptable; locking the merchant out before the end of their paid period is not.
For plan upgrades and downgrades, create a new AppSubscription with the new plan details. Shopify prorates the change automatically — if a merchant upgrades from $29/month to $79/month mid-cycle, Shopify charges the difference for the remaining days. You don't need to calculate proration yourself. Cancel the old subscription and create the new one; Shopify handles the math.
Pricing page design patterns
How you present your pricing has a direct effect on conversion. For subscription apps, the most effective pattern in the Shopify ecosystem is a three-tier pricing page: Free/Starter, Growth, and Pro. Even if you don't have a free tier, displaying three tiers lets the middle tier look reasonably priced by comparison. The Polaris Layout component with its three-column grid renders this pattern cleanly.
Include the trialDays value on your AppSubscription prominently. Merchants in the Shopify ecosystem are accustomed to 7–14 day free trials; anything shorter feels stingy and will reduce install-to-paid conversion. During the trial period, your app should be fully functional — don't gate features during the trial. The App Store review process checks for this specifically.
Annual billing: a revenue stability lever
Shopify's Billing API supports annual recurring subscriptions in addition to monthly. You create an AppSubscription with interval: ANNUAL and a price that's typically 10–20% lower than twelve monthly payments. This is a win for both parties: the merchant pays less overall, and you get twelve months of guaranteed revenue upfront. Shopify collects the annual amount immediately when the merchant accepts the charge.
The implementation for annual billing is identical to monthly — just change the interval field in the appRecurringPricingDetails. Consider offering both options on your pricing page: a monthly plan and an annual plan at a 15-20% discount labeled 'Save 20% — billed annually'. This is a standard SaaS pattern that Shopify merchants are familiar with, and it typically converts 20-30% of high-intent merchants to annual plans.
Testing billing in development
Testing billing is a critical pre-submission step that many developers skip because the Billing API requires a live store. Shopify provides a test mode for charges: set test: true in your appSubscriptionCreate mutation to create a charge that goes through the full confirmation flow without actually billing the merchant. Test charges appear in the Partner dashboard with a 'Test' badge and are excluded from payout calculations.
Make sure to test these specific scenarios: merchant accepts the charge (status becomes ACTIVE, features are unlocked), merchant declines the charge (you show the pricing page again gracefully), merchant cancels mid-subscription via the Shopify billing settings (you receive the app_subscriptions/update webhook and handle it), and merchant reinstalls after cancelling (existing subscription is expired, new charge flow is presented). Each of these is a code path that must work correctly or your app will fail the review.
Frequently asked questions
- Can I use Stripe for payments in a Shopify app?
Not for charging merchants for your app. Shopify requires all App Store app charges to go through the Shopify Billing API — using Stripe, PayPal, or any other payment processor to charge merchants for app access is a rejection reason and a policy violation. However, if your app itself is a payment tool (like a subscription box app that charges customers), you can integrate Stripe to charge the merchants' customers — that's a different use case and is permitted.
- What is Shopify's revenue share on app billing?
As of 2021, Shopify takes 0% revenue share on your first $1 million USD in annual app revenue. Above $1 million, the share is 15%. This applies to both subscriptions and one-time charges. The $1M threshold resets annually. For most apps, this means you pay nothing to Shopify until you reach significant scale — a better deal than the 30% cut that app stores historically charged.
