美文网首页
Swift 支付宝微信去sdk支付

Swift 支付宝微信去sdk支付

作者: 喵喵粉 | 来源:发表于2020-10-24 23:30 被阅读0次

copy源码:XHPayKit

2个支付方式都通过UIApplication.shared.open(url, completionHandler: nil)方式调起支付宝微信客户端支付,不需要集成'SDK'。

Info.plist添加白名单

<key>LSApplicationQueriesSchemes</key>
    <array>
        <string>alipay</string>
        <string>weixin</string>
    </array>

添加URL Types

image.png

组装url的格式:

  1. 微信
  • 让后台将payInfokeyvalue拼接成String
    weixin://app/微信的AppID/pay/?key=value&key=value

格式如下面的wxUrl字段

{
    "errno": "0",
    "errmsg": "请求成功!",
    "wxUrl": "weixin://app/微信的AppID/pay/?nonceStr=ZLOOW0wSxjYZt6AP&package=Sign=WXPay&partnerId=1603068427&prepayId=wx22214520388210c0a8bc66702ed24d0000&timeStamp=1603374320&sign=DBF8AC4C59AAA0B65757421A37EEBBB9",
    "payInfo": {
        "appid": "微信的AppID",
        "noncestr": "ZLOOW0wSxjYZt6AP",
        "package": "Sign=WXPay",
        "partnerid": "1603068427",
        "prepayid": "wx22214520388210c0a8bc66702ed24d0000",
        "sign": "DBF8AC4C59AAA0B65757421A37EEBBB9",
        "timestamp": 1603374320
    }
}
  • 替换Sign=WX
    let urlStr = result["wxUrl"].replacingOccurrences(of: "Sign=WX", with: "Sign%3DWX")

  • 直接打开链接,进入微信支付页面

if let url = URL(string: urlStr) {
    UIApplication.shared.open(url, completionHandler: nil)
}
  • 支付回调,AppDelegate
/// MARK: - open url iOS9.0及以后推荐使用
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let handleUrlStr = url.absoluteString
        
        DebugLog("=========open url Links=========")

        //wx123://pay/?returnKey=&ret=-2
        DebugLog(url.scheme ?? "🈳", handleUrlStr)
    
        //微信的
        if handleUrlStr.contains(微信的AppID) {
            
            var errCode = 0
            var errStr = ""

            //拿到ret returnKey=&ret=-2
            if let rstStr = handleUrlStr.components(separatedBy: "?").last {
                
                let rets = rstStr.components(separatedBy: "&")
                
                for keyV in rets {
                    if keyV.contains("ret=") {
                        errCode = keyV.replacingOccurrences(of: "ret=", with: "").ext2Int
                        break
                    }
                }
            }
            
            switch errCode {
            case 0:
                errStr = "成功"
            case -2:
                errStr = "用户取消"
            case -3:
                errStr = "发送失败"
            case -4:
                errStr = "授权失败"
            case -5:
                errStr = "微信不支持"
            default:
                errStr = "普通错误"
            }
            
            DebugLog("=========微信 errStr: \(errStr) =========")
            NotificationCenter.default.post(name: NSNotification.Name(kNotificatonWechatPayDone), object: nil, userInfo: ["errMsg": errStr])
            return true
        }
        
        return true
    }
  1. 支付宝
  • 后台请求支付宝拿到orderStr
alipay_sdk=alipay-sdk-java-3.4.49.ALL&app_id=123456&biz_content=%7B%22body%22%3A%22%E5%8D%83%E7%AD%BE%E4%BD%99%E9%A2%9D%E5%85%85%E5%80%BC%22%2C%22out_trade_no%22%3A%221603543654767%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3A%22%E5%85%85%E5%80%BC%22%2C%22timeout_express%22%3A%2230m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=UTF-8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2F11.11.11.11%3A8090%2Fa%2Freturn_url_Balan&sign=bhxuUOzWMWzyMtKREEyMEGsvBoYJR4Z2IR%2Bj9S4EPhHssC6QvXS6pMPscfZbaM7kLERpi0Heab6kKouJmeLaCgTecRlTwnVQdxflKb8C9vZBgOEcHVIpAthiUDvYrOnO%2FfZG0MTme6ecSTcTylcVLsRBOLpBoidsSWrcOsSsgxrNhyqkNDr6MhoEF09CiNYtDL0ubqZNekBwt2mKmhO0LHhcEIrkYZ0Gt5daq36z8%2FSPsrdmWt%2FMJoPv4Jz36yflC9oO9%2FhS%2FDXDGe76tAmzlboDy3YmY9LtwzOuR%2FmQUT0LizKurOyjQ3koQIsaogVI6nVmMY7SFHhRvZF%2BpaK5ug%3D%3D&sign_type=RSA2&timestamp=2020-10-24+20%3A47%3A34&version=1.0
  • 组成字典
let dic = [
            "fromAppUrlScheme": "myScheme",
            "requestType": "SafePay",
            "dataString": orderStr
        ]
  • 转成JSON字符串dictJsonStr
