Flutter集成Stripe支付报错:No payment sheet has been initialized yet
Flutter集成Stripe支付报错"No payment sheet has been initialized yet"解决方案
问题根源分析
Payment Intent Client Secret取值错误
在initPaymentSheet参数中,你错误地使用['client_secret'].join('')作为client secret值,这只是字符串"client_secret",而非从paymentIntentData中获取的真实密钥,导致支付表单无法正确初始化。未校验Payment Intent创建结果
若createPaymentIntent请求失败返回null,后续初始化会传入无效的client secret,直接导致初始化失败。流程逻辑不严谨
未确保initPaymentSheet执行成功就调用displayPaymentSheet,可能出现初始化未完成就展示表单的情况。
修改后的完整代码
支付方法代码
Future<void> makePayment() async { try { paymentIntentData = await createPaymentIntent('20', 'USD'); // 校验Payment Intent是否创建成功并包含client_secret if (paymentIntentData == null || !paymentIntentData!.containsKey('client_secret')) { print('创建Payment Intent失败或缺少必要参数'); return; } // 正确初始化支付表单 await Stripe.instance.initPaymentSheet( paymentSheetParameters: SetupPaymentSheetParameters( paymentIntentClientSecret: paymentIntentData!['client_secret'], style: ThemeMode.light, merchantDisplayName: 'John', ), ); // 确保初始化完成后再展示表单 await displayPaymentSheet(); } catch (e) { if (kDebugMode) { print('初始化支付表单出错: ${e.toString()}'); } } } displayPaymentSheet() async { try { await Stripe.instance.presentPaymentSheet(); // 支付成功逻辑 if (kDebugMode) { print('payment intent${paymentIntentData!['id']}'); print('payment intent${paymentIntentData!['client_secret']}'); print('payment intent${paymentIntentData!['amount']}'); print('payment intent$paymentIntentData'); } ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("恭喜您购买了20个积分")), ); paymentIntentData = null; } on StripeException catch (e) { if (kDebugMode) { print('Exception/DISPLAYPAYMENTSHEET==> $e'); } showDialog( context: context, builder: (_) => const AlertDialog( content: Text("支付已取消"), ), ); } catch (e) { print('支付出错: $e'); } } createPaymentIntent(String amount, String currency) async { try { Map<String, dynamic> body = { 'amount': calculateAmount(amount), 'currency': currency, 'payment_method_types[]': 'card' }; var response = await http.post( Uri.parse('https://api.stripe.com/v1/payment_intents'), body: body, headers: { 'Authorization': 'Bearer sk_test_key', // 替换为你的真实测试Secret Key 'Content-Type': 'application/x-www-form-urlencoded' }, ); final data = jsonDecode(response.body.toString()); // 捕获Stripe API返回的错误 if (data.containsKey('error')) { print('Stripe API错误: ${data['error']['message']}'); return null; } return data; } catch (e) { print('创建Payment Intent异常: ${e.toString()}'); return null; } } calculateAmount(String amount) { final price = int.parse(amount) * 100; return price.toString(); }
main文件代码(无需修改,注意密钥有效性)
void main() async { WidgetsFlutterBinding.ensureInitialized(); Stripe.publishableKey = 'pk_test_'; // 替换为你的真实测试Publishable Key Stripe.merchantIdentifier = 'any string works'; await Stripe.instance.applySettings(); runApp(const MyApp()); }
额外注意事项
- 确保Stripe测试密钥(Secret Key和Publishable Key)真实有效,且未切换到生产模式。
- 测试前打印
paymentIntentData,确认返回结果包含client_secret字段。 - 保证设备网络正常,能够访问Stripe API。
内容的提问来源于stack exchange,提问作者Rashid Ali
相关产品推荐
相关产品推荐

