微信支付iOS整合與二次封裝

weixin_34248705發表於2017-06-07

最近在進行的專案,需要整合第三方支付。業務需要整合支付寶,微信,銀聯,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]];
    }
}

寫在最後:

如果我的文章對你有所幫助,請幫忙點個贊?,謝謝!

相關文章