Overview
The billing API provides functions for managing app charges, subscriptions, and usage-based billing.
Access the billing API through your configured Shopify instance:
const shopify = shopifyApi ({ /* config */ });
const billing = shopify . billing ;
Configuration
Define your billing plans when initializing the Shopify API:
import { shopifyApi , BillingInterval } from '@shopify/shopify-api' ;
const shopify = shopifyApi ({
// ... other config
billing: {
'Basic Plan' : {
amount: 10.0 ,
currencyCode: 'USD' ,
interval: BillingInterval . Every30Days ,
},
'Premium Plan' : {
lineItems: [
{
amount: 30.0 ,
currencyCode: 'USD' ,
interval: BillingInterval . Every30Days ,
},
{
amount: 100.0 ,
currencyCode: 'USD' ,
interval: BillingInterval . Usage ,
terms: '1 dollar per 100 emails' ,
},
],
},
},
});
check()
Checks if the shop has an active payment for the specified plan(s).
Signature
type BillingCheck = < Params extends BillingCheckParams >(
params : Params ,
) => Promise < BillingCheckResponse < Params >>;
Parameters
The session to use for this check.
The plan name(s) to check. If not provided, checks for any active subscription.
Whether to include test charges. Test shops and demo shops cannot be charged.
Returns
Returns a Promise<BillingCheckResponseObject>:
Whether the shop has an active payment method for the plan(s).
Array of one-time purchases the shop has made. The ID of the one-time purchase.
The name of the purchased plan.
Whether this is a test purchase.
Status: ACTIVE, CANCELLED, PENDING, DECLINED, EXPIRED, FROZEN, or ACCEPTED.
Array of active app subscriptions. Whether this is a test subscription.
Status: ACTIVE, CANCELLED, PENDING, DECLINED, EXPIRED, FROZEN, or ACCEPTED.
Current period end date/time.
lineItems
ActiveSubscriptionLineItem[]
Line items for this subscription.
Example
Check Any Active Subscription
Check Specific Plan
Check Multiple Plans
const billing = await shopify . billing . check ({ session });
if ( ! billing . hasActivePayment ) {
// Redirect to billing
const confirmation = await shopify . billing . request ({
session ,
plan: 'Basic Plan' ,
});
return redirect ( confirmation );
}
request()
Requests payment from the merchant for a plan.
Signature
type BillingRequest = < Params extends BillingRequestParams >(
params : Params ,
) => Promise < BillingRequestResponse < Params >>;
Parameters
The session to use for this request.
The plan name to request (must match a plan defined in config).
Whether this is a test purchase.
Override the return URL after purchase completion.
Whether to return the full response object instead of just the confirmation URL.
Override the plan amount (one-time purchases only).
Override the currency code.
Returns
By default, returns a Promise<string> containing the confirmation URL.
With returnObject: true, returns:
The URL to redirect the merchant to confirm the charge.
The created one-time purchase (if applicable).
The created app subscription (if applicable).
Example
Basic Usage
Test Purchase
With Full Response
Override Amount
const confirmationUrl = await shopify . billing . request ({
session ,
plan: 'Basic Plan' ,
});
// Redirect merchant to confirm
return redirect ( confirmationUrl );
cancel()
Cancels an active subscription.
Signature
type BillingCancel = (
params : BillingCancelParams ,
) => Promise < AppSubscription >;
Parameters
The session to use for this request.
The subscription ID to cancel.
Whether to prorate the cancellation.
Whether to consider test purchases.
Returns
Returns the cancelled AppSubscription object.
Example
const cancelled = await shopify . billing . cancel ({
session ,
subscriptionId: 'gid://shopify/AppSubscription/1234567890' ,
prorate: true ,
});
console . log ( 'Cancelled subscription:' , cancelled . id );
console . log ( 'Status:' , cancelled . status ); // 'CANCELLED'
subscriptions()
Retrieves all active subscriptions for the shop.
Signature
type BillingSubscriptions = (
params : BillingSubscriptionParams ,
) => Promise < ActiveSubscriptions >;
Parameters
The session to use for this request.
Returns
Array of active app subscriptions.
Example
const { activeSubscriptions } = await shopify . billing . subscriptions ({ session });
activeSubscriptions . forEach ( sub => {
console . log ( `Plan: ${ sub . name } ` );
console . log ( `Status: ${ sub . status } ` );
console . log ( `Created: ${ sub . createdAt } ` );
});
createUsageRecord()
Creates a usage record for a usage-based billing plan.
Signature
type BillingCreateUsageRecord = (
params : BillingCreateUsageRecordParams ,
) => Promise < UsageRecord >;
Parameters
The session to use for this request.
Description of the usage record.
Price information: The amount to charge for this usage.
The currency code (e.g., ‘USD’).
The subscription line item ID to associate the usage record with.
Idempotency key to prevent duplicate charges.
Whether this is a test charge.
Returns
Returns the created UsageRecord object.
Example
const usageRecord = await shopify . billing . createUsageRecord ({
session ,
description: '100 emails sent' ,
price: {
amount: 1.00 ,
currencyCode: 'USD' ,
},
subscriptionLineItemId: 'gid://shopify/AppSubscriptionLineItem/1234' ,
idempotencyKey: `usage- ${ Date . now () } ` ,
});
console . log ( 'Usage record created:' , usageRecord . id );
updateUsageCappedAmount()
Updates the capped amount for a usage-based billing subscription.
Signature
type BillingUpdateUsageCappedAmount = (
params : BillingUpdateUsageCappedAmountParams ,
) => Promise < UpdateCappedAmountConfirmation >;
Parameters
The session to use for this request.
The subscription line item ID to update.
Returns
URL to confirm the update.
The updated subscription.
Example
const result = await shopify . billing . updateUsageCappedAmount ({
session ,
subscriptionLineItemId: 'gid://shopify/AppSubscriptionLineItem/1234' ,
cappedAmount: {
amount: 200.00 ,
currencyCode: 'USD' ,
},
});
// Redirect to confirmation URL if needed
if ( result . confirmationUrl ) {
return redirect ( result . confirmationUrl );
}
Billing Configuration Types
BillingInterval
enum BillingInterval {
OneTime = 'ONE_TIME' ,
Every30Days = 'EVERY_30_DAYS' ,
Annual = 'ANNUAL' ,
Usage = 'USAGE' ,
}
One-Time Plan
interface BillingConfigOneTimePlan {
amount : number ;
currencyCode : string ;
interval : BillingInterval . OneTime ;
}
Recurring Plan
interface BillingConfigRecurringLineItem {
amount : number ;
currencyCode : string ;
interval : BillingInterval . Every30Days | BillingInterval . Annual ;
discount ?: {
durationLimitInIntervals ?: number ;
value : {
amount : number ;
} | {
percentage : number ;
};
};
}
Usage-Based Plan
interface BillingConfigUsageLineItem {
interval : BillingInterval . Usage ;
amount : number ; // Capped amount
currencyCode : string ;
terms : string ; // Usage terms description
}
Subscription with Line Items
interface BillingConfigSubscriptionLineItemPlan {
replacementBehavior ?: BillingReplacementBehavior ;
trialDays ?: number ;
lineItems : ( BillingConfigRecurringLineItem | BillingConfigUsageLineItem )[];
}
Notes
Test charges don’t actually charge the merchant. Use isTest: true during development.
For usage-based billing, you must create usage records within the billing period to charge for usage.
The merchant must approve all charges through the confirmation URL before they take effect.
Plan configurations must be defined when initializing shopifyApi() in the billing config option.