支付__解读我的微信和支付宝封装类库(三)

千呼万唤始出来,终于经过近10天努力,对微信和支付宝支付方面文档以及自己的项目多次研究和尝试,终搞定了支付的技术并有了以下的成果!
感谢开源的环境,可以共享我的项目,如果不错的话,请给个星星哦!
干货:本篇最后会附上自己封装的微信和支付宝支付的类库,欢迎指点,共同进步!

我的家乡欢迎您.jpg

本篇说些什么呢?

首先附上目录:
一.微信和支付宝支付异同点分析
二.我封装的支付类库原理讲解
三.集成我的支付类库的步骤
四.注意事项
五.附上我的演示Demo中的流程图

一.微信和支付宝支付异同点分析
1.二者申请的异同
微信支付申请过程中需要¥300审核费,而支付宝的申请必须提供公司资质才能申请使用;
也就是说,个人申请微信支付您需要是土豪,而申请支付宝支付您需要有靠山,哈哈,开个玩笑!

2.二者的支付整个流程异同
简单来说:

相同的地方:
下订单 —>调支付客户端(微信或者支付宝)—>真正的支付—>通知支付成功

不同的地方:
支付宝:支付成功后,支付宝后台主动把支付情况—>支付宝客户端—>告知我们的商家,这里我称为主动性支付!
微信:支付成功后,
微信后台异步通知—>商户后台
微信App 通知—> 商户App 查询—>商户后台—>告知我们的商家 这里我称为被动性支付!

汇总:
支付宝:主动性支付
微信:被动性支付

3.其他异同
调启支付客户端并回去的异同:如下
支付宝支付:在urlScheme中加入自定义字符串标示回来的应用
微信支付:在url中写申请的AppId标示回来的应用
如下:


支付宝和微信urlScheme设置位置.png

微信支付成功下订单是至少7个参数,支付需要用到
支付宝成功下订单是一串字符串,支付需要
这里的不同点就是我封装的类库的入口处!

支付成功后的回调方式:
微信支付是代理回调
支付宝支付是Block回调

二.我封装的支付类库原理讲解
以上以支付宝和微信的支付不同点作为入口,来解析我封装的类库,即为WechatAliPay
在这个项目中,关于支付的有以下3个文件

1.CMWechatAliPayManager 的.h 和.m文件
一个发送支付请求的单例类,其中含有分别处理微信和支付宝的下订单成功后执行真正的支付是通过返回过来的订单参数
如果是字符串则证明是支付宝的返回,就用下面的方法

// 调用支付宝的支付接口
  [[AlipaySDK defaultService] payOrder:infoStr fromScheme:appScheme callback:^(NSDictionary *resultDic) {
      NSLog(@"reslut = %@",resultDic);
      NSString *resultStatus = resultDic[@"resultStatus"];
      [ws.delegate Wpay:ws andPayKind:WAPayKindAliPay andPayResult:[resultStatus intValue]];

  }];

调用支付宝的接口完成支付;
如果是字典则证明是微信的返回,则通过下面的方法包装PayReq 的参数,调用

// 判断自己的服务器的产生的订单参数返回是否正确,并返回包装好的参数
-(PayReq *)isWpayParamsIsCorrect:(NSDictionary *)params {
    
    if ([params allKeys].count >=6) {
        PayReq *req =[[PayReq alloc]init];
#warning 微信支付的订单参数(AppId等),不要忘记更改了
        req.openID =@"wxe9beac44b65d4815";
        req.partnerId =params[@"partnerid"];
        req.prepayId =params[@"prepayid"];
        req.nonceStr =params[@"noncestr"];
        req.timeStamp =[params[@"timestamp"] intValue];
        req.package =params[@"package"];
        req.sign =params[@"sign"];
        return req;
    }
    return nil;
}

sendReq方法,等待返回onResp 方法

2.CMWpaySearchResultDelegate.h文件
这是设定一个协议,当支付成功之后,会根据这个协议调用对应的方法完成支付后的工作:
如:当微信支付成功,走到 onResp ,我的代理就会调用 CMWpaySearchResultDelegate.h的Wpay:andPayKind:andPayResult: 如下


