版本記錄
| 版本號 | 時間 |
|---|---|
| V1.0 | 2017.05.24 |
前言
很多app都有支付和提現(xiàn)功能,而移動支付中支付寶、微信無疑是國內(nèi)重要的支付平臺和工具,最近有一個項目需要增加支付寶支付功能,這里就講述下關于支付寶集成的問題,感興趣的可以看一下。
支付寶支付業(yè)務流程
在說明支付寶原理之前,首先需要看的是支付寶支付的開發(fā)文檔。
支付寶支付開發(fā)文檔
下面我們就進入正題。
- 創(chuàng)建應用:在開發(fā)平臺創(chuàng)建一個應用,接入App支付能力,需要在開放平臺創(chuàng)建一個應用,通過該應用來接入各種能力??梢愿鶕?jù)下面:
了解應用創(chuàng)建步驟
開始創(chuàng)建應用 - 配置應用
- 為創(chuàng)建的應用添加所需功能。給應用添加App支付功能,這樣就可以在你的應用里使用App支付能力。
了解如何添加APP支付功能
立即開始添加 - 簽約:在使用這些能力的時候,需要在開放平臺里進行簽約,這時候約定的合同就生效了。也可以代替商戶簽約。
- 配置密匙:為了保證交易雙方的身份和數(shù)據(jù)安全,需要配置雙方密鑰。
- 為創(chuàng)建的應用添加所需功能。給應用添加App支付功能,這樣就可以在你的應用里使用App支付能力。
- 設計
- 接入設計:常用的接入方式與架構建議。在開始開發(fā)前,需要了解接入的方式或者材料等
- 安全設計:為了保證交易安全,支付寶采用了一系列的安全手段。
- 開發(fā)
- SDK和開發(fā)語言:App支付為開發(fā)者提供了Android和iOS的客戶端SDK, 為了驗證交易數(shù)據(jù)的來源,開發(fā)者需要在商家后臺對交易數(shù)據(jù)進行加簽, 驗簽,那么就需要集成開放平臺服務端SDK。
- 集成客戶端SDK:在集成App支付能力時,為主流移動平臺的App提供集成方式。
- 支付主流程:在集成App支付能力時,建議實現(xiàn)如下支付場景:(創(chuàng)建訂單并支付,根據(jù)支付結(jié)果確定支付狀態(tài),并且做異常處理,必要時候關閉訂單)。
- 退款流程:商戶由于業(yè)務原因可能需要退款,退款的途徑按照支付途徑原路返回. 支付渠道為花唄、余額等退款即時到賬。銀行卡的退款時間以銀行退款時間為準,一般情況下2小時內(nèi)可到賬。也可以在商戶門戶(b.alipay.com)中退款。
- 對賬:為了保障交易的正確性,支付寶提供了交易賬單數(shù)據(jù)提供給商戶對賬。
- 調(diào)試應用:沙箱環(huán)境供調(diào)試使用,支付能力直接涉及到交易與資金,為了方便開放者調(diào)試支付能力,我們已經(jīng)準備好沙箱環(huán)境,包括沙箱環(huán)境賬號和沙箱版支付寶錢包,這樣就可以在沙箱環(huán)境調(diào)試了。
- 上線應用:上線應用所需步驟,商戶本身應用上線時候,也要把支付寶開放平臺的應用上線。
下面看一下支付流程圖。

下面看一下支付原理圖。

支付寶支付SDK和集成流程
下面我們先看一下支付寶的SDK。

下面說一下SDK的集成流程。
一、導入代碼
步驟1:啟動IDE(如Xcode),把iOS包中的壓縮文件中以下文件拷貝到項目文件夾下,并導入到項目工程中。
AlipaySDK.bundle
AlipaySDK.framework
在Build Phases選項卡的Link Binary With Libraries中,增加以下依賴:

