微信支付填坑記

前言

網(wǎng)上關(guān)于微信支付的文章很多,但是感覺寫的很多而且很亂,而且都是講客戶端和服務(wù)端全都寫出來,搞得看的人根本搞不懂在客戶端應(yīng)該寫寫什么,在服務(wù)端應(yīng)該寫些什么;讓人頭很大!在這里主要區(qū)分客戶端和服務(wù)端應(yīng)該進行的操作流程!其實現(xiàn)流程也是按照微信支付的開發(fā)文檔來實現(xiàn)的;有的人可能會說微信支付的文檔很亂搞不清該寫些什么,說實話對于第一次集成的人來說確實比較亂,一著急就更加迷茫了!所以在此特梳理一下微信支付的實現(xiàn)流程和集成的時候所遇到的坑!

流程

步驟1:用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。
步驟2:商戶后臺收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口。參見【統(tǒng)一下單API】。
步驟3:統(tǒng)一下單接口返回正常的prepay_id,再按簽名規(guī)范重新生成簽名后,將數(shù)據(jù)傳輸給APP。參與簽名的字段名為appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式為Sign=WXPay
步驟4:商戶APP調(diào)起微信支付。api參見本章節(jié)【app端開發(fā)步驟說明
步驟5:商戶后臺接收支付通知。api參見【支付結(jié)果通知API
步驟6:商戶后臺查詢支付結(jié)果。api參見【查詢訂單API

1.客戶端

根據(jù)微信的開發(fā)文檔顯示所有關(guān)于訂單的簽名加密的操作最好放到服務(wù)端去實現(xiàn);下面是微信支付客戶端所需要實現(xiàn)的方法:

1、項目設(shè)置APPID
商戶在微信開放平臺申請開發(fā)APP應(yīng)用后,微信開放平臺會生成APP的唯一標識APPID。在Xcode中打開項目,設(shè)置項目屬性中的URL Schemes為您的APPID;
2、注冊APPID
商戶APP工程中引入微信lib庫和頭文件,調(diào)用API前,需要先向微信注冊您的APPID,代碼如下:
[WXApi registerApp:@"wxd930ea5d5a258f4f"];
3、調(diào)起支付
商戶服務(wù)器生成支付訂單,先調(diào)用【統(tǒng)一下單API】生成預(yù)付單,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼(注意微信支付的單位是分):

//下面所有的參數(shù)都是服務(wù)端返回的(注意事項:就是時間戳在iOS中是10位的,超過10位會越界;)
PayReq *request = [[PayReq alloc] init];
request.partnerId = @"10000100";
request.prepayId = @"1101000000140415649af9fc314aa427";
request.package = @"Sign=WXPay";
request.nonceStr = @"a462b76e7436e98e0ed6e13c64b4fd1c";
request.timeStamp = @"1397527777";
request.sign = @"582282D72DD2B03AD892830965F428CB16E7A256";
[WXApi sendReq:request];

4、支付結(jié)果回調(diào)
照微信SDK Sample,在類實現(xiàn)onResp函數(shù),支付完成后,微信APP會返回到商戶APP并回調(diào)onResp方法,開發(fā)者需要在該方法中接收通知,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結(jié)果再展示用戶實際支付結(jié)果。注意 一定不能以客戶端返回作為用戶支付的結(jié)果,應(yīng)以服務(wù)器端的接收的支付通知或查詢API返回的結(jié)果為準。再者就是此方法一般寫到APPdelegate中或者將其封裝為一個工具類!添加監(jiān)聽的方法為:

[WXApi handleOpenURL:url delegate:self];

監(jiān)聽支付結(jié)果:

