在 Webhook 端点中接收 Stripe 事件
在 Webhook 端点上侦听 Stripe 账户中的事件,以便您的集成应用可以自动触发反应。
向您的 AWS 账户发送事件。
您现在可以直接将事件发送到具有事件接收端的 Amazon EventBridge。
在构建 Stripe 集成应用时,您可能希望在您的 Stripe 账户中有事件发生时,您的应用程序可以接收它们,以便您的后端系统可以执行相应操作。
创建一个事件接收端,以接收 HTTPS Webhook 端点上的事件。在您注册 Webhook 端点后,当您的 Stripe 账户有事件发生时,Stripe 可以将实时事件数据推送到您的应用程序的 Webhook 端点。Stripe 用 HTTPS 将 Webhook 事件以包含事件对象的 JSON 有效载荷发送到您的应用程序。
接收 Webhook 事件对于侦听异步事件尤其有用,例如客户的银行确认付款、客户对收款提出争议、经常性付款成功,或收集订阅付款。
还可以在具有事件接收端的 Amazon EventBridge 中接收事件。
开始
要开始在您的应用程序中接收 Webhook 事件,请创建并注册 Webhook 端点:
- 创建一个 Webhook 端点处理程序来接收事件数据的 POST 请求。
- 使用 Stripe CLI 在本地测试您的 Webhook 端点处理程序。
- 通过管理平台或 API 在 Stripe 中注册您的端点。
- 保护您的 Webhook 端点。
您可以注册并创建一个端点,用它同时处理几个不同的事件类型,也可以为特定事件设置单独的端点。
创建处理程序
设置一个 HTTP 或 HTTPS 端点函数,该函数可以用 POST 方法接受 Webhook 请求。如果您仍在您的本地机器上开发您的端点,则它可以使用 HTTP。可公开访问后,您的 Webhook 端点函数必须使用 HTTPS。
设置您的端点函数,以便它:
- 使用由事件对象组成的 JSON 有效载荷处理 POST 请求。
- 在执行任何可能导致超时的复杂逻辑之前,快速返回一个成功状态码 (
2xx
)。例如,您必须返回一个200
响应,然后才能在您的会计系统中将客户的账单更新为已支付。
备注
或者,您可以利用我们的交互式 Webhook 端点构建器,以您的编程语言构建一个 Webhook 端点函数。
示例端点
此代码片段是一个 Webhook 函数,配置它的目的有三:一是检查事件类型是否可被接收,二是处理事件,三是返回 200 响应。
测试您的处理程序
在您使用 Webhook 端点函数之前,我们建议您测试您的应用程序集成情况。方法是配置本地侦听器,以此将事件发送到您的本地机器,并发送测试事件。测试时,您需要使用 CLI。
将事件转发到本地端点
要将事件转发到本地端点,请使用 CLI 运行以下命令来设置本地侦听器。在测试模式下,--forward-to
标志会将所有的 Stripe 事件发送到您本地的 Webhook 端点。
stripe listen --forward-to localhost:4242/webhook
备注
您还可以在 Stripe Shell 上运行 Stripe 侦听命令,通过 Stripe Shell 终端查看事件,但您无法将事件从 Shell 转发到本地端点。
有些配置有助于用本地侦听器进行测试,这些配置包括:
- 禁用 HTTPS 证书验证,使用
--skip-verify
可选标志。 - 仅转发特定事件时,使用
--events
可选标志,并传入事件列表,用逗号分隔事件。
stripe listen --events payment_intent.created,customer.created,payment_intent.succeeded,checkout.session.completed,payment_intent.payment_failed \ --forward-to localhost:4242/webhook
- 要将事件从已经在 Stripe 上注册的公共 Webhook 端点转发到本地 Webhook 端点,请使用
--load-from-webhooks-api
可选标志。它会加载您注册的端点,解析路径及其注册的事件,然后将路径附加到您本地的 Webhook 端点的--forward-to path
路径中。
stripe listen --load-from-webhooks-api --forward-to localhost:4242/webhook
- 要检查 Webhook 签名,请使用侦听命令初始输出中的
{{WEBHOOK_
。SIGNING_ SECRET}}
Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
触发测试事件
To send test events, trigger an event type that your webhook is subscribed to by manually creating an object in the Stripe Dashboard. Alternatively, you can use the following command in either Stripe Shell or Stripe CLI.
此示例触发一个 payment_
事件:
stripe trigger payment_intent.succeeded Running fixture for: payment_intent Trigger succeeded! Check dashboard for event details.
Learn how to trigger events with Stripe for VS Code.
注册您的端点
测试完 Webhook 端点函数后,通过开发人员管理平台或 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 端点
You can create new event destinations for webhook and AWS EventBridge destinations.
备注
Workbench 将替换掉当前的开发人员管理平台。如果您仍在使用开发人员管理平台,请查看如何创建新的 Webhook 端点。
用 Stripe API 注册 Webhook 端点
您也可以通过编程方式创建 Webhook 端点。
要接收来自 Connect 子账户的事件,请使用 Connect 参数。
下面的示例为创建一个端点,在收款成功或失败时给您发送通知。
保护您的端点
您需要确保,处理程序验证了所有 Webhook 请求都是由 Stripe 生成的,以此来保护您的集成应用。您可以使用我们的官方库来验证 Webhook 签名或手动验证。
调试 Webhook 集成
向 Webhook 端点发送事件时,可能会出现多种问题:
- Stripe 可能无法将事件发送到您的 Webhook 端点。
- 您的 Webhook 端点可能存在 SSL 问题。
- 您的网络连接时断时续。
- 您的 Webhook 端点没有接收到您期望接收的事件。
查看事件的发送情况
要查看特定端点的事件发送情况,请在 Webhook 选项卡中选择 Webhook 端点。
要查看您的账户中触发的所有事件,请查看事件选项卡。
修复 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 错误)ERR | 我们无法与目标服务器建立安全连接。目标服务器证书链中的 SSL/TLS 证书或中间证书的问题通常会导致这些错误。Stripe 要求 v1.2 及以上版本的 TLS。 | 执行 SSL 服务器测试,找出可能导致此错误的问题。 |
(超时) ERR | 目标服务器响应 Webhook 请求的时间过长。 | 务必要在您的 Webhook 处理代码中延迟复杂的逻辑并立即返回成功的响应。 |
事件的发送行为
本节旨在帮助您理解 Stripe 向 Webhook 端点发送事件时的不同行为。
重试行为
In live mode, Stripe attempts to deliver a given event to your webhook endpoint for up to 3 days with an exponential back off. In test mode, Stripe retries three times over a few hours. You can view when the next retry will occur in the Events section of the Dashboard.
You can manually retry transmitting individual events to your webhook endpoint using the Events section of the Dashboard. You can also use the API to process undelivered webhook events.
即使您重新手动尝试向指定端点传输单个 Webhook 事件并且尝试成功,自动重试仍会继续。
如果在 Stripe 尝试重试时,您的端点已被禁用或删除,则会阻止进一步尝试该事件。但是,如果您在 Stripe 重试之前禁用并重新启用了某个 Webhook 端点,那仍可看到后续的重试尝试。
禁用行为
在真实和测试模式下,如果某个端点连续数天没有响应 2xx
HTTP 状态码,则 Stripe 会尝试给您发送邮件通知,告知该端点配置错误。邮件中还会告知何时将自动禁用此端点。
API 版本
当事件发生时,您的账户设置中的 API 版本决定着特定请求的 API 版本,因此决定着在 Webhook 中发送的 Event
对象的结构。例如,如果您的账户设置为旧的 API 版本,如 2015-02-16,并且您通过版本控制更改了特定请求的 API 版本,则生成并发送到您的端点的 Event
对象仍然是基于此 2015-02-16 API 版本。
Event
对象在创建后不能更改。例如,如果您更新某笔收款,则原始收款事件保持不变。这意味着对您账户的 API 版本的后续更新不会追溯性地更改当前的 Event
对象。通过新版本的 API 调用 /v1/events
来获取旧的事件,对收到的事件的结构也没有影响。
您可以将测试 Webhook 端点设置为默认的 API 版本或最新的 API 版本。发送到 Webhook URL的 Event
是为端点的特定版本构建的。您还可以通过编程方式创建具有特定 api_version 的端点。
事件排序
Stripe 不保证能够按事件生成的顺序来发送事件。例如,创建订阅时可能会生成以下事件:
customer.
subscription. created invoice.
created invoice.
paid charge.
(如果有收款)created
您的端点不应期望上述事件按照此顺序发送,而是应该来一个处理一个。您也可以用 API 来获取任何丢失的对象(例如,您可以使用来自 invoice.
的信息获取账单、收款及订阅对象——如果您恰好是先收到的此事件的话)。
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 的密钥可在管理平台的 Webhook 部分来修改。对于每个端点,点击滚动密钥。您可以选择立即使当前密钥过期,也可以最长延迟 24 小时再让它过期,以便让自己有时间更新服务器上的验证码。这段时间内,端点会有多个密钥处于活动状态。Stripe 会为每个密钥生成一个签名,直到过期。为了保证它们的安全,建议您定期或在怀疑密钥泄露时滚动它们。
验证事件是否是从 Stripe 发送的
Stripe 会从一组固定的 IP 地址发送 Webhook 事件。仅信任来自这些 IP 地址的事件。
此外,验证 Webhook 签名以确认收到的事件是从 Stripe 发送的。Stripe 通过在每个事件的 Stripe-Signature
头中包含一个签名来对它发送到您的端点的 Webhook 事件进行签名。这样可表示事件是由 Stripe 发送的,而非第三方。可以用我们的官方库来验证签名,也可以用您自己的方案手动验证。
以下部分描述了 Webhook 签名的验证方式:
- 检索您的端点的密钥。
- 验证签名。
检索您的端点的密钥
使用管理平台的 Webhook 部分。选择要获取其密钥的端点,并在页面的右上角找到此密钥。
Stripe 为每个端点生成一个唯一密钥。如果您为测试和真实 API 密钥使用相同的端点,则每个端点的密钥各不相同。此外,如果您使用多个端点,则必须要为您想用来验证签名的每个端点都获取一个密钥,然后 Stripe 会开始签署它发送到端点的每个 Webhook。
防止重放攻击
重放攻击 (Replay Attack)是攻击者截获有效的有效载荷及其签名,然后再重新传输。为了减轻这类攻击,Stripe 在 Stripe-Signature
头内包含了时间戳。因为此时间戳是已签名的有效载荷的一部分,因此它也由签名验证,所以攻击者在不使签名无效的情况下不能更改时间戳。如果签名有效,但时间戳太旧,则您可以让您的应用程序拒绝有效载荷。
我们的库在时间戳和当前时间之间有 5 分钟的默认容差。您可以通过在验证签名时提供附加参数来更改此容差。使用网络时间协议(Network Time Protocol,简称NTP),确保您的服务器时钟的准确性,并与 Stripe 的服务器时间同步。
常见错误
请勿使用容差值 0
。使用容差值为 0
将完全禁用近期检查。
每当向您的端点发送事件时,Stripe 都会生成时间戳和签名。如果 Stripe 重试一个事件(例如,您的端点之前回复了一个非 2xx
的状态码),则我们会为新的发送尝试生成新的签名和时间戳。
快速返回 2xx 响应
您的端点必须要快速返回一个成功的状态码 (2xx
),然后才能执行任何可能导致超时的复杂逻辑。例如,您必须返回一个 200
响应,然后才能在您的会计系统中将客户的账单更新为已支付。