iOS开发之微信支付的集成

作者: Alexander | 来源:发表于2016-03-21 11:53 被阅读411次

前言

虽然ApplePay的进军中国市场,但是就目前而言,微信支付和支付宝仍占据主导地位,本章主要是介绍项目中的微信支付是如何集成SDK的.想要了解更多关于iOS的知识,可以关注我的微博,@WilliamAlex大叔一起分享今天学到的iOS相关知识.

集成微信支付的主要思路

  • 思路 : 在集成之前,我们先要详细了解官方文档中微信支付这一板块,它已经给我们提出了集成步骤.
  • 主要步骤 :
        1, 项目设置APPID
        2, 注册APPID
        3, 调起支付
        4, 处理支付结果的回调
  • 详细说明步骤;

        1, 设置项目的APPID:
                            商户在微信开放平台申请开发APP应用后,微信开放平台会生成APP的唯一标识APPID。在Xcode中打开项目,设置项目属性中的URL Schemes为您的APPID
        2, 注册APPID:
                            商户APP工程中引入微信lib库和头文件,调用API前,需要先向微信注册您的APPID
        3, 调起支付:
                            商户服务器生成支付订单,先调用【统一下单API】生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付
        4, 处理支付结果的回调:
                            照微信SDK Sample,在类实现onResp函数,支付完成后,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意    一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准
  • 微信注册ID :wxb4ba3c02aa476ea1: 这个ID可以直接在下载的示例项目SDKSample中的AppDelegate中找到

集成思路明白以后,我们开始集成微信支付

  • 集成前的准备工作

  • 了解微信开发文档


    选择APP支付版块.png
  • 文档中需要注意的点


    支付结果回调.png
  • 我们只需要根据文档中的提示步骤即可集成


    集成步骤.png
  • 下载官方文档中提供的头文件和静态库


    头文件和静态库.png
  • 创建自己的一个项目集成微信支付

    • 导入头文件


      导入头文件.png
  • 编译后可能会报很多错误,这时候我们需要导入相关的依赖文件

    添加依赖.png
  • 编译项目项目会崩溃掉,错误提示我们需要在info.plist文件中添加两个key


    添加key.png
  • 添加的结果


    添加key.png
  • 项目APPID的设置


    设置白名单.png
  • 注册APPID

    • 向微信注册支付


      向微信注册.png
  • 调起微信支付


    调起微信支付.png
    • 注意: 这个方法是监听模拟微信支付按钮的方法
  • 具体实现


    支付的实现01.png
支付的实现02.png 支付的实现03.png
  • 处理支付结果的回调
处理支付结果的回调.png
 - 注意: 处理支付结果的回调是代理方法,所以需要遵守协议.
  • 代码实现
  • 向微信注册(注册ID:wxb4ba3c02aa476ea1)
// 导入头文件,第一步就是向微信注册.
#import "AppDelegate.h"
#import "WXApi.h"

@interface AppDelegate ()<WXApiDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //向微信注册
    [WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"com.William.Alex"];

    return YES;
}

  • 注意点 :

  • 1,注册时的ID是根据公司要求到微信公众平台申请注册的,需要300元人民币,所以我这里就用官方文档中提供测试用的ID.

  • 2, 项目中遵守了代理协议,主要是用于处理支付结果回调使用,后面会用到.

  • 调起微信支付


#import "ViewController.h"
#import "WXApi.h"

@interface ViewController ()

@end

@implementation ViewController

/**
 *  调起微信支付
 */
- (IBAction)payFormoneryInAlexWallet {

    NSString *res = [self jumpToBizPay];
    if( ![res isEqual:@""] ) {
        UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"支付失败"
                                                        message:res
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        // 提示用户支付失败,res是支付失败后系统返回的信息
        NSLog(@"支付失败信息%@",res);
        [alter show];
  }
}


- (NSString *)jumpToBizPay {

    // 判断用户当前用户是否下载微信/是否支持微信支付
    if ( ![WXApi isWXAppInstalled] ) {  // 表示用户没有安装微信

        // 提示用户需要安装微信才能使用微信支付
        NSLog(@"需要安装微信才能使用微信支付");

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"支付失败"
                                                            message:@"是否前往Appstore中下载微信"
                                                           delegate:self
                                                  cancelButtonTitle:@"取消"
                                                  otherButtonTitles:nil, nil];
        [alertView show];
        return nil;
    }else if(![WXApi isWXAppSupportApi])
    {  // 表示当前不支持微信支付

        // 提示用户当前环境不支持微信支付
        NSLog(@"不支持微信支付");

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"支付失败"
                                                            message:@"当前不支持微信支付"
                                                           delegate:self
                                                  cancelButtonTitle:@"取消"
                                                  otherButtonTitles:nil, nil];
        [alertView show];
        return nil;
    }

    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];  // 将autoresease去掉,类方法变为对象方法即可
                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 @"服务器返回错误";
    }
}
  • 注意 : 官方文档中提供的是类方法,并且环境是MRC,如果公司要求是MRC,那么直接去:项目-->Bulid-->comple Source -->双击文件-->填写-fobjc-arc.又或者将MRC中释放对象的属性去掉,将类方法,变为实例方法即可.

  • 处理支付结果的回调


/**
 *  不管支付授权是否成功或者失败,又或者是用户自己取消授权,都会调用该代理方法
 */
#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;
        }
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alert show];

    }
}

总结

  • 可能会疑惑的几点:

    • 1, 微信官方文档提供的Demo中使用的MRC(有autorelease等属性标识),为什么文章中不是MRC呢?
      答:我将官方文档中的类方法变成了对象方法了,在本篇文章中,直接调用该方法即可,整体是在ARC环境下创建的.这是一种方法,还有一种方法就是ARC和MRC混编,如下图步骤设置即可.


      ARC和MRC的混编.png
  • 2 官方文档中的示例是这样的


    微信示例.png
  • 3 调起微信支付,需要监听按钮的点击哦


    监听按钮的点击.png

相关文章

网友评论

本文标题:iOS开发之微信支付的集成

本文链接:https://www.haomeiwen.com/subject/ocyklttx.html