iOS-微信支付总结

前言:

在iOS开发中,常常会涉及到支付功能,而微信支付是必不可少的,这里笔者就简单整理了一下微信支付的流程,即使分享也是对自己学习的总结。


一. 微信集成的基本流程(所需资料由公司提供)

微信商户申请步骤:http://kf.qq.com/faq/120911VrYVrA150906F3qqY3.html

1.在微信开放平台注册一个账号:https://open.weixin.qq.com
2.进入管理中心–>移动应用–>创建移动应用;根据页面提示完善应用资料
3.审核通过后,进入应用详情页–>查看应用详情,这里可以查看AppID和AppSecret以及一些接口信息
4.应用创建时是没有支付能力的,需要额外申请,具体的申请过程,可根据网页提示即可完成
5.审核通过后,微信平台会给你填写审核资料时预留邮箱发送一个邮件,邮件中包含了与支付能力相关的微信商户号的信息,然后到微信的商户平台:https://pay.weixin.qq.com 填写相关资料,最主要的是验证开户行,微信会向你填写的开户银行账户汇一笔钱(一般是几分钱),让你们的财务查一下,然后验证一下即可,通过后即获取了支付能力

微信支付开发者文档:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

在文档中,点击”支付账户—>支付账户“,可以看到关于APPID的信息:

iOS-微信支付总结_第1张图片

注意:
1.这个APPID是开发中使用微信支付必须要用的东西,而这个APPID也只有商户通过在该微信支付平台注册,花个300元,填写很多相关重要信息,还要上传营业执照等必要手续,才能获取的APPID。
2.而商业app应用程序,在客户使用app微信消费,程序会根据这个唯一的APPID,查找到商户,然后把消费者的金额数传递到商户的账户里。
3.对于开发者,微信支付平台提供了测试的Demo,也在Demo源码中提供了有用的用于测试代码的APPID。这样开发者就除去了花个300元买个APPID的必要性。

微信支付开发步骤:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5

微信SDK下载:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319164&token=&lang=zh_CN


微信集成的具体步骤

1.添加微信支付SDK,把官方SDK包中的SDKExport文件夹拖到自己的工程里,.text文件可以不用拖,是提供给开发者阅读的。

iOS-微信支付总结_第2张图片

2.打开red_me.text文件,里面主要是各各SDK版本中更新所解决的问题,以及注意事项,红色框中的部分是需要用的。

iOS-微信支付总结_第3张图片

3.点击项目名,在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖:Security.framework、CoreTelephony.framework、SystemConfiguration.framework、libc++.tbd、libz.tbd、libsqlite3.tbd、libWeChatSDK.a
iOS-微信支付总结_第4张图片

4.项目设置APPID,在工程项目中添加商户自己的APPID
商户在微信开放平台申请开发APP应用后,微信开放平台会生成APP的唯一标识APPID。

iOS-微信支付总结_第5张图片

5.由于iOS9默认限制了http协议的访问,所以Xcode7以后就需要在开发中手动添加 App Transport Security Settings 设置,在info.plist中添加如下配置(文中以XML格式描述)

<key>NSAppTransportSecuritykey>
<dict>
<key>NSAllowsArbitraryLoadskey>
<true/>
dict>

6.iOS 9.0以上的系统如果要正常调起微信,还需要将使用的URL Schemes添加为白名单,在App对应的info.plist中添加如下配置(文中以XML格式描述)。

<key>LSApplicationQueriesSchemeskey>
<array>
<string>weixinstring>
array>

修改后info.plist文件中就会出现红色框中的两项内容

iOS-微信支付总结_第6张图片

7.注册APPID,在AppDelegate里注册微信

iOS-微信支付总结_第7张图片

在需要使用微信支付的地方导入:

#import "WXApi.h"

在AppDelegate中的didFinishLaunchingWithOptions方法中添加以下代码向微信注册APP:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //向微信注册APPID
    [WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"demo 2.0"];
    return YES;
}

8.发起支付,调其微信支付
在这之前,我们先打开微信官方提供的Demo

iOS-微信支付总结_第8张图片

iOS-微信支付总结_第9张图片

iOS-微信支付总结_第10张图片

在官方给的代码中,我们会注意到一些细节,比如Demo中使用了MRC的autorelease,你可以把它去掉;类方法可以换成实例方法,根据你的实际项目开发需求:

