1. 程式人生 > >iOS-微信支付總結

iOS-微信支付總結

前言:

在iOS開發中,常常會涉及到支付功能,而微信支付是必不可少的,這裡筆者就簡單整理了一下微信支付的流程,即使分享也是對自己學習的總結。

一. 微信整合的基本流程(所需資料由公司提供)

1.在微信開放平臺註冊一個賬號:https://open.weixin.qq.com
2.進入管理中心–>移動應用–>建立移動應用;根據頁面提示完善應用資料
3.稽核通過後,進入應用詳情頁–>檢視應用詳情,這裡可以檢視AppID和AppSecret以及一些介面資訊
4.應用建立時是沒有支付能力的,需要額外申請,具體的申請過程,可根據網頁提示即可完成
5.稽核通過後,微信平臺會給你填寫稽核資料時預留郵箱傳送一個郵件,郵件中包含了與支付能力相關的微信商戶號的資訊,然後到微信的商戶平臺:

https://pay.weixin.qq.com 填寫相關資料,最主要的是驗證開戶行,微信會向你填寫的開戶銀行賬戶匯一筆錢(一般是幾分錢),讓你們的財務查一下,然後驗證一下即可,通過後即獲取了支付能力

在文件中,點選”支付賬戶—>支付賬戶“,可以看到關於APPID的資訊:

這裡寫圖片描述

注意:
1.這個APPID是開發中使用微信支付必須要用的東西,而這個APPID也只有商戶通過在該微信支付平臺註冊,花個300元,填寫很多相關重要資訊,還要上傳營業執照等必要手續,才能獲取的APPID。
2.而商業app應用程式,在客戶使用app微信消費,程式會根據這個唯一的APPID,查詢到商戶,然後把消費者的金額數傳遞到商戶的賬戶裡。
3.對於開發者,微信支付平臺提供了測試的Demo,也在Demo原始碼中提供了有用的用於測試程式碼的APPID。這樣開發者就除去了花個300元買個APPID的必要性。

微信整合的具體步驟

1.新增微信支付SDK,把官方SDK包中的SDKExport資料夾拖到自己的工程裡,.text檔案可以不用拖,是提供給開發者閱讀的。

這裡寫圖片描述

2.開啟red_me.text檔案,裡面主要是各各SDK版本中更新所解決的問題,以及注意事項,紅色框中的部分是需要用的。

這裡寫圖片描述

3.點選專案名,在Build Phases選項卡的Link Binary With Libraries中,增加以下依賴:Security.framework、CoreTelephony.framework、SystemConfiguration.framework、libc++.tbd、libz.tbd、libsqlite3.tbd、libWeChatSDK.a
這裡寫圖片描述

4.專案設定APPID,在工程專案中新增商戶自己的APPID
商戶在微信開放平臺申請開發APP應用後,微信開放平臺會生成APP的唯一標識APPID。

這裡寫圖片描述

5.由於iOS9預設限制了http協議的訪問,所以Xcode7以後就需要在開發中手動新增 App Transport Security Settings 設定,在info.plist中新增如下配置(文中以XML格式描述)

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

6.iOS 9.0以上的系統如果要正常調起微信,還需要將使用的URL Schemes新增為白名單,在App對應的info.plist中新增如下配置(文中以XML格式描述)。

<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
</array>

修改後info.plist檔案中就會出現紅色框中的兩項內容

這裡寫圖片描述

7.註冊APPID,在AppDelegate裡註冊微信

這裡寫圖片描述

在需要使用微信支付的地方匯入:

#import "WXApi.h"

在AppDelegate中的didFinishLaunchingWithOptions方法中新增以下程式碼向微信註冊APP:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //向微信註冊APPID
    [WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"demo 2.0"];
    return YES;
}

8.發起支付,調其微信支付
在這之前,我們先開啟微信官方提供的Demo

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

在官方給的程式碼中,我們會注意到一些細節,比如Demo中使用了MRC的autorelease,你可以把它去掉;類方法可以換成例項方法,根據你的實際專案開發需求:

- (NSString *)jumpToBizPay {

    //根據查詢微信API文件,我們需要新增兩個需要的判斷
    //判斷是否安裝了微信
    if (![WXApi isWXAppInstalled]) {
        NSLog(@"沒有安裝微信");
        return nil;
    }else if (![WXApi isWXAppSupportApi]){
        NSLog(@"不支援微信支付");
        return nil;
    }

    NSLog(@"安裝了微信,而且微信支援支付");

    //支付流程實現
    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];
                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 @"伺服器返回錯誤";
    }
}

接著新增一個支付按鈕,呼叫上述的方法

這裡寫圖片描述

    NSString *weixinBackStr = [self jumpToBizPay];
    if (![weixinBackStr isEqualToString:@""]) {
        NSLog(@"微信支付返回的資訊:%@",weixinBackStr);
    }

這裡還要注意一點,在調起微信支付之前,需要進行判斷是否安裝了微信

這裡寫圖片描述

    //根據查詢微信API文件,我們需要新增兩個需要的判斷
    //判斷是否安裝了微信
    if (![WXApi isWXAppInstalled]) {
        NSLog(@"沒有安裝微信");
        return nil;
    }else if (![WXApi isWXAppSupportApi]){
        NSLog(@"不支援微信支付");
        return nil;
    }
    NSLog(@"安裝了微信,而且微信支援支付");

9.最後就是處理微信支付的返回資訊(回撥方法)
在官方Demo中可以看到具體如何使用

這裡寫圖片描述

我們只需要紅色框中的程式碼即可

這裡寫圖片描述

#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;
        }

        UIAlertController *alert = [UIAlertController alertControllerWithTitle:strTitle message:strMsg preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *certainAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

        }];

        [alert addAction:certainAction];
        [self.window.rootViewController presentViewController:alert animated:YES completion:nil];

    }

}

10.根據實際開發需求,我們可能還需要回傳App的相關資訊

這裡寫圖片描述

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    return [WXApi handleOpenURL:url delegate:self];
}

常見異常Bug處理

常見問題為微信支付調起不成功,每次調起只能調起一個帶有你返回確認按鈕的頁面。
原因:引數錯誤,特別注意引數(簽名),後臺的返回的引數不正確。
解決方案:逐個校驗引數,簽名可以本地加密處理,不要依賴後臺的返回簽名,有的時候後臺返回的是不正確的

尾巴:

本文只是一個簡單的發起支付流程的演示,下單、簽名、查單和支付通知均在伺服器後臺實現。若遇到其他問題歡迎和樓主分享評論。

以上部分概述內容出自以下部落格的連結,以此感謝!!!