iOSAPP实现H5⽀付⽰例总结
H5⽀付流程
1、发起下单请求()注:交易类型trade_type=MWEB
3、中间页进⾏H5权限的校验,安全性检查()
4、如果权限校验成功,⽀付中间页会发起⽀付请求。请求完毕跳到回调页⾯(由redirect_url决定)。APP需要在webView中监听这个请求,打开进⾏⽀付。如:
weixin://wap/pay?prepayid%3Dwx2718114258281033efb8751f1574826586&package=2965581453&noncestr=1545905512&sign=cb0f6dbd067549a04aada9c3eef09aac
5、⽀付完毕跳回APP。
Referer和redirect_url说明
HTTP Referer是header的⼀部分,当浏览器向web服务器发起请求的时,⼀般会带上Referer,告诉服务器我是从哪个页⾯链接过来。中间页会对Referer进⾏校验,⾮安全域名将不能正常加载。
redirect_url是中间页唤起⽀付之后,页⾯重定向的地址。中间页唤起⽀付后会跳转到指定的redirect_url。并且APP在⽀付完成时,也是通过redirect_url回调结
果,redirect_url⼀般是⼀个页⾯地址,所以⽀付完成会打开Safari浏览器。本⽂通过修改redirect_url,实现⽀付完毕跳回当前APP。
注意:会校验Referer(来源)和redirect_url(⽬标)是否是安全域名。如果不传redirect_url,会将Referer当成redirect_url,唤起⽀付之后会重定向到Referer对应的页⾯。
建议带上redirect_url。
代码实现
1、info.plist配置scheme
需要将H5⽀付的安全域名配置成scheme,⽀付完成会通过这个scheme跳转回APP。
<key>CFBundleURLTypes</key>
<array>
<dict>网页app
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>wxPay</string>
<key>CFBundleURLSchemes</key>
<array>
<string>scheme(安全域名)</string> </array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>wechat</string>
<string>weixin</string>
</array>
2、拦截中间页,截取redirect_url
//这个referer和安全域名以及配置在info.plist中scheme⼀致
NSString *referer = [NSString stringWithFormat:@"%@://",wxScheme];
if ([newUrl rangeOfString:@"wx.tenpay"].location != NSNotFound) {
//截取redirect_url对应的值
NSDictionary *params = [HJStringHelper getUrlParam:newUrl];
NSString *backUrl = params[@"redirect_url"];
if ([backUrl isEqualToString:referer]) {
//截取redirect_url被替换成referer,不拦截
return YES;
}else{
//记录当前的redirectUrl,并拦截请求
dispatch_async(dispatch_get_main_queue(), ^{
NSRange range = [newUrl rangeOfString:@"redirect_url="];
NSString *reqUrl;
if (range.length>0) {
reqUrl = [newUrl substringToIndex:range.location+range.length];
reqUrl = [reqUrl stringByAppendingString:referer];
}else{
reqUrl = [newUrl stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=%@",referer]];
}
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:reqUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
//设置授权域名
[request setValue:referer forHTTPHeaderField:@"Referer"];
[self.webView loadRequest:request];
});
return NO;
}
}
2、拦截中间页中打开请求
中间页加载成功后,会收到⼀个打开的请求,⽤openURL:打开这个url实现跳转到⽀付。
if([newUrl rangeOfString:@"weixin://wap/pay"].location != NSNotFound){
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if (@available(iOS 10.0, *)){
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}else{
[[UIApplication sharedApplication] openURL:url];
}
}else{
}
return NO;
}
3、加载重定向地址
中间页跳转到时,会将页⾯从定向到redirect_url,由于redirect_url被我们修改为scheme,所以需要拦截这个⾮法的scheme请求,替换成记录下的redirect_url。
if([newUrl isEqualToString:referer]){
dispatch_async(dispatch_get_main_queue(), ^{
if (directUrl) {
//注意,这个地⽅需要对redirectUrl解码,因为截取的redirectUrl被完全编码了,需要先解码才能加载
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[HJStringHelper directUrl]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; [self.webView loadRequest:request];
}
});
return NO;
}
完整代码如下
以UIWebView为例
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
/
/添加⽀付功能
NSURL *url = [request URL];
NSString *newUrl = url.absoluteString;
//获取安全域名
NSString *wxScheme = [h5WXPayScheme copy];
if (wxScheme.length>0) {
//使⽤安全域名拼接referer
NSString *referer = [NSString stringWithFormat:@"%@://",wxScheme];
if ([newUrl rangeOfString:@"wx.tenpay"].location != NSNotFound) {
NSDictionary *params = [HJStringHelper getUrlParam:newUrl];
NSString *backUrl = params[@"redirect_url"];
if ([backUrl isEqualToString:referer]) {
return YES;
}else{
dispatch_async(dispatch_get_main_queue(), ^{
NSRange range = [newUrl rangeOfString:@"redirect_url="];
NSString *reqUrl;
if (range.length>0) {
reqUrl = [newUrl substringToIndex:range.location+range.length];
reqUrl = [reqUrl stringByAppendingString:referer];
}else{
reqUrl = [newUrl stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=%@",referer]];
}
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:reqUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
//设置授权域名
[request setValue:referer forHTTPHeaderField:@"Referer"];
[self.webView loadRequest:request];
});
return NO;
}
}else if([newUrl rangeOfString:@"weixin://wap/pay"].location != NSNotFound){
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if (@available(iOS 10.0, *)){
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}else{
[[UIApplication sharedApplication] openURL:url];
}
}else{
}
return NO;
}else if([newUrl isEqualToString:referer]){
dispatch_async(dispatch_get_main_queue(), ^{
if (directUrl) {
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[HJStringHelper directUrl]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; [self.webView loadRequest:request];
}
});
return NO;
}
}
return [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
}
还有⼀篇⽂章讲的是H5⽀付封装,H5⽀付不仅可以在⽹页上使⽤,原⽣也可以调⽤。具体内容见
到此这篇关于iOS APP实现H5⽀付⽰例总结的⽂章就介绍到这了,更多相关iOS APP实现H5⽀付内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论