简体   繁体   English

付款成功后删除所有购物车物品

[英]On payment success remove all cart items

I have integrated stripe api into my ecommerce website.我已将 Stripe api 集成到我的电子商务网站中。 When you checkout you are sent to the stripe api payment link where you type in your information.当您结帐时,您会被发送到您在其中输入信息的 stripe api 付款链接。 Of course two things could happen here, either the payment goes through and succeed or the order gets canceled.当然,这里可能会发生两件事,要么付款通过并成功,要么订单被取消。 Everything works except I am trying to remove all cart items only if the payment succeeds and goes through.一切正常,除了我试图仅在付款成功并通过时删除所有购物车物品。

Here is my code:这是我的代码:

app.post('/api/createCheckoutSession', async (req, res) => {


    try {
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            mode: 'payment',
            line_items: req.body.items.map(item => {
                const storeItem = storeItems.get(item.id)
                return {
                    price_data: {
                        currency: 'usd',
                        product_data: {
                            name: storeItem.name
                        },
                        unit_amount: storeItem.priceInCents
                    },
                    quantity: item.quantity
                }

            }),
            success_url: `${process.env.SERVER_URL}`,
            cancel_url: `${process.env.SERVER_URL}cart`,
        })

        res.json({ url: session.url })
    } catch (e) {
        console.log(e)
        res.status(500).json({ error: e.message })
    }

});

So if I do the following code I can remove all cartItems from the user, however this happens regardless of if the payment was successful or not:因此,如果我执行以下代码,我可以从用户中删除所有 cartItems,但是无论付款是否成功,都会发生这种情况:

app.post('/api/createCheckoutSession', async (req, res) => {


    try {
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            mode: 'payment',
            line_items: req.body.items.map(item => {
                const storeItem = storeItems.get(item.id)
                return {
                    price_data: {
                        currency: 'usd',
                        product_data: {
                            name: storeItem.name
                        },
                        unit_amount: storeItem.priceInCents
                    },
                    quantity: item.quantity
                }

            }),
            success_url: `${process.env.SERVER_URL}`,
            cancel_url: `${process.env.SERVER_URL}cart`,

        })


        cartItem.remove({ user: req.body.user }, function (err) {
            if (err) {
                console.log(err)
            }
        })

        res.json({ url: session.url })
    } catch (e) {
        console.log(e)
        res.status(500).json({ error: e.message })
    }
    });

So looking through Stripe api documentation and googling the only thing that consistently comes up is success_url, which wasn't what I am looking for (at least I do not think it will fix what I am trying to do).因此,查看 Stripe api 文档并在谷歌上搜索唯一始终出现的是success_url,这不是我想要的(至少我认为它不会解决我想要做的事情)。 So for the original code I tried to console.log(session) and found a payment_status: 'unpaid' and figured I could use this to do what I am trying to by the following:因此,对于原始代码,我尝试console.log(session)并找到了payment_status: 'unpaid'并认为我可以使用它来执行以下操作:

app.post('/api/createCheckoutSession', async (req, res) => {


    try {
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            mode: 'payment',
            line_items: req.body.items.map(item => {
                const storeItem = storeItems.get(item.id)
                return {
                    price_data: {
                        currency: 'usd',
                        product_data: {
                            name: storeItem.name
                        },
                        unit_amount: storeItem.priceInCents
                    },
                    quantity: item.quantity
                }

            }),
            success_url: `${process.env.SERVER_URL}`,
            cancel_url: `${process.env.SERVER_URL}cart`,

        })


        console.log(session)
        if (session.payment_status == 'paid') {
        cartItem.remove({ user: req.body.user }, function (err) {
            if (err) {
                console.log(err)
            }
        })
        }


        res.json({ url: session.url })
    } catch (e) {
        console.log(e)
        res.status(500).json({ error: e.message })
    }



});

With the above code, the if statement does not work as the only time something gets logged to the console is when the session first gets created, so the if statement does not execute after the payment succeeds or gets canceled.使用上面的代码,if 语句不起作用,因为只有在会话首次创建时才会将某些内容记录到控制台,因此 if 语句在支付成功或被取消后不会执行。

Another solution is for me to create a different success_url where it pops up and I have a react useEffect call the remove cart items function.另一个解决方案是让我创建一个不同的success_url,它会在其中弹出,并且我有一个react useEffect 调用remove cart items 函数。 And then it redirects again somewhere else, but as I alluded to earlier this just seems like a terrible solution when it feels like I am just missing something very simple to get this to work the way I have attempted to.然后它再次重定向到其他地方,但正如我之前提到的,这似乎是一个糟糕的解决方案,因为我感觉我只是错过了一些非常简单的东西来让它按照我尝试的方式工作。

I'm going to restate what I think your goal is here so I am clear on what the answer is.我将重申我认为你的目标是什么,所以我很清楚答案是什么。

After user is sent to checkout you have 2 potential outcomes you want your app to handle:将用户发送到结帐后,您希望应用处理 2 个潜在结果:

  • Successful payment: Get money, get user their goods支付成功:拿钱,拿货
  • Payment canceled: Empty user cart付款取消:清空用户购物车

The problem you are running into is that your code can only await the creation of the user session.您遇到的问题是您的代码只能等待用户会话的创建 At that point you should just redirect to the Checkout URL.此时,您应该只重定向到 Checkout URL。 At this point your code does not know whether the payment will go through or not because the user is just being redirected to the Checkout UI where they can make their payment.此时,您的代码不知道付款是否会通过,因为用户只是被重定向到他们可以付款的 Checkout UI。

The state of the user's payment is reported back to your app in 2 different ways.用户付款的状态会以 2 种不同的方式反馈给您的应用。

  • Customized Success/Cancel URLS - While this doc focuses on capturing the Session ID in the Success URL, you can do the same thing with the Cancel URL. 自定义的成功/取消 URL - 虽然此文档侧重于捕获成功 URL 中的会话 ID,但您可以对取消 URL 执行相同的操作。 In this case which URL the user is sent to tells your system a Checkout was either successful or was canceled.在这种情况下,用户被发送到哪个 URL 会告诉您的系统 Checkout 是成功还是被取消。 The Session ID injected into the URL identifies which Checkout session it was.注入 URL 的会话 ID 标识了它是哪个 Checkout 会话。

  • Checkout Webhook events - This approach provides confirmation of success but requires waiting until the session is expired to confirm cancelation. 签出 Webhook 事件- 此方法提供成功确认,但需要等到会话过期才能确认取消。 Still, it is recommended that most integrations make use of Webhooks to monitor account activities.尽管如此,还是建议大多数集成使用Webhook来监控帐户活动。

So to circle back to your code, I would move the code that clears the cart to a function that responds to either the user being redirected to the cancel_url in your app or responds to the checkout.session.expired webhook event因此,回到您的代码,我会将清除购物车的代码移动到一个函数,该函数响应用户被重定向到应用程序中的cancel_url或响应checkout.session.expired webhook 事件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM