---
title: Billing
description: Contains function used to bill merchants for your app.
api_version: v1
source_url:
  html: 'https://shopify.dev/docs/api/shopify-app-remix/v1/apis/billing'
  md: 'https://shopify.dev/docs/api/shopify-app-remix/v1/apis/billing.md'
api_name: shopify-app-remix
---

# Billing

Contains function used to bill merchants for your app.

This object is returned on authenticated Admin requests.

#### billing

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

* **cancel**

  **(options: CancelBillingOptions) => Promise\<AppSubscription>**

  **required**

  Cancels an ongoing subscription, given its ID.

* **request**

  **(options: RequestBillingOptions\<Config>) => Promise\<never>**

  **required**

  Requests payment for the plan.

* **require**

  **(options: RequireBillingOptions\<Config>) => Promise\<BillingCheckResponseObject>**

  **required**

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

### CancelBillingOptions

* isTest

  ```ts
  boolean
  ```

* prorate

  Whether to prorate the cancellation.

  ```ts
  boolean
  ```

* subscriptionId

  The ID of the subscription to cancel.

  ```ts
  string
  ```

### RequestBillingOptions

* amount

  Amount to charge for this plan.

  ```ts
  number
  ```

* currencyCode

  Currency code for this plan.

  ```ts
  string
  ```

* interval

  Interval for this plan. Must be set to \`OneTime\`.

  ```ts
  BillingInterval.OneTime
  ```

* isTest

  Whether this is a test purchase.

  ```ts
  boolean
  ```

* lineItems

  The line items for this plan.

  ```ts
  ({ interval?: BillingInterval.Every30Days | BillingInterval.Annual; discount?: { durationLimitInIntervals?: number; value?: { amount?: number; percentage?: never; } | { amount?: never; percentage?: number; }; }; amount?: number; currencyCode?: string; } | { interval?: BillingInterval.Usage; amount?: number; terms?: string; currencyCode?: string; })[]
  ```

* plan

  The plan to request. Must be one of the values defined in the \`billing\` config option.

  ```ts
  keyof Config["billing"]
  ```

* replacementBehavior

  The replacement behavior to use for this plan.

  ```ts
  BillingReplacementBehavior
  ```

* returnUrl

  Override the return URL after the purchase is complete.

  ```ts
  string
  ```

* trialDays

  How many trial days to give before charging for this plan.

  ```ts
  number
  ```

### RequireBillingOptions

* isTest

  Whether to include charges that were created on test mode. Test shops and demo shops cannot be charged.

  ```ts
  boolean
  ```

* onFailure

  How to handle the request if the shop doesn't have an active payment for any plan.

  ```ts
  (error: any) => Promise<Response>
  ```

* plans

  The plans to check for. Must be one of the values defined in the \`billing\` config option.

  ```ts
  (keyof Config["billing"])[]
  ```

Examples

### Examples

* #### Cancelling a subscription

  ##### Description

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

  ##### /app/routes/cancel-subscription.ts

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

  export const loader = async ({ request }: LoaderArgs) => {
    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
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

* #### Using a custom return URL

  ##### Description

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

  ##### /app/routes/\*\*\\/\*.ts

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

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

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

* #### Requesting billing right away

  ##### Description

  Call \`billing.request\` in the \`onFailure\` callback to immediately request payment.

  ##### /app/routes/\*\*\\/\*.ts

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

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

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

* #### Using a plan selection page

  ##### Description

  Redirect to a different page in the \`onFailure\` callback, where the merchant can select a billing plan.

  ##### /app/routes/\*\*\\/\*.ts

  ```ts
  import { LoaderArgs, redirect } from "@remix-run/node";
  import { authenticate, MONTHLY_PLAN, ANNUAL_PLAN } from "../shopify.server";

  export const loader = async ({ request }: LoaderArgs) => {
    const { billing } = await authenticate.admin(request);
    const billingCheck = await billing.require({
      plans: [MONTHLY_PLAN, ANNUAL_PLAN],
      isTest: true,
      onFailure: () => redirect('/select-plan'),
    });

    const subscription = billingCheck.appSubscriptions[0];
    console.log(`Shop is on ${subscription.name} (id ${subscription.id})`);

    // App logic
  };
  ```

  ##### shopify.server.ts

  ```ts
  import { shopifyApp, BillingInterval } from "@shopify/shopify-app-remix/server";

  export const MONTHLY_PLAN = 'Monthly subscription';
  export const ANNUAL_PLAN = 'Annual subscription';

  const shopify = shopifyApp({
    // ...etc
    billing: {
      [MONTHLY_PLAN]: {
        amount: 5,
        currencyCode: 'USD',
        interval: BillingInterval.Every30Days,
      },
      [ANNUAL_PLAN]: {
        amount: 50,
        currencyCode: 'USD',
        interval: BillingInterval.Annual,
      },
    }
  });
  export default shopify;
  export const authenticate = shopify.authenticate;
  ```

***

## Related

[Authenticate requests from Shopify Admin. - Admin context](https://shopify.dev/docs/api/shopify-app-remix/v1/authenticate/admin)

***
