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

Flutter中如何从第三方应用跳转回自有应用并获取支付响应?

Flutter UPI支付后跳转回应用并获取支付响应

核心思路

要实现UPI支付完成后跳转回自有应用并获取响应,需要结合Deep Link配置和UPI支付URL的回调参数,同时在Flutter端监听Deep Link的唤醒事件来解析支付结果。


首先需要给你的Flutter app配置专属的Deep Link,让UPI应用能在支付完成后唤起你的app。

Android 配置(AndroidManifest.xml)

在android/app/src/main/AndroidManifest.xml的主Activity标签内添加以下intent-filter:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- 替换成你的专属scheme,比如myinvoiceapp:// -->
    <data android:scheme="myinvoiceapp" />
</intent-filter>

iOS 配置(Info.plist)

在ios/Runner/Info.plist中添加以下配置:

<!-- 允许调用UPI应用的scheme -->
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>upi</string>
</array>

<!-- 配置Deep Link的URL Scheme -->
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <!-- 替换成你的专属scheme,比如myinvoiceapp -->
            <string>myinvoiceapp</string>
        </array>
    </dict>
</array>

2. 构造带回调的UPI支付URL

在构造UPI支付链接时,必须添加callback参数,指定支付完成后跳转回你的app的Deep Link。示例URL格式:

String upiUrl = 'upi://pay?'
    'pa=merchant@upi&' // 收款方UPI ID
    'pn=商家名称&' // 收款方名称
    'am=100.00&' // 支付金额
    'tn=发票支付:#INV123&' // 交易备注
    'tr=UNIQUE_TXN_ID_123&' // 唯一交易ID(自己生成,用于后续核对)
    'callback=myinvoiceapp://payment-callback'; // 你的Deep Link回调地址

3. 启动UPI支付并监听回调

使用url_launcher启动UPI链接,同时借助app_links包监听Deep Link的唤醒事件(url_launcher本身无法直接接收回调,需要依赖Deep Link监听库)。

添加依赖

在pubspec.yaml中添加:

dependencies:
  url_launcher: ^6.2.4
  app_links: ^3.4.2

初始化监听

在你的主页面或者支付页面初始化Deep Link监听:

import 'package:app_links/app_links.dart';
import 'package:url_launcher/url_launcher.dart';

class PaymentPage extends StatefulWidget {
  const PaymentPage({super.key});

  @override
  State<PaymentPage> createState() => _PaymentPageState();
}

class _PaymentPageState extends State<PaymentPage> {
  final AppLinks _appLinks = AppLinks();
  StreamSubscription<Uri>? _linkSubscription;

  @override
  void initState() {
    super.initState();
    // 监听Deep Link唤醒事件
    _initDeepLinkListener();
  }

  void _initDeepLinkListener() {
    _linkSubscription = _appLinks.uriLinkStream.listen((Uri? uri) {
      if (uri != null && uri.path == '/payment-callback') {
        // 解析回调参数
        String? status = uri.queryParameters['status'];
        String? txnId = uri.queryParameters['txnId'];
        String? tr = uri.queryParameters['tr']; // 之前传入的唯一交易ID

        // 根据status处理支付结果
        if (status == 'success') {
          // 更新发票状态为已支付,跳转回发票列表页等
          print('支付成功,交易ID:$txnId');
        } else if (status == 'failure') {
          print('支付失败');
        }
      }
    });
  }

  // 启动UPI支付的方法
  Future<void> launchUpiPayment() async {
    String upiUrl = 'upi://pay?'
        'pa=merchant@upi&'
        'pn=商家名称&'
        'am=100.00&'
        'tn=发票支付:#INV123&'
        'tr=UNIQUE_TXN_ID_123&'
        'callback=myinvoiceapp://payment-callback';

    final Uri uri = Uri.parse(upiUrl);
    if (await canLaunchUrl(uri)) {
      await launchUrl(uri);
    } else {
      throw '无法启动UPI应用';
    }
  }

  @override
  void dispose() {
    _linkSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('支付发票')),
      body: Center(
        child: ElevatedButton(
          onPressed: launchUpiPayment,
          child: const Text('通过UPI支付'),
        ),
      ),
    );
  }
}

4. 注意事项

  • 回调参数兼容性:不同UPI应用(Google Pay、PhonePe、Paytm)对回调参数的格式可能略有差异,建议测试主流应用,确保能正确解析status、txnId等核心参数。
  • 交易唯一性:tr参数必须是唯一的,用于后续核对支付记录,避免重复支付或状态混乱。
  • 后台校验:前端获取的支付状态仅作参考,必须通过后端调用UPI官方接口校验交易的真实状态,防止伪造回调。

内容的提问来源于stack exchange,提问作者ramit_acube

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:22:46