最近做了一個新項目骂远,涉及到支付寶和微信支付衡未,支付寶和微信都是業(yè)界的老大哥琅绅,相信大家都有所覺得文檔、SDK都是各種坑吧(純粹吐槽而已)仗考,這是繼上篇支付寶支付集成后接著的微信支付集成音同。
1.微信商戶申請步驟
http://kf.qq.com/faq/120911VrYVrA150906F3qqY3.html
2.申請成功后說明
官方支付賬戶說明文檔:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=3_1
賬戶參數(shù)說明:
官方業(yè)務(wù)流程文檔:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3
3.微信支付集成
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417694084&token=&lang=zh_CN
1> 添加微信支付SDK
2> 添加庫
4.開發(fā)步驟說明
官方開發(fā)步驟文擋:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
1> 項目設(shè)置APPID,在工程項目中添加商戶自己的APPID
商戶在微信開放平臺申請開發(fā)APP應(yīng)用后秃嗜,微信開放平臺會生成APP的唯一標(biāo)識APPID权均。在Xcode中打開項目,設(shè)置項目屬性中的URL Schemes為您的APPID
2> iOS 9.0以上的系統(tǒng)如果要正常調(diào)起微信锅锨,還需要添加白名單叽赊,在工程項目的plist文件中添加
3> 開發(fā)者需要在工程中鏈接上:SystemConfiguration.framework, libz.dylib, libsqlite3.0.dylib, libc++.dylib, Security.framework, CoreTelephony.framework, CFNetwork.framework。
4> 在你的工程文件中選擇Build Setting必搞,在"Other Linker Flags"中加入"-Objc -all_load"必指,在Search Paths中添加 libWeChatSDK.a ,WXApi.h恕洲,WXApiObject.h塔橡,文件所在位置
5> 注冊APPID
商戶APP工程中引入微信lib庫和頭文件,調(diào)用API前霜第,需要先向微信注冊您的APPID葛家,代碼如下:
// 在appDelegate.m中,注冊微信應(yīng)用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//向微信注冊
[WXApi registerApp:@"您的APPID"];
}
6> 調(diào)起支付
商戶服務(wù)器生成支付訂單泌类,先調(diào)用【統(tǒng)一下單API】生成預(yù)付單癞谒,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付。以下是調(diào)起微信支付的關(guān)鍵代碼:
為了安全性刃榨,以下字段最好從服務(wù)器去獲取
// 調(diào)起微信支付
PayReq *request = [[PayReq alloc] init];
/** 微信分配的公眾賬號ID -> APPID */
request.partnerId = APPID;
/** 預(yù)支付訂單 從服務(wù)器獲取 */
request.prepayId = @"1101000000140415649af9fc314aa427";
/** 商家根據(jù)財付通文檔填寫的數(shù)據(jù)和簽名 <暫填寫固定值Sign=WXPay>*/
request.package = @"Sign=WXPay";
/** 隨機串弹砚,防重發(fā) */
request.nonceStr= @"a462b76e7436e98e0ed6e13c64b4fd1c";
/** 時間戳,防重發(fā) */
request.timeStamp= @“1397527777";
/** 商家根據(jù)微信開放平臺文檔對數(shù)據(jù)做的簽名, 可從服務(wù)器獲取枢希,也可本地生成*/
request.sign= @"582282D72DD2B03AD892830965F428CB16E7A256";
/* 調(diào)起支付 */
[WXApi sendReq:request];
7> 支付結(jié)果回調(diào)
照微信SDK Sample桌吃,在類實現(xiàn)onResp函數(shù),支付完成后晴玖,微信APP會返回到商戶APP并回調(diào)onResp函數(shù)读存,開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯誤碼呕屎,如果支付成功則去后臺查詢支付結(jié)果再展示用戶實際支付結(jié)果。
注意: 一定不能以客戶端返回作為用戶支付的結(jié)果敬察,應(yīng)以服務(wù)器端的接收的支付通知或查詢API返回的結(jié)果為準(zhǔn)秀睛。
代碼示例如下:
// 支付返回結(jié)果,實際支付結(jié)果需要去微信服務(wù)器端查詢
-(void)onResp:(BaseResp *)resp {
if([resp isKindOfClass:[PayResp class]]){
switch (resp.errCode) {
case WXSuccess:{
NSlog(@"支付成功");
// 發(fā)通知帶出支付成功結(jié)果
[[NSNotificationCenter defaultCenter] postNotificationName:QTXWXReturnSucceedPayNotification object:resp];
}
break;
default:{
NSlog(@“支付失敗:%d”,resp.errCode);
// 發(fā)通知帶出支付失敗結(jié)果
[[NSNotificationCenter defaultCenter] postNotificationName:QTXWXReturnFailedPayNotification object:resp];
}
break;
}
}
}
具體使用先放一下我的部分代碼:
- 一般微信支付和支付寶支付都會被一起集成莲祸,這邊就要在appDelegate.m中一起整理判斷回調(diào)
這里處理新浪微博SSO授權(quán)之后跳轉(zhuǎn)回來蹂安,和微信/支付寶支付完成之后跳轉(zhuǎn)回來
*/
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL result = [UMSocialSnsService handleOpenURL:url wxApiDelegate:nil];
if (result == NO) { // 調(diào)用其他 SDK 支付寶
//如果極簡 SDK 不可用,會跳轉(zhuǎn)支付寶錢包進行支付,需要將支付寶錢包的支付結(jié)果回傳給 SDK
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付椭迎,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
QTXLog(@"支付寶客戶端支付結(jié)果result = %@",resultDic);
if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
// 發(fā)通知帶出支付成功結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
} else {
// 發(fā)通知帶出支付失敗結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
}
}];
}
if ([url.host isEqualToString:@"platformapi"]){//支付寶錢包快登授權(quán)返回 authCode
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
QTXLog(@"支付寶網(wǎng)頁版result = %@",resultDic);
if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
// 發(fā)通知帶出支付成功結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
} else {
// 發(fā)通知帶出支付失敗結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
}
}];
}
//微信的支付回調(diào)
if ([url.host isEqualToString:@"pay"]) {
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
}
return result;
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
BOOL result = [UMSocialSnsService handleOpenURL:url];
if (result == NO) { // 調(diào)用其他 SDK 支付寶
//如果極簡 SDK 不可用,會跳轉(zhuǎn)支付寶錢包進行支付,需要將支付寶錢包的支付結(jié)果回傳給 SDK
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
QTXLog(@"支付寶客戶端支付結(jié)果result = %@",resultDic);
if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
// 發(fā)通知帶出支付成功結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
} else {
// 發(fā)通知帶出支付失敗結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
}
}];
}
if ([url.host isEqualToString:@"platformapi"]){//支付寶錢包快登授權(quán)返回 authCode
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
QTXLog(@"支付寶網(wǎng)頁版result = %@",resultDic);
if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
// 發(fā)通知帶出支付成功結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
} else {
// 發(fā)通知帶出支付失敗結(jié)果
[QTXNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
}
}];
}
//微信的支付回調(diào)
if ([url.host isEqualToString:@"pay"]) {
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
}
return result;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
- 在使用微信支付的當(dāng)前控制器里:
// 調(diào)起微信支付田盈,接收通知畜号,并且判斷手機是否安裝微信
- (void)weChatPay {
// 1.拼接請求參數(shù)
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"orderid"] = self.order;
params[@"userIp"] = [QTXGetIPTool deviceIPAdress]; // 獲取當(dāng)前設(shè)備的ip
// 2.發(fā)送請求
__weak __typeof(self) weakSelf = self;
[QTXHttpTool post:QTX_weChatPay_url params:params success:^(id json) {
QTXLog(@"微信支付返回參數(shù)接口 請求成功-%@", json);
if ([json[@"success"] isEqual:@(YES)]) {
NSMutableDictionary *wechatDic = json[@"data"];
[WXApi registerApp:[wechatDic objectForKey:@"appid"]];
PayReq *request = [[PayReq alloc] init];
request.partnerId = [wechatDic objectForKey:@"mch_id"]; // 商家向財付通申請的商家id
request.prepayId= [wechatDic objectForKey:@"prepay_id"]; // 支付訂單
request.package = @"Sign=WXPay"; // Sign=WXPay 商家根據(jù)財付通文檔填寫的數(shù)據(jù)和簽名
request.nonceStr= [wechatDic objectForKey:@"nonce_str"]; // 隨機串,防重發(fā)
request.timeStamp= [[wechatDic objectForKey:@"timestamp"] intValue]; //時間戳允瞧,防重發(fā)
request.sign= [wechatDic objectForKey:@"sign2"]; // 商家根據(jù)微信開放平臺文檔對數(shù)據(jù)做的簽名 二次簽名
if ([WXApi sendReq:request]) {
[QTXNotificationCenter addObserver:self selector:@selector(paySucceed) name:QTXWXReturnSucceedPayNotification object:nil];
[QTXNotificationCenter addObserver:self selector:@selector(payFailed) name:QTXWXReturnFailedPayNotification object:nil];
} else { // 未安裝微信客戶端相關(guān)處理
QTXAlterView *alter = [[QTXAlterView alloc] initWithMessage:[NSString stringWithFormat:@"未安裝微信客戶端,請使用其他支付方式"] delegate:self rightButtonTitle:@"確定" otherButtonTitles:nil];
[alter show];
}
} else {
[MBProgressHUD showError:[NSString stringWithFormat:@"%@", json[@"errorMessage"]]];
}
[weakSelf.tableView reloadData];
} failure:^(NSError *error) {
[MBProgressHUD showError:@"暫無網(wǎng)絡(luò)简软,稍后再試"];
QTXLog(@"微信支付返回參數(shù)接口 請求失敗-%@", error);
}];
}
目前微信支付SDK已經(jīng)更新到1.7.5, 我這邊也同步更新下. 其實在原有版本基礎(chǔ)上,只需要增加以下三點:
- 更新支持iOS啟用 ATS(App Transport Security)
- 需要在工程中鏈接CFNetwork.framework
- 在工程配置中的”O(jiān)ther Linker Flags”中加入”-Objc -all_load”
如果需要支付寶支付集成, 請移步: iOS支付寶支付集成