因项目需求不能再app内使用苹果内购,苹果审核要求也不能使用支付宝、微信,所以想使用H5支付,这样可以绕开苹果的支付检测。
下面就说一下在对接支付宝H5过程中碰到的问题。
前端同学按照苹果文档做好以后,给我一个地址,但是打开地址不会自动跳转到支付宝app,需要自己做拦截,这一块支付宝文档也有说明,查看上方地址就可以找到相应代码。
但是有一个问题,就是支付完成以后点击完成按钮不会返回到原来的app了,还是停留在支付宝app,这样体验就非常差了。经过一番查找最终得以解决。就是替换掉url里边的一个参数。
通过在webview的代理中拦截打印可以看到支付链接是这样的:
alipay://alipayclient/?%7B%22requestType%22%3A%22SafePay%22%2C%22fromAppUrlScheme%22%3A%22alipays%22%2C%22dataString%22%3A%22h5_route_token%3D%5C%221233456%5C%22%26is_h5_route%3D%5C%22true%5C%22%22%7D
这里边有一个参数是fromAppUrlScheme,对应的值是alipays,很明显这个值就是需要打开app的scheme。然后只需要替换链接中的alipays为自己app的scheme就可以了。但是替换的时候要注意编码问题,alipay://alipayclient/?这部分是不需要编码的,只有后边的参数才需要编码。我把整个修改过程直接贴出来吧。(有人说项目中不要出现“alipays”这样的字符串,怕苹果检测出来。我这边字符串出现了“alipays”,并且通过了审核。如果担心自己就处理一下吧。)
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let reqUrl = navigationAction.request.url?.absoluteString {
if reqUrl.hasPrefix("alipays://") || reqUrl.hasPrefix("alipay://") {
var temp = reqUrl
temp = temp.urlDecode()
var urls = temp.split(separator: "?").map({String($0)})
if urls.count < 1 {
return
}
let jsonData = urls[1].data(using: .utf8)
let json = try? JSONSerialization.jsonObject(with: jsonData!, options: .mutableContainers) as? [String:Any]
guard var dic = json else {
printf("dic is nill")
return
}
dic["fromAppUrlScheme"] = "your scheme"
guard let stringData = (try? JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)) else { return }
urls[1] = String.init(data: stringData, encoding: .utf8)!.urlEncoded
let openUrl = urls.joined(separator: "?")
guard let url = URL(string: openUrl) else {
printf("error url")
return
}
UIApplication.shared.open(url, options: [:], completionHandler: nil)
decisionHandler(.cancel)
return;
}
}
decisionHandler(.allow)
}
这样支付完成就可以愉快的返回到自己app了。
上述代码有一个点需要特别注意一下,就是decisionHandler(.cancel)这个回调,一定要是decisionHandler(.cancel)(webview对应return false),停止网页继续加载。如果这里写成decisionHandler(.allow)(webview对应return true),会导致有时候支付完成点击支付宝右上角完成按钮无法返回到原app。
具体现象是:如果你的支付宝app设置了打开软件的密码锁(就是打开支付宝需要先解锁,不解锁无法使用)。在没有解锁的状态下,H5支付拦截的地方无论写成decisionHandler(.cancel)或者decisionHandler(.allow)都可以。但是,一旦支付宝app已解锁,这个时候再使用H5支付如果回调写成decisionHandler(.allow),就可能会出现支付完成以后点击支付宝右上角完成按钮无法返回到原app的现象。所以当你拦截url跳转到支付宝的时候一定要记得调用decisionHandler(.cancel)停止网页继续加载。
网友评论