You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:05:41