以前接入微信和支付宝的支付, 采用的是导入对应的SDK, 调用和返回都是由SDK内部处理, 这一点从操作和集成角度而言, 安全和方便. 但是局限性也是有的:
那么, 问题来了, 有没有更简单的方案呢, 答案当然是有的.
微信和支付宝的网页支付营运而生…
优点:
缺点:(学习使我快乐, 忽略吧)
目前我遇到的大部分是活动网页.
这边文章目的是使用网页支付, 更好的适配审核, 所以, 有舍有得, 我们不去看缺点, 毕竟, 就过审而言, 这点不算什么…
进入正题, 网页支付, 就是使用WKWebView打开网页, 由网页调用支付宝or微信的网页的SDK, 这部分由前端同学(甩锅中…)完成, 我们这边通过WK的代理获取当前请求的网络连接,判断是不是需要openURL到微信或者支付宝.
这个相当于你App的铭牌, 别的App想要跳转到你的App的时候, 就需要知道你App的铭牌,一个App可以设置多个.
设置进入前台(跳转回来) 处理服务器需要刷新的网页
大致流程:
// 判断非返回或者刷新
if (!(navigationAction.navigationType == WKNavigationType.backForward || navigationAction.navigationType == WKNavigationType.reload)) {
// 微信判断
let pre_string = "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"
if request.url?.absoluteString.hasPrefix(pre_string) ?? false {
let par = WebPayTool.params(of: navigationAction.request.url)
let params: NSMutableDictionary = NSMutableDictionary(dictionary:par);
if var allKeys = params.allKeys as? [String] {
// openWebResult.webpaye.com这个是你自定义的你的App的名牌
// ://app_paycallback/ 是你回调后判断的类型 这个部分自定义, 逻辑自定义
let app_name = "openWebResult.webpaye.com://app_paycallback/"
let return_new_value = WebPayTool.urlDecodedString(app_name);
let returnKey = "redirect_url"
// 判断连接中是不是有redirect_url 参数, 添加或者更换为上面自定义的 app_name
if (allKeys.contains { (item: String) -> Bool in
return item == returnKey
}) {
// 有对应的回调地址
let return_old_value = params[returnKey] as? String
let isOpenOther = return_old_value == return_new_value
if !isOpenOther {
// 保存回调地址 这个是自己服务器的参数,也就是支付或者回来后, 网页需要刷新的页面
self.appWillBecomeActiveWebReloadUrlString = WebPayTool.urlDecodedString(return_old_value ?? "")
params[returnKey] = return_new_value;
allKeys.append(returnKey);
var newURLStr = NSString(format: "%@", pre_string)
for key in allKeys {
if let value = params[key] {
newURLStr = NSString(format: "%@", newURLStr).urlAddCompnent(forValue: value as! String, key: key) as NSString
}
}
// 重新组织好新的连接, 重新请求
if let newUrl = URL(string: newURLStr as String) {
decisionHandler(.cancel)
var newRequest = URLRequest.init(url: newUrl)
newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
webView.load(newRequest)
return;
}
}
}
}
}
}
大致流程:
// 支付宝判断
if let url = request.url {
let urlString = url.absoluteString
if urlString.hasPrefix("https://openapi.alipay.com/gateway.do") {
if let aliUrl = URL(string: urlString) {
let returnReloadKey = "return_url"
let par = WebPayTool.params(of: aliUrl)
let params: NSMutableDictionary = NSMutableDictionary(dictionary:par);
let return_old_value = params[returnReloadKey] as? String
let redirct = WebPayTool.urlDecodedString(return_old_value ?? "")
self.appWillBecomeActiveWebReloadUrlString = redirct
}
}
}
if let urlString = navigationAction.request.url?.absoluteString {
if urlString.contains("alipay://") || urlString.contains("alipays://"){
if urlString.contains("fromAppUrlScheme") {
decisionHandler(.cancel)
// 下面是重点, 这里面处理了支付宝支付的链接参数问题
// 主要 是 你跳去了支付宝App 还可以调回来
WebPayTool.handleWebUrl(urlString)
return
}
}
}
修改fromAppUrlScheme的参数为自定义的App的URL Scheme
if ([url containsString:@"fromAppUrlScheme"]) {
NSString *encodeUrl = [url stringByRemovingPercentEncoding];
NSArray *urlParArry = [encodeUrl componentsSeparatedByString:@"?"];
NSMutableDictionary *beSetParDic = [self dictionaryWithJsonString:urlParArry.lastObject];
// 下面是重点 fromAppUrlScheme的设置, 是支付宝客户端回跳到你的App的参数,设置URL Scheme
[beSetParDic setObject:@"你的App的自定义的URL Scheme" forKey:@"fromAppUrlScheme"];
NSString *overJsonStr = [self dictionaryToJson:beSetParDic];
NSString *overUrlStr = [NSString stringWithFormat:@"%@?%@",urlParArry.firstObject,overJsonStr];
NSString *canUseEncodeUrl = [overUrlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:canUseEncodeUrl]];
}
上面是有关支付宝和微信的网页支付的关键代码内容, 具体的需要根据自己的业务逻辑去做代码适配.
最后
奉上Demo地址