Creem 配置

配置 Creem 产品、Edge secrets 与 webhook。

Creem 运行在桌面应用之外。Tauri 模板只在 webview 中携带公开产品 ID;Supabase Edge Functions 则在服务端保存 API 密钥、验证 webhook,并写入权益记录。

请先完成 Supabase 配置,包括计费迁移;随后再按 计费 启用应用侧开关。

创建产品

在 Creem dashboard 中创建准备销售的产品:

模板方案Creem 产品类型应用环境变量
Pro 月付SubscriptionVITE_CREEM_PRODUCT_PRO_MONTHLY=prod_...
Pro 年付SubscriptionVITE_CREEM_PRODUCT_PRO_YEARLY=prod_...
LifetimeOne-timeVITE_CREEM_PRODUCT_LIFETIME=prod_...

将产品 ID 写入桌面应用的 .env。它们是会被渲染器携带的公开标识符;绝不能将 CREEM_API_KEY 写入其中。

CREEM_SERVER_IDX 选择 Edge Functions 使用的 Creem API 环境:

API 地址
0Production:https://api.creem.io
1Test:https://test-api.creem.io

在验证结账和 webhook 时使用 test 环境。产品 ID、API key 和 webhook 配置必须 来自同一个 Creem 环境。

设置 Edge secrets

将密钥设置在 Supabase 项目中,而不是应用的 .env

supabase secrets set \
  CREEM_API_KEY=creem_test_xxx \
  CREEM_WEBHOOK_SECRET=whsec_xxx \
  CREEM_SERVER_IDX=1 \
  --project-ref <ref>

也可以复制 supabase/functions/.env.example 到已 gitignore 的 supabase/functions/.env,填入值后上传:

supabase secrets set --env-file supabase/functions/.env --project-ref <ref>
Secret使用方说明
CREEM_API_KEYcreate-checkoutcustomer-portalactivate-license服务端 Creem API key。
CREEM_WEBHOOK_SECRETcreem-webhook必须与 Creem 中配置的签名 secret 一致。
CREEM_SERVER_IDX所有 Creem Functions0 为 production;1 为 test。
BILLING_SUCCESS_URLcreate-checkout可选的托管结账返回页。

Supabase 会向 Edge Functions 注入 SUPABASE_URLSUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEY。不要自行将它们加入应用配置或 secret 文件。

部署 Functions

部署前先应用计费迁移:

supabase db push --project-ref <ref>

然后部署全部 Functions:

pnpm supabase:deploy
pnpm supabase:deploy <project-ref>

辅助脚本会部署 supabase/functions/ 中所有非下划线目录。_shared/ 会被打包进 使用它的 Function,不能单独部署。creem-webhook 是唯一公开 Function;脚本对它 使用 --no-verify-jwt,另外三个则依靠 supabase/config.toml 保持 JWT 验证。

FunctionJWT职责
create-checkout开启为已登录用户创建结账并记录待付款。
customer-portal开启为已登录用户已存储的 Creem customer ID 返回 portal URL。
activate-license开启可选的许可证密钥激活和停用。
creem-webhook关闭接收 Creem 投递,验证签名后写入读取模型。

验证部署:

supabase functions list --project-ref <ref>

配置 webhook

在 Creem 中登记下列已部署端点,并将它的签名 secret 设置为 CREEM_WEBHOOK_SECRET 的相同值:

https://<ref>.supabase.co/functions/v1/creem-webhook

当前 handler 有意只处理很小的事件集合:

事件行为
checkout.completed将匹配 object.request_id / order_no 的付款标为 success,然后记录 Creem 订单和客户 ID。
subscription.paidobject.metadata.userId、产品、客户和订阅周期数据 upsert 用户订阅。

其他事件目前会被忽略。若产品需要在应用中反映取消、退款、暂停或逾期状态,请扩展 supabase/functions/_shared/creem.ts,同时保持面向客户端的 subscriptions 读取模型边界。

webhook 会在解析 JSON 之前读取原始 body,使用 CREEM_WEBHOOK_SECRET 重新计算 HMAC-SHA256,并与 creem-signature header 比较。payments.order_no 的唯一更新和 subscriptions.user_id 的 upsert 使重复投递收敛;handler 失败时返回 500,让 Creem 可以重试。

可选结账返回页

桌面结账在系统浏览器中运行,因此托管跳转页是很有用的返回路径。模板提供了 supabase/pay-success.sample.html;它已经使用默认的 soar-tauri://billing 协议并转发订单 ID。

可将文件部署到任意静态托管服务。若已重新品牌化,请把 soar-tauri 改为自己的协议, 再把托管 URL 设置为 Edge secret:

supabase secrets set \
  BILLING_SUCCESS_URL=https://your-domain.com/pay-success \
  --project-ref <ref>

create-checkout 会添加 status=success&orderId=<orderNo>。若未设置此 secret, Creem 会改用产品上配置的 redirect。无论哪种方式,应用都会在 Billing 路由和窗口 获得焦点时刷新服务端权益。

测试路径

使用本地 Edge env 文件启动 Functions:

supabase functions serve --env-file supabase/functions/.env

它们会监听:

http://localhost:54321/functions/v1/<name>

如需本地 Postgres 和 Auth,也运行 supabase start。对完整的 sandbox 结账而言, 部署到测试项目通常更简单,因为 Creem 必须能访问 webhook URL。

sandbox 付款后,查询写入侧证据:

select order_no, user_id, product_id, status, customer_id, updated_at
from public.payments
order by created_at desc
limit 10;

select user_id, product_id, product_type, status, period_end, customer_id, subscription_id
from public.subscriptions
order by updated_at desc
limit 10;

生产检查清单

  • 已为桌面构建设置 VITE_BILLING_ENABLED=true
  • VITE_CREEM_PRODUCT_* 与选定的 Creem 环境匹配。
  • 已应用计费迁移。
  • Creem secrets 只保存在 Supabase Edge secrets 中。
  • pnpm supabase:deploy 已部署四个 Functions。
  • Creem 指向 https://<ref>.supabase.co/functions/v1/creem-webhook
  • 若使用托管返回页,它使用当前 deep-link 协议。
  • sandbox 付款写入预期的 paymentssubscriptions 行。
  • 若业务需要,已实现额外 webhook 事件。

相关页面

On this page