開發(fā)準(zhǔn)備
1.首先新建項(xiàng)目,然后去官網(wǎng)下載最新的開發(fā)包:
http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1,
當(dāng)然也可以用CocoaPods
來(lái)下載不過(guò)用這個(gè)下載的話只會(huì)下載到單純的客戶端與網(wǎng)絡(luò)服務(wù)請(qǐng)求的SDK不包含加密的那些代碼,而有些公司是要把加密做到本地的所以選擇哪種方式看開發(fā)者的習(xí)慣于公司需求.
2.下載后打開點(diǎn)擊開發(fā)包可以打開更新日志
來(lái)比對(duì)當(dāng)前版本不要去一些非官網(wǎng)的地方下載SDK有可能不是最新版本會(huì)出現(xiàn)BUG
3.打開客戶端開發(fā)包找到IOS對(duì)應(yīng)的包文件解壓得到開發(fā)包,包含1個(gè)framework
文件一個(gè)bundle
文件一個(gè)Demo
文件夾
一般情況下支付功能的交互流程
比如我們?nèi)ツ硞€(gè)APP去支付一個(gè)產(chǎn)品,流程為:
1.用戶點(diǎn)擊支付->
2.客戶端請(qǐng)求服務(wù)器用戶支付->
3.服務(wù)器接收請(qǐng)求生成金額訂單等要給第三方支付的一切信息,并生成回調(diào)參數(shù)傳給客戶端->
4.客戶端接收信息(一般會(huì)再讓用戶確認(rèn)支付或者干脆購(gòu)買后是生成訂單,然后才是付款)并將服務(wù)器給的信息分別傳入SDK需要的參數(shù)中,調(diào)用SDK的支付方法->
5.由SDK向SDK自己的服務(wù)器發(fā)出支付請(qǐng)求,SDK自己的服務(wù)器接收支付請(qǐng)求處理成功后,給客戶端本身與公司的后臺(tái)都發(fā)送一條支付成功的消息,客戶端與后臺(tái)根據(jù)這條消息再做處理.
針對(duì)開發(fā)環(huán)境的一些設(shè)置
支付又分為2種情況本地簽名,和服務(wù)器簽名,我用到正好都是公司要求本地簽,服務(wù)器的我就稍微說(shuō)1點(diǎn).
服務(wù)器簽名:
/**
* 支付接口
*
* @param orderStr 訂單信息
* @param schemeStr 調(diào)用支付的app注冊(cè)在info.plist中的scheme
* @param compltionBlock 支付結(jié)果回調(diào)Block
*/
- (void)payOrder:(NSString *)orderStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlock;
服務(wù)器簽名注意的是在callback:回調(diào)中要進(jìn)行驗(yàn)簽,就是把服務(wù)器給的訂單簽名信息在用公鑰解密,比對(duì)訂單細(xì)節(jié),檢查是否被他人篡改,并且如果是wap支付,不會(huì)反回在appDelegate
的application:openURL
方法.
本地簽名:
先拖入實(shí)現(xiàn)加密的文件與模型:
這時(shí)候會(huì)報(bào)錯(cuò)(補(bǔ)充一點(diǎn): 有些朋友找不到NSString或者一些數(shù)據(jù)類型報(bào)錯(cuò)都是因?yàn)槿鄙貴oundation頭文件,可能我寫的不太明白,有些朋友還是不太懂)大部分錯(cuò)誤都是因?yàn)橐恍┪募性谥Ц秾毜腄emo的Pch
文件中統(tǒng)一添加的#import <Foundation/Foundation.h>
,如果我們的項(xiàng)目中沒有這一步,那么要么也建立pch
要么單獨(dú)添加上.
這時(shí)還會(huì)有一個(gè)錯(cuò)誤:
注意這里的Header Search Paths
路徑為空:
打開電腦這個(gè)文件的所在地 雙擊Header Search Paths
將電腦的文件拖入Header Search Paths
會(huì)生成一個(gè)路徑:
導(dǎo)入一來(lái)框架: 這個(gè)最好跟著Demo一個(gè)一個(gè)往里添加,也不要光看網(wǎng)上資料主要還是看Demo:
添加SDK和靜態(tài)庫(kù):
報(bào)錯(cuò):這個(gè)錯(cuò)誤與另外一種說(shuō)SDK不支持64位比較常見,都是把靜態(tài)庫(kù)或者SDK都刪了重新導(dǎo)入就行了
到這里應(yīng)該已經(jīng)可以運(yùn)行程序了.
如果還是出現(xiàn)了編譯錯(cuò)誤等問題,導(dǎo)入框架不全與SDK靜態(tài)庫(kù)的路徑錯(cuò)誤比例比較大.
建議等能夠運(yùn)行程序后在進(jìn)行開發(fā).
正式開發(fā)
首先我們介紹一段代碼:
NSString *orderSpec = [order description];
將商品的信息添加為字符串order
是一個(gè)對(duì)象,而description]
是將這個(gè)對(duì)象的屬性進(jìn)行拼接返回一個(gè)字符串.
在介紹3個(gè)屬性:
//合作商戶ID惭笑。用簽約支付寶賬號(hào)登錄ms.alipay.com后,在賬戶信息頁(yè)面獲取生真。
NSString *partner = @"";
//賬戶ID沉噩。用簽約支付寶賬號(hào)登錄ms.alipay.com后,在賬戶信息頁(yè)面獲取汇歹。
NSString *seller = @"";
//商戶私鑰屁擅,自助生成
NSString *privateKey = @"";
這3個(gè)屬性必須是個(gè)人或公司申請(qǐng)后才能得到的..我用的公司的就不寫上了請(qǐng)自行填寫.
//將商品信息賦予AlixPayOrder的成員變量
Order *order = [[Order alloc] init];
order.partner = partner;
order.seller = seller;
order.tradeNO = @"G111111111111"; //訂單ID(由商家自行制定)
order.productName = @"我的測(cè)試"; //商品標(biāo)題
order.productDescription = @"我的商品描述"; //商品描述
order.amount = @"0.01"; //商品價(jià)格
order.notifyURL = @"http://www.xxx.com"; //回調(diào)URL
order.service = @"mobile.securitypay.pay";
order.paymentType = @"1";
order.inputCharset = @"utf-8";
order.itBPay = @"30m";
order.showUrl = @"m.alipay.com";
//應(yīng)用注冊(cè)scheme,在AlixPayDemo-Info.plist定義URL types
NSString *appScheme = @"alisdkdemo";
//將商品信息拼接成字符串
NSString *orderSpec = [order description];
NSLog(@"orderSpec = %@",orderSpec);
//獲取私鑰并將商戶信息簽名,外部商戶可以根據(jù)情況存放私鑰和簽名,只需要遵循RSA簽名規(guī)范,并將簽名字符串base64編碼和UrlEncode
id<DataSigner> signer = CreateRSADataSigner(privateKey);
NSString *signedString = [signer signString:orderSpec];
NSString *orderString = nil;
生成加密后的字符串 注意的是NSString *appScheme = @"alisdkdemo";
這個(gè)值是從支付寶的商戶地址中填寫的,請(qǐng)保持一致.
最后處理結(jié)果:
if (signedString != nil) {
orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
orderSpec, signedString, @"RSA"];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
//結(jié)果處理,其實(shí)就是取字典里面的內(nèi)容,這個(gè)取字符串然后變個(gè)模型就好了 或者直接取不便模型,方法很多.
NSLog(@"開始確認(rèn)支付狀態(tài) %@",resultDic[@"resultStatus"]);
AlixPayResult* resultModel = [AlixPayResult itemWithDictory:resultDic];
if (resultModel)
{
//狀態(tài)返回9000為成功
if (resultModel.statusCode == 9000)
{
/*
*用公鑰驗(yàn)證簽名 嚴(yán)格驗(yàn)證請(qǐng)使用result.resultString與result.signString驗(yàn)簽
*/
NSLog(@"支付寶交易成功");
/*
*用公鑰驗(yàn)證簽名 嚴(yán)格驗(yàn)證請(qǐng)使用result.resultString與result.signString驗(yàn)簽
*/
//交易成功
NSString* key = AlipayPubKey;//簽約帳戶后獲取到的支付寶公鑰
id<DataVerifier> verifier;
verifier = CreateRSADataVerifier(key);
// 驗(yàn)證簽名
if ([verifier verifyString:resultModel.resultString withSign:resultModel.signString])
{
//驗(yàn)證簽名成功,交易結(jié)果無(wú)篡改
NSLog(@"驗(yàn)證成功");
}
}
}
else if([resultDic[@"resultStatus"]isEqualToString:@"6001"])
{
//用戶取消
NSLog(@"用戶主動(dòng)取消支付");
}else
{
}
}];
}
這里注意:if([resultDic[@"resultStatus"]isEqualToString:@"6001"])
支付寶有BUG 這個(gè)6001 不要信,可以和公司商量下,是加個(gè)確認(rèn)接口還是一定時(shí)間內(nèi)檢查后臺(tái),總之很有可能用戶付錢成功,SDK通知你用戶手動(dòng)取消,這個(gè)BUG是在弱網(wǎng)狀態(tài)下比較多.
然后記得在 AppDelegate
里面加上如下代碼:
//只要是調(diào)用手機(jī)上的支付寶客戶端产弹,在支付寶客戶端操作完成返回自己的app時(shí)派歌,都會(huì)調(diào)用這個(gè)方法,
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
//跳轉(zhuǎn)支付寶錢包進(jìn)行支付,需要將支付寶錢包的支付結(jié)果回傳給SDK(這個(gè)是將支付寶客戶端的支付結(jié)果傳回給SDK)
if ([url.host isEqualToString:@"safepay"]) {
[[AlipaySDK defaultService]
processOrderWithPaymentResult:url
standbyCallback:^(NSDictionary *resultDic)
{
NSLog(@" ------result = %@",resultDic);//返回的支付結(jié)果
}];
}
return YES;
}
最后記得把這里寫了:
NSString *appScheme = @"alisdkdemo"
代碼 網(wǎng)頁(yè)上申請(qǐng)的 圖片上那里填寫的保持一致.
補(bǔ)充: 如果要用swift
來(lái)調(diào)用支付寶SDK 最好把支付的與回調(diào)的邏輯單獨(dú)建立工具類傳遞數(shù)據(jù)便好,從流程上本身無(wú)太大區(qū)別稍微注意的是在swift
中 AlipaySDK.h
有可能因?yàn)檎Z(yǔ)言環(huán)境問題出現(xiàn)缺少引入類的情況,少什么補(bǔ)什么就好,其他也一樣.
如有問題歡迎留言...