實(shí)現(xiàn)支付寶支付的準(zhǔn)備工作:
1.向支付寶簽約,成為支付寶的商戶(hù)
簽約完成后,支付寶會(huì)提供一些必要的數(shù)據(jù)給我們
商戶(hù)ID:partner
賬號(hào)ID:seller 即支付寶賬號(hào)
簽約需要營(yíng)業(yè)執(zhí)照
2.獲取支付相關(guān)的? 私鑰和密鑰,這兩個(gè)東西為了數(shù)據(jù)安全
上面這幾個(gè)東西只要簽約成功就可以看到
3.下載支付寶的SDK
下載網(wǎng)址: http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1
上面部分是準(zhǔn)備工作,從這里開(kāi)始集成
4.下載好之后打開(kāi)客戶(hù)端Demo—>iOS SDK Demo解壓縮,打開(kāi)案例,運(yùn)行程序
可能為有一個(gè)active為YES的錯(cuò)誤,只要在build Setting里搜索這個(gè)active改為NO即可,再清除運(yùn)行就好了
5.將Demo中的SDK提取出來(lái),提取以下幾個(gè)文件
openssl、Order.h、Order.m、Util、libcrypto.a、libssl.a、AlipaySDK.bundle
將這幾個(gè)文件放到一個(gè)文件夾中,然后添加到項(xiàng)目中Order.h、Order.m這兩個(gè)文件可加可不加
添加進(jìn)去編譯,發(fā)現(xiàn)報(bào)錯(cuò)
5.1添加.pch文件 ? 打開(kāi)項(xiàng)目Supporting Files—>右鍵NewFile—>iOS—>Other—>PCH File—>選中Targets第一個(gè)選項(xiàng)—Create—然后在新創(chuàng)建的PCH文件中添加 #import
現(xiàn)在PCH文件還不能使用,需要添加PCH文件 點(diǎn)擊項(xiàng)目—>buildSetting—>右邊搜索pref—>將Apple LLVM7.0 Language的
第二個(gè)選項(xiàng)Precompile Prefix Header后面的NO改成YES ,第三個(gè)選項(xiàng)路徑 直接將項(xiàng)目的名字復(fù)制
比如我這里的項(xiàng)目名字是:01支付寶集成
將這個(gè)名字復(fù)制到Prefix Header路徑上,雙擊這個(gè)選項(xiàng)出現(xiàn)一個(gè)白框,將名字粘貼到這個(gè)白框中,然后
在后面緊接/PrefixHeader.pch,完成的輸入應(yīng)該為? 01支付寶集成/PrefixHeader.pch
01支付寶集成? 項(xiàng)目名稱(chēng)
即 項(xiàng)目名稱(chēng)/PrefixHeader.pch? 這樣的格式
到這里第一步完成
5.2導(dǎo)入相應(yīng)的依賴(lài)庫(kù),大部分其實(shí)是不用導(dǎo)入的,但是為了保險(xiǎn)起見(jiàn),我們?nèi)紝?dǎo)入進(jìn)去
點(diǎn)擊支付寶的Demo,點(diǎn)擊項(xiàng)目—>Build Phases—>第三個(gè)Link Binary WithLibraries查看官方導(dǎo)入的依賴(lài)庫(kù)
然后我們也導(dǎo)入相應(yīng)的依賴(lài)庫(kù),點(diǎn)擊+號(hào)添加相應(yīng)的依賴(lài)庫(kù)
注意,Xcode7以后一些庫(kù)的后綴名字改了 libc++.dylib? 變成了libc++.tbd
這里附一張需要添加的依賴(lài)庫(kù)的截圖