- (NSString *)jumpToBizPay {

    //根据查询微信API文档,我们需要添加两个需要的判断
    //判断是否安装了微信
    if (![WXApi isWXAppInstalled]) {
        NSLog(@"没有安装微信");
        return nil;
    }else if (![WXApi isWXAppSupportApi]){
        NSLog(@"不支持微信支付");
        return nil;
    }

    NSLog(@"安装了微信,而且微信支持支付");

    //支付流程实现
    NSString *urlString   = @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=ios";
    //解析服务端返回json数据
    NSError *error;
    //加载一个NSURL对象
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    //将请求的url数据放到NSData对象中
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    if ( response != nil) {
        NSMutableDictionary *dict = NULL;
        //IOS5自带解析类NSJSONSerialization从response中解析出数据放到字典中
        dict = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];

        NSLog(@"url:%@",urlString);
        if(dict != nil){
            NSMutableString *retcode = [dict objectForKey:@"retcode"];
            if (retcode.intValue == 0){
                NSMutableString *stamp  = [dict objectForKey:@"timestamp"];

                //调起微信支付
                PayReq *req= [[PayReq alloc] init];
                req.partnerId = [dict objectForKey:@"partnerid"];
                req.prepayId = [dict objectForKey:@"prepayid"];
                req.nonceStr = [dict objectForKey:@"noncestr"];
                req.timeStamp = stamp.intValue;
                req.package = [dict objectForKey:@"package"];
                req.sign  = [dict objectForKey:@"sign"];
                [WXApi sendReq:req];
                //日志输出
                NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dict objectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
                return @"";
            }else{
                return [dict objectForKey:@"retmsg"];
            }
        }else{
            return @"服务器返回错误,未获取到json对象";
        }
    }else{
        return @"服务器返回错误";
    }
}

接着添加一个支付按钮,调用上述的方法

iOS-微信支付总结_第11张图片

    NSString *weixinBackStr = [self jumpToBizPay];
    if (![weixinBackStr isEqualToString:@""]) {
        NSLog(@"微信支付返回的信息:%@",weixinBackStr);
    }

这里还要注意一点,在调起微信支付之前,需要进行判断是否安装了微信

iOS-微信支付总结_第12张图片

    //根据查询微信API文档,我们需要添加两个需要的判断
    //判断是否安装了微信
    if (![WXApi isWXAppInstalled]) {
        NSLog(@"没有安装微信");
        return nil;
    }else if (![WXApi isWXAppSupportApi]){
        NSLog(@"不支持微信支付");
        return nil;
    }
    NSLog(@"安装了微信,而且微信支持支付");

9.最后就是处理微信支付的返回信息(回调方法)
在官方Demo中可以看到具体如何使用

iOS-微信支付总结_第13张图片

我们只需要红色框中的代码即可

iOS-微信支付总结_第14张图片

#pragma mark - WXApiDelegate
- (void)onResp:(BaseResp *)resp {
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回结果,实际支付结果需要去微信服务器端查询
        NSString *strMsg,*strTitle = [NSString stringWithFormat:@"支付结果"];

        switch (resp.errCode) {
            case WXSuccess:
                strMsg = @"支付结果:成功!";
                NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
                break;

            default:
                strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
                NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
                break;
        }

        UIAlertController *alert = [UIAlertController alertControllerWithTitle:strTitle message:strMsg preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *certainAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

        }];

        [alert addAction:certainAction];
        [self.window.rootViewController presentViewController:alert animated:YES completion:nil];

    }

}

10.根据实际开发需求,我们可能还需要回传App的相关信息

iOS-微信支付总结_第15张图片

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    return [WXApi handleOpenURL:url delegate:self];
}

常见异常Bug处理

常见问题为微信支付调起不成功,每次调起只能调起一个带有你返回确认按钮的页面。
原因:参数错误,特别注意参数(签名),后台的返回的参数不正确。
解决方案:逐个校验参数,签名可以本地加密处理,不要依赖后台的返回签名,有的时候后台返回的是不正确的


尾巴:

本文只是一个简单的发起支付流程的演示,下单、签名、查单和支付通知均在服务器后台实现。若遇到其他问题欢迎和楼主分享评论。

以上部分概述内容出自以下博客的链接,以此感谢!!!

http://www.cnblogs.com/goodboy-heyang/p/5255818.html

http://www.cnblogs.com/jys509/p/5130990.html

你可能感兴趣的:(iOS)