千呼萬喚始出來,終于經過近10天努力,對微信和支付寶支付方面文檔以及自己的項目多次研究和嘗試,終搞定了支付的技術并有了以下的成果!
感謝開源的環境,可以共享我的項目,如果不錯的話,請給個星星哦!
干貨:本篇最后會附上自己封裝的微信和支付寶支付的類庫,歡迎指點,共同進步!
本篇說些什么呢?
首先附上目錄:
一.微信和支付寶支付異同點分析
二.我封裝的支付類庫原理講解
三.集成我的支付類庫的步驟
四.注意事項
五.附上我的演示Demo中的流程圖
一.微信和支付寶支付異同點分析
1.二者申請的異同
微信支付申請過程中需要¥300審核費,而支付寶的申請必須提供公司資質才能申請使用;
也就是說,個人申請微信支付您需要是土豪,而申請支付寶支付您需要有靠山,哈哈,開個玩笑!
2.二者的支付整個流程異同
簡單來說:
相同的地方:
下訂單 —>調支付客戶端(微信或者支付寶)—>真正的支付—>通知支付成功
不同的地方:
支付寶:支付成功后,支付寶后臺主動把支付情況—>支付寶客戶端—>告知我們的商家,這里我稱為主動性支付!
微信:支付成功后,
微信后臺異步通知—>商戶后臺
微信App 通知—> 商戶App 查詢—>商戶后臺—>告知我們的商家 這里我稱為被動性支付!
匯總:
支付寶:主動性支付
微信:被動性支付
3.其他異同
調啟支付客戶端并回去的異同:如下
支付寶支付:在urlScheme中加入自定義字符串標示回來的應用
微信支付:在url中寫申請的AppId標示回來的應用
如下:
微信支付成功下訂單是至少7個參數,支付需要用到
支付寶成功下訂單是一串字符串,支付需要
這里的不同點就是我封裝的類庫的入口處!
支付成功后的回調方式:
微信支付是代理回調
支付寶支付是Block回調
二.我封裝的支付類庫原理講解
以上以支付寶和微信的支付不同點作為入口,來解析我封裝的類庫,即為WechatAliPay
在這個項目中,關于支付的有以下3個文件
1.CMWechatAliPayManager 的.h 和.m文件
一個發送支付請求的單例類,其中含有分別處理微信和支付寶的下訂單成功后執行真正的支付是通過返回過來的訂單參數
如果是字符串則證明是支付寶的返回,就用下面的方法
// 調用支付寶的支付接口
[[AlipaySDK defaultService] payOrder:infoStr fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
NSString *resultStatus = resultDic[@"resultStatus"];
[ws.delegate Wpay:ws andPayKind:WAPayKindAliPay andPayResult:[resultStatus intValue]];
}];
調用支付寶的接口完成支付;
如果是字典則證明是微信的返回,則通過下面的方法包裝PayReq 的參數,調用
// 判斷自己的服務器的產生的訂單參數返回是否正確,并返回包裝好的參數
-(PayReq *)isWpayParamsIsCorrect:(NSDictionary *)params {
if ([params allKeys].count >=6) {
PayReq *req =[[PayReq alloc]init];
#warning 微信支付的訂單參數(AppId等),不要忘記更改了
req.openID =@"wxe9beac44b65d4815";
req.partnerId =params[@"partnerid"];
req.prepayId =params[@"prepayid"];
req.nonceStr =params[@"noncestr"];
req.timeStamp =[params[@"timestamp"] intValue];
req.package =params[@"package"];
req.sign =params[@"sign"];
return req;
}
return nil;
}
sendReq方法,等待返回onResp 方法
2.CMWpaySearchResultDelegate.h文件
這是設定一個協議,當支付成功之后,會根據這個協議調用對應的方法完成支付后的工作:
如:當微信支付成功,走到 onResp ,我的代理就會調用 CMWpaySearchResultDelegate.h的Wpay:andPayKind:andPayResult: 如下
#pragma mark - 微信支付成功后返回
-(void) onResp:(BaseResp*)resp {
if([resp isKindOfClass:[PayResp class]]){
//支付返回結果,實際支付結果需要去微信服務器端查詢
if ([self.delegate respondsToSelector:@selector(Wpay:andPayKind:andPayResult:)]) {
[self.delegate Wpay:self andPayKind:WAPayKindWechat andPayResult:resp.errCode];
}
}
}
告訴我的客戶端支付成功了
而當支付寶支付成功后,就會走到其設置的block種同樣由我的代理調用Wpay:andPayKind:andPayResult: 如下
完成支付完成后的事情。
3.支付完成后走到如下Wpay:andPayKind:andPayResult: 中,然后展示如下:
#pragma mark - CMWpaySearchResultDelegate
-(void)Wpay:(CMWechatAliPayManager *)manager andPayKind:(WAPayKind)payKind andPayResult:(int)code {
DDLog(@"走到回調的地方了");
if (payKind ==WAPayKindWechat) { // 微信
switch (code) {
case WXSuccess:
// 1. 包裝對應查詢參數
[DisplayHelper displaySuccessAlert:@"微信支付成功!"];
// 2. 發送查詢的是否成功的請求
break;
default:
break;
}
}else { // 支付寶
switch (code) {
case 9000:// 成功
[DisplayHelper displaySuccessAlert:@"支付寶支付成功!"];
break;
case 6001:// 取消
break;
default:
break;
}
}
}
三.集成我的支付類庫的步驟(具體部分詳情請參照最后附帶我另外2篇講的關于微信和支付寶支付集成)
1.導入的庫
導入的SDK如下:
導入的系統庫如下:
在Build Phases選項卡的Link Binary With Libraries中加入以下的依賴:
libc++.tbd
libz.tbd
SystemConfiguration.framework
CoreTelephony.framework
QuartzCore.framework
CoreText.framework
CoreGraphics.framework
Foundation.framework
UIKit.framework
CoreMotion.framework
CFNetwork.framework
Security.framework
libsqlite3.0.dylib
UIKit.framework
// 支付寶依賴的
AlipaySDK.framework
// 微信官方的庫
libWeChatSDK.a
導入我的3個文件夾
2.更改的文件
AppDelegate中頭文件和代理:
導入
#import "WXApi.h"
遵循
<WXApiDelegate>
AppDelegate中Code處理方面:
初始化微信支付方法如下:
#pragma mark - 初始化微信支付
- (void)initWpay
{
#warning 記得更改微信Appid為您的
[WXApi registerApp:@"wx685a5f98e4497044" withDescription:@"com.zzdlwx.com"];
}
Application的代理方法實現如下:
#pragma mark - UIApplicationDelegate
- (BOOL)application:(UIApplication *)application
handleOpenURL:(NSURL *)url
{
return [WXApi handleOpenURL:url delegate:self];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
NSString *resultStatus = resultDic[@"resultStatus"];
switch (resultStatus.integerValue) {
case 9000:// 成功
break;
case 6001:// 取消
break;
default:
break;
}
}];
// 授權跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
// 解析 auth code
NSString *result = resultDic[@"result"];
NSString *authCode = nil;
if (result.length>0) {
NSArray *resultArr = [result componentsSeparatedByString:@"&"];
for (NSString *subResult in resultArr) {
if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
authCode = [subResult substringFromIndex:10];
break;
}
}
}
NSLog(@"授權結果 authCode = %@", authCode?:@"");
}];
}
return [WXApi handleOpenURL:url delegate:self];
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if ([url.host isEqualToString:@"safepay"]) {
// 支付跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
// 授權跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
// 解析 auth code
NSString *result = resultDic[@"result"];
NSString *authCode = nil;
if (result.length>0) {
NSArray *resultArr = [result componentsSeparatedByString:@"&"];
for (NSString *subResult in resultArr) {
if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
authCode = [subResult substringFromIndex:10];
break;
}
}
}
NSLog(@"授權結果 authCode = %@", authCode?:@"");
}];
}
return [WXApi handleOpenURL:url delegate:self];
}
要支付的文件中的頭文件導入
(注意CMHttpRequestModel 這個類我已經加入我的Pch中,沒加入的話,您也要導入)
#import "CMWechatAliPayManager.h"
要支付的文件中的Code處理方面
發送下訂單的請求
-(void)yesPayBtnClick:(UIButton *)button {
CMHttpRequestModel *paramsModel =[[CMHttpRequestModel alloc]init];
paramsModel.localHost =kTestHttpHost;
paramsModel.appendUrl =kPay_topay;
// 參數設置
[paramsModel.paramDic setValue:@"e1370e6a9995a7010ded1596308acfc6" forKey:@"token"];
[paramsModel.paramDic setValue:@"Z20170421114853LK8pc" forKey:@"orderid"];
// 3.發送的網絡請求
if (self.selectedTableView.indexKind==0) {// 支付寶支付
[paramsModel.paramDic setValue:@(3) forKey:@"paytype"];
}else if (self.selectedTableView.indexKind==1) {// 微信支付
[paramsModel.paramDic setValue:@(4) forKey:@"paytype"];
}else {// 銀聯支付
}
[[CMWechatAliPayManager sharedWpayManager] sendWeChatAliPayRequestParam:paramsModel];
}
支付成功后的回調處理
#pragma mark - CMWpaySearchResultDelegate
-(void)Wpay:(CMWechatAliPayManager *)manager andPayKind:(WAPayKind)payKind andPayResult:(int)code {
DDLog(@"走到回調的地方了");
if (payKind ==WAPayKindWechat) { // 微信
switch (code) {
case WXSuccess:
// 1. 包裝對應查詢參數
[DisplayHelper displaySuccessAlert:@"微信支付成功!"];
// 2. 發送查詢的是否成功的請求
break;
default:
break;
}
}else { // 支付寶
switch (code) {
case 9000:// 成功
[DisplayHelper displaySuccessAlert:@"支付寶支付成功!"];
break;
case 6001:// 取消
break;
default:
break;
}
}
}
3.注意更改以下地方
全局搜索 “#warning” 找到下面的5個地方,分別按照提示更改為您的信息
4.其他要更改的
在info.plist中把微信加入白名單等
urlType中分別加入微信和支付寶的urlScheme
支付寶導入SDK后報錯 : #include <openssl/asn1.h> 找不到
解決方案:
在Build Settings選項卡中搜索 header search添加新的路徑為$(PROJECT_DIR)/FarmAndAnimal/Vendor/AliPaySDK/
其中這里的AliPaySDK 指的是openssl 的上一級文件為止,不一定是AliPaySDK, 切記!
四.注意事項
1.注意修改以上集成步驟中“#warning”搜索后要改的內容
2.微信支付需要和項目Bundle綁定在一起,支付寶任何應用都可以完成支付功能
3.關于微信和支付寶的應用跳轉和返回應用:
微信注意3個地方
應用啟動時注冊AppId
urlScheme中添加AppId
支付發送PayReq中帶上對應的AppId
支付寶注意2個地方
urlScheme中添加自定義字符串
發送支付請求時加上appScheme 標示應用程序
五.附上我的演示Demo中的流程圖
1.支付寶流程:
1.微信流程:
納尼,微信為什么會支付失敗呢,就是因為微信的AppId必須綁定到對應的BundleId才能生效
ps:微信支付正在申請中,嘿嘿!
附上:
1.支付寶接入流程分享:
http://www.lxweimin.com/p/d8edb82e51a7
2.微信支付接入流程分享:
http://www.lxweimin.com/p/8205595a932d
3.我的支付寶和微信分享Demo:
https://github.com/zxwIsCode/WechatAliPay
支付模塊暫時告一段落,以后有時間有機會會整理一下關于銀聯支付甚至第三方Ping++等有關支付的問題!
有任何問題,歡迎聯系QQ:1824496534,備注:支付。
期待中吧,小伙伴,感謝支持!