跳到主要内容

2 篇博文 含有标签「D1」

查看所有标签

Stripe Webhook 不是一次回调:Tuziyo 如何处理幂等与订阅状态同步

· 阅读需 12 分钟
Gwynn
独立开发者 · wawov 作者

最近在给 Tuziyo 接入 Stripe 订阅支付。

最开始的目标看起来很简单:用户选择套餐,跳转到 Stripe Checkout,支付成功后升级会员并发放 Credits。但真正开始处理续费、支付失败、取消订阅和年度套餐后,我发现支付成功页面只是整个流程中最轻的一部分。

真正决定这套系统能不能稳定运行的,是 Webhook。

Stripe 的事件可能延迟、乱序,也可能因为超时被重复投递。如果把每一次 Webhook 都当成只会执行一次的普通回调,最直接的后果就是重复发放 Credits,或者 Stripe 和本地数据库中的订阅状态不一致。

这篇文章记录 Tuziyo 当前订阅了哪些 Stripe 事件、每个事件做了什么,以及我如何用 Cloudflare Workers 和 D1 处理 Webhook 幂等与订阅状态同步。

Cloudflare Workers + D1 的生产实践:Tuziyo 的无服务器后端

· 阅读需 16 分钟
Gwynn
独立开发者 · wawov 作者

最近半年在开发 Tuziyo 时,我把整个产品的基础设施都放在了 Cloudflare 上。

前端通过 Cloudflare Pages 发布,API 运行在 Cloudflare Workers,业务数据保存在 D1,生成结果进入 R2,再由 Cloudflare Images 按不同页面需要生成缩略图和展示图。

一开始选择这套架构,主要是因为它对独立开发者足够轻:不需要购买服务器,不需要配置 Nginx,也不需要为了一个还在验证阶段的产品提前维护 Kubernetes、数据库主从和复杂的网络环境。

但真正把它用于生产之后,我发现 Serverless 只是省掉了服务器,并没有省掉后端工程。数据一致性、环境隔离、异步任务、数据库迁移、权限校验、幂等和故障恢复,一个都不会自动消失。

这篇文章记录 Tuziyo 使用 Cloudflare Workers + D1 构建生产后端时,最终保留下来的架构和实践。