前言
支付寶支付是很常見的支付方式,下面這篇就是親測有用的文章,純手打,會持續(xù)更新。
? ?賣家跟支付寶簽約
? (需要實名認證這個支付寶賬號,需要提供企業(yè)資料,成為企業(yè)支付寶賬號,一般為公司的支付寶賬號)
? ? ?第一步:登陸支付寶官方網(wǎng)站(支付寶商家中心)。
? ? ? 這是沒有簽約的賬戶效果
? ? ? 以下是申請好了的效果圖,(申請好套餐后正常2-5天會有申請狀態(tài),成功后進入【我的商家服務】)
? ? ? ? 第二步:點擊導航欄中“商家服務”,找到“合作身份(Partner ID)查詢”與“安全校驗碼(key)查詢”。
? ? ?合作者身份ID(partner)和交易安全校驗碼(key)是商戶與支付寶簽約后,商戶獲得的支付寶商戶唯一識別碼與密鑰。當商戶把支付寶功能接入商戶網(wǎng)站時會用到它們,以便讓支付寶認證商戶。 即可查詢到合作者身份ID,以2088開頭的16位純數(shù)字。
生成公鑰和私鑰,并上傳公鑰里的字符串
? ?怎么上傳公鑰呢?輸入支付寶密碼,跳轉到查看交易安全校驗碼(key)頁面,在那個頁面設置下,打開公鑰把公鑰里面的字符串粘到指定位置并上傳即可,公鑰必須給支付寶,不然他們解密不了。打開終端,生成共私鑰:
? ?私鑰:OpenSSL genrsa -out rsa_private_key.pem 1024
? ?公鑰:OpenSSL rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
? 編碼后:openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem
代碼里需要使用 編碼后的私鑰進行加密,注意是編碼后的。
? ? (上傳公鑰)
? ? (RSA秘鑰)
? 項目集成支付寶SDK
? 下載支付寶SDK,把支付寶相關的SDK和依賴的系統(tǒng)庫資源文件導入到本地工程項目中。
?#define gxPartner? ? ? @"2088*******"? 商家的PID
#define gxSeller? ? ? @"2000000000@qq.com"? ? 收錢的支付寶賬號
#define gxPrivateKey? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //商戶方的私鑰,pkcs8 格式。 ? ?@"MIICeAIBADANBgkqdasdasdasdasdasdoGBAM09Ym+y5Tzw/xVIdQ6xCZnpqh7ZUr-------"
?+(void)PayMoney :(NSDictionary *)dataDic;{? ??
/*? ? *生成訂單信息及簽名? ? */? ? //將商品信息賦予AlixPayOrder的成員變量? ??
Order *order = [[Order alloc] init];? ??
order.partner = gxPartner;? ?
//支付寶賬號
?order.seller = gxSeller;? ??
//訂單ID不能兩次一樣,否則第二次無法支付。
order.tradeNO = [dataDic objectForKey:@"fid"]; //訂單ID(由商家自行制定)? ??
order.orderNumber =[dataDic objectForKey:@"orderNumber"]; //訂單號? ??
order.productDescription = @"呵呵"; //商品描述? ??
order.amount = [dataDic objectForKey:@"fpayMoney"]; //商品價格? ??
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";? ? //應用注冊scheme,在AlixPayDemo-Info.plist定義URL types`該字符串是你自定義的 URL scheme 的名字。建議采用反轉域名的方法保證該名字的唯一性`? ?
NSString *appScheme = @"Mall";? ? >? //將商品信息拼接成字符串? NSString *orderSpec = [order description];? DMLog(@"orderSpec = %@",orderSpec);? ? ? >? //獲取私鑰并將商戶信息簽名,外部商戶可以根據(jù)情況存放私鑰和簽名,只需要遵循RSA簽名規(guī)范,并將簽名字符串base64編碼和UrlEncode? ? idsigner = CreateRSADataSigner(gxPrivateKey);
NSString *signedString = [signer signString:orderSpec];
?//將簽名成功字符串格式化為訂單字符串,請嚴格按照該格式
NSString *orderString = nil;
if (signedString != nil) {
orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
orderSpec, signedString, @"RSA"];
? ?[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
DMLog(@"reslut = %@",resultDic);
if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"9000"]) {
//支付成功了
}
}];}}
resultStatus,狀態(tài)碼,SDK里沒對應信息,第一個文檔里有提到:支付成功后,后臺的訂單狀態(tài)已經(jīng)改變了,此時可以通知頁面刷新,以后臺的數(shù)據(jù)狀態(tài)為準,更新前端頁面中訂單的支付狀態(tài)。
9000 訂單支付成功
8000 正在處理中
4000 訂單支付失敗
6001 用戶中途取消
6002 網(wǎng)絡連接出錯
memo, 提示信息,比如狀態(tài)碼為6001時,memo就是“用戶中途取消”。但千萬別完全依賴這個信息,如果未安裝支付寶app,采用網(wǎng)頁支付時,取消時狀態(tài)碼是6001,但這個memo是空的。。(當我發(fā)現(xiàn)這個問題的時候,我就決定,對于這么不靠譜的SDK,還是盡量靠自己吧。。)
result,訂單信息,以及簽名驗證信息。如果你不想做簽名驗證,那這個字段可以忽略了。。
*****************************更新 **************************
iOS9上面不能跳轉到支付寶客戶端支付 什么情況只能跳到網(wǎng)頁
(一)為了適配 iOS9.0 中的 App Transport Security(ATS)對 http 的限制,這里需要對 支付寶的請求地址 alipay.com 做例外,在 app 對應的 info.list 中添加如下配置 (文中以 XML 格式描述)。
(二) 同時需要在Plist中設置支付寶為白名單
支付結果不回調(diào)
- (BOOL)application:(UIApplication*)application
openURL:(NSURL*)url
sourceApplication:(NSString*)sourceApplication
annotation:(id)annotation {
if([url.hostisEqualToString:@"safepay"]) {
//跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDKdefaultService]processOrderWithPaymentResult:urlstandbyCallback:^(NSDictionary*resultDic) {
NSLog(@"result = %@",resultDic);
}];
}
returnYES;
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication*)app openURL:(NSURL*)url options:(NSDictionary *)options
{
if([url.hostisEqualToString:@"safepay"]) {
//跳轉支付寶錢包進行支付,處理支付結果
[[AlipaySDKdefaultService]processOrderWithPaymentResult:urlstandbyCallback:^(NSDictionary*resultDic) {
NSLog(@"result = %@",resultDic);
}];
}
returnYES;
}
你會發(fā)現(xiàn) callback:^(NSDictionary *resultDic)? 沒有結果返回了,查了官網(wǎng)后發(fā)現(xiàn),需要在APPDelegate里手動獲取下返回結果,保持原支付代碼不變的情況下,復制上面的代碼粘貼到 APPDelegate里,支付密代碼那里的回調(diào)callback里就會有內(nèi)容返回了。