在 Webhook 端点中接收 Stripe 事件
通过 Webhook 端点,监听 Stripe 账户中的事件,以便您的集成自动触发响应。
向您的 AWS 账户发送事件。
您现在可以将事件作为事件接收端直接发送到 Amazon EventBridge。
创建一个事件接收端,以接收 HTTPS Webhook 端点上的事件。在您注册 Webhook 端点后,当您的 Stripe 账户有事件发生时,Stripe 可以将实时事件数据推送到您的应用程序的 Webhook 端点。Stripe 用 HTTPS 将 Webhook 事件以包含事件对象的 JSON 有效载荷发送到您的应用程序。
接收 Webhook 事件可帮助您响应异步事件,如客户银行确认付款、客户对收款提出异议或经常性付款成功。
开始
要开始在您的应用程序中接收 Webhook 事件:
- 创建一个 Webhook 端点处理程序来接收事件数据的 POST 请求。
- 使用 Stripe CLI 在本地测试您的 Webhook 端点处理程序。
- 为 Webhook 端点创建新的事件接收端。
- 保护您的 Webhook 端点。
您可以注册并创建一个端点,用它同时处理几个不同的事件类型,也可以为特定事件设置单独的端点。
组织事件接收端不支持的事件类型行为
Stripe 会异步发送大多数事件类型,但对于某些事件类型,会等待响应。在这些情况下,Stripe 会根据事件接收端是否响应而采取不同的处理方式。
如果您的事件接收端接收组织事件,需要响应的事件有以下限制:
- 您无法订阅组织接收端的
issuing_
。相反,请在组织内的 Stripe 账户中设置一个 Webhook 端点来订阅此事件类型。使用authorization. request issuing_
实时授权购买请求。authorization. request - 当您在网站中直接嵌入 Checkout 或将客户重定向到 Stripe 托管的支付页面时,接收
checkout_
的组织目标无法处理重定向行为。要控制 Checkout 重定向行为,请使用组织内某个 Stripe 账户中配置的 Webhook 端点处理此事件类型。sessions. completed - 如果组织目标对
invoice.
事件响应失败,在使用自动收款的情况下,无法影响账单自动定稿。您须使用组织内某个 Stripe 账户中配置的 Webhook 端点处理此事件类型,才能触发账单自动定稿。created
创建处理程序
设置一个 HTTP 或 HTTPS 端点函数,该函数可以用 POST 方法接受 Webhook 请求。如果您仍在您的本地机器上开发您的端点,则它可以使用 HTTP。可公开访问后,您的 Webhook 端点函数必须使用 HTTPS。
设置您的端点函数,以便它:
- 使用由事件对象组成的 JSON 有效载荷处理 POST 请求。
- 对于组织事件处理程序,Stripe 会检查
上下文
值,确定组织中哪个账户生成了此事件,随后设置与上下文
值相对应的Stripe-Context
标头。 - 在执行任何可能导致超时的复杂逻辑之前,快速返回一个成功状态码 (
2xx
)。例如,您必须返回一个200
响应,然后才能在您的会计系统中将客户的账单更新为已支付。
注意
借助我们的交互式 Webhook 端点构建器,使用您的编程语言构建一个 Webhook 端点函数。
示例端点
此代码片段是一个 Webhook 函数,配置它的目的是检查从 Stripe 账户接收的事件、处理事件并返回 200
响应。使用 API v1 资源时引用快照事件处理程序,使用 API v2 资源时引用精简事件处理程序。
组织处理程序示例
测试您的处理程序
在您使用 Webhook 端点函数之前,我们建议您测试您的应用程序集成情况。方法是配置本地侦听器,以此将事件发送到您的本地机器,并发送测试事件。测试时,您需要使用 CLI。
将事件转发到本地端点
要将事件转发到本地端点,请使用 CLI 运行以下命令来设置本地侦听器。在沙盒环境中,--forward-to
标志会将所有的 Stripe 事件发送到您本地的 Webhook 端点。请使用下面的相应 CLI 命令,具体取决于您使用的是精简还是快照事件。
注意
您也可以运行 stripe listen
来查看 Stripe Shell 中的事件,但无法将事件从 shell 转发到本地端点。
有些配置有助于用本地侦听器进行测试,这些配置包括:
- 禁用 HTTPS 证书验证,使用
--skip-verify
可选标志。 - 仅转发特定事件时,使用
--events
可选标志,并传入事件列表,用逗号分隔事件。
- 要将事件从已经在 Stripe 上注册的公共 Webhook 端点转发到本地 Webhook 端点,请使用
--load-from-webhooks-api
可选标志。它会加载您注册的端点,解析路径及其注册的事件,然后将路径附加到您本地的 Webhook 端点的--forward-to path
路径中。
- 要检查 Webhook 签名,请使用侦听命令初始输出中的
{{WEBHOOK_
。SIGNING_ SECRET}}
Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
触发测试事件
要发送测试事件,请通过 Stripe 管理平台手动创建对象来触发事件接收端订阅的事件类型。了解如何用 Stripe for VS Code 触发事件。
注册您的端点
测试 Webhook 端点函数后,使用 Workbench 中的 API 或 Webhook 选项卡注册 Webhook 端点的可访问 URL,以便 Stripe 知道将事件传递到何处。您最多可以在 Stripe 上注册 16 个 Webhook 端点。注册的 Webhook 端点必须是可公开访问的 HTTPS URL。
Webhook URL 格式
注册 Webhook 端点时使用的 URL 格式:
https://<your-website>/<your-webhook-endpoint>
例如,如果您的域名是 https://mycompanysite.
,您的 Webhook 端点的路径为 @app.
,那便指定 https://mycompanysite.
作为端点 URL。
为 Webhook 端点创建事件接收端
在管理平台中用 Workbench 创建事件接收端,或通过API 程序化地创建。最多可以在每个 Stripe 账户上注册 16 个事件接收端。
注意
Workbench 将替换掉当前的开发人员管理平台。如果您仍在使用开发人员管理平台,请查看如何创建新的 Webhook 端点。
保护您的端点
您需要确保,处理程序验证了所有 Webhook 请求都是由 Stripe 生成的,以此来保护您的集成。您可以使用我们的官方库来验证 Webhook 签名或手动验证。
调试 Webhook 集成
向 Webhook 端点发送事件时,可能会出现多种问题:
- Stripe 可能无法将事件发送到您的 Webhook 端点。
- 您的 Webhook 端点可能存在 SSL 问题。
- 您的网络连接时断时续。
- 您的 Webhook 端点没有接收到您期望接收的事件。
查看事件的发送情况
要查看事件传送情况,请在 Webhook 中选择 Webhook 端点,然后选择事件选项卡。
事件选项卡中提供了一个事件列表,并显示它们的状态是Delivered
、Pending
还是 Failed
。点击某个事件,即可查看元数据,包括交付尝试的 HTTP 状态代码以及未来待处理交付的时间。
修复 HTTP 状态代码
当一个事件显示状态代码 200
时,它表示已成功地发送到 Webhook 端点。您可能还会收到一个不同于 200
的状态代码。有关常见 HTTP 状态代码和推荐解决方案的列表,请查看下表。
待处理的 Webhook 状态 | 描述 | 修复 |
---|---|---|
(无法连接)ERR | 我们无法建立到目标服务器的连接。 | 确保您的主机域名可以公开访问互联网。 |
(302 ) ERR(或其他 3xx 状态) | 目标服务器尝试将请求重定向到另一个位置。这种情况,我们认为对 Webhook 请求的重定向响应是失败的。 | 将 Webhook 端点目的地设置为重定向解析的 URL。 |
(400 ) ERR(或其他 4xx 状态) | 目标服务器不能或不会处理请求。当服务器检测到错误 (400 )、目标 URL 有访问限制 (401 , 403 ) 或目标 URL 不存在 (404 ) 时,可能会发生这种情况。 |
|
(500 ) ERR(或其他 5xx 状态) | 目标服务器在处理请求时遇到了错误。 | 查看应用程序的日志,了解它为什么返回 500 错误。 |
(TLS 错误)错误 | 我们无法与目标服务器建立安全连接。目标服务器的证书链中的 SSL/TLS 证书或中间证书的问题通常会导致这些错误。Stripe 需要 v1. 或更高版本的 TLS。 | 执行 SSL 服务器测试,找出可能导致此错误的问题。 |
(超时) 错误 | 目标服务器响应 Webhook 请求的时间过长。 | 务必要在您的 Webhook 处理代码中延迟复杂的逻辑并立即返回成功的响应。 |
事件的发送行为
本节旨在帮助您理解 Stripe 向 Webhook 端点发送事件时的不同行为。
自动重试
在真实模式下,我们会尽量连续三天一直尝试将事件发送到您的接收端,但尝试频率递减。在事件接收端的事件发送选项卡中查看下次重试的时间(如果适用)。我们在几个小时内重试了三次在沙盒中创建的事件发送操作。如果在我们重新尝试时您的接收端已被禁用或删除,我们将阻止您再次尝试该事件。但是,如果您在我们重试之前禁用并又重新启用事件接收端,则仍可以看到今后的重试尝试。
手动重试
有两种方法可以手动重试事件:
- 在 Stripe 管理平台中,查看特定事件时点击重新发送。这适用于创建事件后的 15 天内。
- 用 Stripe CLI 运行
stripe events resend <event_
命令。这适用于创建事件后的 30 天内。id> --webhook-endpoint=<endpoint_ id>
手动向 Webhook 端点重新发送之前发送失败的事件并不会解除 Stripe 的自动重试行为。自动重试仍会发生,直到您用2xx
状态代码对其中一次重试做出响应。
事件排序
Stripe 不保证事件按照生成的顺序发送。例如,创建订阅时可能会生成以下事件:
customer.
subscription. created invoice.
created invoice.
paid charge.
(如果有收款)created
确保您的事件接收端不依赖于以特定顺序接收事件。准备好适当管理他们的提交操作。您还可以使用 API 来检索任何缺少的对象。例如,如果您先收到此事件,可以使用 invoice.
中的信息检索账单、收款和订阅对象。
API 版本控制
事件发生时您的账户设置中的 API 版本表示 API 版本,因此会将 Event 的结构发送到您的目的地。例如,如果您的账户设置为旧的 API 版本,如 2015-02-16,并且您通过 versioning 更改特定请求的 API 版本,则生成并发送到您的接收端的 Event 对象仍然是基于这个 2015-02-16 API 版本。Event 对象一经创建即不能修改。例如,如果您更新某笔收款,则原始收款事件保持不变。因此,对您的账户 API 版本的后续更新不会追溯更改现有的 Event 对象。通过较新版本的 API 调用 /v1/events
来获取旧的 Event 对收到的事件的结构也没有影响。您可以将测试事件接收端设置到默认的 API 版本或最新的 API 版本。发送到接收端的 Event 是针对接收端的指定版本而构建的。
Webhook 用法最佳实践
查看这些最佳做法,时刻确保您的 Webhook 安全,并与您的集成应用良好运行。
处理重复事件
Webhook 端点有时可能会多次收到同一事件。您可以通过记录已处理的事件 ID,然后不处理已记录的事件来防止接收重复事件。
在某些情况下,会生成并发送两个单独的 Event 对象。要识别这些重复项,请使用 data.
中对象 ID 和 event.
。
仅侦听集成所需的事件类型
将 Webhook 端点配置为仅接收集成所需的事件类型。侦听额外的事件(或所有事件)会给您的服务器带来过度的压力,因此不建议这样做。
您可以在管理平台或通过 API 更改事件(Webhook 端点收到的事件)。
异步处理事件
配置您的处理程序来处理带有异步队列的传入事件。如果选择同步处理事件,可能会遇到扩展性问题。Webhook 发送量的任何大峰值(例如,在所有订阅都续订的月初)都可能会使您的端点主机不堪重负。
异步队列可让您以系统支持的速度处理并发事件。
去除 Webhook 路由的 CSRF 保护
如果您正在使用 Rails、Django 或其他网络框架,则您的站点可能会自动检查每个 POST 请求是否包含一个_CSRF 令牌_。这是一个重要的安全功能,有助于保护您及您的用户免受跨站请求伪造 (cross-site request forgery, CSRF) 攻击。但是,这一安全措施也可能会阻止您的站点处理合法事件。如果是这样,则您可能需要从 CSRF 保护中去除 Webhook 路由。
通过 HTTPS 服务器接收事件
如果您为您的 Webhook 端点使用了 HTTPS URL(真实模式下要求),则 Stripe 会在发送您的 Webhook 数据之前先验证到您的服务器的连接是否安全。为此,您的服务器必须要正确配置,具有支持 HTTPS 的有效服务器证书。Stripe Webhook 仅支持 TLS 版本 v1.2 和 v1.3。
定期滚动端点签名密钥
用于验证事件来源于 Stripe 的私钥可在 Workbench 的 Webhook选项卡中中修改。为了保证它们的安全,建议您定期或者在怀疑私钥泄露时滚动(更改)私钥。
要滚动私钥:
- 在 Workbench Webhook 选项卡中,点击您想要滚动私钥的每个端点。
- 导航到溢出菜单 (),然后点击滚动私钥。您可以选择立即使当前私钥过期,也可以延迟 24 小时后再让它过期,以便让自己有时间更新服务器上的验证码。这段时间内,端点会有多个密钥处于活动状态。Stripe 会为每个私钥生成一个签名,直到过期。
验证事件是否是从 Stripe 发送的
Stripe 会从一组固定的 IP 地址发送 Webhook 事件。仅信任来自这些 IP 地址的事件。
还要验证 Webhook 签名,以确认 Stripe 发送了接收的事件。Stripe 通过在每个事件的 Stripe-Signature
头中包含一个签名来对它发送到您的端点的 Webhook 事件进行签名。这样可表示事件是由 Stripe 发送的,而非第三方。可以用我们的官方库来验证签名,也可以用您自己的方案手动验证。
以下部分描述了 Webhook 签名的验证方式:
- 检索您的端点的密钥。
- 验证签名。
检索您的端点的密钥
使用 Workbench 并转到 Webhooks 标签页查看所有端点。选择要获取密钥的端点,然后单击单击显示。
Stripe 为每个端点生成一个唯一私钥。如果您为测试和真实 API 私钥使用相同的端点,则每个端点的私钥各不相同。此外,如果您使用多个端点,则必须要为您想用来验证签名的每个端点都获取一个私钥。有了这种设置,Stripe 便可开始对它发送到端点的每个 Webhook 进行签名。
防止重放攻击
重放攻击 (Replay Attack)是攻击者截获有效的有效载荷及其签名,然后再重新传输。为了减轻这类攻击,Stripe 在 Stripe-Signature
头内包含了时间戳。因为此时间戳是已签名的有效载荷的一部分,因此它也由签名验证,所以攻击者在不使签名无效的情况下不能更改时间戳。如果签名有效,但时间戳太旧,则您可以让您的应用程序拒绝有效载荷。
我们的库在时间戳和当前时间之间有 5 分钟的默认容差。您可以通过在验证签名时提供附加参数来更改此容差。使用网络时间协议(Network Time Protocol,简称NTP),确保您的服务器时钟的准确性,并与 Stripe 的服务器时间同步。
常见错误
请勿使用容差值 0
。使用容差值为 0
将完全禁用近期检查。
每当向您的端点发送事件时,Stripe 都会生成时间戳和签名。如果 Stripe 重试一个事件(例如,您的端点之前回复了一个非 2xx
的状态码),则我们会为新的发送尝试生成新的签名和时间戳。
快速返回 2xx 响应
您的端点必须要快速返回一个成功的状态码 (2xx
),然后才能执行任何可能导致超时的复杂逻辑。例如,您必须返回一个 200
响应,然后才能在您的会计系统中将客户的账单更新为已支付。