Skip to main content

Billing
object

Contains function used to bill merchants for your app with the Billing API.

This object is returned on authenticated Admin requests.

Note

Managed App Pricing is now available. Define your app’s pricing plans directly in the Shopify Partner Dashboard, without needing to use the Billing API.

Provides utilities that apps can use to request billing for the app using the Admin API.

(options: ) => Promise<AppSubscription>
required

Cancels an ongoing subscription, given its ID.

<Options extends <Config>>(options?: Options) => Promise<BillingCheckResponseObject>
required

Checks if the shop has an active payment for any plan defined in the billing config option.

(options: ) => Promise<UsageRecord>
required

Creates a usage record for an app subscription.

(options: <Config>) => Promise<never>
required

Requests payment for the plan.

(options: <Config>) => Promise<BillingCheckResponseObject>
required

Checks if the shop has an active payment for any plan defined in the billing config option.

Anchor to updateUsageCappedAmount
updateUsageCappedAmount
(options: ) => Promise<never>
required

Updates the capped amount for a usage billing plan.

Was this section helpful?

Use the billing.cancel function to cancel an active subscription with the id returned from billing.require.

Was this section helpful?

Cancelling a subscription

import { LoaderFunctionArgs } from "@remix-run/node";
import { authenticate, MONTHLY_PLAN } from "../shopify.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
const { billing } = await authenticate.admin(request);
const billingCheck = await billing.require({
plans: [MONTHLY_PLAN],
onFailure: async () => billing.request({ plan: MONTHLY_PLAN }),
});

const subscription = billingCheck.appSubscriptions[0];
const cancelledSubscription = await billing.cancel({
subscriptionId: subscription.id,
isTest: true,
prorate: true,
});

// App logic
};

Anchor to example-check-what-billing-plans-a-merchant-is-subscribed-toCheck what billing plans a merchant is subscribed to

Use billing.check if you want to determine which plans are in use. Unlike require, check does notthrow an error if no active billing plans are present.

Anchor to example-check-for-payments-without-filteringCheck for payments without filtering

Use billing.check to see if any payments exist for the store, regardless of whether it's a test ormatches one or more plans.

Was this section helpful?

Check what billing plans a merchant is subscribed to

import { LoaderFunctionArgs } from "@remix-run/node";
import { authenticate, MONTHLY_PLAN } from "../shopify.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
const { billing } = await authenticate.admin(request);
const { hasActivePayment, appSubscriptions } = await billing.check({
plans: [MONTHLY_PLAN],
isTest: false,
});
console.log(hasActivePayment);
console.log(appSubscriptions);
};

Create a usage record for the active usage billing plan

Was this section helpful?

Creating a usage record

import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate, MONTHLY_PLAN } from "../shopify.server";

export const action = async ({ request }: ActionFunctionArgs) => {
const { billing } = await authenticate.admin(request);

const chargeBilling = await billing.createUsageRecord({
description: "Usage record for product creation",
price: {
amount: 1,
currencyCode: "USD",
},
isTest: true,
});
console.log(chargeBilling);

// App logic
};

Change where the merchant is returned to after approving the purchase using the returnUrl option.

Customize the plan for a merchant when requesting billing. Any fields from the plan can be overridden, as long as the billing interval for line items matches the config.

Was this section helpful?

Using a custom return URL

import { LoaderFunctionArgs } from "@remix-run/node";
import { authenticate, MONTHLY_PLAN } from "../shopify.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
const { billing } = await authenticate.admin(request);
await billing.require({
plans: [MONTHLY_PLAN],
onFailure: async () => billing.request({
plan: MONTHLY_PLAN,
isTest: true,
returnUrl: 'https://admin.shopify.com/store/my-store/apps/my-app/billing-page',
}),
});

// App logic
};

Call billing.request in the onFailure callback to immediately redirect to the Shopify page to request payment.

When the app has multiple plans, create a page in your App that allows the merchant to select a plan. If a merchant does not have the required plan you can redirect them to page in your app to select one.

Was this section helpful?

Requesting billing right away

import { LoaderFunctionArgs } from "@remix-run/node";
import { authenticate, MONTHLY_PLAN } from "../shopify.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
const { billing } = await authenticate.admin(request);
await billing.require({
plans: [MONTHLY_PLAN],
isTest: true,
onFailure: async () => billing.request({ plan: MONTHLY_PLAN }),
});

// App logic
};

Anchor to example-updating-the-capped-amount-for-a-usage-billing-planUpdating the capped amount for a usage billing plan

Update the capped amount for the usage billing plan specified by subscriptionLineItemId.

Was this section helpful?

Updating the capped amount for a usage billing plan

import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";

export const action = async ({ request }: ActionFunctionArgs) => {
const { billing } = await authenticate.admin(request);

await billing.updateUsageCappedAmount({
subscriptionLineItemId: "gid://shopify/AppSubscriptionLineItem/12345?v=1&index=1",
cappedAmount: {
amount: 10,
currencyCode: "USD"
},
});

// App logic
};