【问题标题】:Stripe Redirect After Event事件后的条带重定向
【发布时间】:2020-07-18 09:35:10
【问题描述】:

我正在使用 .NET 和 Stripe 创建一个网上商店,并且我正在尝试弄清楚如何在收费成功后将客户重定向到成功页面。然而,Stripe 最近更改了他们的 API,我一直无法在网上找到任何资源来解释如何做到这一点。

我尝试创建一个监听 charge.succeeded 事件的 webhook,我可以触发该事件,但我无法从 webhook 将客户重定向到任何页面。

我尝试过的另一件事是在结帐页面中,我在表单中添加了 method="post",并分别在按钮中添加了 type="submit" 和 formmethod="post",这样当客户点击“付款”,客户通过结帐页面的 post 方法重定向,但我无法运行 post 方法。

结帐剃须刀页面:

    <head>
        <title>Checkout</title>
        <script src="https://js.stripe.com/v3/"></script>
    </head>

<--! This is where I've tried method="post", type="submit" and formmethod="post" -->
    <form id="payment-form">
        <div id="card-element">
            <!-- Elements will create input elements here -->
        </div>

        <!-- We'll put the error messages in this element -->
        <div id="card-errors" role="alert"></div>

        <button id="submit">Pay</button>
    </form>

@section scripts{
    <script>
        // Set your publishable key: remember to change this to your live publishable key in production
        // See your keys here: https://dashboard.stripe.com/account/apikeys
        var stripe = Stripe('{PUBLIC KEY}');
        var elements = stripe.elements();

        window.onload = function () {
            // Set up Stripe.js and Elements to use in checkout form
            var style = {
                base: {
                    color: "#32325d",
                }
            };

            var card = elements.create("card", { style: style });
            card.mount("#card-element");


            card.addEventListener('change', function (event) {
                var displayError = document.getElementById('card-errors');
                if (event.error) {
                    displayError.textContent = event.error.message;
                } else {
                    displayError.textContent = '';
                }
            });

            var form = document.getElementById('payment-form');

            form.addEventListener('submit', function (ev) {
                ev.preventDefault();
                stripe.confirmCardPayment('@Model.ClientSecret', {
                    payment_method: {
                        card: card,
                        billing_details: {
                            name: '@Model.CustomerInformation.FirstName',
                            email: '@Model.CustomerInformation.Email',
                            address: {
                                city: '@Model.CustomerInformation.City',
                                line1: '@Model.CustomerInformation.Address1',
                                postal_code: '@Model.CustomerInformation.ZipCode'
                            }
                        }
                    }
                }).then(function (result) {
                    if (result.error) {
                        // Show error to your customer (e.g., insufficient funds)
                        console.log(result.error.message);
                    } else {
                        // The payment has been processed!
                        if (result.paymentIntent.status === 'succeeded') {
                            // Show a success message to your customer
                            // There's a risk of the customer closing the window before callback
                            // execution. Set up a webhook or plugin to listen for the
                            // payment_intent.succeeded event that handles any business critical
                            // post-payment actions.
                        }
                    }
                });
            });
        };
    </script> 

网络钩子:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Stripe;

namespace workspace.Controllers
{
    [Route("api/[controller]")]
    public class StripeWebHook : Controller
    {
        // If you are testing your webhook locally with the Stripe CLI you
        // can find the endpoint's secret by running `stripe listen`
        // Otherwise, find your endpoint's secret in your webhook settings in the Developer Dashboard
        const string endpointSecret = "ENDPOINT SECRET";

        [HttpPost]
        public async Task<IActionResult> Index()
        {
            var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();

            try
            {
                var stripeEvent = EventUtility.ParseEvent(json);

                // Handle the event
                if (stripeEvent.Type == Events.PaymentIntentSucceeded)
                {
                    var paymentIntent = stripeEvent.Data.Object as PaymentIntent;

                    Console.WriteLine("Successful!");
                    return Ok();
                }
                else if (stripeEvent.Type == Events.ChargeSucceeded)
                {
                    Console.WriteLine("Successful!");
                    // This is where I've tried return RedirectToPage("/Index");
                    return Ok();
                }
                else if (stripeEvent.Type == Events.PaymentIntentCreated)
                {
                    Console.WriteLine("Successful!");
                    return Ok();
                }
                else if (stripeEvent.Type == Events.PaymentMethodAttached)
                {
                    var paymentMethod = stripeEvent.Data.Object as PaymentMethod;
                    Console.WriteLine("PaymentMethod was attached to a Customer!");
                }
                // ... handle other event types
                else
                {
                    // Unexpected event type
                    return BadRequest();
                } 

                return Ok();
            }
            catch (StripeException e)
            {
                return BadRequest();
            }
        }
    }
}

【问题讨论】:

    标签: c# .net stripe-payments e-commerce


    【解决方案1】:

    我认为我们应该首先解决一些概念。 webhook 端点是一个独立的 API,它存在于您系统中的某个位置,并对从 Stripe 发布到它的事件做出反应,例如 charge.succeeded 事件。

    您在浏览器中的 Elements 实现是完全独立的,无法响应您的 webhook 端点可以返回的任何 HTTP 代码(重定向等)。

    要直接回答您的核心问题,请在表示付款已成功处理的 else 块中的 Javascript 中,您可以调用 [0]

    location.href = "https://your-success-page.com"
    

    ... 将用户发送到成功页面。表单不会提交的原因是因为表单的提交事件被ev.preventDefault();阻止了。

    这里详细记录了整个流程 [1][2]。

    希望这会有所帮助!

    [0]https://developer.mozilla.org/en-US/docs/Web/API/Window/location

    [1]https://stripe.com/docs/payments/accept-a-payment

    [2]https://stripe.com/docs/webhooks

    【讨论】:

    • 太棒了,谢谢! webhook 端点是否适合处理,例如向客户发送一封包含购买收据的电子邮件?
    • 好吧,如果您愿意,Stripe 会自动向客户发送收据 [0],如果您愿意,您也可以自己处理。不过,Webhook 端点绝对是针对这类事情的,即在您的数据库中记录付款状态、履行订单等。 [0] stripe.com/docs/receipts
    • 太棒了!非常感谢!然而,一个问题是我无法从 webhook 访问存储在会话中的购物车或客户信息,因为会话在 webhook 运行的方法中发生了变化。详细解释请看我的另一篇帖子:stackoverflow.com/questions/61080662/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 2017-07-29
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    相关资源
    最近更新 更多