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
相关产品推荐
相关产品推荐

