接入支付
如果你想收钱,对独立开发者而言的标准路径是 Stripe(或者 Lemon Squeezy / Paddle,如果你想让它们替你处理销售税——作为登记在册的销售方(),它们抽成更高,但让税务的头疼消失)。这些机制是重复且文档完善的,这让它们非常适合外包出去。你需要的几块拼图:
- 一个**结账(checkout)**流程——Stripe Checkout 是最快的;它直接给你一个托管好的支付页面,让你永远不必碰原始卡信息。
- 把 webhook 想象成支付公司在一笔交易刚一清算成功的那一刻就打电话通知你的应用,而不是让你的应用反复地追问"到底成没成?"。一个 webhook 正是如此:它是支付服务商会去调用的一个端点(endpoint,你服务器上的一个 ),让你的应用知道一笔支付究竟何时真正成功了。这是新手会跳过的部分,然后他们纳闷为什么订单从来不会被履约。回到你站点的那个重定向可能被关闭、被拦截或被伪造;webhook 才是服务器对服务器的事实来源。绝不要只信任那个重定向;要信任 webhook。
- 一种**存储权益(entitlements)**的方式——在你的数据库里把用户标记为已付费。这样刷新一下或换一台设备,他们买的东西依然在。
关键的洞察在于你信任哪一根箭头。把用户带回你站点的那个重定向可能丢失或被伪造;真正解锁产品的,是服务器对服务器的那条 webhook 线:
┌──────┐ 1. 点击购买 ┌───────────┐
│ 用户 │────────────────▶│ YOUR APP │
└──────┘ └─────┬─────┘
▲ │ 2. 创建结账会话
│ ▼
│ ┌─────────────┐
│ 3. 在托管页支付 │ STRIPE │
└───────────────────▶│ Checkout │
(卡信息) └──────┬──────┘
│
┌─────────────────────┴─────────────────────┐
│ 4a. 重定向返回 4b. WEBHOOK 调用 │
│ (可能丢失/伪造) (服务器→服务器, │
▼ 签名·可信) ▼
┌──────────────┐ ┌────────────────────┐
│ 感谢页 │ ✗ 请勿在此解锁 │ YOUR APP /webhook │
│ (仅 UI) │ │ 验证签名 → │
└──────────────┘ │ 标记用户为 PAID ✓ │
└────────────────────┘
让 AI 把这三块都搭好,并解释 webhook 的签名验证,因为那是其中唯一对安全敏感的一步——没有它,任何找到你 webhook URL 的人都能伪造一个"支付成功"事件,把你的产品免费解锁。在切换到正式 key 之前,用 Stripe 的测试模式和它们的测试卡号(4242 4242 4242 4242 是最有名的那个)把一切都测一遍,并用 Stripe 把 webhook 事件转发到你的本地机器,亲眼看着它们触发。不要跳过测试模式这场带妆彩排。第一笔流经你应用的真钱,应该是一笔你已经看过它成功运作十几次的交易。