Appearance
Billing & payments
Public apps charge merchants through Shopify. The charge appears on the merchant's Shopify invoice, and Shopify pays you out. App Store apps can't use Stripe or other external billing for app fees.
Two ways to charge
| Managed Pricing | Billing API | |
|---|---|---|
| Setup | Define plans in the dashboard | Write GraphQL mutations |
| Plan selection page | Hosted by Shopify | You build it |
| Flexibility | Recurring plans + trials | Recurring, usage-based, one-time, discounts, custom logic |
| Best for | Simple tiered plans | Usage pricing (e.g. per WhatsApp message), complex plans |
Billing API building blocks
| Mutation | Charge type |
|---|---|
appSubscriptionCreate | Recurring (every 30 days or annual), optional trial, optional usage component |
appUsageRecordCreate | Add a usage charge against a subscription's capped usage line |
appPurchaseOneTimeCreate | One-time charge |
appSubscriptionCancel | Cancel |
The flow
Recurring + usage example (FlowFlex-style)
graphql
mutation {
appSubscriptionCreate(
name: "Growth"
returnUrl: "https://admin.shopify.com/store/my-shop/apps/my-app"
trialDays: 7
test: true
lineItems: [
{ plan: { appRecurringPricingDetails: { price: { amount: 29, currencyCode: USD }, interval: EVERY_30_DAYS } } }
{ plan: { appUsagePricingDetails: { cappedAmount: { amount: 200, currencyCode: USD }, terms: "$0.01 per WhatsApp message" } } }
]
) {
confirmationUrl
appSubscription { id lineItems { id } }
userErrors { field message }
}
}Then, when messages are sent:
graphql
mutation {
appUsageRecordCreate(
subscriptionLineItemId: "gid://shopify/AppSubscriptionLineItem/123?v=1&index=1"
price: { amount: 1.50, currencyCode: USD }
description: "150 WhatsApp messages"
idempotencyKey: "shop-123-2026-10-22"
) { appUsageRecord { id } userErrors { field message } }
}In the React Router template
ts
const { billing } = await authenticate.admin(request);
await billing.require({
plans: ["Growth"],
isTest: true,
onFailure: async () => billing.request({ plan: "Growth", isTest: true }),
});Rules to remember
test: trueon dev stores. Test charges are never billed.- A merchant can only have one active subscription per app. Creating a new one replaces the old (upgrade or downgrade).
- Usage charges can't exceed the capped amount. Ask the merchant to approve a higher cap with
appSubscriptionLineItemUpdate. - Listen to
app_subscriptions/updateto keep your database in sync. - Prorating, trials and charge timing follow Shopify's billing cycle. Read the billing docs for the specifics.
Revenue share
Shopify takes a share of app revenue above a threshold. Reports from mid-2025 say the $1M exemption became lifetime rather than annual, with 15% above it.
Unverified
These terms couldn't be confirmed on an official Shopify page while writing this. Check the current Partner Program Agreement before planning pricing.
Project step: require a $9/month "Basic" plan with a 7-day trial before showing the orders page.
Check yourself
- Merchant is on Growth and picks Pro. What happens to the Growth subscription?
- How do you charge per message without surprising the merchant?