一:介紹
項目中要用到支付功能,需要支付寶支付、支付寶網(wǎng)頁支付、微信支付、銀聯(lián)支付、Apple_pay,所以打算總結(jié)一下,方便以后的查閱,也方便大家, 用到的地方避免再次被坑。
今天我們就主要介紹一下微信支付,其他支付也寫了對應(yīng)教程,并且給出了連接。
集成前首先要看看文檔,微信支付開發(fā)文檔里面有詳細的字段和說明。
微信支付是需要簽名的,跟支付寶一樣,可以在客戶端簽名,也可以在后臺簽名(當(dāng)然,為了安全還是推薦在服務(wù)器上做簽名,邏輯也比較好理解)
更多iOS干貨Demo源碼獲取方法
關(guān)注 【網(wǎng)羅開發(fā)】微信公眾號,選取需要的文章類別,根據(jù)序號便可領(lǐng)取。
網(wǎng)羅天下方法,方便你我開發(fā),所有文檔會持續(xù)更新,歡迎關(guān)注一起成長!
二:業(yè)務(wù)流程
以下是交互時序圖,統(tǒng)一下單API、支付結(jié)果通知API和查詢訂單API等都涉及簽名過程,調(diào)用都必須在商戶服務(wù)器端完成。
商戶系統(tǒng)和微信支付系統(tǒng)主要交互說明:
- 用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。
- 商戶后臺收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口。
- 統(tǒng)一下單接口返回正常的prepay_id,再按簽名規(guī)范重新生成簽名后,將數(shù)據(jù)傳輸給APP。參與簽名的字段名為appid,partnerid,prepayid,noncestr,timestamp,package。
- 商戶APP調(diào)起微信支付。
- 商戶后臺接收支付通知。
- 商戶后臺查詢支付結(jié)果。
三:下載微信SDK
如果集成了友盟分享里的微信,那就不用下載,也不用配置環(huán)境,因為配置友盟分享的時候已經(jīng)把微信支付的環(huán)境都配置好了(包括框架,schema跳轉(zhuǎn),白名單)如果沒有集成過友盟分享那么請到微信開放平臺下載SDK。
建議把iOS頭文件和支付示例都下載下來
四:導(dǎo)入庫集成SDK
4.1 導(dǎo)入SDK庫
導(dǎo)入上面那個iOS頭文件和庫下載下載出來的SDK包的就行,然后需要鏈接上依賴庫,在Target —> BuildPhases —> Link Binary With Libraries— 點擊+號 -> 搜索你需要的系統(tǒng)庫。
- SystemConfiguration.framework
- libz.tbd
- libsqlite3.0.tbd
- CoreTelephony.framework
- QuartzCore.framework
4.2 設(shè)置URL Scheme
商戶在微信開放平臺申請開發(fā)APP應(yīng)用后,微信開放平臺會生成APP的唯一標(biāo)識APPID,在APP端開發(fā)步驟里面說得很清楚了,需要填在URL Schemes這個地方。
4.2 在Appdelegate中注冊APPID
首先要在Appdelegate中引用頭文件
//微信支付
#import "WXApi.h"
然后注冊APPID
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 向微信終端注冊ID
[WXApi registerApp:@"wxd930ea5d5a258f4f"];
return YES;
}
在支付成功之后,支付結(jié)果返回,需要獲取url,也需要在Appdelegate中完成,代碼如下:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
}else if ([url.host isEqualToString:@"pay"]) {
// 處理微信的支付結(jié)果
[WXApi handleOpenURL:url delegate:self];
}
return YES;
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
}else if ([url.host isEqualToString:@"pay"]) {
// 處理微信的支付結(jié)果
[WXApi handleOpenURL:url delegate:self];
}
return YES;
}
微信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é)果:成功!";
break;
case -1:
payResoult = @"支付結(jié)果:失敗!";
break;
case -2:
payResoult = @"用戶已經(jīng)退出支付!";
break;
default:
payResoult = [NSString stringWithFormat:@"支付結(jié)果:失敗!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
break;
}
}
}
4.3 調(diào)用支付接口
在調(diào)用微信支付類里面,首先增加頭文件引用。
#import "WXApi.h"
在調(diào)起支付的方法中,需要上傳的參數(shù)包括:appid、partid(商戶號)、prepayid(預(yù)支付訂單ID)、noncestr(參與簽名的隨機字符串)、timestamp(參與簽名的時間戳)、sign(簽名字符串)這六個。
在點擊支付的控制器中使用核心代碼來調(diào)起微信客戶端支付,這些個參數(shù)都是后臺傳給你的。 加上了注釋,應(yīng)該很好理解的。代碼如下:
#pragma mark 微信支付方法
- (void)WechatPay{
//需要創(chuàng)建這個支付對象
PayReq *req = [[PayReq alloc] init];
//由用戶微信號和AppID組成的唯一標(biāo)識,用于校驗微信用戶
req.openID = appid;
// 商家id,在注冊的時候給的
req.partnerId = partnerid;
// 預(yù)支付訂單這個是后臺跟微信服務(wù)器交互后,微信服務(wù)器傳給你們服務(wù)器的,你們服務(wù)器再傳給你
req.prepayId = prepayid;
// 根據(jù)財付通文檔填寫的數(shù)據(jù)和簽名
req.package = package;
// 隨機編碼,為了防止重復(fù)的,在后臺生成
req.nonceStr = noncestr;
// 這個是時間戳,也是在后臺生成的,為了驗證支付的
NSString * stamp = timestamp;
req.timeStamp = stamp.intValue;
// 這個簽名也是后臺做的
req.sign = sign;
//發(fā)送請求到微信,等待微信返回onResp
[WXApi sendReq:req];
}
4.4 判斷手機是否安裝微信客戶端
在需要微信支付的地方調(diào)用封裝的類方法之后會跳轉(zhuǎn)到微信app,如果沒有安裝則沒有任何反應(yīng)。這里需要注意,因為沒有安裝微信,必須要提供webview的方式登錄微信來支付,否則蘋果公司會拒絕應(yīng)用上架。但是微信又不自帶webview的方式,(支付寶是自帶的)所以要判斷用戶有沒有安裝微信,如果沒有安裝微信就不顯示微信支付這個按鈕。
// 判斷手機有沒有微信
if ([WXApi isWXAppInstalled]) {
wechatButton.hidden = NO;
}else{
wechatButton.hidden = YES;
}
到這里微信支付就基本完成了,如果小伙伴們在集成過程中遇到什么問題,可以留言給我或者添加qq,在線幫你解決。
后續(xù):常見問題解決
- 如果支付完成后,一直留在微信,那就檢查下URLType中的Scheme設(shè)置問題。
- 能夠打開微信客戶端,但是打開后只有中間一個白色的 “確定按鈕”,點擊后會回到客戶端上,如果是這樣,那應(yīng)該是prepayid 參數(shù)的問題,過期了,或者不是真實的id。
- 微信支付的單位是分
- 工程->build setttings -> 搜索other linker flags 添加-Objc -all_load ,運行工程可能會崩潰,原因是程序沒有找到sdk庫。
- 白名單:不配置白名單也可以調(diào)起支付,如果調(diào)不起支付,查看是否是白名單的問題。
打開工程里的info.plist文件 添加LSApplicationQueriesSchemes數(shù)組并添加wechat 和 weixin字符串。
或者info.plist右鍵->source code打開添加下面這段代碼
<key>LSApplicationQueriesSchemes</key>
<array><string>wechat</string>
<string>weixin </string>
</array>
- 中文名的工程會報這個錯誤,英文名則不會,這是因為缺少UIKit庫 在WXApiObject.h里導(dǎo)入庫#import <UIKit/UIKit.h>。
希望可以幫助大家
如果哪里有什么不對或者不足的地方,還望讀者多多提意見或建議
iOS技術(shù)交流群:668562416
源碼Demo獲取方法
關(guān)注「網(wǎng)羅開發(fā)」公眾號 ,有iOS demo、RN 視頻以及demo、Android demo等你領(lǐng)取。