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

Flutter集成Stripe支付后导航报错:上下文已失效问题

问题描述

我做了一个BottomSheet,点击按钮即可关闭。但在Stripe支付场景中,若在调用presentPaymentSheet前执行Navigator.of(context).pop()关闭BottomSheet,完成Stripe支付表单提交后,当前上下文已不再活跃,无法跳转至新路由。

相关代码

// 1. create payment intent on the server
final response = await http.post(
    Uri.parse(
        'https://stripe//'),
    body: {
        'email': email,
        'amount': amount.toString(),
    });

final jsonResponse = jsonDecode(response.body);
//log(jsonResponse.toString());

//2. initialize the payment sheet
await stripe.Stripe.instance.initPaymentSheet(
    paymentSheetParameters: stripe.SetupPaymentSheetParameters(
        // Enable custom flow
        customFlow: true,
        // Main params
        paymentIntentClientSecret: jsonResponse['paymentIntent'],
        merchantDisplayName: 'GamRelay',
        // Customer keys
        customerId: jsonResponse['customer'],
        customerEphemeralKeySecret: jsonResponse['ephemeralKey'],
        // Extra options
        //applePay: true,
        //googlePay: true,
        style: ThemeMode.dark,
        //testEnv: true,
        //merchantCountryCode: 'SG',
    ),
);


Navigator.of(context).pop(); 

await stripe.Stripe.instance.presentPaymentSheet();


Navigator.of(context).pushAndRemoveUntil(
    MaterialPageRoute(builder: (BuildContext context) => MainScreen()),
    (Route<dynamic> route) => false);

Navigator.of(context).push(MaterialPageRoute(
    builder: (BuildContext context) => ShippingConfirmation()));

相关截图

  • BottomSheet截图:BottomSheet截图
  • 支付完成后报错截图:报错截图
解决方案

问题核心是关闭BottomSheet后,原context已绑定到被弹出的BottomSheet路由,不再属于活跃的上下文环境。以下两种方案可解决:

方案1:使用根导航器上下文

操作导航时指定rootNavigator: true,确保使用的是根导航器而非BottomSheet的局部导航上下文:

// 关闭BottomSheet时使用根导航器
Navigator.of(context, rootNavigator: true).pop(); 

await stripe.Stripe.instance.presentPaymentSheet();

// 路由跳转同样使用根导航器
Navigator.of(context, rootNavigator: true).pushAndRemoveUntil(
    MaterialPageRoute(builder: (BuildContext context) => MainScreen()),
    (Route<dynamic> route) => false);

Navigator.of(context, rootNavigator: true).push(MaterialPageRoute(
    builder: (BuildContext context) => ShippingConfirmation()));

方案2:调整流程顺序

先完成支付操作,再关闭BottomSheet并跳转路由:

// 先执行支付,不提前关闭BottomSheet
await stripe.Stripe.instance.presentPaymentSheet();

// 支付成功后再关闭BottomSheet并跳转
Navigator.of(context).pop(); 
Navigator.of(context).pushAndRemoveUntil(
    MaterialPageRoute(builder: (BuildContext context) => MainScreen()),
    (Route<dynamic> route) => false);

Navigator.of(context).push(MaterialPageRoute(
    builder: (BuildContext context) => ShippingConfirmation()));

额外提示

你的代码中pushAndRemoveUntil已经移除所有前置路由并跳转到MainScreen,后续的push(ShippingConfirmation())大概率不会生效,建议调整路由逻辑——比如直接跳转至ShippingConfirmation并清除前置路由,或在MainScreen内部处理跳转逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:13:18