Flutter Web集成Stripe支付报错:Client-only Checkout不支持custom_unit_amount
解决Stripe Client-only Checkout不支持
custom_unit_amount价格的问题 问题原因
你当前使用的是客户端直接调用Checkout(client-only integration)模式,而Stripe明确限制这种模式不能使用带有custom_unit_amount属性的价格ID。这类价格用于允许买家自定义支付金额,仅支持在服务端创建Checkout Session的集成模式下使用。
解决方案
1. 改用服务端创建Checkout Session
你已写出部分创建Session的代码,需补全并调整请求格式以符合Stripe API要求:
import 'dart:convert'; import 'dart:typed_data'; import 'package:http/http.dart' as http; Future<String> createCheckout() async { final auth = 'Basic ' + base64Encode(utf8.encode('$secretKey:')); final url = Uri.parse('https://api.stripe.com/v1/checkout/sessions'); // Stripe API要求使用x-www-form-urlencoded格式的请求体 final body = { 'payment_method_types[]': 'card', 'line_items[0][price]': PriceId, 'line_items[0][quantity]': '1', 'mode': 'payment', 'success_url': 'http://localhost:8080/#/success', 'cancel_url': 'http://localhost:8080/#/cancel', }; final response = await http.post( url, headers: { 'Authorization': auth, 'Content-Type': 'application/x-www-form-urlencoded', }, body: body, ); if (response.statusCode == 200) { final sessionData = jsonDecode(response.body); return sessionData['id']; } else { throw Exception('创建结账会话失败: ${response.body}'); } }
关键提醒:禁止在Flutter Web前端代码中直接使用Stripe Secret Key,上述代码仅作示例,实际应将创建Session的逻辑部署到你的后端服务,前端通过调用自有后端接口获取Session ID,避免密钥泄露。
2. 修改前端跳转逻辑
不再直接传入商品信息,而是通过Session ID跳转至Checkout页面:
void redirectToCheckout(BuildContext _) async { try { // 若已将createCheckout移至后端,此处改为调用后端接口获取sessionId final sessionId = await createCheckout(); final stripe = Stripe(apiKey); await stripe.redirectToCheckout( CheckoutOptions(sessionId: sessionId), ); } catch (e) { print('跳转失败: $e'); } }
3. 替代方案(仅适用于固定金额场景)
如果你的业务不需要自定义金额,可直接在Stripe后台创建一个固定金额的价格(不启用custom_unit_amount),替换当前的PriceId,即可继续使用客户端直接调用的模式。
内容的提问来源于stack exchange,提问作者ᴅ ᴇ ʙ ᴊ ᴇᴇ ᴛ
相关产品推荐
相关产品推荐

