指南

如何为应用添加支付:结账、订阅与 Webhook

在应用中添加支付最简单的方式是 Stripe:如果你只需要一个“购买”按钮,并且可以手动处理订单,就使用付款链接;如果你的应用需要知道是谁付了款并自动作出反应,就使用 Stripe Checkout;如果是定期计费,则使用订阅模式的 Checkout,再加上 Stripe 的客户门户。除了最简单的情况外,你还需要一个 Webhook——即 Stripe 在付款成功时调用的服务端端点。在切换到正式密钥之前,你应使用 Stripe 的测试密钥和测试卡号测试所有功能。

本指南会介绍每种方案、大多数教程都会略过的 Webhook 部分,以及在收取真实款项前需要检查的事项。Stripe 的细节来自其截至 2026 年 9 月的官方文档。

为什么要使用支付服务商

绝不要在你自己的表单中收集卡号。直接处理原始卡数据会使你承担 PCI DSS(信用卡行业安全标准)的合规范围,并带来严重的法律责任。像 Stripe 这样的支付服务商会托管付款表单、保存卡信息、处理银行验证,并告诉你的应用支付结果。你的应用只会看到“客户 X 为 Y 付了款”这样的信息。

本指南使用 Stripe,是因为它应用广泛、文档完善,并且大多数 AI 应用构建工具都支持。其他服务商也存在,其中一些作为“销售记录方”(merchant of record)会为你处理销售税;如果税务合规让你担心,可以对比一下这类模式。

使用 Stripe 收款的三种方式

方案需要编写的代码应用是否知道谁付了款最适合
付款链接无只有添加了 Webhook 才知道销售少量固定产品、捐款、测试需求
Checkout(一次性)服务端代码,用于创建会话是,通过 Webhook商店、付费下载、一次性购买
Checkout(订阅)服务端代码加 Webhook 处理是,通过 WebhookSaaS、会员、任何定期收费的业务

付款链接

付款链接是你在 Stripe 控制台中创建的、由 Stripe 托管的付款页面,无需编写代码。你会得到一个 URL,可以放在应用的按钮后面、通过邮件分享,或者显示为二维码。Stripe 的文档称,付款链接可以销售产品、订阅,也可以接受捐款;你还可以让客户自行选择付款金额,或限制购买次数。

需要注意的是:你的应用不会自动知道某个已登录的用户是否付了款。对于捐款页面,或者你根据 Stripe 的邮件通知手动处理订单的小店铺来说,这样没有问题。但如果是“付费解锁专业版功能”,就不适用了。

Stripe Checkout

Checkout 是你的服务端针对某次特定购买按需创建的付款页面。你的服务端告诉 Stripe 正在购买什么(以及可选的购买客户是谁),Stripe 返回一个 URL,然后你把客户引导到该 URL。Stripe 的文档称,它同时支持一次性付款和订阅付款,形式可以是完全由 Stripe 托管的页面、嵌入你网站的页面,或嵌入式表单。

流程如下:

  1. 客户在你的应用中点击购买。
  2. 你的服务端使用密钥创建一个 Checkout 会话,并包含一个将其与你的用户或订单关联起来的 ID。
  3. 客户被重定向到 Stripe 并完成付款。
  4. Stripe 将他们重定向回你的成功页面。
  5. Stripe 向你的 Webhook 发送 checkout.session.completed 事件,你的服务端随即将订单标记为已付款或解锁访问权限。

第 2 步必须在服务端完成,因为它需要使用你的密钥。这也是 Checkout 需要后端的主要原因。

订阅

订阅使用订阅模式的 Checkout,并配合你在 Stripe 中设置的定期价格。第一次付款的流程与上述相同。之后,续费、银行卡失败、升级和取消都会随时间发生——通常客户根本不在你的应用中——因此你的应用只能通过 Webhook 得知这些变化。

如果要让客户自行管理订阅,Stripe 提供了托管的客户门户。根据 Stripe 的文档,客户可以在那里更新支付方式和账单信息,更改或取消订阅,并查看和下载发票。你在 Stripe 控制台中进行配置,并添加一个“管理账单”按钮,将客户引导至该门户。这样你就不必自己开发这些页面。

Webhook:不能跳过的部分

