shopify-billing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Shopify Billing Skill

Shopify 计费技能

The Billing API allows you to charge merchants for your app using recurring subscriptions or one-time purchases.
[!IMPORTANT] GraphQL Only: The REST Billing API is deprecated. Always use the GraphQL Admin API for billing operations.
Billing API 允许您通过定期订阅或一次性购买向商家收取应用费用。
[!IMPORTANT] 仅支持GraphQL:REST Billing API 已被弃用。计费操作请始终使用 GraphQL Admin API。

1. Recurring Subscriptions (
appSubscriptionCreate
)

1. 定期订阅 (
appSubscriptionCreate
)

Use this mutation to create a recurring charge (e.g., monthly plan).
使用该mutation创建定期收费(如月度套餐)。

Example (Remix / Shopify App Template)

示例(Remix / Shopify App Template)

javascript
/* app/routes/app.upgrade.tsx */
import { authenticate } from "../shopify.server";

export const action = async ({ request }) => {
  const { admin } = await authenticate.admin(request);
  const shop = await admin.graphql(`
    mutation AppSubscriptionCreate($name: String!, $lineItems: [AppSubscriptionLineItemInput!]!, $returnUrl: URL!) {
      appSubscriptionCreate(name: $name, returnUrl: $returnUrl, lineItems: $lineItems) {
        userErrors {
          field
          message
        }
        appSubscription {
          id
        }
        confirmationUrl
      }
    }
  `,
  {
    variables: {
      name: "Pro Plan",
      returnUrl: "https://myapp.com/app",
      lineItems: [{
        plan: {
          appRecurringPricingDetails: {
            price: { amount: 10.00, currencyCode: "USD" },
            interval: "EVERY_30_DAYS"
          }
        }
      }]
    }
  });

  const response = await shop.json();
  const confirmationUrl = response.data.appSubscriptionCreate.confirmationUrl;
  
  // Redirect merchant to approve charge
  return redirect(confirmationUrl);
};
javascript
/* app/routes/app.upgrade.tsx */
import { authenticate } from "../shopify.server";

export const action = async ({ request }) => {
  const { admin } = await authenticate.admin(request);
  const shop = await admin.graphql(`
    mutation AppSubscriptionCreate($name: String!, $lineItems: [AppSubscriptionLineItemInput!]!, $returnUrl: URL!) {
      appSubscriptionCreate(name: $name, returnUrl: $returnUrl, lineItems: $lineItems) {
        userErrors {
          field
          message
        }
        appSubscription {
          id
        }
        confirmationUrl
      }
    }
  `,
  {
    variables: {
      name: "Pro Plan",
      returnUrl: "https://myapp.com/app",
      lineItems: [{
        plan: {
          appRecurringPricingDetails: {
            price: { amount: 10.00, currencyCode: "USD" },
            interval: "EVERY_30_DAYS"
          }
        }
      }]
    }
  });

  const response = await shop.json();
  const confirmationUrl = response.data.appSubscriptionCreate.confirmationUrl;
  
  // Redirect merchant to approve charge
  return redirect(confirmationUrl);
};

2. One-Time Purchases (
appPurchaseOneTimeCreate
)

2. 一次性购买 (
appPurchaseOneTimeCreate
)

Use this mutation for non-recurring charges (e.g., specific service, lifetime access).
javascript
const response = await admin.graphql(`
  mutation AppPurchaseOneTimeCreate($name: String!, $price: MoneyInput!, $returnUrl: URL!) {
    appPurchaseOneTimeCreate(name: $name, returnUrl: $returnUrl, price: $price) {
      userErrors { field message }
      confirmationUrl
    }
  }
`, {
  variables: {
    name: "Concierge Setup",
    returnUrl: "https://myapp.com/app",
    price: { amount: 50.00, currencyCode: "USD" }
  }
});
使用该mutation收取非定期费用(如特定服务、终身权限)。
javascript
const response = await admin.graphql(`
  mutation AppPurchaseOneTimeCreate($name: String!, $price: MoneyInput!, $returnUrl: URL!) {
    appPurchaseOneTimeCreate(name: $name, returnUrl: $returnUrl, price: $price) {
      userErrors { field message }
      confirmationUrl
    }
  }
`, {
  variables: {
    name: "Concierge Setup",
    returnUrl: "https://myapp.com/app",
    price: { amount: 50.00, currencyCode: "USD" }
  }
});

3. Checking Active Subscriptions

3. 查询活跃订阅

To gate features, check the
currentAppInstallation
for active subscriptions.
javascript
/* app/shopify.server.ts (billing config) */
export const billing = {
  "Pro Plan": {
    amount: 10.00,
    currencyCode: "USD",
    interval: "EVERY_30_DAYS",
  },
};

/* Checking in loader */
const { billing } = await authenticate.admin(request);
const billingCheck = await billing.require({
  plans: ["Pro Plan"],
  isTest: true, // Use true for development stores
  onFailure: async () => billing.request({ plan: "Pro Plan", isTest: true }),
});
const subscription = billingCheck.appSubscriptions[0];
如需限制功能访问,可通过
currentAppInstallation
查询活跃订阅。
javascript
/* app/shopify.server.ts (billing config) */
export const billing = {
  "Pro Plan": {
    amount: 10.00,
    currencyCode: "USD",
    interval: "EVERY_30_DAYS",
  },
};

/* Checking in loader */
const { billing } = await authenticate.admin(request);
const billingCheck = await billing.require({
  plans: ["Pro Plan"],
  isTest: true, // Use true for development stores
  onFailure: async () => billing.request({ plan: "Pro Plan", isTest: true }),
});
const subscription = billingCheck.appSubscriptions[0];

Manual Query (if not using billing helper)

手动查询(若不使用计费助手)

graphql
query {
  currentAppInstallation {
    activeSubscriptions {
      id
      name
      status
      lineItems {
        plan {
          pricingDetails {
            ... on AppRecurringPricing {
              price { amount currencyCode }
            }
          }
        }
      }
    }
  }
}
graphql
query {
  currentAppInstallation {
    activeSubscriptions {
      id
      name
      status
      lineItems {
        plan {
          pricingDetails {
            ... on AppRecurringPricing {
              price { amount currencyCode }
            }
          }
        }
      }
    }
  }
}

4. Best Practices

4. 最佳实践

  • Test Mode: Always set
    test: true
    (or
    isTest
    ) when developing. Test charges do not bill the merchant.
  • Confirmation URL: You MUST redirect the user to the
    confirmationUrl
    returned by the mutation. The charge is not active until they approve it.
  • Webhooks: Listen for
    app_subscriptions/update
    to handle cancellations or status changes in real-time.
  • 测试模式:开发时请始终设置
    test: true
    (或
    isTest
    )。测试收费不会向商家实际扣费。
  • 确认URL:您必须将用户重定向到mutation返回的
    confirmationUrl
    。只有在商家确认后,收费才会生效。
  • Webhooks:监听
    app_subscriptions/update
    Webhook,实时处理订阅取消或状态变更。