首先要說(shuō)明的是支付寶SDK的使用埃元,官方建議泥从,數(shù)據(jù)加密和下單等操作盡量由商戶后臺(tái)服務(wù)器完成,這樣才能保證財(cái)產(chǎn)和私密信息的安全性哨免。因此本文介紹內(nèi)容茎活,是APP和自己公司后臺(tái)服務(wù)器一起協(xié)作完成支付寶支付的方法昙沦。
一琢唾、首先需要介紹的是:支付寶的接入(可參考官方文檔)
還是簡(jiǎn)單給大家理一下流程,(1)在螞蟻金服后臺(tái)創(chuàng)建應(yīng)用盾饮,拿到APPID采桃,給后臺(tái)開發(fā)人員(2)添加APP支付功能(3)簽約商戶號(hào),簽約有一個(gè)審核時(shí)間丘损,這中間可能會(huì)遇到各種問(wèn)題普办,(4)配置秘鑰,分別是公鑰和私鑰徘钥,這個(gè)讓后臺(tái)人員去弄
下載SDKhttps://docs.open.alipay.com/54/104509拖入工程里面衔蹲。
手動(dòng)導(dǎo)入靜態(tài)庫(kù),然后command + B 編譯一下呈础,看報(bào)不報(bào)錯(cuò)舆驶。
二、接下來(lái)給大家介紹項(xiàng)目里面的配置而钞。
(1)第一步點(diǎn)擊工程名——>第二步點(diǎn)擊info——>第三步在URL Types里面添加一個(gè)支付寶返回URL type.如圖所示:
(2)在plist文件中確認(rèn)URL是否添加成功沙廉。
(3)在需要用到支付的ViewController里面添加以下代碼:
///支付寶sdk
#import <AlipaySDK/AlipaySDK.h>
#define AppScheme @"ShouNew"
注意上面三條的Scheme一定要保持一致,不然可能導(dǎo)致支付成功后不能返回原APP臼节。
三撬陵、支付寶支付流程及代碼體現(xiàn)
(1)支付寶流程圖:
簡(jiǎn)單解釋一下:
第一步:APP向自己公司服務(wù)器發(fā)起下單請(qǐng)求(下單的時(shí)候要把商品的各項(xiàng)信息傳給服務(wù)器珊皿,比如價(jià)格,數(shù)量巨税,商品名等)蟋定,自己公司服務(wù)器向支付寶服務(wù)器統(tǒng)一下單,然后返回訂單號(hào)給用戶草添。
第二步:APP拿訂單號(hào)向服務(wù)器請(qǐng)求加密后的訂單信息溢吻,用于向支付寶服務(wù)器發(fā)起請(qǐng)求。
類似于這樣一串?dāng)?shù)據(jù)
"alipayInfo":"partner=2088321034383926&seller_id=717449318@qq.com&out_trade_no=r2017051922165642529&subject=首牛云控APP充值-¥10.0&body=首牛云控APP充值-¥10.0&total_fee=10.0¬ify_url=http://*******.cn/*********/alipayNotify.do&service=mobile.securitypay.pay&payment_type=1&_input_charset=utf-8&it_b_pay=30m&sign=hS%2BJNs3FT9Sx0U2CGIK58xs6Cdjx%2FsvBqw18Ah%2BwrtBUdNjQnqP99fjW4YK6JxjuRG5YocZmS5ZfcrtnXq7fmq9jf%2Fj%2Fz858CBBWPxtoGQZuEAPy91q8vbYYHkSgwO8qM8mtCTast9LjXyJ2un%2B6nPhNxHN0cX1%2FZxUMWwwmQQc%3D&sign_type=RSA",這是后臺(tái)用支付寶提供的RSA加密算法加密后的數(shù)據(jù)果元。
第三步:通過(guò)SDK向支付寶服務(wù)器發(fā)起支付請(qǐng)求促王。發(fā)起請(qǐng)求的時(shí)候要帶上APPScheme,用于返回APP支付結(jié)果回調(diào)而晒。
第四步:完成支付后蝇狼,支付寶會(huì)返回一個(gè)字典給APP,這個(gè)里面就有支付結(jié)果倡怎,但是這并不能作為支付成功與否的判斷結(jié)果迅耘,因?yàn)椋@個(gè)結(jié)果只是APP端成功监署,所以還要將這個(gè)字典內(nèi)容轉(zhuǎn)成json傳給服務(wù)器颤专,查詢服務(wù)器支付結(jié)果,可能有朋友會(huì)問(wèn)钠乏,服務(wù)器支付結(jié)果從何而來(lái)栖秕,其實(shí)在APP端完成支付后,支付寶會(huì)根據(jù)這個(gè)訂單異步通知商戶服務(wù)器晓避,讓服務(wù)器記錄這個(gè)訂單的支付結(jié)果簇捍。中間任何一環(huán)斷了,這個(gè)訂單都不算支付成功俏拱。
最后根據(jù)服務(wù)器查詢到的訂單支付結(jié)果來(lái)反應(yīng)給用戶暑塑。
接下來(lái)我們看代碼實(shí)現(xiàn):
首先是下單:
NSString *urlStr = @"orderz.do?method=submitOrderz";
//這兒需要包裝的參數(shù)由服務(wù)器來(lái)定
NSDictionary *dic = @{@"color":@"怪味胡豆60克",@"price":@"0.01",@"mallproductId":@"19",@"type" : @"1",@"num":@"1",@"jSessionId":@"這兒填寫你們APP的唯一登錄標(biāo)示符,也可以說(shuō)是token",@"locationId": @"94"
};
[[SNNetWorkTools sharedTools]requestWithUrl:urlStr withRequestStyle:POST parameters:dic callback:^(id data, NSError *error) {
NSNumber *num = data[@"statusCode"];
if (codeNum) {
self.orderNum = data[@"data"][@"orderzNo"];
[self payWithAlipay];
}
}];
向服務(wù)器拿到加密信息锅必,并向支付寶發(fā)起支付
-(void)payWithAlipay{
NSString *str = @"pay.do?method=getAlipayInfo";
NSDictionary *para = @{@"orderzNo":self.orderNum,@"jSessionId":@"這兒填寫你們APP的唯一登錄標(biāo)示符事格,也可以說(shuō)是token"};
[[SNNetWorkTools sharedTools]requestWithUrl:str withRequestStyle:GET parameters:para callback:^(id data, NSError *error) {
NSNumber *num = data[@"statusCode"];
if (codeNum) {
NSString *orderStr = data[@"data"][@"alipayInfo"];
// 應(yīng)用注冊(cè)scheme,在AliPayDemo-Info.plist定義URL types
[[AlipaySDK defaultService]payOrder:orderStr fromScheme:AppScheme callback:^(NSDictionary *resultDic) {
}];
}
}];
}
在viewDidLoad方法中注冊(cè)監(jiān)聽支付結(jié)果的通知
//注冊(cè)通知-支付寶
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(dealALiPayResult:) name:@"ALiPayresult" object:nil];
在APPDelegate中接受支付寶返回的支付結(jié)果轉(zhuǎn)化成Json傳給服務(wù)器查詢支付結(jié)果
#pragma mark -- 支付回調(diào)方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
//支付寶支付回調(diào)
if ([url.host isEqualToString:@"safepay"]) {
//跳轉(zhuǎn)支付寶錢包進(jìn)行支付,處理支付結(jié)果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
// NSLog(@"result = %@",resultDic);
NSString *jsonStr = [self DataTOjsonString:resultDic];
//將支付寶返回的dictionary轉(zhuǎn)成json再傳給服務(wù)器,查詢服務(wù)器支付狀態(tài)搞隐。
NSString *urlStr = @"pay.do?method=checkAlipayOrderz";
NSDictionary *para = @{@"data":jsonStr,@"jSessionId":@"這兒填寫你們APP的唯一登錄標(biāo)示符驹愚,也可以說(shuō)是token"};
[[SNNetWorkTools sharedTools]requestWithUrl:urlStr withRequestStyle:POST parameters:para callback:^(id data, NSError *error) {
//發(fā)送通知,將支付結(jié)果傳給ViewController
[[NSNotificationCenter defaultCenter] postNotificationName:@"ALiPayresult" object:data[@"data"][@"trade_state"]];
}];
}];
}
return false;
}
//字典轉(zhuǎn)Json
-(NSString*)DataTOjsonString:(id)object
{
NSString *jsonString = nil;
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:&error];
if (!jsonData) {
NSLog(@"字典轉(zhuǎn)json錯(cuò)誤: %@", error);
}else {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
return jsonString;
}
回到ViewController中實(shí)現(xiàn)通知監(jiān)聽事件
#pragma mark --支付寶支付后查詢服務(wù)器訂單結(jié)果尔许,展示給用戶
-(void)dealALiPayResult:(NSNotification*)notification{
NSString *result = notification.object;
NSLog(@"支付結(jié)果:%@",result);
if ([result isEqualToString:@"9000"]) {
NSLog(@"支付成功");
}else if([result isEqualToString:@"6001"]){
NSLog(@"支付失敗么鹤,中途取消");
}else{
NSLog(@"支付失敗,其他原因");
}
}