Flutter集成Stripe支付失败,报错‘o is not defined’求解决
Stripe支付网关集成报错:
o is not defined 解决方法 问题描述
测试Flutter+Stripe支付集成时,点击支付按钮触发错误,日志输出:[log] {success: false, error: o is not defined}。相关代码及截图如下:
Flutter端Main.dart代码
import 'dart:convert'; import 'dart:log'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:http/http.dart' as http; Future <void> main() async{ WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: FirebaseOptions(apiKey: "AIzaSyD7Uhhiv85NCcDjoTEQ-K7T5qU4bNXci8M", appId: "XXX", messagingSenderId: "XXX", projectId: "itt632-56973", )); Stripe.publishableKey = "pk_test_51LHIjvJ5bt4B4CmJ3xTspeufDqv4VojZlmhuBaVvjhUoDbJaoKziiUkFZPOTl3a4CbVcfdmnJKosItZiiweRYfvF00aOI2xKIS"; Stripe.instance.applySettings(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: Demo(), ); } } class Demo extends StatelessWidget { const Demo({Key? key}) : super(key: key); Future<void> initPayment( {required String email, required double amount, required BuildContext context}) async { try { final response = await http.post( Uri.parse( 'https://us-central1-itt632-56973.cloudfunctions.net/stripePaymentIntentRequest'), body: { 'email': email, 'amount': amount.toString(), }); final jsonResponse = jsonDecode(response.body); log(jsonResponse.toString()); await Stripe.instance.initPaymentSheet( paymentSheetParameters: SetupPaymentSheetParameters( paymentIntentClientSecret: jsonResponse['paymentIntent'], merchantDisplayName: 'Grocery Flutter course', customerId: jsonResponse['customer'], customerEphemeralKeySecret: jsonResponse['ephemeralKey'], testEnv: true, merchantCountryCode: 'SG', )); await Stripe.instance.presentPaymentSheet(); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Payment is successful'), ), ); } catch (errorr) { if (errorr is StripeException) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('An error occured ${errorr.error.localizedMessage}'), ), ); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('An error occured $errorr'), ), ); } } } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: ElevatedButton( child: const Text('Pay 50\$'), onPressed: () async { await initPayment( amount: 50.0, context: context, email: 'JEFRILUQMAN@test.com'); }, )), ); } }
Stripe云函数index.js代码
const functions = require("firebase-functions"); const stripe = require("stripe")("sk_test_51LHIjvJ5bt4B4CmJclvzNcSaSPICuutFIjmg3GZb1sv6fySDehLAhvHOW2hl1W7EWXYM5oqfHkHZyJDeB36rIJpf00ksfQJnWa"); exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => { try { let customerId; const customerList = await stripe.customers.list({ email: req.body.email, limit: 1 }); if (customerList.data.length !== 0) { customerId = customerList.data[0].id; } else { const customer = await stripe.customers.create({ email: req.body.email }); customerId = customer.data.id; } const ephemeralKey = await stripe.ephemeralKeys.create( { customer: customerId }, { apiVersion: '2020-08-27' } ); const paymentIntent = await stripe.paymentIntents.create({ amount: parseInt(req.body.amount), currency: 'usd', customer: customerId, }) res.status(200).send({ paymentIntent: paymentIntent.client_secret, ephemeralKey: ephemeralKey.secret, customer: customerId, success: true, }) } catch (error) { res.status(404).send({ success: false, error: error.message }) } });
问题截图


错误原因及修复方案
1. 云函数Customer创建逻辑错误
stripe.customers.create()返回的直接是Customer对象,不存在data属性。原代码中customerId = customer.data.id;会导致读取未定义属性,触发Stripe内部错误,最终输出模糊的o is not defined提示。
修复:
将创建Customer后的赋值代码改为:
customerId = customer.id;
2. 支付金额单位错误
Stripe要求amount参数以货币最小单位传入(美元为分)。原代码中传入50.0会被转为50,实际代表0.5美元,与按钮显示的50美元不符,可能引发支付流程异常。
修复(二选一):
- Flutter端修改:
body: { 'email': email, 'amount': (amount * 100).toStringAsFixed(0), // 转换为整数分 },
- 云函数端修改:
amount: parseInt(req.body.amount) * 100,
3. Ephemeral Key API版本兼容问题
原代码使用的API版本2020-08-27较旧,可能与当前Stripe SDK版本不兼容,导致密钥生成失败。建议更新为Stripe Dashboard中显示的最新兼容版本。
修复示例:
const ephemeralKey = await stripe.ephemeralKeys.create( { customer: customerId }, { apiVersion: '2024-06-20' } // 替换为最新版本 );
修复后的云函数完整代码
const functions = require("firebase-functions"); const stripe = require("stripe")("sk_test_51LHIjvJ5bt4B4CmJclvzNcSaSPICuutFIjmg3GZb1sv6fySDehLAhvHOW2hl1W7EWXYM5oqfHkHZyJDeB36rIJpf00ksfQJnWa"); exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => { try { let customerId; const customerList = await stripe.customers.list({ email: req.body.email, limit: 1 }); if (customerList.data.length !== 0) { customerId = customerList.data[0].id; } else { const customer = await stripe.customers.create({ email: req.body.email }); customerId = customer.id; // 修复Customer ID赋值 } const ephemeralKey = await stripe.ephemeralKeys.create( { customer: customerId }, { apiVersion: '2024-06-20' } // 更新API版本 ); const paymentIntent = await stripe.paymentIntents.create({ amount: parseInt(req.body.amount) * 100, // 修复金额单位 currency: 'usd', customer: customerId, }) res.status(200).send({ paymentIntent: paymentIntent.client_secret, ephemeralKey: ephemeralKey.secret, customer: customerId, success: true, }) } catch (error) { res.status(404).send({ success: false, error: error.message }) } });
内容的提问来源于stack exchange,提问作者JEFRI LUQMAN HAKIM JUNAIDE
相关产品推荐
相关产品推荐

