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

Flutter Web中如何优雅监听Stripe Checkout支付状态?

Flutter Web集成Stripe:替代轮询的优雅支付状态监听方案

问题背景

我在Flutter Web应用中集成Stripe,已创建Stripe Checkout会话与Firebase云函数,通过url_launcher包可打开支付页面,但无法掌控后续支付状态。目前采用轮询Stripe API的方式查询支付状态,代码如下:

do {
  res = await http.get(Uri.parse("https://api.stripe.com/v1/checkout/sessions/XXXUUUU"), headers: headers);
  if (res.statusCode != 200)
  throw Exception('http.post error: statusCode= ${res.statusCode}');
  else {
    risultato = jsonDecode(res.body);
    print(risultato["payment_status"]);
    await Future.delayed(Duration(seconds: 2));
  }
} while ((risultato["payment_status"] == "unpaid") || !pagamentoInCorso);

想了解是否有更优雅的实现方式,比如使用Stream?


优雅实现方案

1. 用Stream封装轮询逻辑

把轮询逻辑包装成Stream,利用响应式特性简化UI层状态监听,比原生循环更易维护:

Stream<String> pollPaymentStatus(String sessionId, Map<String, String> headers) async* {
  bool keepPolling = true;
  while (keepPolling) {
    try {
      final res = await http.get(
        Uri.parse("https://api.stripe.com/v1/checkout/sessions/$sessionId"),
        headers: headers,
      );
      if (res.statusCode != 200) {
        throw Exception('http.get error: statusCode= ${res.statusCode}');
      }
      final data = jsonDecode(res.body);
      final status = data["payment_status"] as String;
      yield status;
      
      // 状态达标或支付取消时停止轮询
      if (status == "paid" || !pagamentoInCorso) {
        keepPolling = false;
      } else {
        await Future.delayed(const Duration(seconds: 2));
      }
    } catch (e) {
      yield "error";
      await Future.delayed(const Duration(seconds: 2));
    }
  }
}

// 使用示例
pollPaymentStatus("XXXUUUU", headers).listen((status) {
  switch(status) {
    case "paid":
      // 处理支付成功逻辑
      break;
    case "unpaid":
      // 显示支付中状态
      break;
    case "error":
      // 处理请求错误
      break;
  }
});

2. Stripe Webhook + Firebase实时数据库/Cloud Firestore(推荐)

完全替代轮询,实现状态实时推送:

  • 在Stripe后台配置Webhook,监听checkout.session.completed、checkout.session.expired事件,将接收地址指向你的Firebase云函数。
  • 云函数收到Stripe事件后,把支付状态写入Firebase实时数据库或Cloud Firestore对应文档。
  • Flutter Web端监听数据库中会话ID对应的状态变化:
// 监听Firestore中支付状态更新
FirebaseFirestore.instance
  .collection("payment_sessions")
  .doc("XXXUUUU")
  .snapshots()
  .listen((snapshot) {
    if (snapshot.exists) {
      final status = snapshot.data()?["payment_status"];
      if (status == "paid") {
        // 执行支付成功逻辑
      } else if (status == "expired") {
        // 处理会话过期逻辑
      }
    }
  });

这种方式无需前端主动请求,状态更新及时且减少API调用量。

3. 利用Checkout会话重定向特性

创建Checkout会话时,配置success_url和cancel_url为你的Flutter Web应用路由(例如https://yourapp.com/payment-success?session_id={CHECKOUT_SESSION_ID})。用户支付完成/取消后会跳转回应用,在对应路由页面通过session_id一次性查询支付状态即可,无需轮询。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:06:02