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

Flutter集成Stripe报错:List<dynamic>无法转为Map<String, dynamic>?

问题解决:type 'List' is not a subtype of type 'Map<String, dynamic>?'

这个错误的核心原因是你的createPaymentIntent函数中,jsonDecode(response.body)返回的是List类型数据,但函数声明的返回值是Map<String, dynamic>?,类型不匹配导致后续流程抛出异常。

解决步骤:

  1. 修正返回数据类型转换
    检查后端接口返回的JSON结构,如果返回的是包裹在数组中的支付意图对象(格式类似[{...paymentIntentData...}]),需要从数组中提取第一个元素;如果接口返回的是单个对象,直接转换即可。修改stripe_api.dart代码:

    Future<Map<String, dynamic>?> createPaymentIntent() async {
      try {
        var response = await postAPIAuthenticated('path');
        final decodedResponse = jsonDecode(response.body);
        
        // 处理返回为数组的情况
        if (decodedResponse is List) {
          return decodedResponse.isNotEmpty 
              ? decodedResponse.first as Map<String, dynamic> 
              : null;
        }
        
        // 返回为单个对象的情况
        return decodedResponse as Map<String, dynamic>?;
      } catch (err) {
        throw Exception(err);
      }
    }
    
  2. 增加空值校验(可选但推荐)
    在初始化支付表单前,确保client_secret不为空,避免潜在的空指针问题,修改stripe_bloc.dart中的逻辑:

    void _onRequestedStripePaymentEvent(RequestedStripePaymentEvent event,
        Emitter<StripeState> emit) async {
      try {
        final Map<String, dynamic>? paymentIntent = await createPaymentIntent();
        final clientSecret = paymentIntent?['client_secret'];
        
        // 校验clientSecret是否有效
        if (clientSecret == null) {
          // 这里可以emit错误状态,提示用户支付初始化失败
          emit(StripePaymentFailedState('支付参数获取失败'));
          return;
        }
        
        await Stripe.instance.initPaymentSheet(
          paymentSheetParameters: SetupPaymentSheetParameters(
            paymentIntentClientSecret: clientSecret,
            // 补充必填的商户名称参数,避免初始化异常
            merchantDisplayName: '你的商户名称',
          ),
        );
        await Stripe.instance.presentPaymentSheet();
        // 支付成功后的逻辑,比如emit成功状态
        emit(const StripePaymentSuccessState());
      } on StripeException catch (e) {
        if (e.error.code == FailureCode.Canceled) {
          emit(const StripePaymentCanceledState());
        }
        if (e.error.code == FailureCode.Failed ||
            e.error.code == FailureCode.Timeout) {
          emit(StripePaymentFailedState(e.error.message ?? '支付失败'));
        }
      } catch (e) {
        // 捕获其他类型的异常
        emit(StripePaymentFailedState(e.toString()));
      } finally {
        // 可以在这里处理一些收尾逻辑
      }
    }
    

补充说明:

虽然你提到后端在Stripe仪表盘中显示支付意图正常,但接口返回的JSON结构不符合前端的预期(返回了数组而非单个对象),这是导致类型转换错误的根本原因,和Stripe SDK本身无关。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 10:03:11