Flutter集成Stripe Payment Intent遇阻:flutter_stripe v7.0.0需密钥但密钥在后端
解决方案:flutter_stripe v7.0.0 集成 Payment Intent 流程
1. 前端基础配置
- 仅在Flutter项目中配置Stripe的Publishable Key(可从Stripe控制台获取,该密钥可安全暴露在前端):
import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化Stripe SDK,仅传入Publishable Key Stripe.publishableKey = 'pk_test_xxxxxx'; await Stripe.instance.applySettings(); runApp(const MyApp()); } - 绝对不要在前端代码中使用Stripe的Secret Key,所有涉及Secret Key的操作必须由后端完成。
2. 后端创建Payment Intent(核心步骤)
后端通过Stripe官方SDK调用API创建Payment Intent,生成clientSecret后返回给前端。以下是Node.js示例:
const stripe = require('stripe')('sk_test_xxxxxx'); // 此处使用后端管控的Secret Key // 后端API接口,供前端调用获取clientSecret app.post('/create-payment-intent', async (req, res) => { const { amount, currency } = req.body; const paymentIntent = await stripe.paymentIntents.create({ amount: amount, // 金额单位为分,如1000代表10美元 currency: currency, automatic_payment_methods: { enabled: true }, }); res.json({ clientSecret: paymentIntent.client_secret }); });
3. 前端完成支付流程
前端先调用自有后端API获取clientSecret,再通过flutter_stripe完成支付操作:
import 'package:http/http.dart' as http; import 'dart:convert'; // 调用后端接口获取clientSecret Future<String> _getClientSecret() async { final response = await http.post( Uri.parse('https://your-backend-domain.com/create-payment-intent'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'amount': 1000, 'currency': 'usd'}), ); final data = jsonDecode(response.body); return data['clientSecret']; } // 发起支付流程 Future<void> _processPayment(BuildContext context) async { try { final clientSecret = await _getClientSecret(); // 初始化支付面板 await Stripe.instance.initPaymentSheet( paymentSheetParameters: SetupPaymentSheetParameters( paymentIntentClientSecret: clientSecret, merchantDisplayName: '你的商家名称', ), ); // 展示支付面板 await Stripe.instance.presentPaymentSheet(); // 支付成功后的处理逻辑 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('支付成功!')), ); } catch (e) { // 错误处理 if (e is StripeException) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('支付失败:${e.error.localizedMessage}')), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('未知错误:$e')), ); } } }
4. 关键注意事项
- 禁止在前端代码中硬编码或暴露Stripe Secret Key,否则会引发严重安全风险。
- 该流程是Stripe官方推荐的标准安全流程,替代了旧库stripe_payment的直接调用方式,必须严格遵循。
- 后端API需添加身份验证逻辑,防止恶意请求非法创建Payment Intent。
内容的提问来源于stack exchange,提问作者Aneeq Shah
相关产品推荐
相关产品推荐

