PDS2 Stripe Success Webhook 和其他问题

Posted

技术标签:

【中文标题】PDS2 Stripe Success Webhook 和其他问题【英文标题】:PDS2 Stripe Success Webhook and other issues 【发布时间】:2020-01-08 12:19:12 【问题描述】:

这有成为 TLDR 的危险 - 所以我的问题是:在成功付款时 - stripes 会向我的成功 webhook 发送“成功”有效负载。查看有效负载,我看不到任何可以用来查找成功付款的信息。我应该从我的条带会话中保存一些东西到我的待付款吗?

更多细节:

为了遵守 PSD2,我不得不重新调整我们的条带付款方式。我们支持几种不同的付款方式,这影响了我的流程。

之前,使用条带,我们会得到一个令牌 - 发送给客户端...付款 - 订单保存到数据库.. 工作完成。

现在,流程反过来了……

我有一个“条纹”按钮 - 客户点击它。对服务器进行 POST。在服务器上,我抓取客户的购物车并创建一个付款状态为待处理的订单。

然后我创建一个条带会话 - 并将条带会话 ID 返回给客户端(代码被删节)

                  //creates order and returns Order ID
                  const orderid = await createOrder(cart); 

                  const stripeSession = await stripe.checkout.sessions.create(
                        customer_email: request.payload.billingEmail,
                        payment_method_types: ["card"],
                        line_items: [
                            
                                name: "###",
                                description: "###" + orderid,
                                amount: cart.total.total,
                                currency: cart.total.currency,
                                quantity: 1
                            
                        ],
                        success_url: "###" + orderid,
                        cancel_url: "###/checkout"
                    );

                    return 
                        stripeSessionID: stripeSession.id
                    ;

在我的客户端上,我有这种方法方法可以发布到服务器并自动重定向到外部条带结帐页面:

        stripeCheckout: function () 
           ...
            axios.post('/pay/get-stripe-session', data)
                .then(function (response) 
                    var checkoutSessionID = response.data.stripeSessionID
                    stripe.redirectToCheckout(
                        sessionId: checkoutSessionID
                    ) ...

支付成功后,stripe 会向我的成功 webhook 发送一个“成功”负载。我检查了条纹签名 - 并收到了消息......这一切都有效......但是,我在有效负载中看不到任何可用于将付款与订单匹配的数据(以更新订单付款状态)。

当我创建我的条带会话时,有什么可以使用的吗?

** 编辑** -

    创建条带会话时,可以将client_reference_id. 作为唯一键传递给创建会话方法。但是,stripes success webhook 不会在其有效负载中返回此密钥 - 因此它不能用于将成功的付款与订单核对。

    我们有自己的客户账户系统。在旧 API 下,我们可以这样设置收费:

    const charge = await stripe.charges.create(
      amount: total,
      currency: currency,
      source: token, // obtained with Stripe.js
      description: orderid
    )
    

描述将出现在条纹仪表板中,便于查找付款(退款或其他)。我们不使用 Stripes 的“客户”。我们将订单和客户存储在我们的系统中(stripe 不是客户管理系统)。如果客户在结账时已登录,我们会将其链接到他们的订单。客人订单未与任何人关联。

但是,在新的 api 下,您必须创建一个 stripeSession,每个会话都会在 stripes 仪表板中创建一个客户。我们可以防止这种情况发生吗?

此外,无法像使用旧的收费 API 那样为整个会话/收费添加描述 - 所以在 Stripes Payments 仪表板中,我们最终会为每个付款描述添加无法使用的垃圾...

有谁知道如何解决这个问题?我希望 Stripe 不必牺牲他们出色的开发人员经验来遵守 PDS2

【问题讨论】:

【参考方案1】:

创建CheckoutSession 时,可以将client_reference_id 传递给它。该值稍后将出现在对象上,以便您在自己的系统中引用订单。

【讨论】:

谢谢。我已经这样做了 - 但是,成功 webhook 似乎没有将 client_reference_id 发送回成功负载中? 如果 client_reference_id 不在 Webhook 事件负载中,您可以在看到事件发生时通过从 API 中检索 CheckoutSession 来获取它。【参考方案2】:

解决了:

诀窍是在您的条带会话上设置元数据:

                        const stripeSession = await stripe.checkout.sessions.create(
                        customer_email: billingEmail,
                        client_reference_id: orderid,
                        payment_method_types: ["card"],
                        line_items: [
                            
                                name: "My charge",
                                description: "Lorem ipsum",
                                amount: total,
                                currency: currency,
                                quantity: 1
                            
                        ],
                        payment_intent_data: 
                            description: `orderID: $orderid`,
                            metadata: 
                                orderid : orderid
                            
                        ,
                        success_url: "https://example.com/thankyou/",
                        cancel_url: "https://example.com/checkout"
                    );

在 charge.success 事件(webhook)中返回元数据。使用此元数据,我可以在我的数据库中找到订单并对其进行更新。 在我们的例子中,我从 Charge.success 事件中获取 transaction.id、卡类型和最后 4 位卡位,然后将付款状态更新为已付款。

如果您不需要此信息 - 您可以简单地将您的 webhook 设置为接收 checkout.session.complete 事件,因为该事件包含 client_reference_id (我相信这是确认交易的首选事件)

因为我们没有在 Stripe 中使用客户帐户,所以我还将客户从 Stripe 中删除:

        // Delete the customer from Stripes Dashboard (we don't use it - its clutter)
        const customerID = event.data.object.customer

        stripe.customers.del(
            customerID,
            function(err, confirmation) 
                // asynchronously called
            
        );

基本上就是这样。使用元 - 它似乎在每个事件上都发送。

【讨论】:

以上是关于PDS2 Stripe Success Webhook 和其他问题的主要内容,如果未能解决你的问题,请参考以下文章

Ionic 5 Stripe 如何使用success_url将用户重定向回应用程序?

Stripe Checkout 会话的有效期是多久?

Ruby - 即使抛出了 Stripe 异常,else 块中的代码也会执行

为条带付款创建发票

如何处理条带支付成功?

使用 @stripe/stripe-react-native 处理 Stripe 时抛出错误