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

Flutter移动端WebView嵌入Stripe Checkout遇页面缺失问题求助

Flutter移动端通过WebView集成Stripe Checkout报错排查

已使用flutter_stripe插件实现移动端表单支付,但因需要支持仅在Web/Checkout端可用的MobilePay支付方式,尝试通过WebView嵌入Stripe Checkout会话,但访问生成的URL时出现提示:出错了 - 找不到您要访问的页面,请检查URL或联系商家。

服务端代码

Stripe会话创建代码片段

const session = await stripe.checkout.sessions.create({
  ui_mode: config.checkout.embedded ? 'embedded' : 'hosted',
  expires_at: Math.floor(DateTime.now().plus({ minutes: 30 }).toSeconds()), // expire this session after 30 minutes
  locale: preferredLocale,
  line_items: [
    {
      price_data: {
        currency: quotation.currency,
        unit_amount: Math.round(quotation.amount * 100),  // amount in cents
        product_data: {
          name: config.checkout.productName,
          description: config.checkout.productDescription,
        }
      },
      quantity: 1,
    },
  ],
  mode: 'payment',
  payment_intent_data: {
    metadata,
  },
  redirect_on_completion: config.checkout.embedded ? 'never' : undefined,
  success_url: config.checkout.embedded ? undefined
    : `${config.checkout.successUrl}?session_id={CHECKOUT_SESSION_ID}`,
});

返回数据

sessionId: session.id,
clientSecret: session.client_secret ?? undefined,

Flutter前端代码

获取会话并配置WebView的代码

Future<bool> beginStripePayment() async {
  Apis apis = Apis();
  try {
    Map<String, dynamic> response = json.decode(
        await apis.createStripePaymentSession(
            widget.quoteId));
    clientSecret = response["clientSecret"];
    checkoutUrl = 'https://checkout.stripe.com/pay/$clientSecret';
    debugPrint(checkoutUrl);
    controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse(checkoutUrl));
    return Future.value(true);
  } catch (e) {
    debugPrint(e.toString());
  }
  return Future.value(false);
}

@override
Widget build(BuildContext context) {
  return FutureBuilder<bool>(
    future: pageInitialization,
    builder: (context, snapshot) {
      if (snapshot.data == true) {
        return SizedBox(
            height: commonFunctions.getTotalHeightDividedByPassedValue(
                context, 2),
            width:
                commonFunctions.getTotalWidthDividedByPassedValue(context, 2),
            child: WebViewWidget(
              controller: controller,
              gestureRecognizers: Set()
                ..add(Factory(() => VerticalDragGestureRecognizer())),
            ));
      } else {
        return Container(
          color: Colors.white,
          child: centeredLoadingIndicator(context,
          ),
        );
      }
    },
  );
}

请问问题是出在URL、密钥配置,还是需要其他额外步骤才能让WebView中的Checkout会话正常工作?Web端使用自定义Stripe UI元素生成URL,希望不需要进行类似操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:34:55