You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 8 MVC项目嵌入式Stripe支付初始化异常求助

问题排查:Stripe嵌入式支付表单初始化失败

背景

正在为Stripe关联账户开发嵌入式支付表单,已在Program.cs中配置好测试API密钥,后端StripeCheckoutSession端点可正常返回Client Secret,但前端初始化流程异常。

后端控制器代码

[HttpGet]
[AllowAnonymous]
public ContentResult StripeCheckoutSession()
{
        var options = new Stripe.Checkout.SessionCreateOptions
        {
            LineItems = new List<Stripe.Checkout.SessionLineItemOptions>
        {
            new Stripe.Checkout.SessionLineItemOptions
            {
                PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions
                {
                    Currency = "aud",
                    ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions
                    {
                        Name = "T-shirt",
                    },
                    UnitAmount = 1000,
                },
                Quantity = 1,
            },
        },
            PaymentIntentData = new Stripe.Checkout.SessionPaymentIntentDataOptions
            {
                ApplicationFeeAmount = 123,
            },
            Mode = "payment",
            UiMode = "embedded",
            ReturnUrl = "abc={CHECKOUT_SESSION_ID}"
        };
        var requestOptions = new RequestOptions
        {
            StripeAccount = "acct_12345...";
        };
        var service = new SessionService();
        Session session = service.Create(options, requestOptions);
        return Content(JsonConvert.SerializeObject(session.ClientSecret));
}

前端基础配置

  • 引入Stripe.js:
<script src="https://js.stripe.com/v3/"></script>
  • 页面挂载容器:
<div id="checkout"></div>

前端JS代码及问题现象

修改后的JS代码:

<script type="text/javascript">
    // initialize Stripe.js
    const stripe = Stripe('pk_test_blah...', {
        stripeAccount: '@Model.StripeAccountID',
    });

    $(document).ready(function () {
        initialize();
    })

    // fetch checkout session and retrieve the client secret
    async function initialize() {
        try {
            alert('Start');
            const fetchClientSecret = async () => {
                const response = await fetch("StripeCheckoutSession", {
                    method: "GET",
                });
                const { clientSecret } = await response.json();
                return clientSecret;
            };
            // initialize checkout
            alert('Init checkout');
            const checkout = await stripe.initEmbeddedCheckout({
                fetchClientSecret,
            });
            // mount checkout
            alert('Finish mount');
            checkout.mount('#checkout');
        }
        catch (err) {
            alert(err);
        }
    }
</script>

运行后可触发alert('Start')和alert('Finish mount'),但alert('Init checkout')从未触发,单独用AJAX获取Client Secret后仍无法完成Checkout初始化。


问题根因分析及解决方案

1. 后端返回格式错误(核心问题)

后端直接序列化并返回session.ClientSecret字符串,返回内容为类似"cs_test_xxxx"的纯JSON字符串,但前端尝试解构clientSecret字段:

const { clientSecret } = await response.json();

这会导致解构失败抛出错误,代码直接进入catch块,跳过alert('Init checkout')。

解决方案:修改后端返回格式,返回包含clientSecret字段的JSON对象:

// 替换原return语句
return Json(new { clientSecret = session.ClientSecret });

2. 错误捕获不清晰

当前catch块仅用alert(err)提示错误,无法展示具体错误信息(如解构失败、请求404等)。

解决方案:优化错误提示,在控制台打印详细错误:

catch (err) {
    console.error('初始化失败:', err);
    alert('初始化失败,请查看控制台日志');
}

3. Fetch请求路径可能不正确

fetch("StripeCheckoutSession")使用相对路径时,可能因页面路由问题导致请求404,需确保路径指向正确的控制器端点。

解决方案:使用完整相对路径,例如:

const response = await fetch("/YourControllerName/StripeCheckoutSession", { method: "GET" });

4. Stripe初始化参数验证

  • 确认pk_test_blah...是平台账户的公钥,而非关联账户的公钥
  • 确认@Model.StripeAccountID输出的是正确格式的关联账户ID(以acct_开头)

内容的提问来源于stack exchange,提问作者Ross Kelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:47:33