Webhook 是 Stripe 在某件事发生时发送给你服务端的 HTTP 请求。(通用概念请参见什么是 Webhook。)Stripe 的履约指南明确指出:不能只依赖成功页面来履行订单,因为客户可能在付款后、该页面加载前就断开了连接。对于订阅和延迟支付方式,Webhook 是必需的。

值得处理的事件

事件含义你的应用应做什么
checkout.session.completedCheckout 已完成将订单标记为已付款,或开通访问权限
checkout.session.async_payment_succeeded延迟支付方式(例如银行扣款)稍后成功立即履约
checkout.session.async_payment_failed该延迟支付失败告知客户;不要履约
invoice.paid订阅付款成功,包括续费延长访问期限
invoice.payment_failed续费失败提醒用户;Stripe 可能会重试
customer.subscription.updated套餐已更改,或已安排取消更新用户的套餐
customer.subscription.deleted订阅已结束移除付费访问权限

正确的 Webhook 处理程序规则

这些规则直接来自 Stripe 的 Webhook 文档,AI 生成的处理程序有时会漏掉其中某一条:

  • **验证签名。**每个事件都包含一个 Stripe-Signature 请求头。你的处理程序需要使用端点的签名密钥(以 whsec_ 开头)进行验证。如果不这样做,任何人都可以向你的服务端发送伪造的“付款成功”请求。
  • **使用原始请求体。**如果你的框架在验证前先解析或修改了请求体,签名校验就会失败。
  • 快速返回 2xx 响应,然后再执行较慢的工作。超时会被视为失败。
  • **处理重复事件。**Stripe 可能会多次投递同一个事件。应记录已处理的事件 ID,或者让履约操作可以安全地重复执行。
  • **不要假设事件顺序。**Stripe 不保证事件按发生的顺序到达。
  • **预计会有重试。**在正式模式下,Stripe 会在最多三天内重试失败的投递,因此短暂的故障不会丢失付款——但你的处理程序必须能够应对迟到的事件。

Webhook 需要一个公开的 HTTPS 地址,因此通常只有在应用发布之后才能正常工作(开发人员可以使用 Stripe CLI 将事件转发到本地机器)。

覆盖完整流程的提示词

使用 Stripe Checkout 为“Pro 礼包”添加一次性购买(价格 ID 保存在 STRIPE_PRICE_ID 中)。在服务端使用机密中的 STRIPE_SECRET_KEY 创建 Checkout 会话,并在会话中包含已登录用户的 ID。添加一个 POST /api/stripe/webhook 端点,使用原始请求体并通过 STRIPE_WEBHOOK_SECRET 验证 Stripe 签名,处理 checkout.session.completed,并将该用户标记为已拥有 Pro 礼包。确保同一事件重复到达时也是安全的。添加成功页面和取消页面。切勿将密钥暴露给浏览器。

如果需要订阅,再添加:“对 STRIPE_PRICE_ID 使用订阅模式。处理 invoice.paid、invoice.payment_failed、customer.subscription.updated 和 customer.subscription.deleted。添加一个“管理账单”按钮,打开 Stripe 客户门户。”

测试模式

Stripe 有独立的沙盒(测试)环境和正式环境,密钥也互相独立。沙盒密钥以 pk_test_、sk_test_ 或 rk_test_ 开头;正式密钥以 pk_live_、sk_live_ 或 rk_live_ 开头。测试交易不会转移资金。

来自 Stripe 测试文档的常用测试卡(有效期任意填写未来日期,CVC 填写任意三位数字):

卡号结果
4242 4242 4242 4242付款成功
4000 0000 0000 0002卡被拒绝
4000 0000 0000 3220需要 3D Secure 验证,然后成功

至少要测试以下内容:

  • 成功付款会为正确的用户解锁正确的内容
  • 银行卡被拒时会显示清晰的提示,并且不解锁任何内容
  • 付款后立即关闭浏览器标签页,访问权限仍然会生效(这证明是 Webhook 在起作用,而不仅仅是成功页面)
  • 在 Stripe 页面上取消,会将用户返回你的应用,且没有任何扣款
  • 对于订阅:在客户门户中取消,并确认访问权限在应当结束时结束

