悠閑時光, 順便將開發(fā)過程中, 經(jīng)常使用到的一些功能, 記錄分享出來,比如支付!
本想寫一篇銀聯(lián)支付,不過看了之前轉(zhuǎn)載過一篇關(guān)于銀聯(lián)支付的文章寫得很詳細(xì),我就不再重復(fù)了, 有興趣的童鞋可以去看一下; 戳這里
首先介紹一下微信支付的實(shí)現(xiàn)流程:
- 注冊微信開放平臺,創(chuàng)建應(yīng)用獲取appid,appSecret,申請支付功能(需要花費(fèi)300大洋進(jìn)行開發(fā)者資質(zhì)認(rèn)證),申請成功之后會返回一些參數(shù).
- 下載微信支付sdk
- 客戶端請求訂單,后臺與微信后臺交互,返回給客戶端支付參數(shù)
- 調(diào)用微信客戶端,由微信客戶端和微信服務(wù)器打交道;
- 客戶端和服務(wù)端都會收到支付結(jié)果;(前臺消息不可靠,我們需要去后臺驗(yàn)證,如果后臺沒有收到支付通知,后臺去微信服務(wù)器驗(yàn)證然后將結(jié)果返回給客戶端)
開發(fā)步驟
在微信開放平臺注冊應(yīng)用, 并開通支付功能之后(期間各種認(rèn)證, 確認(rèn)信息等操作按照流程走就可以, 在此省略)
第一步: 下載微信 SDK

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

- 將 SDK 拖入工程
- 導(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等框架;
- 將微信支付要用到的APPID設(shè)置為URL Schemes

第三步: 就是寫代碼了
- 注冊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(@"注冊微信失敗");
}
}
- 調(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)個心吧。