从0到1搞定iOS支付接入:微信、支付宝、订阅一文通关

随着“钱包”变得越来越轻,手机支付早已成为我们日常生活的一部分,尤其是在微信和支付宝的“陪伴”下,几乎每个iOS应用都能享受这种便捷的支付方式。但对于开发者来说,接入微信支付、支付宝支付以及自动续费功能,往往像在玩“闯关游戏”——时不时遇到一些让你头疼的小坑,有时你明明觉得自己已经做得天衣无缝,结果支付结果还是迟迟不来,或者签名验证变成了无解难题。

不用怕!本文将带你一起跳过这些坑,像大厨一样轻松“烹饪”出微信支付、支付宝支付与自动续费功能的完美接入方案。结合项目代码,解锁开发过程中的常见问题和解决技巧,让你能顺利接入支付功能,告别支付失败的烦恼,迎接用户钱包里的满满“钞票”。

iOS接入微信支付、支付宝支付和自动续费步骤:

  1. 微信支付:在微信开放平台下载SDK,配置Info.plistURL Schemes,实现AppDelegate中的回调逻辑。通过后台获取支付参数,使用WXApi发起支付请求并监听支付结果。

  2. 支付宝支付:从支付宝开放平台下载SDK,配置Info.plistURL Schemes,并在AppDelegate中处理AlipaySDK的支付回调。调用支付宝SDK接口发起支付,监听支付结果。

  3. 自动续费:在App Store Connect创建订阅商品,使用StoreKit请求商品信息并发起购买。通过SKPaymentQueue监听交易状态,完成购买和验证。

  4. 结合逻辑:根据用户选择调用对应支付方法,支付结果由服务端或苹果验证处理,实现自动续费或一次性支付功能。

在 iOS 中接入微信支付、支付宝支付,并支持自动续费,通常需要结合官方 SDK 和 Apple 的订阅机制。以下是实现方案和示例代码。


在这里插入图片描述

一、微信支付接入

步骤 1:获取微信支付 SDK

步骤 2:配置项目

  1. 在 Info.plist 中添加 URL Scheme:

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>weixin</string>
    </array>
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>wx1234567890abcdef</string> <!-- 替换为你的微信 AppID -->
            </array>
        </dict>
    </array>
    
  2. 在 AppDelegate.swift 中实现回调:

    import UIKit
    import WXApi
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate, WXApiDelegate {
        func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
            return WXApi.handleOpen(url, delegate: self)
        }
    
        func onResp(_ resp: BaseResp) {
            if let payResp = resp as? PayResp {
                switch payResp.errCode {
                case WXSuccess.rawValue:
                    print("支付成功")
                default:
                    print("支付失败,错误码:\(payResp.errCode)")
                }
            }
        }
    }
    

步骤 3:调用支付接口

  • 在你的支付界面,获取后台返回的支付参数并发起支付。
    import WXApi
    
    func startWeChatPay(orderInfo: [String: Any]) {
        let req = PayReq()
        req.partnerId = orderInfo["partnerId"] as? String
        req.prepayId = orderInfo["prepayId"] as? String
        req.package = orderInfo["package"] as? String
        req.nonceStr = orderInfo["nonceStr"] as? String
        req.timeStamp = UInt32(orderInfo["timeStamp"] as? String ?? "0") ?? 0
        req.sign = orderInfo["sign"] as? String
        
        WXApi.send(req) { success in
            print(success ? "支付请求已发起" : "支付请求失败")
        }
    }
    

二、支付宝支付接入

步骤 1:获取支付宝 SDK

步骤 2:配置项目

  1. 在 Info.plist 中添加 URL Scheme:

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>alipay123456</string> <!-- 替换为你的支付宝 Scheme -->
            </array>
        </dict>
    </array>
    
  2. 在 AppDelegate.swift 中实现回调:

    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
            if url.host == "safepay" {
                AlipaySDK.defaultService()?.processOrder(withPaymentResult: url, standbyCallback: { result in
                    print("支付结果:\(result ?? [:])")
                })
            }
            return true
        }
    }
    

步骤 3:调用支付接口

  • 从后台获取订单信息后,调用以下代码:
    import AlipaySDK
    
    func startAlipay(orderInfo: String) {
        AlipaySDK.defaultService()?.payOrder(orderInfo, fromScheme: "alipay123456") { result in
            print("支付结果:\(result ?? [:])")
        }
    }
    

三、自动续费(Apple 内购)

步骤 1:配置 Apple 内购商品

  1. 在 App Store Connect 创建订阅商品。
  2. 设置订阅周期、价格等信息。

步骤 2:实现内购逻辑

  • 使用 StoreKit 框架。
  1. 请求商品信息:

    import StoreKit
    
    class IAPManager: NSObject, SKProductsRequestDelegate {
        static let shared = IAPManager()
        private var products: [SKProduct] = []
    
        func fetchProducts(productIDs: [String]) {
            let request = SKProductsRequest(productIdentifiers: Set(productIDs))
            request.delegate = self
            request.start()
        }
    
        func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
            self.products = response.products
            for product in response.products {
                print("商品名称: \(product.localizedTitle), 价格: \(product.price)")
            }
        }
    }
    
  2. 发起购买:

    extension IAPManager: SKPaymentTransactionObserver {
        func purchase(productID: String) {
            guard let product = products.first(where: { $0.productIdentifier == productID }) else { return }
            let payment = SKPayment(product: product)
            SKPaymentQueue.default().add(self)
            SKPaymentQueue.default().add(payment)
        }
    
        func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
            for transaction in transactions {
                switch transaction.transactionState {
                case .purchased:
                    print("购买成功")
                    SKPaymentQueue.default().finishTransaction(transaction)
                case .failed:
                    print("购买失败")
                    SKPaymentQueue.default().finishTransaction(transaction)
                default:
                    break
                }
            }
        }
    }
    

