Flutter WebView中获取Stripe支付响应及页面跳转问题
Flutter Stripe支付:解决result.id为空及支付后返回原页面问题
1. 解决result.id返回null的问题
你当前代码中result.id为空的核心原因是redirectToCheckout是异步方法,未使用await等待异步操作完成,直接拿到的是Future对象而非实际会话结果。
修正后的代码:
void redirectToCheckout(BuildContext _, var plan) async { final stripe = Stripe(apiKey); // 加入await等待异步操作结束 final result = await stripe.redirectToCheckout(CheckoutOptions( lineItems: [ LineItem(price: plan, quantity: 1), ], clientReferenceId: '1', mode: 'payment', successUrl: 'https://localhost:8080/#/success/{CHECKOUT_SESSION_ID}', cancelUrl: 'https://localhost:8080/#/cancel', )); if (result != null) { print(result.id); // 现在能正确输出会话ID } }
注:即便修正异步调用,redirectToCheckout仍无法直接获取支付完成后的最终状态,需结合WebView拦截或后端Webhook实现。
2. 支付完成后返回Flutter页面并获取支付详情
要实现不跳转外部successUrl而是返回原页面,需通过WebView导航拦截+Stripe会话查询来实现:
实现思路
- 用自定义协议(如
stripe://success)替代外部跳转URL,方便WebView拦截 - 提前创建支付会话获取ID,后续用于查询支付详情
- 拦截WebView的跳转请求,检测到自定义协议时终止跳转,返回原页面并查询会话状态
示例代码(基于webview_flutter)
import 'package:webview_flutter/webview_flutter.dart'; import 'package:stripe_platform_interface/stripe_platform_interface.dart'; void launchStripeCheckout(BuildContext context, String plan) async { final stripe = Stripe(apiKey); // 前端创建支付会话(建议后端创建,避免API密钥暴露) final session = await stripe.createCheckoutSession(CheckoutSessionCreateParams( lineItems: [LineItemParams(price: plan, quantity: 1)], mode: 'payment', successUrl: 'stripe://success', // 自定义拦截协议 cancelUrl: 'stripe://cancel', clientReferenceId: '1', )); // 跳转至WebView加载Stripe Checkout页面 Navigator.push( context, MaterialPageRoute( builder: (context) => WebView( initialUrl: 'https://checkout.stripe.com/pay/${session.id}', javascriptMode: JavascriptMode.unrestricted, navigationDelegate: (NavigationRequest request) { // 拦截成功跳转 if (request.url.startsWith('stripe://success')) { _fetchPaymentSession(session.id); Navigator.pop(context); // 返回原Flutter页面 return NavigationDecision.prevent; } // 拦截取消跳转 if (request.url.startsWith('stripe://cancel')) { Navigator.pop(context); return NavigationDecision.prevent; } return NavigationDecision.navigate; }, ), ), ); } // 查询支付会话详情,获取支付状态等信息 Future<void> _fetchPaymentSession(String sessionId) async { final stripe = Stripe(apiKey); final session = await stripe.retrieveCheckoutSession(sessionId); print('支付会话ID:${session.id}'); print('支付状态:${session.status}'); print('支付Intent ID:${session.paymentIntent}'); print('总金额:${session.amountTotal}'); // 此处可添加支付成功后的业务逻辑,如更新本地状态、提示用户等 }
关键注意事项
- 自定义协议需确保不会与系统或其他应用的协议冲突
- 生产环境建议通过后端创建支付会话,前端仅获取会话ID,避免API密钥泄露
- 若需更可靠的支付状态通知,可在Stripe后台配置Webhook,支付完成后由后端主动通知前端
内容的提问来源于stack exchange,提问作者akm
相关产品推荐
相关产品推荐