即注意添加庫(kù)的時(shí)候 別以為沒(méi)有了,是改了后綴名而已
5.3添加好相應(yīng)的庫(kù)以后,編譯,會(huì)有一個(gè)錯(cuò)誤,提示? #include ? 這個(gè)文件未找到
是因?yàn)閄code6以后導(dǎo)入是有問(wèn)題的,以前Xcode5導(dǎo)入是沒(méi)有問(wèn)題的,只要配置一下就行了
因?yàn)槭菍?dǎo)入.a文件的時(shí)候它找不到里面的頭文件,意思是找不到.a文件里面的這個(gè)頭部文件,意思是找不到文件路徑,那怎么配置呢,配置一下,指定一下路徑就行了
點(diǎn)擊項(xiàng)目—>build Setting 然后在右邊搜索header S? 在第二個(gè)選項(xiàng)Header Search Paths 雙擊之后點(diǎn)擊左下角的+號(hào),然后填寫(xiě)? $(SRCROOT)/01支付寶集成/支付寶SDK ? ? 即可
注意
01支付寶集成 ? 為你的項(xiàng)目名稱(chēng)
支付寶SDK ? ? ? 為你導(dǎo)入的支付寶SDK文件夾的名字
然后清除一個(gè),重新運(yùn)行即可
5.4 除了上述依賴(lài)庫(kù)還需要一個(gè)框架,支付寶的SDK框架,在支付寶的示例程序中有一個(gè)框架名為AlipaySDK.framework的框架,右鍵show in Finder? 找到這個(gè)框架,然后復(fù)制,在 你的項(xiàng)目中點(diǎn)擊支付寶SDK文件,show in Finder? ,將AlipaySDK.framework粘貼到該目錄下, 這時(shí)候在項(xiàng)目中不會(huì)顯示這個(gè)框架,然后點(diǎn)擊支付寶SDK文件名,右鍵Add File To”” 就會(huì)打開(kāi)文件目錄,支付寶SDK(你自己的支付寶SDK文件夾名字,就是我們剛才導(dǎo)入的那個(gè)文件夾名字)—>選中AlipaySDK.framework,點(diǎn)擊右下角的add,然后就添加進(jìn)去了,要使用的時(shí)候只要導(dǎo)入頭文件
#import 就可以使用了
到這一步說(shuō)明支付寶已經(jīng)集成到項(xiàng)目中去了,完畢!
一、使用官方的Demo
需要配置基本信息:
打開(kāi)“APViewController.m”文件,對(duì)以下三個(gè)參數(shù)進(jìn)行編輯。


二、集成支付寶到自己的工程
1、啟動(dòng)Xcode,為了方便快速開(kāi)發(fā),將解壓包里面的AlipaySDK.bundle和AlipaySDK.framework
和Demo里面的以下文件拷貝到自己的工程文件夾中去,并導(dǎo)入到項(xiàng)目工程中。

2、在Build Phases選項(xiàng)卡的Link Binary With Libraries中,增加以下依賴(lài):

3、如果你的app基于9.0編譯,那么為了適配iOS9.0中的App Transport Security(ATS)對(duì)http的限制,這里需要對(duì)支付寶的請(qǐng)求地址alipay.com、alipayobjects.com做例外,在app對(duì)應(yīng)的info.list中添加如下配置

4、在需要支付功能的.m里面

#import"Order.h"#import"DataSigner.h"#import#import"APAuthV2Info.h"

根據(jù)自己的APP,修改下面的參數(shù)即可:





三、注意事項(xiàng)
1、缺少頭文件


出現(xiàn)這種情況,在它的文件上面加上:
#import#import
即可消除錯(cuò)誤
2、'openssl/asn1.h'file not found

解決方法如下:在你的Xcode里的header search paths 里添加支付寶SDK(openssl的路徑) 即?“Header Search Paths”只需要設(shè)置$(SRCROOT)/項(xiàng)目名稱(chēng)。
3、使用支付寶客戶(hù)端支付之后,無(wú)法返回原APP系統(tǒng)
(1)在AppDelegate.m文件中,
#import

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
[[AlipaySDK defaultService]
processOrderWithPaymentResult:url
standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);//返回的支付結(jié)果//【由于在跳轉(zhuǎn)支付寶客戶(hù)端支付的過(guò)程中,商戶(hù)app在后臺(tái)很可能被系統(tǒng)kill了,所以pay接口的callback就會(huì)失效,請(qǐng)商戶(hù)對(duì)standbyCallback返回的回調(diào)結(jié)果進(jìn)行處理,就是在這個(gè)方法里面處理跟callback一樣的邏輯】}];returnYES;
}