四、支付与自动续费结合逻辑

  1. 在 App 内提供切换选项:

    • 用户选择微信支付或支付宝支付,用于一次性付费。
    • 用户选择订阅方案,跳转到 Apple 内购。
  2. 通过服务端验证支付或订阅状态:

    • 微信/支付宝:通过支付订单状态接口查询支付结果。
    • Apple 订阅:通过 Apple 的验证服务端 API 检查用户的订阅状态。

完整示例代码逻辑

根据项目需求,将微信、支付宝与内购逻辑集成到统一的支付管理类,动态调用对应方法。详细代码可进一步细化,视项目功能而定。

接入微信支付、支付宝支付和自动续费的过程中,有几个常见的坑需要注意。以下结合代码分析这些问题,并提供解决方案。


1. 微信支付

坑点 1:签名错误导致支付失败
  • 问题:后台生成的签名必须与微信支付文档中的规则完全一致。
  • 解决
    • 确保签名字段严格按照微信官方文档的顺序拼接。
    • 使用后台生成的签名进行验证。
    • 示例:
      func validateSignature(orderInfo: [String: Any]) -> Bool {
          // 示例:后台生成的签名,确保和前端匹配
          let serverSign = orderInfo["sign"] as? String ?? ""
          // 本地签名计算,确保一致
          let localSign = calculateSignature(params: orderInfo)
          return serverSign == localSign
      }
      
      func calculateSignature(params: [String: Any]) -> String {
          // 根据微信规则拼接字段
          // 示例实现需根据具体项目补充
          return "calculated_sign"
      }
      
坑点 2:无法正确处理支付回调
  • 问题:回调未正确实现,导致支付状态无法传递到前端。
  • 解决:确保在AppDelegate中实现微信回调:
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        return WXApi.handleOpen(url, delegate: self)
    }
    
    func onResp(_ resp: BaseResp) {
        if let payResp = resp as? PayResp {
            // 处理支付结果
            switch payResp.errCode {
            case WXSuccess.rawValue:
                print("支付成功")
                // 通知前端或更新UI
            default:
                print("支付失败,错误码:\(payResp.errCode)")
            }
        }
    }
    

2. 支付宝支付

坑点 1:无法获取支付结果回调
  • 问题:如果未正确配置Info.plist中的URL Schemes,支付回调无法触发。
  • 解决:确保支付宝URL Schemes配置正确,并在回调中处理结果:
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        if url.host == "safepay" {
            AlipaySDK.defaultService()?.processOrder(withPaymentResult: url, standbyCallback: { result in
                print("支付结果:\(result ?? [:])")
            })
            return true
        }
        return false
    }
    
坑点 2:签名格式不匹配
  • 问题:支付宝签名校验失败常因私钥或拼接方式错误。
  • 解决
    • 使用正确的RSA私钥加密生成签名。
    • 确保与支付宝官方工具校验一致。

3. 自动续费(内购)

坑点 1:用户订阅状态同步不及时
  • 问题:用户支付完成,但服务端未及时验证订阅状态,导致功能无法解锁。
  • 解决
    • 使用服务器端验证收据,确保订阅状态实时更新:
      func validateReceipt(receiptData: Data) {
          // 将收据发送到服务器进行验证
          let receiptString = receiptData.base64EncodedString()
          // 示例:发送到服务器的请求代码
          let url = URL(string: "https://yourserver.com/validateReceipt")!
          var request = URLRequest(url: url)
          request.httpMethod = "POST"
          request.httpBody = try? JSONSerialization.data(withJSONObject: ["receipt": receiptString], options: [])
          
          URLSession.shared.dataTask(with: request) { data, response, error in
              // 处理服务器返回结果
          }.resume()
      }
      
坑点 2:商品 ID 不匹配
  • 问题:请求的商品 ID 与 App Store 配置不一致。
  • 解决:确保代码中的商品 ID 和 App Store 的设置完全一致:
    let productIDs = ["com.yourapp.subscription.monthly"]
    IAPManager.shared.fetchProducts(productIDs: productIDs)
    
坑点 3:交易未正确完成
  • 问题:忘记调用finishTransaction,导致交易无法结束,用户无法继续购买。
  • 解决
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased:
                print("购买成功")
                SKPaymentQueue.default().finishTransaction(transaction)
            case .failed:
                print("购买失败")
                SKPaymentQueue.default().finishTransaction(transaction)
            default:
                break
            }
        }
    }
    

4. 服务端与客户端逻辑结合

坑点 1:未验证支付结果
  • 问题:支付结果仅通过客户端判断,存在安全风险。
  • 解决:将支付结果发送至服务端,统一验证微信、支付宝、Apple 内购的状态。
坑点 2:网络超时处理不当
  • 问题:支付完成后,网络延迟导致状态无法及时同步。
  • 解决:提供重试机制,确保支付或订阅结果能正确处理。

总结

  1. 签名问题:严格遵循微信/支付宝的签名规则,确保服务端与客户端一致。
  2. 回调处理:微信、支付宝回调配置必须正确,且前后端逻辑要同步。
  3. 内购验证:Apple 自动续费必须通过服务端验证收据,避免本地校验被绕过。
  4. 网络延迟与重试机制:支付结果同步到服务端时需增加重试机制,避免因网络问题导致订单状态异常。

以上方案和代码示例,可有效规避常见坑点,确保支付功能稳定可靠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值