Flutter应用集成Google Pay等支付:跳转及状态回调问题求解
Flutter集成UPI支付(Google Pay/PhonePe/Paytm)方案
一、Google Pay 集成(修复url_launcher跳转问题)
之前用url_launcher失败大概率是UPI URL格式不正确,Google Pay遵循UPI标准协议,正确的URL格式如下:
upi://pay?pa=收款方UPI_ID&pn=收款方名称&am=金额&cu=INR&tn=交易备注
实现步骤:
- 添加
url_launcher依赖到pubspec.yaml,执行flutter pub get。 - 封装跳转方法,处理跳转失败场景:
import 'package:url_launcher/url_launcher.dart'; Future<void> launchGooglePay(String upiId, String name, double amount, String note) async { final uri = Uri.parse( 'upi://pay?pa=$upiId&pn=$name&am=${amount.toStringAsFixed(2)}&cu=INR&tn=$note' ); if (await canLaunchUrl(uri)) { await launchUrl(uri, mode: LaunchMode.externalApplication); } else { throw '无法打开Google Pay,请检查是否已安装'; } }
- 监听支付状态返回:
仅url_launcher无法直接获取回调,需用uni_links或app_links插件监听返回链接。以uni_links为例:
import 'package:uni_links/uni_links.dart'; StreamSubscription? _linkSubscription; void initPaymentCallbackListener() async { _linkSubscription = uriLinkStream.listen((Uri? uri) { if (uri != null) { final status = uri.queryParameters['status']; final txnId = uri.queryParameters['txnId']; // 根据status处理状态:SUCCESS/FAILURE/CANCELLED if (status == 'SUCCESS') { // 支付成功逻辑 } else if (status == 'FAILURE') { // 支付失败逻辑 } else { // 支付取消逻辑 } } }, onError: (err) { // 错误处理 }); } // 页面销毁时取消监听 @override void dispose() { _linkSubscription?.cancel(); super.dispose(); }
二、PhonePe 集成
PhonePe支持UPI URL Scheme跳转,也可使用需商家资质的官方SDK,先讲无资质的URL方式:
URL Scheme方式:
Future<void> launchPhonePe(String upiId, String name, double amount, String note) async { final uri = Uri.parse( 'phonepe://pay?pa=$upiId&pn=$name&am=${amount.toStringAsFixed(2)}&cu=INR&tn=$note' ); if (await canLaunchUrl(uri)) { await launchUrl(uri, mode: LaunchMode.externalApplication); } else { throw '无法打开PhonePe,请检查是否已安装'; } }
状态监听同样用uni_links,解析返回的status参数即可。
官方SDK方式(需商家认证):
- 申请PhonePe商家账号,获取商户ID、密钥等信息。
- 使用官方提供的Flutter插件(联系官方获取),按文档初始化并发起支付,SDK会直接返回支付状态回调。
三、Paytm 集成
Paytm推荐使用官方Flutter插件paytm_allinone_flutter,步骤如下:
- 添加依赖到
pubspec.yaml:
dependencies: paytm_allinone_flutter: ^1.0.15
- 平台配置:
- Android:在
AndroidManifest.xml中添加Paytm的Activity配置及网络权限。 - iOS:在
Info.plist中添加LSApplicationQueriesSchemes,包含paytm。
- Android:在
- 初始化并发起支付:
import 'package:paytm_allinone_flutter/paytm_allinone_flutter.dart'; Future<void> startPaytmPayment() async { // 敏感信息需从后端获取,禁止前端硬编码 final orderId = 'ORDER_20240501'; final mid = 'YOUR_MERCHANT_ID'; final txnToken = 'YOUR_TXN_TOKEN_FROM_BACKEND'; final amount = '100.00'; try { var response = await AllInOnePaytm.startPayment( mid, orderId, txnToken, amount, 'YOUR_WEBSITE_NAME', 'https://your-callback-url.com', // 后端回调地址 false, // 测试环境设为true ); if (response['STATUS'] == 'TXN_SUCCESS') { // 支付成功逻辑 } else { // 支付失败/取消逻辑 } } catch (e) { // 错误处理 } }
Paytm插件会直接返回支付状态,无需额外监听链接。
注意事项
- UPI支付金额必须保留两位小数,避免解析错误。
- 商户ID、密钥、交易令牌等敏感信息必须从后端获取,防止安全风险。
- 测试可使用各平台提供的测试UPI ID和商户信息,避免产生真实交易。
内容的提问来源于stack exchange,提问作者Naimish Patel
相关产品推荐
相关产品推荐

