跳到正文

指南

配方:SaaS 订阅

用加密货币支付的月度或年度套餐。每个周期一张账单并附提醒;应用向 Perly Pay 询问谁有访问权限。

加密货币无法从钱包里直接扣款,所以订阅靠账单续订:周期结束前买家收到下一张账单,之后会有提醒,直到付清为止。没有自动扣款。应用自己不算天数 — 它询问 entitlements.check。

配合助手:Perly Pay 插件的 sell-subscription 技能会在你的项目中实现这个配方。可运行的示例是插件仓库中的 examples/saas-subscription(MIT)。

如何运作

  1. 1

    套餐

    一个商品和一个价格,带 model: "subscription" 和 recurring.interval(month、year…),可选试用天数和宽限天数。

  2. 2

    订阅

    以该价格、以用户为客户开出的账单会开启订阅及其第一张账单。付清后套餐生效。

  3. 3

    功能访问

    在服务器上调用 entitlements.check({ customer_external_id, product }) → has_access 和 ends_at,每次访问调用或配合短时缓存。

  4. 4

    监听

    invoice.fulfilled — 首次付款和每次续订;subscription.past_due、subscription.unpaid 和 subscription.ended — 用于提醒和关闭。

  5. 5

    买家自助管理

    客户门户链接(portalSessions.create):支付待付的续订、预付或取消。

Subscribe, then gate
const invoice = await pay.invoices.create(
  { line_items: [{ price: PRO_MONTHLY }], customer: customer.id, metadata: { user: userId }, return_url },
  { idempotencyKey: `subscribe-${userId}-${today}` },
);
redirect(invoice.url); // invoice.subscription is the new subscription

const { has_access } = await pay.entitlements.check({ customer_external_id: userId, product: PRO });

宽限天数、更换套餐和状态见 Subscriptions and reminders。

运行示例

  1. 1

    安装

    在 examples/saas-subscription 中运行 npm install(Node 20.12+)。

  2. 2

    密钥

    把 .env.example 复制为 .env,在 PERLY_PAY_SECRET_KEY 中填入测试密钥(sk_test_…)。

  3. 3

    准备

    npm run setup 用你的密钥创建商品和价格,并打印它们的 ID 供 .env 使用。

  4. 4

    启动

    按其 README 运行 npm start(或 npm run dev)。

  5. 5

    无需钱包即可付款

    在首页订阅,在账单上点 Simulate payment,然后打开 /pro?user=you@example.com:Pro 已开通至周期结束。

陷阱

  • 承诺“我们会自动从你的钱包扣款”。什么都不会被扣;要说“按账单续订”。
  • 客户邮箱缺失或是编的:续订账单和提醒都发到那里。
  • 一逾期就立刻关闭访问。先决定 past_due 意味着什么(在宽限天数内)。
  • 买家从付款页返回时就开通访问。“已付款”只意味着经过校验的 invoice.fulfilled Webhook,或你的服务器调用的 entitlements.check。