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

Flutter WebView中获取Stripe支付响应及页面跳转问题

Flutter Stripe支付:解决result.id为空及支付后返回原页面问题

1. 解决result.id返回null的问题

你当前代码中result.id为空的核心原因是redirectToCheckout是异步方法,未使用await等待异步操作完成,直接拿到的是Future对象而非实际会话结果。

修正后的代码:

void redirectToCheckout(BuildContext _, var plan) async {
  final stripe = Stripe(apiKey);
  // 加入await等待异步操作结束
  final result = await stripe.redirectToCheckout(CheckoutOptions(
    lineItems: [
      LineItem(price: plan, quantity: 1),
    ],
    clientReferenceId: '1',
    mode: 'payment',
    successUrl: 'https://localhost:8080/#/success/{CHECKOUT_SESSION_ID}', 
    cancelUrl: 'https://localhost:8080/#/cancel',
  ));
  if (result != null) {
    print(result.id); // 现在能正确输出会话ID
  }
}

注:即便修正异步调用,redirectToCheckout仍无法直接获取支付完成后的最终状态,需结合WebView拦截或后端Webhook实现。

2. 支付完成后返回Flutter页面并获取支付详情

要实现不跳转外部successUrl而是返回原页面,需通过WebView导航拦截+Stripe会话查询来实现:

实现思路

  • 用自定义协议(如stripe://success)替代外部跳转URL,方便WebView拦截
  • 提前创建支付会话获取ID,后续用于查询支付详情
  • 拦截WebView的跳转请求,检测到自定义协议时终止跳转,返回原页面并查询会话状态

示例代码(基于webview_flutter)

import 'package:webview_flutter/webview_flutter.dart';
import 'package:stripe_platform_interface/stripe_platform_interface.dart';

void launchStripeCheckout(BuildContext context, String plan) async {
  final stripe = Stripe(apiKey);
  // 前端创建支付会话(建议后端创建,避免API密钥暴露)
  final session = await stripe.createCheckoutSession(CheckoutSessionCreateParams(
    lineItems: [LineItemParams(price: plan, quantity: 1)],
    mode: 'payment',
    successUrl: 'stripe://success', // 自定义拦截协议
    cancelUrl: 'stripe://cancel',
    clientReferenceId: '1',
  ));

  // 跳转至WebView加载Stripe Checkout页面
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (context) => WebView(
        initialUrl: 'https://checkout.stripe.com/pay/${session.id}',
        javascriptMode: JavascriptMode.unrestricted,
        navigationDelegate: (NavigationRequest request) {
          // 拦截成功跳转
          if (request.url.startsWith('stripe://success')) {
            _fetchPaymentSession(session.id);
            Navigator.pop(context); // 返回原Flutter页面
            return NavigationDecision.prevent;
          }
          // 拦截取消跳转
          if (request.url.startsWith('stripe://cancel')) {
            Navigator.pop(context);
            return NavigationDecision.prevent;
          }
          return NavigationDecision.navigate;
        },
      ),
    ),
  );
}

// 查询支付会话详情,获取支付状态等信息
Future<void> _fetchPaymentSession(String sessionId) async {
  final stripe = Stripe(apiKey);
  final session = await stripe.retrieveCheckoutSession(sessionId);
  
  print('支付会话ID:${session.id}');
  print('支付状态:${session.status}');
  print('支付Intent ID:${session.paymentIntent}');
  print('总金额:${session.amountTotal}');
  
  // 此处可添加支付成功后的业务逻辑,如更新本地状态、提示用户等
}

关键注意事项

  • 自定义协议需确保不会与系统或其他应用的协议冲突
  • 生产环境建议通过后端创建支付会话,前端仅获取会话ID,避免API密钥泄露
  • 若需更可靠的支付状态通知,可在Stripe后台配置Webhook,支付完成后由后端主动通知前端

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:54:36