(2)點(diǎn)擊項(xiàng)目名稱(chēng),點(diǎn)擊“Info”選項(xiàng)卡,在“URL Types”選項(xiàng)中,點(diǎn)擊“+”,在“URL Schemes”中輸入自己的APP標(biāo)示,如:“alisdkdemo”?!癮lisdkdemo”來(lái)自于以下代碼:
支付代碼中的:

這里的URL Schemes中輸入的alisdkdemo,為測(cè)試demo,實(shí)際商戶(hù)的app中要填寫(xiě)?yīng)毩⒌膕cheme,建議跟商戶(hù)的app有一定的標(biāo)示度,要做到和其他的商戶(hù)app不重復(fù),否則可能會(huì)導(dǎo)致支付寶返回的結(jié)果無(wú)法正確跳回商戶(hù)app

4、可能遇到的錯(cuò)誤:
1:支付寶交易訂單處理失敗 AL159
注意:支付寶的金額只能精確到分,所以不能用小數(shù)點(diǎn)后面超過(guò)兩位的浮點(diǎn)型數(shù)字。
所以:應(yīng)該使用?%.2f
2:支付寶支付失?。?000
檢查訂單的各種參數(shù),比如訂單ID寫(xiě)錯(cuò)為浮點(diǎn)型了。
3:其他
檢查各種參數(shù)和公匙密匙等等
交互流程
這個(gè)流程和支付寶的流程都差不多,理解了其實(shí)是一樣的。

微信支付流程
首先需要理清楚流程:
用戶(hù)使用APP客戶(hù)端,選擇商品下單。
商戶(hù)客戶(hù)端(就是你做的APP)將用戶(hù)的商品數(shù)據(jù)傳給商戶(hù)服務(wù)器,請(qǐng)求生成支付訂單。
商戶(hù)后臺(tái)調(diào)用統(tǒng)一下單API向微信的服務(wù)器發(fā)送請(qǐng)求,微信服務(wù)器生成預(yù)付單,并生成一個(gè)prepay_id返回給商戶(hù)后臺(tái)。
商戶(hù)后臺(tái)將這個(gè)prepay_id返回給商戶(hù)客戶(hù)端。
用戶(hù)點(diǎn)擊確認(rèn)支付,這時(shí)候商戶(hù)客戶(hù)端調(diào)用SDK打開(kāi)微信客戶(hù)端,進(jìn)行微信支付。
微信客戶(hù)端向微信服務(wù)器發(fā)起支付請(qǐng)求并返回支付結(jié)果(他們之間交互用的就是prepay_id這個(gè)參數(shù),微信的服務(wù)器要驗(yàn)證微信客戶(hù)端傳過(guò)去的參數(shù)是否跟第三步中生成的那個(gè)id一致)。
用戶(hù)輸入支付密碼后,微信客戶(hù)端提交支付授權(quán),跟微信服務(wù)器交互,完成支付
微信服務(wù)器給微信客戶(hù)端發(fā)送支付結(jié)果提示,并異步給商戶(hù)服務(wù)器發(fā)送支付結(jié)果通知。
商戶(hù)客戶(hù)端通過(guò)支付結(jié)果回調(diào)接口查詢(xún)支付結(jié)果,并向后臺(tái)檢查支付結(jié)果是否正確,后臺(tái)返回支付結(jié)果。
商戶(hù)客戶(hù)端顯示支付結(jié)果,完成訂單,發(fā)貨。
雖然看起來(lái)有點(diǎn)多,但是理解起來(lái)并不復(fù)雜,跟我們平時(shí)手機(jī)上買(mǎi)東西是一樣的。我們客戶(hù)端需要做的就是
調(diào)起微信客戶(hù)端發(fā)起支付
顯示支付結(jié)果
集成過(guò)程
首先是要下載SDK,