#pragma mark - 微信支付成功后返回

-(void) onResp:(BaseResp*)resp {
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回结果,实际支付结果需要去微信服务器端查询
        if ([self.delegate respondsToSelector:@selector(Wpay:andPayKind:andPayResult:)]) {
            [self.delegate Wpay:self andPayKind:WAPayKindWechat andPayResult:resp.errCode];
        }

       
    }
}

告诉我的客户端支付成功了
而当支付宝支付成功后,就会走到其设置的block种同样由我的代理调用Wpay:andPayKind:andPayResult: 如下


支付宝支付成功Block回调.png

完成支付完成后的事情。

3.支付完成后走到如下Wpay:andPayKind:andPayResult: 中,然后展示如下:

#pragma mark - CMWpaySearchResultDelegate
-(void)Wpay:(CMWechatAliPayManager *)manager andPayKind:(WAPayKind)payKind andPayResult:(int)code {
    DDLog(@"走到回调的地方了");
    if (payKind ==WAPayKindWechat) { // 微信
        switch (code) {
            case WXSuccess:
                
                // 1. 包装对应查询参数
                [DisplayHelper displaySuccessAlert:@"微信支付成功!"];
                // 2. 发送查询的是否成功的请求
                break;
                
            default:
                
                break;
        }
    }else { // 支付宝
        switch (code) {
            case 9000:// 成功
                [DisplayHelper displaySuccessAlert:@"支付宝支付成功!"];

                break;
            case 6001:// 取消
                break;
            default:
                break;
        }
    }
    
   
}

三.集成我的支付类库的步骤(具体部分详情请参照最后附带我另外2篇讲的关于微信和支付宝支付集成)

1.导入的库
导入的SDK如下:


导入的SDK最终效果.png

导入的系统库如下:
在Build Phases选项卡的Link Binary With Libraries中加入以下的依赖:

libc++.tbd
libz.tbd
SystemConfiguration.framework
CoreTelephony.framework
QuartzCore.framework
CoreText.framework
CoreGraphics.framework
Foundation.framework
UIKit.framework
CoreMotion.framework
CFNetwork.framework
Security.framework
libsqlite3.0.dylib
UIKit.framework

// 支付宝依赖的
AlipaySDK.framework

// 微信官方的库
libWeChatSDK.a

导入我的3个文件夹


导入我封装的库.png

2.更改的文件
AppDelegate中头文件和代理:

导入
#import "WXApi.h"
遵循
<WXApiDelegate>

AppDelegate中Code处理方面:
初始化微信支付方法如下:

#pragma mark - 初始化微信支付
- (void)initWpay
{
    #warning 记得更改微信Appid为您的
    [WXApi registerApp:@"wx685a5f98e4497044" withDescription:@"com.zzdlwx.com"];
}

Application的代理方法实现如下:

#pragma mark - UIApplicationDelegate

- (BOOL)application:(UIApplication *)application
      handleOpenURL:(NSURL *)url
{
    return [WXApi handleOpenURL:url delegate:self];
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            NSString *resultStatus = resultDic[@"resultStatus"];
            switch (resultStatus.integerValue) {
                case 9000:// 成功
                    break;
                case 6001:// 取消
                    break;
                default:
                    break;
            }
        }];
        
        // 授权跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"授权结果 authCode = %@", authCode?:@"");
        }];
    }
    return [WXApi handleOpenURL:url delegate:self];
}

// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
        
        // 授权跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"授权结果 authCode = %@", authCode?:@"");
        }];
    }
    return [WXApi handleOpenURL:url delegate:self];
}

要支付的文件中的头文件导入
(注意CMHttpRequestModel 这个类我已经加入我的Pch中,没加入的话,您也要导入)

#import "CMWechatAliPayManager.h"

要支付的文件中的Code处理方面
发送下订单的请求

