Skip to main content

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

session
Session
required
The session to use for this check.
plans
string | string[]
The plan name(s) to check. If not provided, checks for any active subscription.
isTest
boolean
default:"false"
Whether to include test charges. Test shops and demo shops cannot be charged.

Returns

Returns a Promise<BillingCheckResponseObject>:
hasActivePayment
boolean
Whether the shop has an active payment method for the plan(s).
oneTimePurchases
OneTimePurchase[]
Array of one-time purchases the shop has made.
appSubscriptions
AppSubscription[]
Array of active app subscriptions.

Example

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

session
Session
required
The session to use for this request.
plan
string
required
The plan name to request (must match a plan defined in config).
isTest
boolean
default:"false"
Whether this is a test purchase.
returnUrl
string
Override the return URL after purchase completion.
returnObject
boolean
default:"false"
Whether to return the full response object instead of just the confirmation URL.
amount
number
Override the plan amount (one-time purchases only).
currencyCode
string
Override the currency code.

Returns

By default, returns a Promise<string> containing the confirmation URL. With returnObject: true, returns:
confirmationUrl
string
The URL to redirect the merchant to confirm the charge.
oneTimePurchase
OneTimePurchase
The created one-time purchase (if applicable).
appSubscription
AppSubscription
The created app subscription (if applicable).

Example

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

session
Session
required
The session to use for this request.
subscriptionId
string
required
The subscription ID to cancel.
prorate
boolean
default:"false"
Whether to prorate the cancellation.
isTest
boolean
default:"false"
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

session
Session
required
The session to use for this request.

Returns

activeSubscriptions
AppSubscription[]
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

session
Session
required
The session to use for this request.
description
string
required
Description of the usage record.
price
object
required
Price information:
subscriptionLineItemId
string
The subscription line item ID to associate the usage record with.
idempotencyKey
string
Idempotency key to prevent duplicate charges.
isTest
boolean
default:"false"
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

session
Session
required
The session to use for this request.
subscriptionLineItemId
string
required
The subscription line item ID to update.
cappedAmount
object
required
The new capped amount:

Returns

confirmationUrl
string
URL to confirm the update.
appSubscription
AppSubscription
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.

Build docs developers (and LLMs) love