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

Flutter基于Deep Link实现UPI支付(Paytm网关):支付完成后返回APP并验单方法

Flutter实现Paytm UPI支付后自动返回APP并校验交易状态

一、配置APP的Deep Link回调地址

要让Paytm支付完成后能跳回你的APP,需先给APP配置专属的Deep Link Scheme(示例用myapp://paymentcallback),以下是Android和iOS的配置步骤:

Android端配置

在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和Host -->
    <data
        android:scheme="myapp"
        android:host="paymentcallback" />
</intent-filter>

iOS端配置

  1. 打开ios/Runner/Info.plist,添加允许调用Paytm的Scheme:
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>paytmmp</string>
</array>
  1. 配置APP自身的Deep Link Scheme:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string>
        </array>
        <key>CFBundleURLName</key>
        <string>paymentcallback</string>
    </dict>
</array>

二、修改Paytm UPI支付链接,添加回调参数

在原有支付Deep Link末尾追加url参数,值为你配置的APP回调Deep Link,同时带上交易号tr方便后续校验:

// 基础支付链接
String baseUrl = "paytmmp://pay?pa=paytm-67035308@paytm&pn=Reciver_NAME&mc=5812&tid=PYTM3101623366056793109&tr=3101623366056793109&am=3&cu=INR";
// 自定义回调地址,替换为你的Scheme
String callbackUrl = "myapp://paymentcallback?tr=3101623366056793109";
// 拼接完整支付链接
String deepLinkUrl = "$baseUrl&url=$callbackUrl";

注意:回调参数里的tr要和支付请求中的交易号完全一致,确保回来后能精准定位对应交易。

三、Flutter端监听Deep Link回调并处理

无需额外第三方库,直接通过Flutter原生的WidgetsBindingObserver监听APP生命周期与Deep Link:

class PaymentPage extends StatefulWidget {
  @override
  State<PaymentPage> createState() => _PaymentPageState();
}

class _PaymentPageState extends State<PaymentPage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    // 启动时检查是否通过Deep Link打开APP
    _checkInitialDeepLink();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  // 监听APP从后台回到前台的状态,触发Deep Link检查
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.resumed) {
      _checkDeepLink();
    }
  }

  // 检查APP启动时的初始Deep Link
  Future<void> _checkInitialDeepLink() async {
    final Uri? initialUri = await WidgetsBinding.instance.getInitialUri();
    if (initialUri != null) {
      _handlePaymentCallback(initialUri);
    }
  }

  // 检查APP恢复时的Deep Link
  Future<void> _checkDeepLink() async {
    final Uri? uri = await WidgetsBinding.instance.getInitialUri();
    if (uri != null) {
      _handlePaymentCallback(uri);
    }
  }

  // 处理支付回调,触发交易校验
  void _handlePaymentCallback(Uri uri) {
    String? transactionId = uri.queryParameters['tr'];
    if (transactionId != null) {
      // 调用已集成的Paytm API校验交易状态
      _verifyTransaction(transactionId);
    }
  }

  // 交易状态校验方法(替换为你的实际API调用逻辑)
  Future<void> _verifyTransaction(String transactionId) async {
    bool isSuccess = await paytmApi.verifyTransaction(transactionId);
    if (isSuccess) {
      print("交易成功,执行后续逻辑");
      // 这里添加支付成功后的UI更新、业务处理
    } else {
      print("交易失败,请重试");
      // 这里添加支付失败后的提示、重试逻辑
    }
  }

  // 发起支付的方法
  Future<void> launchPayment() async {
    String baseUrl = "paytmmp://pay?pa=paytm-67035308@paytm&pn=Reciver_NAME&mc=5812&tid=PYTM3101623366056793109&tr=3101623366056793109&am=3&cu=INR";
    String callbackUrl = "myapp://paymentcallback?tr=3101623366056793109";
    String deepLinkUrl = "$baseUrl&url=$callbackUrl";
    
    bool launchResult = await launchUrl(Uri.parse(deepLinkUrl));
    if (!launchResult) {
      print('无法启动Paytm支付,请检查是否安装Paytm APP');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: launchPayment,
          child: const Text("发起Paytm支付"),
        ),
      ),
    );
  }
}

四、关键注意事项

  • 测试时需确保设备已安装Paytm APP,否则launchUrl会返回false。
  • 回调Deep Link的参数需做URL编码,避免特殊字符导致解析失败。
  • 交易状态校验必须在服务器端执行,不要仅依赖客户端校验,防止数据篡改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:17:23