-(void)yesPayBtnClick:(UIButton *)button {
    
    CMHttpRequestModel *paramsModel =[[CMHttpRequestModel alloc]init];
    paramsModel.localHost =kTestHttpHost;
    paramsModel.appendUrl =kPay_topay;
    // 参数设置

    [paramsModel.paramDic setValue:@"e1370e6a9995a7010ded1596308acfc6" forKey:@"token"];
    [paramsModel.paramDic setValue:@"Z20170421114853LK8pc" forKey:@"orderid"];
    
    
    // 3.发送的网络请求
    
    if (self.selectedTableView.indexKind==0) {// 支付宝支付
        [paramsModel.paramDic setValue:@(3) forKey:@"paytype"];

    }else if (self.selectedTableView.indexKind==1) {// 微信支付
        [paramsModel.paramDic setValue:@(4) forKey:@"paytype"];

    }else {// 银联支付
        
    }
    [[CMWechatAliPayManager sharedWpayManager] sendWeChatAliPayRequestParam:paramsModel];
   
}

支付成功后的回调处理

#pragma mark - CMWpaySearchResultDelegate
-(void)Wpay:(CMWechatAliPayManager *)manager andPayKind:(WAPayKind)payKind andPayResult:(int)code {
    DDLog(@"走到回调的地方了");
    if (payKind ==WAPayKindWechat) { // 微信
        switch (code) {
            case WXSuccess:
                
                // 1. 包装对应查询参数
                [DisplayHelper displaySuccessAlert:@"微信支付成功!"];
                // 2. 发送查询的是否成功的请求
                break;
                
            default:
                
                break;
        }
    }else { // 支付宝
        switch (code) {
            case 9000:// 成功
                [DisplayHelper displaySuccessAlert:@"支付宝支付成功!"];

                break;
            case 6001:// 取消
                break;
            default:
                break;
        }
    }
    
   
}

3.注意更改以下地方
全局搜索 “#warning” 找到下面的5个地方,分别按照提示更改为您的信息


按照要求修改为您的信息.png

4.其他要更改的

在info.plist中把微信加入白名单等

urlType中分别加入微信和支付宝的urlScheme

支付宝导入SDK后报错 : #include <openssl/asn1.h> 找不到
解决方案:
在Build Settings选项卡中搜索 header search添加新的路径为$(PROJECT_DIR)/FarmAndAnimal/Vendor/AliPaySDK/
其中这里的AliPaySDK 指的是openssl 的上一级文件为止,不一定是AliPaySDK, 切记!

四.注意事项
1.注意修改以上集成步骤中“#warning”搜索后要改的内容

2.微信支付需要和项目Bundle绑定在一起,支付宝任何应用都可以完成支付功能

3.关于微信和支付宝的应用跳转和返回应用:
微信注意3个地方
应用启动时注册AppId
urlScheme中添加AppId
支付发送PayReq中带上对应的AppId

支付宝注意2个地方
urlScheme中添加自定义字符串
发送支付请求时加上appScheme 标示应用程序

五.附上我的演示Demo中的流程图
1.支付宝流程:


1我的主界面.png
2支付宝的入口.png
调启支付宝客户端支付.png

1.微信流程:


1我的主界面.png
调启微信客户端.png
微信支付失败.png

纳尼,微信为什么会支付失败呢,就是因为微信的AppId必须绑定到对应的BundleId才能生效
ps:微信支付正在申请中,嘿嘿!

附上:

1.支付宝接入流程分享:
http://www.jianshu.com/p/d8edb82e51a7
2.微信支付接入流程分享:
http://www.jianshu.com/p/8205595a932d
3.我的支付宝和微信分享Demo:
https://github.com/zxwIsCode/WechatAliPay

支付模块暂时告一段落,以后有时间有机会会整理一下关于银联支付甚至第三方Ping++等有关支付的问题!
有任何问题,欢迎联系QQ:1824496534,备注:支付。
期待中吧,小伙伴,感谢支持!

推荐阅读更多精彩内容