一、需求
在原生App内镶嵌H5页,由H5页面调起支付
- WebView加载H5页面(一般是订单页)
- 点击支付,调起支付App客户端进行支付
- 支付完成,返回APP
二、微信H5支付
1. 调起微信的项目设置
选中
TARGETS
一栏,在info
中的LSApplicationQueriesSchemes
添加weixin
,已添加过的可以忽略此步骤
2. 后台通过微信统一下单接口生成下单url
web端通过url请求微信统一下单接口 例如:h5点击【立即支付】按钮,h5通过订单参数创建微信订单,返回相应的支付链接(wx.tenpay.com/cgi-bin/mmp…
3. 拦截WKWebView加载的微信支付统一下单链接, 将redirect_url参数修改为唤起自己App的URLScheme
4. 跳转 微信支付
5. URL Types配置
选中TARGETS
一栏,在info
中的URL Types
添加一项,URL Schemes 填写www.xxx.cn
和 redirect_url 一致,为了能使微信回调打开App
6. 微信支付取消或完成回调打开App
AppDelegate
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if url.scheme == "www.xxx.cn" {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNotifaication_Name_WXPay_H5), object: nil)
return true
}
return false
}
WebViewController
// 在viewDidLoad中监听
NotificationCenter.default.addObserver(self, selector: #selector(dealWXH5PayResult), name: NSNotification.Name(rawValue: kNotifaication_Name_WXPay_H5), object: nil)
@objc func dealWXH5PayResult() {
// 查询订单信息
}
在app 以下是实现代码:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.url else {
decisionHandler(.allow)
return
}
// 拦截微信支付
let absoluteString = url.absoluteString
let redirect_url = "www.xxx.cn%3A%2F%2Fwxpaycallback%2F" //www.xxx.cn://wxpaycallback/
// 拦截微信支付统一下单链接,修改 redirect_url 参数为自定义 URL Scheme
if absoluteString.hasPrefix("https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"),
!absoluteString.hasSuffix("redirect_url=\(redirect_url)") {
decisionHandler(.cancel)
let redirectUrl: String
if absoluteString.contains("redirect_url=") {
if let redirectRange = absoluteString.range(of: "redirect_url=") {
redirectUrl = absoluteString[..<redirectRange.lowerBound] +
"redirect_url=\(redirect_url)"
} else {
redirectUrl = absoluteString + "redirect_url=\(redirect_url)"
}
} else {
redirectUrl = absoluteString + "&redirect_url=\(redirect_url)"
}
guard let newUrl = URL(string: redirectUrl) else { return }
var newRequest = URLRequest(url: newUrl, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 30)
newRequest.allHTTPHeaderFields = navigationAction.request.allHTTPHeaderFields
webView.load(newRequest)
return
}
// 跳转 微信支付
if url.scheme == "weixin" {
decisionHandler(.cancel)
let canOpen = UIApplication.shared.canOpenURL(navigationAction.request.url!)
if canOpen {
UIApplication.shared.open(navigationAction.request.url!)
}
return
}
decisionHandler(.allow)
}
三、支付宝支付
支付宝支付相对简单
1. 拦截支付宝H5支付
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let url = navigationAction.request.url else {
decisionHandler(.allow)
return
}
// 支付宝支付
if url.host == "mclient.alipay.com" {
decisionHandler(.cancel)
AlipaySDK.defaultService().payInterceptor(withUrl: navigationAction.request.url?.absoluteString, fromScheme: "QKYC") { [weak self] reponse in
guard let strongSelf = self else {return}
// 处理支付成功与否
strongSelf.dealShopAlipayReponse(reponse)
}
return
}
}
支付宝 h5 支付转 native 支付接口
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////支付宝 h5 支付转 native 支付接口////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
/**
* 从h5链接中获取订单串并支付接口(自版本15.4.0起,推荐使用该接口)
*
* @param urlStr 拦截的 url string
*
* @return YES为成功获取订单信息并发起支付流程;NO为无法获取订单信息,输入url是普通url
*/
- (BOOL)payInterceptorWithUrl:(NSString *)urlStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlock;
2. 在AppDelegate 检测支付宝打开App
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
/// 支付宝支付
if url.host == "safepay" {
AlipaySDK.defaultService().processOrder(withPaymentResult: url, standbyCallback: nil)
return true
}
return false
}