iOS微信支付整合 SDK1 7 5

smile麗語發表於2018-01-03

最近做了一個新專案,涉及到支付寶和微信支付,支付寶和微信都是業界的老大哥,相信大家都有所覺得文件、SDK都是各種坑吧(純粹吐槽而已),這是繼上篇支付寶支付整合後接著的微信支付整合。

1.微信商戶申請步驟 kf.qq.com/faq/120911V… 2.申請成功後說明 官方支付賬戶說明文件: pay.weixin.qq.com/wiki/doc/ap… 賬戶引數說明:

iOS微信支付整合 SDK1 7 5

官方業務流程文件: pay.weixin.qq.com/wiki/doc/ap… 3.微信支付整合 open.weixin.qq.com/cgi-bin/sho… 1> 新增微信支付SDK

iOS微信支付整合 SDK1 7 5
2> 新增庫

iOS微信支付整合 SDK1 7 5

4.開發步驟說明 官方開發步驟文擋: pay.weixin.qq.com/wiki/doc/ap… 1> 專案設定APPID,在工程專案中新增商戶自己的APPID

商戶在微信開放平臺申請開發APP應用後,微信開放平臺會生成APP的唯一標識APPID。在Xcode中開啟專案,設定專案屬性中的URL Schemes為您的APPID

8C3D3014-8177-4D73-BABD-6CB829BC470E.png

2> iOS 9.0以上的系統如果要正常調起微信,還需要新增白名單,在工程專案的plist檔案中新增

8B7F4118-5698-430B-A559-DE41B7C3E615.jpg

3> 開發者需要在工程中連結上:SystemConfiguration.framework, libz.dylib, libsqlite3.0.dylib, libc++.dylib, Security.framework, CoreTelephony.framework, CFNetwork.framework。

4> 在你的工程檔案中選擇Build Setting,在"Other Linker Flags"中加入**"-Objc -all_load"**,在Search Paths中新增 libWeChatSDK.a ,WXApi.h,WXApiObject.h,檔案所在位置

5> 註冊APPID 商戶APP工程中引入微信lib庫和標頭檔案,呼叫API前,需要先向微信註冊您的APPID,程式碼如下:

// 在appDelegate.m中,註冊微信應用    
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //向微信註冊
    [WXApi registerApp:@"您的APPID"];
}
複製程式碼

6> 調起支付 商戶伺服器生成支付訂單,先呼叫【統一下單API】生成預付單,獲取到prepay_id後將引數再次簽名傳輸給APP發起支付。以下是調起微信支付的關鍵程式碼: 為了安全性,以下欄位最好從伺服器去獲取

// 調起微信支付
PayReq *request = [[PayReq alloc] init];
/** 微信分配的公眾賬號ID -> APPID */
request.partnerId = APPID;
/** 預支付訂單 從伺服器獲取 */
request.prepayId = @"1101000000140415649af9fc314aa427";
/** 商家根據財付通文件填寫的資料和簽名 <暫填寫固定值Sign=WXPay>*/
request.package = @"Sign=WXPay";
/** 隨機串,防重發 */
request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";
/** 時間戳,防重發 */
request.timeStamp= @“1397527777";
/** 商家根據微信開放平臺文件對資料做的簽名, 可從伺服器獲取,也可本地生成*/
request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";
/* 調起支付 */
[WXApi sendReq:request];
複製程式碼

7> 支付結果回撥 照微信SDK Sample,在類實現onResp函式,支付完成後,微信APP會返回到商戶APP並回撥onResp函式,開發者需要在該函式中接收通知,判斷返回錯誤碼,如果支付成功則去後臺查詢支付結果再展示使用者實際支付結果。 注意: 一定不能以客戶端返回作為使用者支付的結果,應以伺服器端的接收的支付通知或查詢API返回的結果為準。 程式碼示例如下:

// 支付返回結果,實際支付結果需要去微信伺服器端查詢
-(void)onResp:(BaseResp *)resp {
   if([resp isKindOfClass:[PayResp class]]){
      switch (resp.errCode) {
          case WXSuccess:{
             NSlog(@"支付成功");
            // 發通知帶出支付成功結果
                [[NSNotificationCenter defaultCenter] postNotificationName:QTXWXReturnSucceedPayNotification object:resp];
          }
            break;
        default:{
            NSlog(@“支付失敗:%d”,resp.errCode);
             // 發通知帶出支付失敗結果
                [[NSNotificationCenter defaultCenter] postNotificationName:QTXWXReturnFailedPayNotification object:resp];
        }
          break;
    }
  }  
}
複製程式碼

