iOS-微信支付功能實(shí)現(xiàn)

悠閑時光, 順便將開發(fā)過程中, 經(jīng)常使用到的一些功能, 記錄分享出來,比如支付!
本想寫一篇銀聯(lián)支付,不過看了之前轉(zhuǎn)載過一篇關(guān)于銀聯(lián)支付的文章寫得很詳細(xì),我就不再重復(fù)了, 有興趣的童鞋可以去看一下; 戳這里
首先介紹一下微信支付的實(shí)現(xiàn)流程:

  1. 注冊微信開放平臺,創(chuàng)建應(yīng)用獲取appid,appSecret,申請支付功能(需要花費(fèi)300大洋進(jìn)行開發(fā)者資質(zhì)認(rèn)證),申請成功之后會返回一些參數(shù).
  1. 下載微信支付sdk
  2. 客戶端請求訂單,后臺與微信后臺交互,返回給客戶端支付參數(shù)
  3. 調(diào)用微信客戶端,由微信客戶端和微信服務(wù)器打交道;
  4. 客戶端和服務(wù)端都會收到支付結(jié)果;(前臺消息不可靠,我們需要去后臺驗(yàn)證,如果后臺沒有收到支付通知,后臺去微信服務(wù)器驗(yàn)證然后將結(jié)果返回給客戶端)

開發(fā)步驟
在微信開放平臺注冊應(yīng)用, 并開通支付功能之后(期間各種認(rèn)證, 確認(rèn)信息等操作按照流程走就可以, 在此省略)

第一步: 下載微信 SDK

微信 SDK 下載

在這里下載微信 SDK

第二步: 集成 SDK
當(dāng)下載 SDK 之后, 會看到其中有一個** read_me.txt ** 文件, 其實(shí)里面就是講了最近幾個版本的更新中解決的問題,以及使用該SDK的注意事項(xiàng),所以這個 read_me 文件是很重要的。

read_me

  1. 將 SDK 拖入工程
  2. 導(dǎo)入一下框架和鏈接庫:
SystemConfiguration.framework, 
libz.dylib, libsqlite3.0.dylib, 
libc++.dylib, Security.framework, 
CoreTelephony.framework, 
CFNetwork.framework

注: 如果是XCode 7之前,估計(jì)還需要手動導(dǎo)入Foundation.framework、UIKit.framework等框架;

  1. 將微信支付要用到的APPID設(shè)置為URL Schemes
2B2A9042-0FDD-4C5B-AE88-20EEBE749F8A.png

第三步: 就是寫代碼了

  1. 注冊APPID
    商戶APP工程中引入微信lib庫和頭文件,調(diào)用API前,需要先向微信注冊您的APPID,代碼如下:
#pragma mark 微信支付
- (void)wxPay {
    /**
     *  微信支付
     *  APPID: 
     */
    
    //向微信注冊
    BOOL isok = [WXApi registerApp:@"項(xiàng)目 APPID" withDescription:@"項(xiàng)目名稱"];
    if (isOk) {
        
        TY_Log(@"注冊微信成功");
    }else{
        
        TY_Log(@"注冊微信失敗");
    }
}
  1. 調(diào)起支付
    商戶服務(wù)器生成支付訂單,先調(diào)用【統(tǒng)一下單API】生成預(yù)付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼:
    現(xiàn)在我們只需要在控制器上添加一個button, 名字改成微信支付就可以了
    button事件:
- (void)wxPayBtnClick:(UIButton *)sender {
    
    if (![WXApi isWXAppInstalled]){  // 是否安裝了微信
        
        UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"沒有安裝微信" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alter show];
    } else if (![WXApi isWXAppSupportApi]){ // 是否支持微信支付
        
        UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"不支持微信支付" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alter show];
        
    }else{  //已安裝微信, 進(jìn)行支付
        
        [self WXPay];
    }
    
}
#pragma mark 微信支付方法
- (void)WXPay{
    
//將微信支付所需參數(shù)信息,傳給服務(wù)器
    [BusinessEngine getWXPayParameteFlowCode:self.flowCode Body:self.storeName Price:self.orderValue Completion:^(NSDictionary *aDic) {
        
        //需要創(chuàng)建這個支付對象
        PayReq* req= [[PayReq alloc]init];
        //由用戶微信號和AppID組成的唯一標(biāo)識,用于校驗(yàn)微信用戶
        //req.openID = [aDic objectForKey:@"appid"];
        
        // 商家id,在注冊的時候給的
        req.partnerId = [aDic objectForKey:@"partnerid"];
        // 預(yù)支付訂單這個是后臺跟微信服務(wù)器交互后,微信服務(wù)器傳給你們服務(wù)器的,你們服務(wù)器再傳給你
        req.prepayId  = [aDic objectForKey:@"prepayid"];
        // 根據(jù)財(cái)付通文檔填寫的數(shù)據(jù)和簽名
        //這個比較特殊,是固定的,只能是即req.package = Sign=WXPay
        req.package = @"Sign=WXPay";
        // 隨機(jī)編碼,為了防止重復(fù)的,在后臺生成
        req.nonceStr = [aDic objectForKey:@"noncestr"];
        // 這個是時間戳,也是在后臺生成的,為了驗(yàn)證支付的
        NSString * stamp = [aDic objectForKey:@"timestamp"];
        req.timeStamp = stamp.intValue;
        // 這個簽名也是后臺做的
        req.sign = [aDic objectForKey:@"sign"];
        //日志輸出
        //NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\nsign=%@",[aDic objectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.sign );
        //發(fā)送請求到微信,等待微信返回onResp
        [WXApi sendReq:req];
    }];
    
}

