PDS2 Stripe Success Webhook 等问题

PDS2 Stripe Success Webhook and other issues

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

更多细节:

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

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

现在,流程逆转了...

我有一个 "Stripe" 按钮 - 客户点击它。 POST 发送到服务器。在服务器上,我获取客户购物车并创建一个付款状态为待处理的订单。

然后我创建一个条带会话 - return 客户端的条带会话 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
                    };

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

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

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

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

** 编辑 ** -

  1. 创建条带会话时,可以将client_reference_id.作为唯一键传递到创建会话方法中。但是,stripes success webhook 在其有效负载中没有 return 这个键 - 因此它不能用于协调成功的付款与订单。

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

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

描述会出现在 stripes 仪表板中,便于查找付款(退款或其他)。我们不使用条纹 'customers'。我们在我们的系统中存储订单和客户(stripe 不是客户管理系统)。如果客户在结账时已登录,我们会 link 他们下订单。客人订单不会 link 发送给任何人。

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

此外,无法像使用旧收费那样向整个会话/收费添加描述 api - 因此在 Stripes 支付仪表板中,我们最终得到了每个支付描述无法使用的垃圾...

有谁知道如何解决这个问题?我希望 Stripe 不必为了遵守 PDS2

而牺牲他们出色的开发人员体验

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

已解决:

诀窍是在你的条带会话中设置元数据:

                        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(我相信 stripes 首选事件来确认交易)

因为我们没有在 Stripe 中使用 Customers 帐户,所以我也从 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
            }
        );

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