具體使用先放一下我的部分程式碼:

  1. 一般微信支付和支付寶支付都會被一起整合,這邊就要在appDelegate.m中一起整理判斷回撥
 這裡處理新浪微博SSO授權之後跳轉回來,和微信/支付寶支付完成之後跳轉回來
 */
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    BOOL result = [UMSocialSnsService handleOpenURL:url wxApiDelegate:nil];
    if (result == NO) {  // 呼叫其他 SDK 支付寶
        
        //如果極簡 SDK 不可用,會跳轉支付寶錢包進行支付,需要將支付寶錢包的支付結果回傳給 SDK
        if ([url.host isEqualToString:@"safepay"]) {
            //跳轉支付寶錢包進行支付,處理支付結果
            [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
                QTXLog(@"支付寶客戶端支付結果result = %@",resultDic);
                if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
                    
                    // 發通知帶出支付成功結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
                } else {
                    
                    // 發通知帶出支付失敗結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
                }
                
            }];
        }
        
        if ([url.host isEqualToString:@"platformapi"]){//支付寶錢包快登授權返回 authCode
            [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
                QTXLog(@"支付寶網頁版result = %@",resultDic);
                if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
                    
                    // 發通知帶出支付成功結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
                } else {
                    
                    // 發通知帶出支付失敗結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
                }
            }];
        }
        
        //微信的支付回撥
        if ([url.host isEqualToString:@"pay"]) {
            return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
        }
    }
    return result;
}
複製程式碼
// NOTE: 9.0以後使用新API介面
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
    BOOL result = [UMSocialSnsService handleOpenURL:url];
    if (result == NO) {  // 呼叫其他 SDK 支付寶
        
        //如果極簡 SDK 不可用,會跳轉支付寶錢包進行支付,需要將支付寶錢包的支付結果回傳給 SDK
        if ([url.host isEqualToString:@"safepay"]) {
            //跳轉支付寶錢包進行支付,處理支付結果
            [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
                QTXLog(@"支付寶客戶端支付結果result = %@",resultDic);
                if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
                    
                    // 發通知帶出支付成功結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
                } else {
                    
                    // 發通知帶出支付失敗結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
                }
            }];
        }
        
        if ([url.host isEqualToString:@"platformapi"]){//支付寶錢包快登授權返回 authCode
            [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
                QTXLog(@"支付寶網頁版result = %@",resultDic);
                if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
                    
                    // 發通知帶出支付成功結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
                } else {
                    
                    // 發通知帶出支付失敗結果
                    [QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
                }
            }];
        }
       
        //微信的支付回撥
        if ([url.host isEqualToString:@"pay"]) {
            return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
        }
    }
    return result;
}

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

複製程式碼
  1. 在使用微信支付的當前控制器裡:
// 調起微信支付,接收通知,並且判斷手機是否安裝微信
- (void)weChatPay {
    
    // 1.拼接請求引數
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"orderid"] = self.order;
    params[@"userIp"] = [QTXGetIPTool deviceIPAdress]; // 獲取當前裝置的ip
    
    // 2.傳送請求
    __weak __typeof(self) weakSelf = self;
    [QTXHttpTool post:QTX_weChatPay_url params:params success:^(id json) {
        QTXLog(@"微信支付返回引數介面 請求成功-%@", json);
        
        if ([json[@"success"] isEqual:@(YES)]) {
            
            NSMutableDictionary *wechatDic = json[@"data"];
            
          [WXApi registerApp:[wechatDic objectForKey:@"appid"]];
            PayReq *request = [[PayReq alloc] init];
            request.partnerId = [wechatDic objectForKey:@"mch_id"]; // 商家向財付通申請的商家id
            request.prepayId= [wechatDic objectForKey:@"prepay_id"]; // 支付訂單
            request.package = @"Sign=WXPay"; // Sign=WXPay 商家根據財付通文件填寫的資料和簽名
            request.nonceStr= [wechatDic objectForKey:@"nonce_str"]; // 隨機串,防重發
            request.timeStamp= [[wechatDic objectForKey:@"timestamp"] intValue]; //時間戳,防重發
            request.sign= [wechatDic objectForKey:@"sign2"]; // 商家根據微信開放平臺文件對資料做的簽名 二次簽名
            
            if ([WXApi sendReq:request]) {
                
                [QTXNotificationCenter addObserver:self selector:@selector(paySucceed) name:QTXWXReturnSucceedPayNotification object:nil];
                [QTXNotificationCenter addObserver:self selector:@selector(payFailed) name:QTXWXReturnFailedPayNotification object:nil];
            } else { // 未安裝微信客戶端相關處理
                
                QTXAlterView *alter = [[QTXAlterView alloc] initWithMessage:[NSString stringWithFormat:@"未安裝微信客戶端,請使用其他支付方式"] delegate:self rightButtonTitle:@"確定" otherButtonTitles:nil];
                [alter show];
            }
            
        } else {
            [MBProgressHUD showError:[NSString stringWithFormat:@"%@", json[@"errorMessage"]]];
        }
        
        [weakSelf.tableView reloadData];
    } failure:^(NSError *error) {
        
        [MBProgressHUD showError:@"暫無網路,稍後再試"];
        QTXLog(@"微信支付返回引數介面 請求失敗-%@", error);
    }];

}
複製程式碼

目前微信支付SDK已經更新到1.7.5, 我這邊也同步更新下. 其實在原有版本基礎上,只需要增加以下三點:

  1. 更新支援iOS啟用 ATS(App Transport Security)
  2. 需要在工程中連結CFNetwork.framework
  3. 在工程配置中的”Other Linker Flags”中加入”-Objc -all_load”

如果需要支付寶支付整合, 請移步: iOS支付寶支付整合

相關文章