条纹支付元素和一页结账 - 啥是正确的支付流程?

Posted

技术标签:

【中文标题】条纹支付元素和一页结账 - 啥是正确的支付流程?【英文标题】:Stripe Payment Element and one page checkout - what is the correct payment flow?条纹支付元素和一页结账 - 什么是正确的支付流程? 【发布时间】:2022-01-18 06:51:43 【问题描述】:

我想升级我的简单 Stripe 一页结帐以使用新的付款元素,该元素将许多不同的付款方式统一在一个组件下。我的意思很简单,客户在一种产品的几个变体中进行选择,提供所需的信息并提交订单。收钱、发送电子邮件、完成订单等。只是香草html/CSS/JS 和一点php。使用Payment Intents API 处理付款,之前在Charges API 上。

我喜欢这个统一元素的前提,所以我决定试一试。事实证明,我无法理解如何处理 stripe.confirmPayment 方法和 return_url 参数。

我猜return_url 应该是我的结帐页面?另外,有没有办法在不硬刷新的情况下重定向?理想情况下,我可以在重定向发生之前做一些服务器端的事情,但如果成功解析,stripe.confirmPayment 似乎会自动重定向。

这是我的代码。顺便说一句,我是一名设计师,所以我想我还是像往常一样遗漏了一些明显的东西。

        // init Stripe elements
        fetch('/config.php', 
        method: 'get',
        headers: 
            'Content-Type': 'application/json'
        
    )
    .then((response) => 
        return response.json();
    )
    .then((response) => 
        return setupElements(response.publishableKey)
    )

var setupElements = function (publishableKey) 
    stripe = Stripe(publishableKey);
    // create payment intent to setup payment element
    fetch('/setup-elements.php', 
            method: 'POST',
            headers: 
                "Content-Type": "application/json"
            ,
            body: JSON.stringify(order)
        )
        .then(function (response) 
            return response.json()
        )
        .then(function (data) 
            const appearance = 
            theme: 'none',
            labels: 'floating',
            // etc.....
            ;
            elements = stripe.elements(
                clientSecret: data.clientSecret,
                fonts: [
                    cssSrc: 'https://use.typekit.net/hly2qug.css'
                , ],
                appearance
            );
            const paymentElement = elements.create("payment", 
                fields: 
                    billingDetails: 
                        email: 'never',
                        address: 
                            line1: 'never',
                            city: 'never',
                            state: 'never',
                            country: 'never',
                            postalCode: 'never'
                        
                    
                
            );
            paymentElement.mount("#payment-element");
          
        )


form.addEventListener('submit', function (e) 
    e.preventDefault();
    var isFormValid = validate.validateAll(form);
    if (isFormValid.length < 1) 
        loading(true);
        collectFormInfo();
        confirmPayment();
    
)

var confirmPayment = function () 
    stripe.confirmPayment(
            elements,
            confirmParams: 
                return_url: 'checkout-page?',
                payment_method_data: 
                    billing_details: 
                        email: order.customer.email,
                        address: 
                            line1: order.delivery.address,
                            city: order.delivery.city,
                            state: order.delivery.state,
                            country: order.delivery.country,
                            postal_code: order.delivery.postcode
                        
                    
                
            
        )
        .then(function (result) 
            // This is where I get stuck. How to do stuff after 
            // payment is confirmed
            // and not get redirected immediately? If 
            //redirected, where to and is it 
            // possible to do so asynchronously?    
            if (result.error.type === "card_error" || result.error.type === "validation_error") 
                showMessage(result.error.message);
             else 
                // get client secret
                const clientSecret = new URLSearchParams(window.location.search).get(
                    "payment_intent_client_secret"
                );
                // bail if no client secret
                if (!clientSecret) 
                    return;
                 else 
                    stripe.retrievePaymentIntent(clientSecret).then(function (response) 
                        switch (response.paymentIntent.status) 
                            case "succeeded":
                                showMessage("Payment succeeded!");
                                break;
                            case "processing":
                                showMessage("Your payment is processing.");
                                break;
                            case "requires_payment_method":
                                showMessage("Payment failed. Please try another payment method.");
                                break;
                            default:
                                showMessage("Something went wrong.");
                                break;
                        
                    );
                
            

        )

我只需要朝正确的方向轻推,至少我希望如此

【问题讨论】:

【参考方案1】:

是的,return_url 应该是您自己的页面,Stripe 会在您的客户完成付款后自动重定向:Stripe Doc。 “结帐页面?”看起来不是一个有效的 URL。通常你会想要类似'http://localhost:4242/success'

这个动作是在客户端自动完成的,你不能拦截它。您想在服务器上执行的任何操作都应通过 webhook 处理,在上面同一篇文章的第 6 步“处理付款后事件”中。

【讨论】:

感谢您解决问题。我希望有一种方法可以拦截重定向。我还不清楚一件事。检索支付意图和检查状态的部分在哪里?该代码应该放在重定向页面上,对吗?我没有按照文档使用 async/await,这是个问题吗? 是的,代码应该放在重定向页面上。而且我认为不使用 async/await 不会有问题

以上是关于条纹支付元素和一页结账 - 啥是正确的支付流程?的主要内容,如果未能解决你的问题,请参考以下文章

带有订阅和试用期的条纹支付元素

支付宝错误。此交易无效。请返回收款人的网站以使用他们的常规结账流程完成您的交易

小wordpress上的条纹支付图标

条纹支付链接

条纹支付示例未显示

条纹支付 APIConnection 错误