支付
Webhooks
Creem Webhook 处理机制。
端点
POST /api/payments/creem/webhook安全机制
签名验证
每个 webhook 使用 HMAC-SHA256 验证:
const isValid = verifyCreemWebhookSignature(body, signature, CREEM_TEST_WEBHOOK_SECRET);签名在 creem-signature 请求头中。使用时序安全比较防止时序攻击。
幂等性
发放积分的 webhook 会在同一事务中检查 providerPaymentId 和积分账本。如果已成功的支付再次投递,webhook 会被确认,但不会再次发放积分。退款和争议事件只更新已有支付状态,不创建负积分账本,也不会擅自追回已消费的积分。
支持的事件
| 事件 | 操作 |
|---|---|
checkout.completed | 创建支付记录、发放积分、发送邮件 |
subscription.active | 标记订阅有效并恢复方案权益 |
subscription.trialing | 保存试用中的订阅状态和方案权益 |
subscription.paid | 发放月度积分、更新订阅 |
subscription.update | 保存 Creem 订阅状态和周期结束时间 |
subscription.scheduled_cancel | 停止未来周期发放,但在取消前保留权益 |
subscription.canceled | 标记取消、停止计划发放并清理方案权益 |
subscription.unpaid | 标记未付款、停止计划发放并清理方案权益 |
subscription.past_due | 标记逾期、停止计划发放并清理方案权益 |
subscription.expired | 标记过期、停止计划发放并清理方案权益 |
subscription.paused | 标记暂停、停止计划发放并清理方案权益 |
refund.created | 更新对应支付状态,不改变积分 |
dispute.created | 将对应支付标记为争议,不改变积分 |
当前 Dashboard 可选的事件字符串就是上表中的精确值。本 Creem webhook 列表没有独立的 payment.failed 事件;订阅支付失败通过 subscription.unpaid 或 subscription.past_due 表示。
设置
在 Creem Dashboard 中设置 webhook URL:
https://your-domain.com/api/payments/creem/webhook在 Preview 环境配置 Test Mode 的支付提供商、环境和 webhook 密钥:
PAYMENT_PROVIDER="creem"
CREEM_ENVIRONMENT="test"
CREEM_TEST_WEBHOOK_SECRET="whsec_your_test_secret"Preview 部署必须使用独立 Neon 分支或其他非 Production 的 DATABASE_URL,并设置 BILLING_DATA_ENVIRONMENT="preview"。数据环境为 Production 时,Test webhook 会被拒绝。
调试
如果 webhook 没有触发:
- 检查 Creem Dashboard 的 webhook 投递日志
- 验证
CREEM_TEST_WEBHOOK_SECRET与 Creem Test 设置匹配 - 确保端点可公开访问(不在认证保护下)
- 检查服务器日志中的签名验证错误