//微信SDK自帶的方法,處理從微信客戶端完成操作后返回程序之后的回調(diào)方法,顯示支付結(jié)果的
- (void)onResp:(BaseResp *)resp{
    //啟動微信支付的response
    NSString *payResoult = [NSString stringWithFormat:@"errcode:%d",resp.errCode];
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回結(jié)果,實際支付結(jié)果需要去微信服務(wù)器端查詢
        switch (resp.errCode) {
            case 0:
                payResoult = @"支付結(jié)果:成功!";
                NSLog(@"支付成功!");
                break;
            case -1:
                payResoult = @"支付結(jié)果:失敗!";
                NSLog(@"支付失?。?);
                break;
            case -2:
                payResoult = @"用戶已經(jīng)退出支付!";
                NSLog(@"用戶退出!");
                break;
            default:
                payResoult = [NSString stringWithFormat:@"支付結(jié)果:失??!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
                break;
        }
    }
}

2.服務(wù)端

對于集成微信支付來說任務(wù)基本上都是在服務(wù)端來完成;主要是為了安全起見,防止被別人篡改信息;

第一步:統(tǒng)一下單

客戶端將生成訂單所需要的信息傳給服務(wù)端,服務(wù)端接收到的參數(shù)格式化為XML格式的數(shù)據(jù),完成之后將微信返回的數(shù)據(jù)進行解析,取出客戶端需要的數(shù)據(jù),用戶喚起微信進行支付(所需參數(shù)包括:appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式為Sign=WXPay);

總結(jié):

1.請求參數(shù)需要按照參數(shù)的key進行字母的ASCII碼進行排序;
2.對排序后的數(shù)據(jù)進行MD5簽名,微信服務(wù)端會進行校驗,防止數(shù)據(jù)在網(wǎng)絡(luò)傳輸過程中被篡改。
3.拿到微信響應(yīng)的數(shù)據(jù),首先要做的事,也是對獲取的數(shù)據(jù)進行簽名校驗,理由同上。
4.需要注意的一點,返回給app客戶端的數(shù)據(jù)的key一定是小寫,這點微信的api是沒有說明白的,之前和客戶端聯(lián)調(diào)時耽誤了很多時間,這也是微信支付被很多開發(fā)者吐槽的地方api比較難用^-^

第二步:調(diào)起支付

一般是通過客戶端來調(diào)起微信進行支付的;
通過上一步服務(wù)器返回的支付參數(shù)通過調(diào)用SDK調(diào)起微信支付;向微信支付系統(tǒng)發(fā)起支付請求,微信支付系統(tǒng)驗證支付參數(shù),APP支付權(quán)限等,返回需要支付的授權(quán),用戶確認支付,輸入支付密碼;提交支付授權(quán),微信支付系統(tǒng)驗證授權(quán)完成支付;

第三步:查詢訂單

客戶端在接收到微信支付系統(tǒng)的支付結(jié)果回調(diào)之后并不代表最終的支付結(jié)果成功,還需要向后臺查詢實際的支付結(jié)果,服務(wù)端需要調(diào)用微信的查詢API查詢支付結(jié)果,服務(wù)端返回支付結(jié)果記錄!客戶端通過后臺查詢的支付結(jié)果才是最終的支付結(jié)果;

3.總結(jié)

整個微信支付的整個流程就是這樣,中間寫的多有不足,還望大家批評指點!如有什么問題歡迎大家下方留言!O(∩_∩)O謝謝....

備注:最近項目針對微信支付有個特殊的需求,就是在進行微信的支付的時候想對針對不同的商家使用不同的APPID, 經(jīng)過一番查找之后發(fā)現(xiàn)目前iOS中并不支持這種多賬戶支付,因為在集成微信支付的時候需要設(shè)置App scheme;但是這個字段又不能在程序運行中動態(tài)設(shè)置App scheme,因此就沒更好的方法來實現(xiàn)這一功能;但是支付寶針對這中需求還是支持的比較好的!不知道大家有遇到這種需求沒有,或者有什么好的解決辦法沒有?歡迎在下方留言討論,或者私信我!O(∩_∩)O謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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