其中,需要注意的是:
- 如果是Xcode 7.0之后的版本,需要添加libc++.tbd、libz.tbd。
- 如果是Xcode 7.0之前的版本,需要添加libc++.dylib、libz.dylib。
步驟2:在需要調(diào)用AlipaySDK的文件中,增加頭文件引用。
#import <AlipaySDK/AlipaySDK.h>
步驟3:組裝請求信息。
這里需要注意:這一步應在商戶服務端完成,商戶服務端直接將組裝和簽名后的請求串orderString傳給客戶端,客戶端直接傳給SDK發(fā)起請求。文檔和Demo是為了示例效果在客戶端實現(xiàn)。
//將商品信息賦予AlixPayOrder的成員變量
Order* order = [Order new];
// NOTE: app_id設置
order.app_id = appID;
// NOTE: 支付接口名稱
order.method = @"alipay.trade.app.pay";
// NOTE: 參數(shù)編碼格式
order.charset = @"utf-8";
// NOTE: 當前時間點
NSDateFormatter* formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
order.timestamp = [formatter stringFromDate:[NSDate date]];
// NOTE: 支付版本
order.version = @"1.0";
// NOTE: sign_type設置
order.sign_type = @"RSA";
// NOTE: 商品數(shù)據(jù)
order.biz_content = [BizContent new];
order.biz_content.body = @"我是測試數(shù)據(jù)";
order.biz_content.subject = @"1";
order.biz_content.out_trade_no = [self generateTradeNO]; //訂單ID(由商家自行制定)
order.biz_content.timeout_express = @"30m"; //超時時間設置
order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f", 0.01]; //商品價格
//將商品信息拼接成字符串
NSString *orderInfo = [order orderInfoEncoded:NO];
NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
NSLog(@"orderSpec = %@",orderInfo);
// NOTE: 獲取私鑰并將商戶信息簽名,外部商戶的加簽過程請務必放在服務端,防止公私鑰數(shù)據(jù)泄露;
// 需要遵循RSA簽名規(guī)范,并將簽名字符串base64編碼和UrlEncode
id<DataSigner> signer = CreateRSADataSigner(privateKey);
NSString *signedString = [signer signString:orderInfo];
// NOTE: 如果加簽成功,則繼續(xù)執(zhí)行支付
if (signedString != nil) {
//應用注冊scheme,在AliSDKDemo-Info.plist定義URL types
NSString *appScheme = @"alisdkdemo";
// NOTE: 將簽名成功字符串格式化為訂單字符串,請嚴格按照該格式
NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
orderInfoEncoded, signedString];
// NOTE: 調(diào)用支付結(jié)果開始支付
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
}];
}
步驟4: 配置支付寶客戶端返回url處理方法。(外部存在支付包錢包,支付寶錢包將處理結(jié)果通過url返回。)如示例AliSDKDemo\APAppDelegate.m文件中,增加引用代碼:
#import <AlipaySDK/AlipaySDK.h>
在@implementation AppDelegate中以下代碼中的NSLog改為實際業(yè)務處理代碼:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
}
return YES;
}
// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
{
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
}
return YES;
}
二、配置基本信息
打開“APViewController.m”文件,對以下2個參數(shù)進行編輯。
SString *appid = @"";
NSString *privateKey = @"";
iOS基本信息配置表:
| 參數(shù) | 含義 |
|---|---|
| appid | 應用ID,調(diào)用API時用來識別開發(fā)者。請參考創(chuàng)建應用并獲取APPID。 |
| private_key | 應用私鑰,pkcs8格式。請參考配置密鑰。 |
注意:這些參數(shù)配置僅作為客戶端示例使用。商戶實際支付過程中參數(shù)需要放置在服務端,且整個簽名過程必須在服務端進行。
三、代碼示例運行邏輯
步驟1:調(diào)用order.m里的函數(shù)description將商品信息拼接成字符串作為待簽名字符串,如:
app_id=2015052600090779&biz_content={"timeout_express":"30m","seller_id":"","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.02","subject":"1","body":"我是測試數(shù)據(jù)","out_trade_no":"ZQLM3O56MJD4SK3"}&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2×tamp=2016-07-28 20:36:11&version=1.0
步驟2:使用類CreateRSADataSigner,調(diào)用signString簽名函數(shù)做簽名,如:
"GsSZgPloF1vn52XAItRAldwQAbzIgkDyByCxMfTZG%2FMapRoyrNIJo4U1LUGjHp6gdBZ7U8jA1kljLPqkeGv8MZigd3kH25V0UK3Jc3C94Ngxm5S%2Fz5QsNr6wnqNY9sx%2Bw6DqNdEQnnks7PKvvU0zgsynip50lAhJmflmfHvp%2Bgk%3D"
步驟3:把簽名結(jié)果賦值給參數(shù)sign,并把sign加入之前的待簽名數(shù)組中,此時得到的便是要請求給支付寶的全部數(shù)據(jù)。
app_id=2015052600090779&biz_content={"timeout_express":"30m","seller_id":"","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.02","subject":"1","body":"我是測試數(shù)據(jù)","out_trade_no":"ZQLM3O56MJD4SK3"}&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2×tamp=2016-07-28 20:36:11&version=1.0&sign=*********
步驟4:調(diào)用(AlipaySDK *)defaultService類下面的支付接口函數(shù),喚起支付寶支付頁面。
(void)payOrder:(NSString *)orderStr
fromScheme:(NSString *)schemeStr
callback:(CompletionBlock)completionBlock
步驟5:當這筆交易被買家支付成功后支付寶收銀臺上顯示該筆交易成功,并提示用戶“返回”。此時在APAppDelegate.m的 - (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 中調(diào)用獲取返回數(shù)據(jù)的代碼【iOS9.0以上(包括iOS9.0)需要在 - (BOOL)application:(UIApplication *)app openURL:(NSURL )url options:(NSDictionary<NSString, id> *)options 中執(zhí)行 】。
[[AlipaySDK defaultService]
processOrderWithPaymentResult:url
standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);//返回的支付結(jié)果
}];
注意:
- 同步返回數(shù)據(jù)校驗邏輯請參考。
- SDK付款有兩種模式:如果外部存。
支付寶支付iOS調(diào)用說明
一、支付全部接口
- 接口名稱:AlipaySDK
- 接口描述:提供支付功能。
- Alipay接口主要為商戶提供訂單支付功能。接口所提供的方法,如下表所示。

