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

Flutter中实现UPI支付:iOS端Google Pay Intent处理咨询

iOS端Flutter集成UPI(Google Pay)支付实现方案

核心思路

iOS上通过URL Scheme唤起Google Pay处理UPI支付,通过App的回调机制捕获支付结果,再通过Method Channel回传给Flutter层。逻辑和Android端对齐,但需适配iOS的URL跳转与回调规则。

1. 配置Info.plist

先在Info.plist中添加以下配置,允许App调用UPI相关URL Scheme,并声明专属回调Scheme(用于接收支付结果):

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>upi</string>
</array>
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <!-- 替换为你的App专属回调Scheme,例如 yourapp-upi://callback -->
            <string>your-app-upi-scheme</string>
        </array>
    </dict>
</array>

2. Swift端核心实现代码

构建UPI支付URL并唤起Google Pay

在Flutter Method Channel的处理类中,实现唤起支付的方法:

import UIKit
import Flutter

class UpiPaymentHandler: NSObject, FlutterPlugin {
    static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "com.yourapp/upi_payment", binaryMessenger: registrar.messenger())
        let instance = UpiPaymentHandler()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }
    
    func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        guard call.method == "makeGooglePayTransaction" else {
            result(FlutterMethodNotImplemented)
            return
        }
        
        guard let args = call.arguments as? [String: String],
              let merchantVpa = args["merchantVpa"],
              let merchantName = args["merchantName"],
              let merchantCode = args["mc"],
              let transactionRefId = args["tr"],
              let transactionNote = args["tn"],
              let orderAmount = args["am"] else {
            result(FlutterError(code: "INVALID_ARGS", message: "缺少必要参数", details: nil))
            return
        }
        
        // 构建UPI支付URL
        var components = URLComponents()
        components.scheme = "upi"
        components.host = "pay"
        components.queryItems = [
            URLQueryItem(name: "pa", value: merchantVpa),
            URLQueryItem(name: "pn", value: merchantName),
            URLQueryItem(name: "mc", value: merchantCode),
            URLQueryItem(name: "tr", value: transactionRefId),
            URLQueryItem(name: "tn", value: transactionNote),
            URLQueryItem(name: "am", value: orderAmount),
            URLQueryItem(name: "cu", value: "INR"),
            // 指定回调Scheme,支付完成后跳转回当前App
            URLQueryItem(name: "url", value: "your-app-upi-scheme://upi-callback")
        ]
        
        guard let upiUrl = components.url else {
            result(FlutterError(code: "URL_ERROR", message: "构建UPI URL失败", details: nil))
            return
        }
        
        // 检查是否可打开UPI支付链接(兼容无支付App的情况)
        if UIApplication.shared.canOpenURL(upiUrl) {
            UIApplication.shared.open(upiUrl, options: [:]) { success in
                if !success {
                    result(FlutterError(code: "OPEN_FAILED", message: "打开支付App失败", details: nil))
                }
            }
        } else {
            result(FlutterError(code: "NO_UPI_APP", message: "未安装UPI支付应用", details: nil))
        }
    }
}

处理支付回调结果

在AppDelegate(iOS 13+可使用SceneDelegate)中捕获支付完成后的回调URL,解析结果并回传给Flutter:

// AppDelegate.swift
import UIKit
import Flutter

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
    // 保存Flutter结果回调,用于接收支付结果后回传
    var upiPaymentResult: FlutterResult?
    
    override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        // 拦截UPI回调URL
        if url.scheme == "your-app-upi-scheme" && url.host == "upi-callback" {
            let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems
            
            // 解析核心支付参数
            let status = queryItems?.first(where: { $0.name == "Status" })?.value
            let txnId = queryItems?.first(where: { $0.name == "txnId" })?.value
            let responseCode = queryItems?.first(where: { $0.name == "responseCode" })?.value
            
            // 将结果回传给Flutter
            upiPaymentResult?([
                "status": status ?? "",
                "txnId": txnId ?? "",
                "responseCode": responseCode ?? "",
                "rawResponse": url.absoluteString
            ])
            upiPaymentResult = nil
            return true
        }
        return super.application(app, open: url, options: options)
    }
}

3. 关键注意事项

  • 回调Scheme唯一性:确保设置的回调Scheme为App专属,避免与其他App冲突。
  • 支付结果兼容性:不同UPI支付App的回调参数可能略有差异,核心参数Status(SUCCESS/FAILURE/PENDING)、txnId是通用的,需做兼容处理。
  • 强制唤起Google Pay:如果需要跳过系统选择框直接唤起Google Pay,可检查Google Pay的Bundle ID(com.google.apps.wallet),但直接通过UPI URL唤起的方式已支持用户选择Google Pay,满足大部分场景需求。

4. Flutter层调用示例

import 'package:flutter/services.dart';

const MethodChannel _upiChannel = MethodChannel('com.yourapp/upi_payment');

Future<void> initiateGooglePayUpi() async {
  try {
    final Map<String, dynamic> result = await _upiChannel.invokeMethod('makeGooglePayTransaction', {
      'merchantVpa': 'merchant@exampleupi',
      'merchantName': '测试商户',
      'mc': '1234',
      'tr': 'TXN20240501001',
      'tn': '商品购买支付',
      'am': '99.00',
    });
    print('支付结果: $result');
    // 根据status处理成功/失败/待确认逻辑
  } on PlatformException catch (e) {
    print('支付错误: ${e.message}');
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:00:59