3 . 支付結(jié)果回調(diào)
按照微信SDKSample,在類實(shí)現(xiàn)onResp函數(shù),支付完成后,微信APP會返回到商戶APP并回調(diào)onResp函數(shù),開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結(jié)果再展示用戶實(shí)際支付結(jié)果。
注意:
一定不能以客戶端返回作為用戶支付的結(jié)果,應(yīng)以服務(wù)器端的接收的支付通知或查詢API返回的結(jié)果為準(zhǔn)。
這是最后一步了, 我們在支付頁面支付完成以后呢要知道支付結(jié)果, 怎么做呢?

首先, 在 AppDelegate.m 里面實(shí)現(xiàn)該方法

#pragma mark 跳轉(zhuǎn)支付寶, 微信 進(jìn)行支付,處理支付結(jié)果
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    
    NSString *urlStr = [NSString stringWithFormat:@"%@",url];
    
    if ([url.host isEqualToString:@"safepay"]) {  //判斷支付寶回調(diào)
        //跳轉(zhuǎn)支付寶錢包進(jìn)行支付,處理支付結(jié)果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            //TYLLog(@"result = %@",resultDic);
            //TYLLog(@"result", resultDic)
        }];
        
    }else if ([sourceApplication isEqualToString:@"com.tencent.xin"] && [urlStr containsString:@"pay"]){  //判斷微信回調(diào)

        TY_Log(@"跳轉(zhuǎn)微信支付處理支付方式結(jié)果");
        return [WXApi handleOpenURL:url delegate:self];
        
    }
    
    return YES;
}

接下來我們需要遵守下協(xié)議


#pragma mark 微信支付回調(diào)
-(void)onResp:(BaseResp*)resp{
    //NSString * strMsg = [NSString stringWithFormat:@"errorCode: %d",resp.errCode];
    
    //TY_Log(@"微信 = strMsg:", strMsg)
    
    //NSString * errStr = [NSString stringWithFormat:@"errStr: %@",resp.errStr];
    
    //TY_Log(@"微信 = errStr:", errStr)
    
    NSString *strTitle;
    if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
        strTitle = [NSString stringWithFormat:@"發(fā)送媒體消息結(jié)果"];
    }
    
    NSString * wxPayResult;
    if ([resp isKindOfClass:[PayResp class]]) {
        
        strTitle = [NSString stringWithFormat:@"支付結(jié)果"];
        
        switch (resp.errCode) {
            case WXSuccess:
            {
                TYLLog(@"支付結(jié)果: 成功!");
                wxPayResult = @"success";
            }
                break;
            case WXErrCodeCommon:
            { //簽名錯誤、未注冊APPID、項(xiàng)目設(shè)置APPID不正確、注冊的APPID與設(shè)置的不匹配、其他異常等
                
                TYLLog(@"支付結(jié)果: 失敗!");
                wxPayResult = @"faile";
            }
                break;
            case WXErrCodeUserCancel:
            { //
                TYLLog(@"用戶點(diǎn)擊取消并返回");
                wxPayResult = @"cancel";
            }
                break;
            case WXErrCodeSentFail:
            { //發(fā)送失敗
                TYLLog(@"發(fā)送失敗");
                wxPayResult = @"faile";
            }
                break;
            case WXErrCodeUnsupport:
            { //微信不支持
                TYLLog(@"微信不支持");
                wxPayResult = @"faile";
            }
                break;
            case WXErrCodeAuthDeny:
            { //授權(quán)失敗
                TYLLog(@"授權(quán)失敗");
                wxPayResult = @"faile";
            }
                break;
            default:
                break;
        }
        
        //發(fā)出通知 從微信回調(diào)回來之后,發(fā)一個通知,讓請求支付的頁面接收消息,并且展示支付結(jié)果,或者進(jìn)行一些自定義的展示或者跳轉(zhuǎn)
        NSNotification * notification = [NSNotification notificationWithName:@"WXPay" object:wxPayResult];
        [[NSNotificationCenter defaultCenter] postNotification:notification];
        //------------------------
    }
    
}

其實(shí)移動端實(shí)現(xiàn)起來還是很簡單的, 至于各種驗(yàn)證還是后臺辛苦下了??

如果這篇文章對您有些許幫助 請給我點(diǎn)個心吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 實(shí)現(xiàn)支付寶支付的準(zhǔn)備工作: 1.向支付寶簽約,成為支付寶的商戶 簽約完成后,支付寶會提供一些必要的數(shù)據(jù)給我們 商戶...
    Anson楊春安閱讀 8,614評論 0 6
  • 在被支付寶、銀聯(lián)坑過之后,發(fā)現(xiàn)其實(shí)微信支付的集成并沒有想象中的那么困難,像支付寶那樣簡單地調(diào)用個方法就行,重要的難...
    petry閱讀 741評論 2 2
  • 自己總結(jié)的微信支付寶支付流程和注意點(diǎn): 準(zhǔn)備工作: 需要公司的營業(yè)執(zhí)照,稅務(wù)信息,等老板的身份證信息等,我記得,用...
    Www劉閱讀 18,679評論 2 50
  • 銀聯(lián)支付,支付寶支付,微信支付的三大總結(jié),之前也有寫過兩篇。 微信支付,支付寶支付,銀聯(lián)支付——三大支付總結(jié): h...
    LucasAdam閱讀 5,080評論 2 23
  • 剛打開微博,推送消息是喬任梁死亡。我都驚呆了。一路走好。
    老魚的迷妹閱讀 148評論 0 0

友情鏈接更多精彩內(nèi)容