二、快捷訂單支付iOS
- 方法名稱:pay方法
- 方法原型:(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;
- 方法功能:提供給商戶快捷訂單支付功能。

orderStr示例如下:
app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.02%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22314VYGIAGG7ZOYY%22%7D&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2×tamp=2016-08-15%2012%3A12%3A15&version=1.0&sign=MsbylYkCzlfYLy9PeRwUUIg9nZPeN9SfXPNavUCroGKR5Kqvx0nEnd3eRmKxJuthNUx4ERCXe552EV9PfwexqW%2B1wbKOdYtDIb4%2B7PL3Pc94RZL0zKaWcaY3tSL89%2FuAVUsQuFqEJdhIukuKygrXucvejOUgTCfoUdwTi7z%2BZzQ%3D
三、處理客戶端返回url
- 方法名稱:處理客戶端方法
- 方法原型:-(void)processOrderWithPaymentResult:(NSURL*)resultUrl standbyCallback:(CompletionBlock)completionBlock;
- 方法功能:設備已安裝支付寶客戶端情況下,處理支付寶客戶端返回的url。
注意:該方法必須實現(xiàn),否則將會導致在安裝手機支付寶的情況下,支付結(jié)果無法正常同步返回。

備注:請在APPDelegate的 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 中調(diào)用該方法,iOS9.0以上(包括iOS9.0)請在 - (BOOL)application:(UIApplication *)app openURL:(NSURL )url options:(NSDictionary<NSString, id> *)options 中調(diào)用該方法。
四、回調(diào)接口
在支付過程結(jié)束后,會通過callbackBlock同步返回支付結(jié)果(callbackBlock是調(diào)用支付同步的回調(diào))。支付結(jié)果中參數(shù)的提取,必須通過CompletionBlock獲取,禁止開發(fā)者私自解析支付結(jié)果返回的URL。
支付寶支付工程代碼
下面我就以我寫的代碼說明支付寶支付的集成和實現(xiàn)。先看代碼。
//從后臺獲取簽名數(shù)據(jù)
- (void)requesstAlipaySignedString
{
NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
[mutableDict setObject:@"0" forKey:@"chargeType"];
[mutableDict setObject:self.cashNumTextField.text forKey:@"totalAmount"];
[[JJNetWorkManager manager] requestByPostNetworkWithPayUrl:kalipayPharchase parameters:mutableDict success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"responseObject--%@",responseObject);
if ([[responseObject objectForKey:@"code"] integerValue] == 0) {
self.dataDictM = [responseObject objectForKey:@"data"];
self.alipayOrderStr = [self.dataDictM objectForKey:@"sign"];
if (self.alipayOrderStr) {
// NOTE: 調(diào)用支付結(jié)果開始支付
[[AlipaySDK defaultService] payOrder:self.alipayOrderStr fromScheme:@"ZebraChat" callback:^(NSDictionary *resultDic) {
NSLog(@"resultDic = %@",resultDic);
}];
}
}
} error:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error--%@",error);
}];
}
下面的代碼就是的AppDelegate中了。
//配置支付寶客戶端返回url處理方法
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
//支付寶
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
//在這里獲得支付結(jié)果,發(fā)送通知給相應的服務器更新余額
}];
return YES;
}
if ([url.host isEqualToString:@"platformapi"])//支付寶錢包快登授權返回 authCode
{
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
return YES;
}
return NO;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
{
//支付寶
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
return YES;
}
if ([url.host isEqualToString:@"platformapi"])//支付寶錢包快登授權返回 authCode
{
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
return YES;
}
//這里判斷是否發(fā)起的請求為微信支付,如果是的話,用WXApi的方法調(diào)起微信客戶端的支付頁面(://pay 之前的那串字符串就是你的APPID,)
return [WXApi handleOpenURL:url delegate:self];
}
下面看結(jié)果圖。




后記
??到此為止,主要的和支付相關的我都寫完了,涉及到微信,內(nèi)購,支付寶這三種支付方式,后續(xù)如有需要我還會添加其他的支付方式,比如銀聯(lián)支付等,有什么不對的地方希望大家能夠批評指出。