微信SDK下載
建議頭文件和示例都下載出來(lái)看看。(吐槽下,官方的示例難看死了,看的眼暈!注釋都沒(méi)幾個(gè)。。。鄙視之)
導(dǎo)入微信支付SDK庫(kù)
導(dǎo)入上面那個(gè)iOS頭文件和庫(kù)下載下載出來(lái)的SDK包的就行啦,我這里的是SDK1.6.2. 然后需要鏈接上依賴(lài)庫(kù),在Target —> BuildPhases —> Link Binary With Libraries— 點(diǎn)擊+號(hào) -> 搜索你需要的系統(tǒng)庫(kù)。
SystemConfiguration.framework
libz.tbd
libsqlite3.0.tbd
CoreTelephony.framework
QuartzCore.framework
設(shè)置URL Scheme
在注冊(cè)微信平臺(tái)APP的時(shí)候,會(huì)給一個(gè)唯一識(shí)別標(biāo)識(shí)符(APPID),在APP端開(kāi)發(fā)步驟里面說(shuō)得很清楚了,需要填在URL Schemes這個(gè)地方,

URL scheme
在Appdelegate中注冊(cè)APPID
如下:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
/**
*? 向微信終端注冊(cè)ID,這里的APPID一般建議寫(xiě)成宏,容易維護(hù)。@“測(cè)試demo”不需用管。這里的id是假的,需要改這里還有target里面的URL Type
*/
[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"測(cè)試demo"];
return YES;
}
處理微信通過(guò)URL啟動(dòng)時(shí)傳遞的數(shù)據(jù)
//前面的兩個(gè)方法被iOS9棄用了,如果是Xcode7.2網(wǎng)上的話會(huì)出現(xiàn)無(wú)法進(jìn)入進(jìn)入微信的onResp回調(diào)方法,就是這個(gè)原因。本來(lái)我是不想寫(xiě)著兩個(gè)舊方法的,但是一看官方的demo上寫(xiě)的這兩個(gè),我就也寫(xiě)了。。。。
//9.0前的方法,為了適配低版本 保留
- (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{
return [WXApi handleOpenURL:url delegate:self];
}
//9.0后的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
//這里判斷是否發(fā)起的請(qǐng)求為微信支付,如果是的話,用WXApi的方法調(diào)起微信客戶(hù)端的支付頁(yè)面(://pay 之前的那串字符串就是你的APPID,)
return? [WXApi handleOpenURL:url delegate:self];
}
//微信SDK自帶的方法,處理從微信客戶(hù)端完成操作后返回程序之后的回調(diào)方法,顯示支付結(jié)果的
-(void) onResp:(BaseResp*)resp
{
//啟動(dòng)微信支付的response
NSString *payResoult = [NSString stringWithFormat:@errcode:%d, resp.errCode];
if([resp isKindOfClass:[PayResp class]]){
//支付返回結(jié)果,實(shí)際支付結(jié)果需要去微信服務(wù)器端查詢(xún)
switch (resp.errCode) {
case 0:
payResoult = @支付結(jié)果:成功!;
break;
case -1:
payResoult = @支付結(jié)果:失敗!;
break;
case -2:
payResoult = @用戶(hù)已經(jīng)退出支付!;
break;
default:
payResoult = [NSString stringWithFormat:@支付結(jié)果:失??!retcode = %d, retstr = %@, resp.errCode,resp.errStr];
break;
}
}
}
最重要的來(lái)了??!
調(diào)用微信支付前,需要下單、簽名等操作,以便獲取微信支付所必要的參數(shù)。為了提高安全性,下單、簽名操作一般是在后臺(tái)完成,在前臺(tái)做的話被捕獲改信息就不開(kāi)心了。。。。。
需要的參數(shù)包括:appid、partid(商戶(hù)號(hào))、prepayid(預(yù)支付訂單ID)、noncestr(參與簽名的隨機(jī)字符串)、timestamp(參與簽名的時(shí)間戳)、sign(簽名字符串)這六個(gè)。
在點(diǎn)擊支付的控制器中使用核心代碼來(lái)調(diào)起微信客戶(hù)端支付,這些個(gè)參數(shù)都是后臺(tái)傳給你的。 加上了注釋?zhuān)瑧?yīng)該很好理解的。
#pragma mark 微信支付方法
- (void)WXPay{
//需要?jiǎng)?chuàng)建這個(gè)支付對(duì)象
PayReq *req? = [[PayReq alloc] init];
//由用戶(hù)微信號(hào)和AppID組成的唯一標(biāo)識(shí),用于校驗(yàn)微信用戶(hù)
req.openID = @"";
// 商家id,在注冊(cè)的時(shí)候給的
req.partnerId = @"";
// 預(yù)支付訂單這個(gè)是后臺(tái)跟微信服務(wù)器交互后,微信服務(wù)器傳給你們服務(wù)器的,你們服務(wù)器再傳給你
req.prepayId? = @"";
// 根據(jù)財(cái)付通文檔填寫(xiě)的數(shù)據(jù)和簽名
//這個(gè)比較特殊,是固定的,只能是即req.package = Sign=WXPay
req.package? = @"";
// 隨機(jī)編碼,為了防止重復(fù)的,在后臺(tái)生成
req.nonceStr? = @"";
// 這個(gè)是時(shí)間戳,也是在后臺(tái)生成的,為了驗(yàn)證支付的
NSString * stamp = @"";
req.timeStamp = stamp.intValue;
// 這個(gè)簽名也是后臺(tái)做的
req.sign = @"";
//發(fā)送請(qǐng)求到微信,等待微信返回onResp
[WXApi sendReq:req];
}
這個(gè)JSON里面的數(shù)據(jù)(上面的參數(shù))就是后臺(tái)需要傳給你的,至于怎么來(lái),也有后臺(tái)的文檔,讓他去看下就行啦~~~
{
"appid": "wxb4ba3c02aa476ea1",
"noncestr": "d1e6ecd5993ad2d06a9f50da607c971c",
"package": "Sign=WXPay",
"partnerid": "10000100",
"prepayid": "wx20160218122935e3753eda1f0066087993",
"timestamp": "1455769775",
"sign": "F6DEE4ADD82217782919A1696500AF06"
}
到這里,不出意外的話應(yīng)該都能正常的支付了。流程最重要,理解了就知道怎么做了,強(qiáng)烈建議需要做的朋友們先理理思路,不要急著下手。
PS:這篇文章中,簽名都是在后臺(tái)做的,如果需要在你客戶(hù)端做,可以參考下這篇文章,和這篇文章,他們的簽名在客戶(hù)端做的,寫(xiě)的也比較詳細(xì)了。
可能遇到的問(wèn)題
1.如果支付完成后,一直留在微信,那就檢查下URLType中的Scheme設(shè)置問(wèn)題。
2.能夠打開(kāi)微信客戶(hù)端,但是打開(kāi)后只有中間一個(gè)白色的 “確定按鈕”,點(diǎn)擊后會(huì)回到客戶(hù)端上,如果是這樣,那應(yīng)該是prepayid 參數(shù)的問(wèn)題,過(guò)期了,或者不是真實(shí)的id。代碼沒(méi)有問(wèn)題的。特別注意的是,微信要兩次簽名,兩次~~~~
3.如果APP里面使用了友盟或者ShareSDK做分享,那就不用再導(dǎo)入SDK了,否則會(huì)出現(xiàn)一些詭異的問(wèn)題,例如無(wú)法調(diào)起手機(jī)微信客戶(hù)端、無(wú)法調(diào)起微信客戶(hù)端web頁(yè)面,調(diào)起了但是一閃而過(guò)。。。這都基本上都是因?yàn)榉窒淼腟DK里面已經(jīng)包括了微信的SDK。所以如果出現(xiàn)詭異的錯(cuò)誤了看看是不是兩個(gè)沖突了!
4.微信支付的單位是分,被坑過(guò)的人都知道了。。。。哎,
如果在集成過(guò)程中遇到什么問(wèn)題,大家可以一起討論下,我記錄這些如果有什么錯(cuò)誤的話也請(qǐng)告訴我!謝謝!