考虑到 GET 请求应该是安全的,如何处理 Stripe 上的成功 URL?

How to handle the success URL on Stripe considering GET requests should be safe?

当我们进行条带结帐会话时,我们包含成功 url:

 session = await this.stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: lineItems,
payment_intent_data: {
transfer_data: {
amount: 9999999,
destination: someaccountId,
},
},
success_url: `http://localhost:4000/api/checkout/success?true&session_id={CHECKOUT_SESSION_ID}&alias_id=${aliasId}`, 
cancel_url: `http://localhost:4000/api/checkout/canceled?session_id={CHECKOUT_SESSION_ID}`,
});

successURL是stripe在支付成功后发送给用户的地方。这是一个 GET 请求,因为 stripe 正在重定向用户。许多使用 stripe 的应用程序在成功结账后需要采取行动——发送电子邮件收据、通知、发送付费内容、更新数据库中的订单等。但建议不要在 GET 请求中执行这些操作,因为 GET 请求应该是 idempotent and safe.

例如,电子邮件中的退订 link 不应该退订用户,而是 "退订 links 的正确方法是引导到用户所在的页面可以单击按钮取消订阅(单击按钮会触发 POST 请求)。"src This is because "Many, many, many tools, utilities, web crawlers and other thingamajiggies assume that GET will never be a destructive action (rightly so, since it's specified this way). If you now break your application by breaking that specification, you'll get to keep both parts of your application." src

所以我想知道处理条纹成功的正确方法是什么 url?如果我们遵循上面的建议,那么成功 url 将 link 到一个页面,用户在该页面上单击更新订单的按钮,通过电子邮件发送收据等。但是我们依赖于客户完成已经付款的订单。如果他们不按下那个按钮,那么重要的动作就没有完成。这样做的正确方法是什么?还是出于某种原因,不根据 GET 请求更改数据库的建议不适用于这些类型的操作?

使该页面中处理结帐会话代码的部分成为幂等的——即让它首先检查它的步骤是否已经被处理(在这种情况下跳过),否则无论它做什么处理可以在第一次运行后重复多次而不会产生任何额外效果。

对于“工具、实用程序、网络爬虫和其他 thingamajiggies”来说,使用有效的结帐会话 ID 来访问您的 URL 几乎是不可能的,因此无论您使用什么代码来处理 'bad session ID' 会处理得很好。

您还应该有一个用于此的 webhook - 它会收到 POST 请求。 https://stripe.com/docs/payments/checkout/fulfill-orders#handle-the---event