Flutter中如何从UPI应用获取支付响应?
实现UPI支付回调接收交易响应
要接收UPI应用返回的交易状态、ID等数据,需要完成应用URL Scheme配置、UPI支付URL添加回调地址、监听回调链接并解析参数这三个核心步骤,以下是具体实现:
1. 配置应用URL Scheme
让UPI支付完成后能跳回你的应用,需要为应用配置自定义URL Scheme:
Android端
修改android/app/src/main/AndroidManifest.xml,在主<activity>标签内添加intent-filter:
<activity android:name=".MainActivity" android:launchMode="singleTop" <!-- 添加这个避免重复创建页面 --> ...> <!-- 现有代码 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 自定义Scheme,比如myappupi,可自行修改 --> <data android:scheme="myappupi" /> </intent-filter> </activity>
iOS端
修改ios/Runner/Info.plist,添加URL Scheme配置:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myappupi</string> <!-- 和Android端一致的Scheme --> </array> </dict> </array>
2. 修改UPI支付URL,添加回调地址
在原有的UPI支付URL中加入url参数,指定回调到你的应用Scheme:
String upiUrl = 'bhim://pay?pa=xxx@okbizaxis&pn=ABC&tr=15330175804633937&tn=MangOO Transaction&am=1&cu=INR&mc=5411&url=myappupi://paymentresponse';
url=myappupi://paymentresponse是告诉UPI应用,支付完成后跳转到这个地址。
3. 监听回调链接并解析交易数据
推荐使用uni_links插件监听外部应用跳转链接,实现实时接收UPI返回的参数:
步骤3.1 添加依赖
在pubspec.yaml中添加:
dependencies: url_launcher: ^6.1.12 uni_links: ^0.5.1
步骤3.2 实现监听与解析
import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:uni_links/uni_links.dart'; class UpiPaymentPage extends StatefulWidget { const UpiPaymentPage({super.key}); @override State<UpiPaymentPage> createState() => _UpiPaymentPageState(); } class _UpiPaymentPageState extends State<UpiPaymentPage> { @override void initState() { super.initState(); // 初始化链接监听 _setupLinkListener(); } // 监听外部应用跳转链接 void _setupLinkListener() { uriLinkStream.listen((Uri? uri) { if (uri == null) return; // 验证是我们的回调Scheme if (uri.scheme == 'myappupi') { _parseUpiResponse(uri); } }, onError: (err) { print('监听回调链接出错: $err'); }); } // 解析UPI返回的交易参数 void _parseUpiResponse(Uri uri) { final status = uri.queryParameters['status']; final txnId = uri.queryParameters['txnId']; final txnRef = uri.queryParameters['txnRef']; // 对应你传入的tr参数 final responseCode = uri.queryParameters['responseCode']; // 根据交易状态处理下单逻辑 switch (status) { case 'SUCCESS': // 支付成功,提交订单 _handlePaymentSuccess(txnId, txnRef); break; case 'FAILURE': // 支付失败,提示用户 _handlePaymentFailed(); break; case 'PENDING': // 支付待确认,需后续查询交易状态 _handlePaymentPending(txnRef); break; default: print('未知交易状态: $status'); } } // 发起UPI支付 Future<void> _initiateUpiPayment() async { final upiUrl = 'bhim://pay?pa=xxx@okbizaxis&pn=ABC&tr=15330175804633937&tn=MangOO Transaction&am=1&cu=INR&mc=5411&url=myappupi://paymentresponse'; final uri = Uri.parse(upiUrl); if (await canLaunchUrl(uri)) { await launchUrl(uri, mode: LaunchMode.externalApplication); } else { throw '无法打开UPI应用'; } } // 支付成功处理逻辑 void _handlePaymentSuccess(String? txnId, String? txnRef) { print('支付成功,交易ID: $txnId,订单参考号: $txnRef'); // 调用你的后端API,完成下单流程 // 示例:Navigator.push(context, MaterialPageRoute(builder: (_) => OrderSuccessPage())); } // 支付失败处理逻辑 void _handlePaymentFailed() { print('支付失败'); // 显示失败提示 // 示例:ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('支付失败,请重试'))); } // 支付待确认处理逻辑 void _handlePaymentPending(String? txnRef) { print('支付待确认,订单参考号: $txnRef'); // 提示用户等待,或定时查询交易状态 } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('UPI支付')), body: Center( child: ElevatedButton( onPressed: _initiateUpiPayment, child: const Text('发起支付'), ), ), ); } }
关键说明
- UPI应用返回的参数可能因应用不同略有差异,但核心参数
status、txnId、txnRef是通用的。 - Android端设置
android:launchMode="singleTop"是为了确保应用从后台唤起时,回调参数能正确传递到当前页面。 - 必须在真实设备上测试,模拟器通常没有UPI应用,且回调功能依赖系统跳转机制。
内容的提问来源于stack exchange,提问作者Taniksha Sharma
相关产品推荐
相关产品推荐

