美文网首页iOS开发iOS 开发iOS相关
微信支付iOS集成与二次封装

微信支付iOS集成与二次封装

作者: reyzhang | 来源:发表于2017-06-07 13:04 被阅读589次

    最近在进行的项目,需要集成第三方支付。业务需要集成支付宝,微信,银联,Paypal等支付方式。在使用各家sdk时会发现有些第三方sdk调用时不够方便,简单。所以就有了进行再次封装的想法。
    已经发布过关于支付宝支付的二次封装,如果对文章感兴趣,可以移步到支付宝iOS集成与二次封装 查阅。

    官方下载与集成相关文档

    下载地址 :Demo及SDK下载
    集成文档: iOS接入指南
    业务流程:官方流程文档

    怎么集成看官方文档就可以了,本文重点在二次封装上

    二次封装

    相比支付宝sdk,微信支付使用起来更简单些,要了解微信的支付业务流程,可参考上面的文档。
    微信支付需要服务端根据订单信息,返回一个预支付数据PrepayData,客户端拿到这个预支付数据后,调用微信支付sdk完成支付。封装后的代码如下:
    创建一个微信支付的服务类WXPayService

    //  Created by reyzhang on 2017/4/10.
    //  Copyright © 2017年 hhkx All rights reserved.
    //  微信支付服务封装
    
    #import <Foundation/Foundation.h>
    #import "WXApi.h"
    
    @interface WXPayService : NSObject <WXApiDelegate>
    
    ///单例来接收微信请求的回调
    + (instancetype)sharedInstance;
    
    // -- 根据接口返回的预支付信息,构造支付请求
    + (PayReq *)getPayRequest:(NSDictionary *)prepayData;
    
    
    ///处理非支付请求的回调
    - (void)onRespCallBack:(void(^)(BaseResp * resp))callback;
    
    ///从服务器端获取到微信返回的支付请求用到的参数来发起支付请求
    - (void)startPayWithReq:(PayReq *)req callback:(void(^)(BaseResp * resp))callback;
    
    
    @end
    

    实现代码 .m

    //  Created by reyzhang on 2017/4/10.
    //  Copyright © 2017年 hhkx All rights reserved.
    //  微信支付服务封装
    
    #import "WXPayService.h"
    
    @interface WXPayService ()
    @property (nonatomic,copy) void(^RespCallBack)(BaseResp *);
    @end
    
    
    static WXPayService *sharedInstance;
    @implementation WXPayService
    
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedInstance = [super allocWithZone:zone];
        });
        return sharedInstance;
    }
    
    ///单例来接收微信请求的回调
    + (instancetype)sharedInstance {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            sharedInstance = [[self alloc] init];
        });
        return sharedInstance;
    }
    
    
    // -- 根据接口返回的预支付信息,构造支付请求
    + (PayReq *)getPayRequest:(NSDictionary *)prepayData {
        if (prepayData) {
            PayReq *req = [[PayReq alloc] init];
            req.partnerId           = [prepayData stringForKey:@"partnerid"];      // -- 商家id
            req.prepayId            = [prepayData stringForKey:@"prepayid"];
            req.nonceStr            = [prepayData stringForKey:@"noncestr"];
            req.timeStamp           = [[prepayData stringForKey:@"timestamp"] intValue];
            req.package             = [prepayData stringForKey:@"package"];
            req.sign                = [prepayData stringForKey:@"sign"];
            
            //日志输出
            NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[prepayData stringForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign);
            
            return req;
        }
        return nil;
    }
    
    
    ///处理非支付请求的回调
    - (void)onRespCallBack:(void(^)(BaseResp * resp))callback {
        self.RespCallBack = callback;
    }
    
    ///从服务器端获取到微信返回的支付请求用到的参数来发起支付请求
    - (void)startPayWithReq:(PayReq *)req callback:(void(^)(BaseResp * resp))callback {
        NSAssert(req !=nil , @"未成功创建微信支付请求");
        self.RespCallBack = callback;
        
        if ([WXApi isWXAppInstalled]) { // -- 判断是否安装微信应用
            //发起微信支付,设置参数
            [WXApi sendReq:req];
        }else {
            self.RespCallBack(nil);
        }
    }
    
    
    
    #pragma mark WXApiDelegate
    - (void)onResp:(BaseResp *)resp {
        if ([resp isKindOfClass:[PayResp class]]) { // -- 判断是否为支付的回调
            self.RespCallBack(resp);
        }
    }
    
    @end
    

    调用

    在应用启动时还是先配置微信支付的AppKey

    - (void)setupWXPay {
        [WXApi registerApp:@"your appkey" withDescription:@"description"];
    }
    

    使用

    - (void)WXPay {
        
        // -- first check 微信是否安装
        if (![WXApi isWXAppInstalled]) {
            NSLog(@"微信应用未安装");
            return;
        }
    
       // -- second 调用服务器接口获取预支付数据
       [_service getPrepayData:^(id prepayData) {
               // -- 构造支付请求PayReq
                PayReq *req = [WXPayService getPayRequest:prepayData];
                // -- 调起微信支付sdk
                [[WXPayService sharedInstance] startPayWithReq:req callback:^(BaseResp *resp) {
                    
                    if (!resp) {
                        return ;
                    }
                    
                    if (resp.errCode == WXSuccess) {
                        NSLog(@"支付成功");
                    }else {
                        NSLog(@"支付失败");
                    }
                }];
      }];
    }
    

    在AppDelegate中的回调处理

    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation {
        [self handleOpenURL:url];
        return YES;
    }
    
    -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
        [self handleOpenURL:url];
        return YES;
    }
    - (void)handleOpenURL:(NSURL*)url {
         if ([url.host isEqualToString:@"pay"]) { // -- 微信支付
            [WXApi handleOpenURL:url delegate:[WXPayService sharedInstance]];
        }
    }
    

    写在最后:

    如果我的文章对你有所帮助,请帮忙点个赞👍,谢谢!

    相关文章

      网友评论

      • 进击的小恶魔:stringForKey 是怎么实现的?
        reyzhang:@浪漫紫薇星 这里调用的后端的接口,后端接口返回微信支付控件需要的prepayData
        浪漫紫薇星: [_service getPrepayData:^(id prepayData) 这个怎么写的 ??谢谢
        reyzhang:@Lxx_D 就是对可能出现nil的情况做的一些处理
        -(NSString *)stringForKey:(NSString *)theKey
        {
        if (!self) {
        return @"";
        }

        id val = [self objectForKey:theKey];
        if (val == [NSNull null]) {
        return @"";
        }

        if (!val) {
        return @"";
        }

        NSString * theNewStr =[NSString stringWithFormat:@"%@",[self objectForKey:theKey]];
        if ([theNewStr isEqualToString:@"<null>"]) {
        return @"";
        }
        if ([theNewStr isEqualToString:@"<NULL>"]) {
        return @"";
        }
        if ([theNewStr isEqualToString:@"NULL"]) {
        return @"";
        }
        if ([theNewStr isEqualToString:@"null"]) {
        return @"";
        }
        if ([theNewStr isEqualToString:@"(null)"]) {
        return @"";
        }
        return theNewStr;
        }
      • 正义必胜biu:能给个demo吗
        正义必胜biu:@reyzhang 好的,谢谢
        reyzhang:@正义ing 代码基本上都在上面了

      本文标题:微信支付iOS集成与二次封装

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