PDS2 Stripe Success Webhook和其他问题

时间:2019-09-05 14:56:03

标签: node.js stripe-payments webhooks hapi

这有成为TLDR的危险-所以我的问题是:成功付款后-条带向我的成功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。我检查了条带签名-并收到消息...这一切正常...但是,我看不到有效载荷中的任何数据,可用于将付款与订单进行匹配(以便更新订单付款)状态)。

创建条纹会话时,可以使用其中的任何内容吗?

**编辑**-

  1. 在创建条带会话时,可以将client_reference_id.作为唯一键传递到create session方法中。但是,stripes成功webhook不会在其有效载荷中返回此密钥-因此,不能将其用于与订单进行成功付款对帐。

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

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

并且说明将显示在条纹仪表板中,从而可以轻松找到付款(进行退款或其他方式)。我们不使用Stripes的“客户”。我们将订单和客户存储在我们的系统中(条带不是客户管理系统)。如果客户在结帐时已登录,我们会将其链接到他们的订单。访客订单未链接到任何人。

但是,在新的api下,您必须在每个新会话中创建一个stripeSession,以在Strips仪表板中创建一个客户。我们可以预防吗?

此外,您无法像使用旧的收费api一样在整个会话/费用中添加说明-因此,在Stripes Payments仪表板中,每个付款说明最终都变成了无法使用的垃圾...

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

解决了:

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

                        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
            }
        );

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