iOS開發(fā)之微信支付的集成

前言

雖然ApplePay的進軍中國市場,但是就目前而言,微信支付和支付寶仍占據(jù)主導地位,本章主要是介紹項目中的微信支付是如何集成SDK的.想要了解更多關于iOS的知識,可以關注我的微博,@WilliamAlex大叔一起分享今天學到的iOS相關知識.

集成微信支付的主要思路

  • 思路 : 在集成之前,我們先要詳細了解官方文檔中微信支付這一板塊,它已經(jīng)給我們提出了集成步驟.
  • 主要步驟 :
        1, 項目設置APPID
        2, 注冊APPID
        3, 調(diào)起支付
        4, 處理支付結果的回調(diào)
  • 詳細說明步驟;

        1, 設置項目的APPID:
                            商戶在微信開放平臺申請開發(fā)APP應用后趁蕊,微信開放平臺會生成APP的唯一標識APPID。在Xcode中打開項目市埋,設置項目屬性中的URL Schemes為您的APPID
        2, 注冊APPID:
                            商戶APP工程中引入微信lib庫和頭文件,調(diào)用API前甥捺,需要先向微信注冊您的APPID
        3, 調(diào)起支付:
                            商戶服務器生成支付訂單淹辞,先調(diào)用【統(tǒng)一下單API】生成預付單牛隅,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付
        4, 處理支付結果的回調(diào):
                            照微信SDK Sample飘庄,在類實現(xiàn)onResp函數(shù)脑蠕,支付完成后,微信APP會返回到商戶APP并回調(diào)onResp函數(shù)竭宰,開發(fā)者需要在該函數(shù)中接收通知空郊,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結果再展示用戶實際支付結果切揭。注意    一定不能以客戶端返回作為用戶支付的結果,應以服務器端的接收的支付通知或查詢API返回的結果為準
  • 微信注冊ID :wxb4ba3c02aa476ea1: 這個ID可以直接在下載的示例項目SDKSample中的AppDelegate中找到

集成思路明白以后,我們開始集成微信支付

  • 集成前的準備工作

  • 了解微信開發(fā)文檔


    選擇APP支付版塊.png
  • 文檔中需要注意的點


    支付結果回調(diào).png
  • 我們只需要根據(jù)文檔中的提示步驟即可集成


    集成步驟.png
  • 下載官方文檔中提供的頭文件和靜態(tài)庫


    頭文件和靜態(tài)庫.png
  • 創(chuàng)建自己的一個項目集成微信支付

    • 導入頭文件


      導入頭文件.png
  • 編譯后可能會報很多錯誤,這時候我們需要導入相關的依賴文件

    添加依賴.png

  • 編譯項目項目會崩潰掉,錯誤提示我們需要在info.plist文件中添加兩個key


    添加key.png
  • 添加的結果


    添加key.png
  • 項目APPID的設置


    設置白名單.png
  • 注冊APPID

    • 向微信注冊支付


      向微信注冊.png
  • 調(diào)起微信支付


    調(diào)起微信支付.png
    • 注意: 這個方法是監(jiān)聽模擬微信支付按鈕的方法
  • 具體實現(xiàn)


    支付的實現(xiàn)01.png
支付的實現(xiàn)02.png
支付的實現(xiàn)03.png
  • 處理支付結果的回調(diào)
處理支付結果的回調(diào).png
 - 注意: 處理支付結果的回調(diào)是代理方法,所以需要遵守協(xié)議.
  • 代碼實現(xiàn)
  • 向微信注冊(注冊ID:wxb4ba3c02aa476ea1)
// 導入頭文件,第一步就是向微信注冊.
#import "AppDelegate.h"
#import "WXApi.h"

@interface AppDelegate ()<WXApiDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //向微信注冊
    [WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"com.William.Alex"];

    return YES;
}

  • 注意點 :

  • 1,注冊時的ID是根據(jù)公司要求到微信公眾平臺申請注冊的,需要300元人民幣,所以我這里就用官方文檔中提供測試用的ID.

  • 2, 項目中遵守了代理協(xié)議,主要是用于處理支付結果回調(diào)使用,后面會用到.

  • 調(diào)起微信支付


#import "ViewController.h"
#import "WXApi.h"

@interface ViewController ()

@end

@implementation ViewController

/**
 *  調(diào)起微信支付
 */