正式上线

  1. 激活你的 Stripe 账户,填写你的企业和银行信息。
  2. **在应用的机密中替换为正式密钥。**Stripe 建议使用受限密钥,只授予你的集成所需的权限,而不是使用不受限制的密钥。
  3. 创建正式环境的 Webhook 端点,指向你已发布的应用。它有自己的签名密钥,与测试环境的不同——记得更新。
  4. 在正式模式下重新创建产品和价格;测试模式下的 ID 在正式模式中不存在。
  5. 完成一笔真实的小额购买,并将其退款。

所有密钥都应保存在项目的机密中,绝不要放在代码或聊天中。我们的安全检查清单更详细地介绍了密钥和 Webhook 验证。

税务、退款与手续

收款会带来代码无法解决的义务。以下内容不构成税务建议,请咨询会计师。

  • **销售税、增值税和商品及服务税。**根据你和客户所在的地区,你可能需要注册、收取并申报税款。Stripe Tax 可以在结账时计算并收取税款,监控你的销售可能产生纳税义务的地区,并协助注册和申报——但责任仍在你自己。销售记录方类服务商是一种替代方案,它会承担更多此类工作。
  • **退款和争议。**上线前确定你的退款政策,并将其放在网站上。争议(拒付)时有发生;请保留购买和交付内容的记录。
  • **收据和发票。**Stripe 可以通过邮件发送收据;企业可能需要正式的发票。
  • **手续费。**每家服务商都按交易收费。请查看服务商当前的定价页面,而不要依赖文章中的数字。

哪种方案适合你的应用

  • **捐款或少量产品:**付款链接。参见如何搭建非营利机构捐赠网站。
  • **带购物车的商店:**使用包含商品明细的 Checkout 和 Webhook。参见如何搭建在线商店。
  • **SaaS 或会员:**订阅模式的 Checkout、Webhook 和客户门户。参见如何搭建 SaaS MVP和如何为 SaaS 产品定价。
  • **向卖家付款的市场平台:**这是一种不同的、监管更严格的方案(Stripe Connect 或类似方案)。请单独规划。

在 Mythex 中添加支付

你在 Mythex 上构建的应用中的支付功能使用的是你自己的 Stripe 账户和密钥;应用中没有一键“连接 Stripe”的功能。通常的流程如下:

  1. 获取 Stripe 测试密钥。
  2. 将 STRIPE_SECRET_KEY(稍后再添加 Webhook 密钥)添加到项目机密中——可通过 /secrets、项目设置,或代理需要密钥时显示的机密卡片完成。
  3. 使用类似上面的提示词,请代理实现 Checkout。
  4. 在预览中使用测试卡进行测试。在注册 Webhook 之前先发布,因为它需要你的公开 URL。
  5. 切换到正式密钥后,再次发布,以便正式应用获取这些密钥。

请参见文档中的使用 Stripe 接受付款和在后端处理 Webhook。

常见问题

在应用中收款最简单的方法是什么?

Stripe 付款链接无需编写代码:你在 Stripe 控制台中创建它,然后从应用中链接过去即可。如果你的应用需要知道是谁付了款,并自动解锁某些功能,则应使用 Stripe Checkout 加上 Webhook。

收款一定需要 Webhook 吗?

如果你的应用需要对付款做出反应,例如解锁账户、将订单标记为已付款、处理续费,那么需要。Stripe 的文档指出,不能只依赖成功页面,因为客户可能已经付款却从未到达该页面。订阅同样必须使用 Webhook。

怎样在不花真钱的情况下测试支付?

使用 Stripe 的沙盒(测试)API 密钥和测试卡号,例如 4242 4242 4242 4242,有效期任意填写未来日期,CVC 填写任意三位数字。测试交易不会转移真实资金。

Stripe 会替我处理销售税和增值税吗?

Stripe Tax 可以在结账时计算并收取税款,并监控你在哪些地区可能需要办理注册,但你仍然要对自己的纳税义务负责。请根据你的具体情况咨询会计师。

Mythex · Pricing · 用 AI 构建任何东西 · 网站和应用模板 · Mythex 对比 · AI 应用构建术语表 · 免费的 AI 应用构建工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 繁體中文(香港) 繁體中文(台灣)