通过H5直接打开微信支付

时间:2024-05-31 11:35:06

前两天通过H5集成了一款游戏,游戏中集成了微信支付。但是我们的产品对H5跳转微信充值有一定要求,我大致说明一下。

前言:直接使用[[UIApplication sharedApplication] openURL:request.URL]; 这句代码只是跳转了safari浏览器,这样不满足我们产品的需求,另外在safari浏览器中还会有一个弹窗,”是否打开微信“。
如果使用SFSafariViewController也会出现是否打开微信的弹窗。

在这里需要引进一个概念 URL重定向

1、一般情况下服务器端会给一个象征着H5页面调起充值页面的链接。这个链接就是我们所需要的链接,请注意一定要确保这个链接是可用的。
2、在项目的Info.plist中添加一个URL Schemes(用于跳回我们项目),如下图所示通过H5直接打开微信支付这个URL schemes 是跳转到微信支付无论成功失败,要返回本app的依据,当然这个依据要让微信知道,请往下看:
3、流程中最重要的一步 使用webview加载(load)这个url,注意仅仅是load这个url即可,不需要讲webview展示出来,也不需要设置位置什么的,但是要设置代理。

4、直接看代码:

#import "XLLianyunPayWK.h"
#import <WebKit/WebKit.h>

static const NSString *CompanyFirstDomainByWeChatRegister = @"xianlaigame.com";
#define XDX_URL_TIMEOUT 10

@interface XLLianyunPayWK()<WKUIDelegate,WKNavigationDelegate>


@property (nonatomic,strong) WKWebView * wkweb;


@end

@implementation XLLianyunPayWK

//创建webview
- (void)createWKWebView{
    WKWebViewConfiguration * configura = [[WKWebViewConfiguration alloc] init];
    WKUserContentController * userCont = [[WKUserContentController alloc] init];
    configura.userContentController = userCont;
    self.wkweb = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configura];
    [self.wkweb loadRequest: [NSURLRequest requestWithURL:[NSURL URLWithString:self.targetUrl]]];
    self.wkweb.navigationDelegate = self;
    self.wkweb.UIDelegate = self;
}

// 开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    [SVProgressHUD show];
}


- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"加载完成");
    [SVProgressHUD dismiss];
}


#pragma mark - WKNavigation Delegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSLog(@"---- 跳转 ----- ");
    NSURLRequest *request        = navigationAction.request;
    NSString     *scheme         = [request.URL scheme];
    // decode for all URL to avoid url contains some special character so that it wasn't load.
    NSString     *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    NSLog(@"Current URL is %@",absoluteString);
    
    static NSString *endPayRedirectURL = nil;
    
//     Wechat Pay, Note : modify redirect_url to resolve we couldn't return our app from wechat client.
    if ([absoluteString hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![absoluteString hasSuffix:[NSString stringWithFormat:@"redirect_url=XLHY.%@://",CompanyFirstDomainByWeChatRegister]]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        
#warning Note : The string "xiaodongxie.cn://" must be configured by wechat background. It must be your company first domin. You also should configure "URL types" in the Info.plist file.
        
        // 1. If the url contain "redirect_url" : We need to remember it to use our scheme replace it.
        // 2. If the url not contain "redirect_url" , We should add it so that we will could jump to our app.
        //  Note : 2. if the redirect_url is not last string, you should use correct strategy, because the redirect_url's value may contain some "&" special character so that my cut method may be incorrect.
        NSString *redirectUrl = nil;
        if ([absoluteString containsString:@"redirect_url="]) {
            NSRange redirectRange = [absoluteString rangeOfString:@"redirect_url"];
            endPayRedirectURL =  [absoluteString substringFromIndex:redirectRange.location+redirectRange.length+1];
            redirectUrl = [[absoluteString substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=XLHY.%@://",CompanyFirstDomainByWeChatRegister]];
        }else {
            redirectUrl = [absoluteString stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=XLHY.%@://",CompanyFirstDomainByWeChatRegister]];
        }
        
        NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT];
        newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
        newRequest.URL = [NSURL URLWithString:redirectUrl];
        [webView loadRequest:newRequest];
        return;
    }
    
    // Judge is whether to jump to other app.
    if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        if ([scheme isEqualToString:@"weixin"]) {
            // The var endPayRedirectURL was our saved origin url's redirect address. We need to load it when we return from wechat client.
            if (endPayRedirectURL) {
                [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:endPayRedirectURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT]];
            }
        }else if ([scheme isEqualToString:[NSString stringWithFormat:@"XLHY.%@",CompanyFirstDomainByWeChatRegister]]) {
            
        }
        
        BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:request.URL];
        if (canOpen) {
            [[UIApplication sharedApplication] openURL:request.URL];
            self.openBlock();
        }
        return;
    }
    
    decisionHandler(WKNavigationActionPolicyAllow);
}

5、这个代码是可以直接使用的,但是要注意:static const NSString *CompanyFirstDomainByWeChatRegister = @"xianlaigame.com"; 这个静态全局变量要与刚才url scheme 保持一致。注意URL SCHEME 中的那个XLHY可以不写。

6、webview的那个代理方法中所有redirect_url=XLHY这个位置中的XLHY,可以*替换,但是请和URL scheme 中保持一致。

总结:这个方法中非常重要的一个概念是:url重定向,至于什么是重定向,我将在下篇博客说明;
我是磊怀 2849765859 是我的QQ 欢迎联系我