- (IBAction)payFormoneryInAlexWallet {

    NSString *res = [self jumpToBizPay];
    if( ![res isEqual:@""] ) {
        UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"支付失敗"
                                                        message:res
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        // 提示用戶支付失敗,res是支付失敗后系統(tǒng)返回的信息
        NSLog(@"支付失敗信息%@",res);
        [alter show];
  }
}


- (NSString *)jumpToBizPay {

    // 判斷用戶當前用戶是否下載微信/是否支持微信支付
    if ( ![WXApi isWXAppInstalled] ) {  // 表示用戶沒有安裝微信

        // 提示用戶需要安裝微信才能使用微信支付
        NSLog(@"需要安裝微信才能使用微信支付");

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"支付失敗"
                                                            message:@"是否前往Appstore中下載微信"
                                                           delegate:self
                                                  cancelButtonTitle:@"取消"
                                                  otherButtonTitles:nil, nil];
        [alertView show];
        return nil;
    }else if(![WXApi isWXAppSupportApi])
    {  // 表示當前不支持微信支付

        // 提示用戶當前環(huán)境不支持微信支付
        NSLog(@"不支持微信支付");

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"支付失敗"
                                                            message:@"當前不支持微信支付"
                                                           delegate:self
                                                  cancelButtonTitle:@"取消"
                                                  otherButtonTitles:nil, nil];
        [alertView show];
        return nil;
    }

    NSString *urlString   = @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=ios";

    //解析服務端返回json數(shù)據(jù)
    NSError *error;

    //加載一個NSURL對象
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];

    //將請求的url數(shù)據(jù)放到NSData對象中
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    if ( response != nil) {
        NSMutableDictionary *dict = NULL;

        //IOS5自帶解析類NSJSONSerialization從response中解析出數(shù)據(jù)放到字典中
        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"];

                //調(diào)起微信支付
                PayReq* req              = [[PayReq alloc] init];  // 將autoresease去掉,類方法變?yōu)閷ο蠓椒纯?                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 @"服務器返回錯誤";
    }
}
  • 注意 : 官方文檔中提供的是類方法,并且環(huán)境是MRC,如果公司要求是MRC,那么直接去:項目-->Bulid-->comple Source -->雙擊文件-->填寫-fobjc-arc.又或者將MRC中釋放對象的屬性去掉,將類方法,變?yōu)閷嵗椒纯?

  • 處理支付結果的回調(diào)


/**
 *  不管支付授權是否成功或者失敗,又或者是用戶自己取消授權,都會調(diào)用該代理方法
 */
#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;
        }
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alert show];

    }
}

總結

  • 可能會疑惑的幾點:

    • 1, 微信官方文檔提供的Demo中使用的MRC(有autorelease等屬性標識),為什么文章中不是MRC呢?
      答:我將官方文檔中的類方法變成了對象方法了,在本篇文章中,直接調(diào)用該方法即可,整體是在ARC環(huán)境下創(chuàng)建的.這是一種方法,還有一種方法就是ARC和MRC混編,如下圖步驟設置即可.


      ARC和MRC的混編.png
  • 2 官方文檔中的示例是這樣的


    微信示例.png
  • 3 調(diào)起微信支付,需要監(jiān)聽按鈕的點擊哦


    監(jiān)聽按鈕的點擊.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末励背,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子砸西,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜒秤,死亡現(xiàn)場離奇詭異膝擂,居然都是意外死亡,警方通過查閱死者的電腦和手機鸳慈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門饱溢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人走芋,你說我怎么就攤上這事绩郎。” “怎么了翁逞?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵肋杖,是天一觀的道長。 經(jīng)常有香客問我熄攘,道長兽愤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮浅萧,結果婚禮上逐沙,老公的妹妹穿的比我還像新娘。我一直安慰自己洼畅,他們只是感情好吩案,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帝簇,像睡著了一般徘郭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丧肴,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天残揉,我揣著相機與錄音,去河邊找鬼芋浮。 笑死抱环,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的纸巷。 我是一名探鬼主播镇草,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瘤旨!你這毒婦竟也來了梯啤?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤存哲,失蹤者是張志新(化名)和其女友劉穎因宇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宏胯,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡羽嫡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杭棵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魂爪。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡撩笆,死狀恐怖氮兵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情南片,我是刑警寧澤螺捐,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布诞外,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盾致,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一惠遏、第九天 我趴在偏房一處隱蔽的房頂上張望器一。 院中可真熱鬧渺贤,春花似錦、人聲如沸请毛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽方仿。三九已至固棚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仙蚜,已是汗流浹背此洲。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留委粉,地道東北人呜师。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像贾节,于是被迫代替她去往敵國和親汁汗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容