guard let dicJsonStr = dic.ext2JsonString(true) else { return }
DebugLog(dicJsonStr)
  • dictJsonStr URL编码成dicJsonEncodeStr
let dicJsonEncodeStr = dicJsonStr.extUrlEncode()
DebugLog(dicJsonEncodeStr)
  • 拼接"alipay://alipayclient/?"+dicJsonEncodeStr,得到url
    直接打开链接,进入支付宝支付页面
if let url = URL(string: url) {
    UIApplication.shared.open(url, completionHandler: nil)
}
func zfbPay() {    
        let dic = [
            "fromAppUrlScheme": "myScheme",
            "requestType": "SafePay",
            "dataString": orderStr
        ]
        guard let dicJsonStr = dic.ext2JsonString(true) else { return }
        DebugLog(dicJsonStr)
        let dicJsonEncodeStr = dicJsonStr.extUrlEncode()
        DebugLog(dicJsonEncodeStr)

        if let url = URL(string: "alipay://alipayclient/?"+dicJsonEncodeStr) {
            DebugLog(url)
            UIApplication.shared.open(url, completionHandler: nil)
        }
    } 
}
  • 支付回调
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let handleUrlStr = url.absoluteString
        
        DebugLog("=========open url Links=========")
/** rstDic:
{
    memo = "支付未完成";
    result = "";
    resultStatus = 6001;
}
*/
            
        if let scheme = url.scheme {
            ///支付宝的
            if scheme == kSelfScheme {
                
                let urlDecoded = handleUrlStr.extUrlDecoded()
                DebugLog("解码:", urlDecoded)
                
                //拿到{"memo"字典
                if var rstStr = urlDecoded.components(separatedBy: "?").last {
                    rstStr = rstStr.replacingOccurrences(of: "ResultStatus", with: "resultStatus")
                    
                    if let rstDic = rstStr.ext2Dictionary() {
                        DebugLog(rstDic)
                        
                        if let mmDic = rstDic["memo"] as? [String: Any], let resultStatus = mmDic["resultStatus"] as? String {
                            DebugLog(mmDic)
                            DebugLog(resultStatus)
                            
                            var errStr = ""
                            let errCode = resultStatus.ext2Int
                            
                            switch errCode {
                            case 9000:
                                errStr = "成功"
                            case 6002:
                                errStr = "网络连接出错"
                            case 6001:
                                errStr = "用户取消"
                            case 4000:
                                errStr = "订单失败"
                            case 5000:
                                errStr = "重复请求"
                            default:
                                errStr = "请查询订单的状态"
                            }
                            
                            DebugLog("===============baobao errStr: \(errStr) ================")
                            NotificationCenter.default.post(name: NSNotification.Name(kNotificatonZfbPayDone), object: nil, userInfo: ["errMsg": errStr])
                            return true
                        }
                    }
                }
                
                return true
            }
        }

        return true
    }
  1. String扩展
//
// MARK: - URL编码 解码
//
extension String {
    
    func extUrlEncode() -> String {
        let str = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,self as NSString, nil,
                                                          "!*'();:@&=+$,/?%#[]" as CFString, CFStringConvertNSStringEncodingToEncoding(String.Encoding.utf8.rawValue))
        return str! as String
    }
    
    func extUrlDecoded() -> String {
        return removingPercentEncoding ?? ""
    }
}

extension String {
    
    func ext2Dictionary() -> [String: Any]? {
        
        guard let data = data(using: .utf8) else {
            return nil
        }
        
        guard let dic = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String: Any] else {
            DebugLog(self, " 不能解析成字典")
            return nil
        }
        
        return dic
    }
}

oc 拼接url

NSDictionary *dic = @{
    @"appid": @"微信的AppID",
    @"noncestr": @"ZLOOW0wSxjYZt6AP",
    @"package": @"Sign=WXPay",
    @"partnerid": @"1603068427",
    @"prepayid": @"wx22214520388210c0a8bc66702ed24d0000",
    @"sign": @"DBF8AC4C59AAA0B65757421A37EEBBB9",
    @"timestamp": @"1603374320"
};
NSMutableString *result= [NSMutableString string];
for (NSString *key in dic) {
    NSString *value = dic[key];
    [result appendFormat:@"%@=%@&", key, value];
}
NSString *rst = [result stringByReplacingOccurrencesOfString:@"Sign=WX" withString:@"Sign%3DWX"];
rst = [rst substringToIndex:result.length-1];
NSLog(@"%@\n%@", result, rst);
  1. 支付宝返回码
返回码 含义
9000 订单支付成功
8000 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
4000 订单支付失败
5000 重复请求
6001 用户中途取消
6002 网络连接出错
6004 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
其它 其它支付错误

最后贴个集成SDK的文档链接

https://opendocs.alipay.com/open/204/105295/
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html#jump2

相关文章

网友评论

      本文标题:Swift 支付宝微信去sdk支付

      本文链接:https://www.haomeiwen.com/subject/inzwmktx.html