使用MVC Core条纹“无此付款”错误

时间:2020-10-23 14:12:07

标签: c# asp.net-core-mvc stripe-payments

我正在尝试将Stripe实现到我的MVC Core项目中,并收到此错误:“无此付款方式:pm_xxx”。我想接受同步付款。我在这里做错什么了吗?我已经能够将错误跟踪到paymentIntentService Create函数,并且该错误显示在局部视图中。

HTML:

    <link rel="stylesheet" href="~/css/payment_client_global.css" />
<section>
    <form id="payment-form" class="sr-payment-form">
        <div class="sr-combo-inputs-row">
            <div class="sr-input sr-card-element" id="card-element"></div>
        </div>
        <div class="sr-field-error" id="card-errors" role="alert"></div>
        <button id="submit">
            <div class="spinner hidden" id="spinner"></div>
            <span id="button-text">Pay</span><span id="order-amount"></span>
        </button>
    </form>
    <div class="sr-result hidden">
        <p>Payment completed<br /></p>
        <pre>
        <code></code>
          </pre>
    </div>
</section>

<script>
    // A reference to Stripe.js
    var stripe;

    var orderData = {
        items: [{ id: "prod_IFwyjFBhip0bTF" }],
        currency: "usd"
    };

    // Disable the button until we have Stripe set up on the page
    document.querySelector("button").disabled = true;

    fetch("/stripe-key")
        .then(function (result) {
            return result.json();
        })
        .then(function (data) {
            return setupElements(data);
        })
        .then(function ({ stripe, card, clientSecret }) {
            document.querySelector("button").disabled = false;

            var form = document.getElementById("payment-form");
            form.addEventListener("submit", function (event) {
                event.preventDefault();
                pay(stripe, card, clientSecret);
            });
        });

    var setupElements = function (data) {
        stripe = Stripe(data.publishableKey);
        /* ------- Set up Stripe Elements to use in checkout form ------- */
        var elements = stripe.elements();
        var style = {
            base: {
                color: "#32325d",
                fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                fontSmoothing: "antialiased",
                fontSize: "16px",
                "::placeholder": {
                    color: "#aab7c4"
                }
            },
            invalid: {
                color: "#fa755a",
                iconColor: "#fa755a"
            }
        };

        var card = elements.create("card", { style: style });
        card.mount("#card-element");
        alert(data.clientSecret); //TEST
        return {
            stripe: stripe,
            card: card,
            clientSecret: data.clientSecret
        };
    };

    var handleAction = function (clientSecret) {
        stripe.handleCardAction(clientSecret).then(function (data) {
            if (data.error) {
                showError("Your card was not authenticated, please try again");
            } else if (data.paymentIntent.status === "requires_confirmation") {
                fetch("/pay", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json"
                    },
                    body: JSON.stringify({
                        paymentIntentId: data.paymentIntent.id
                    })
                })
                    .then(function (result) {
                        return result.json();
                    })
                    .then(function (json) {
                        if (json.error) {
                            showError(json.error);
                        } else {
                            orderComplete(clientSecret);
                        }
                    });
            }
        });
    };

    /*
     * Collect card details and pay for the order
     */
    var pay = function (stripe, card) {
        changeLoadingState(true);

        // Collects card details and creates a PaymentMethod
        stripe
            .createPaymentMethod("card", card)
            .then(function (result) {
                if (result.error) {
                    showError(result.error.message);
                } else {
                    orderData.paymentMethodId = result.paymentMethod.id;

                    return fetch("/pay", {
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json"
                        },
                        body: JSON.stringify(orderData)
                    });
                }
            })
            .then(function (result) {
                return result.json();
            })
            .then(function (response) {
                if (response.error) {
                    showError(response.error);
                } else if (response.requiresAction) {
                    // Request authentication
                    handleAction(response.clientSecret);
                } else {
                    orderComplete(response.clientSecret);
                }
            });
    };

    /* ------- Post-payment helpers ------- */

    /* Shows a success / error message when the payment is complete */
    var orderComplete = function (clientSecret) {
        stripe.retrievePaymentIntent(clientSecret).then(function (result) {
            var paymentIntent = result.paymentIntent;
            var paymentIntentJson = JSON.stringify(paymentIntent, null, 2);

            document.querySelector(".sr-payment-form").classList.add("hidden");
            document.querySelector("pre").textContent = paymentIntentJson;

            document.querySelector(".sr-result").classList.remove("hidden");
            setTimeout(function () {
                document.querySelector(".sr-result").classList.add("expand");
            }, 200);

            changeLoadingState(false);
        });
    };

    var showError = function (errorMsgText) {
        changeLoadingState(false);
        var errorMsg = document.querySelector(".sr-field-error");
        errorMsg.textContent = errorMsgText;
        setTimeout(function () {
            errorMsg.textContent = "";
        }, 4000);
    };

    // Show a spinner on payment submission
    var changeLoadingState = function (isLoading) {
        if (isLoading) {
            document.querySelector("button").disabled = true;
            document.querySelector("#spinner").classList.remove("hidden");
            document.querySelector("#button-text").classList.add("hidden");
        } else {
            document.querySelector("button").disabled = false;
            document.querySelector("#spinner").classList.add("hidden");
            document.querySelector("#button-text").classList.remove("hidden");
        }
    };
</script>

控制器:

    [Route("/pay")]
public class ConfirmPaymentController : Controller
{
    public IActionResult Index([FromBody] ConfirmPaymentRequest request)
    {
        var paymentIntentService = new PaymentIntentService();
        PaymentIntent paymentIntent = null;

        try
        {
            if (request.PaymentMethodId != null)
            {
                // Create the PaymentIntent
                var createOptions = new PaymentIntentCreateOptions
                {
                    Amount = 1099,
                    Currency = "cad",

                    ConfirmationMethod = "manual",
                    PaymentMethodTypes = new List<string> { "card" },
                    PaymentMethod = request.PaymentMethodId,
                    Confirm = true,
                };
                paymentIntent = paymentIntentService.Create(createOptions);
            }
            else if (request.PaymentIntentId != null)
            {
                var confirmOptions = new PaymentIntentConfirmOptions { };
                paymentIntent = paymentIntentService.Confirm(
                    request.PaymentIntentId,
                    confirmOptions
                );
            }
        }
        catch (StripeException e)
        {
            return Json(new { error = e.StripeError.Message });
        }
        return generatePaymentResponse(paymentIntent);
    }

    [HttpGet]
    [Route("/stripe-key")]
    public JsonResult StripeKey()
    {
        return new JsonResult(new StripeKeyResponse("[my pk_test here]"));
    }

    private IActionResult generatePaymentResponse(PaymentIntent intent)
    {
        // Note that if your API version is before 2019-02-11, 'requires_action'
        // appears as 'requires_source_action'.
        if (intent.Status == "requires_action" &&
            intent.NextAction.Type == "use_stripe_sdk")
        {
            // Tell the client to handle the action
            return Json(new
            {
                requires_action = true,
                payment_intent_client_secret = intent.ClientSecret
            });
        }
        else if (intent.Status == "succeeded")
        {
            // The payment didn’t need any additional actions and completed!
            // Handle post-payment fulfillment
            return Json(new { success = true });
        }
        else
        {
            // Invalid status
            return StatusCode(500, new { error = "Invalid PaymentIntent status" });
        }
    }
}

0 个答案:

没有答案