iOS 開發(fā)之支付

iOS 開發(fā)支付篇

隨著互聯(lián)網(wǎng)的發(fā)展教翩,電商平臺已經(jīng)成為人們的習(xí)慣一種生活方式,電商個人認(rèn)為站在開發(fā)的角度看签夭,也就多了一個購物車和支付尝艘,而支付稱為很多剛接觸電商平臺開發(fā)人員很向往的一個技術(shù)點,那么現(xiàn)在我講自己了解的當(dāng)前所有支付方式以及如何使用分享給大家炕吸。

支付寶支付:

支付流程 :

(1)先與支付寶簽約伐憾,獲取商戶id(partner)和賬號id(seller)

(2)下載相應(yīng)的公私鑰文件(加密簽名使用),在客戶端我們可能只需要私鑰

(3)下載支付寶sdk

(4)生成訂單信息算途,可以直接客戶端或者自己服務(wù)端生存都可以塞耕,但是大多是服務(wù)端生存的蚀腿。

(5)調(diào)用支付寶客戶端嘴瓤,有支付寶客戶端跟支付寶打交道

(6)支付完畢之后返回結(jié)果給客戶端和服務(wù)端。


//回到本應(yīng)用urlScheme

NSString *appScheme=@"Practice";

NSString * orderInfo=[self getOrderInfo:indexPath.row];

NSString * signedStr=[self doRsa:orderInfo];

NSString*orderString=[NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",orderInfo,signedStr,@"RSA"];

[AlixLibService payOrder:orderString AndScheme:appScheme seletor:_result target:self];

-(NSString *)doRsa:(NSString *)orderInfo

{

idsigner;

signer=CreateRSADataSigner(PartnerPrivKey);

NSString * signedString=[signer signString:orderInfo];

return signedString;

}

-(NSString *)getOrderInfo:(NSInteger)index

{

//點擊獲取product實例莉钙,并初始化訂單信息

Pruduct *pruduct=[_dataArray objectAtIndex:index];

AlixPayOrder * order=[[AlixPayOrder alloc]init];

order.partner=PartnerID;

order.seller=SellerID;

//訂單ID

order.tradeNO=[self generateTradeNO];

// 商品標(biāo)題

order.productName=pruduct.subject;

// 商品描述

order.productDescription =pruduct.body;

//商品價格

order.amount=[NSString stringWithFormat:@"%.2f",pruduct.price];

order.notifyURL = @"http%3A%2F%2Fwwww.xxx.com"; //回調(diào)URL

return order.description;

}

-(NSString *)generateTradeNO

{

const int N =15;

NSString * sourceString=@"SSSSSSSSSSSSSSSS";

NSMutableString *re=[[NSMutableString alloc]init];

srand(time(0));

for (int i=0; i unsigned index=rand()%[sourceString length];

NSString * s=[sourceString substringWithRange:NSMakeRange(index, 1)];

[re appendString:s];

}

return re;

}

-(void)paymentResultDelegate:(NSString *)result

{

NSLog(@"%@",result);

}

//支付寶也就這么幾行代碼而已廓脆,所謂的高大上是不是讓朋友們失望了


微信支付:

支付流程:

(1)注冊微信開放平臺,創(chuàng)建應(yīng)用獲取appid磁玉,appSecret停忿,申請支付功能,申請成功之后會返回一些參數(shù)詳情見圖

(2)下載微信支付sdk

(3)客戶端請求訂單蚊伞,后臺與微信后臺交互席赂,返回給客戶端支付參數(shù);

(4)調(diào)用微信客戶端时迫,由微信客戶端和微信服務(wù)器打交道颅停;

(5)客戶端和服務(wù)端都會收到支付結(jié)果;(前臺消息不可靠掠拳,我們需要去后臺驗證癞揉,如果后臺沒有收到支付通知,后臺去微信服務(wù)器驗證然后將結(jié)果返回給客戶端)



//需要的依賴庫溺欧,環(huán)境搭建可以參見文檔喊熟,或者直接用cocoapods倒入

/**

*? 微信開放平臺申請得到的 appid, 需要同時添加在 URL schema

*/

NSString * const WXAppId = @"wxd930ea5d5a258f4f";

/**

* 微信開放平臺和商戶約定的支付密鑰

*

* 注意:不能hardcode在客戶端,建議genSign這個過程由服務(wù)器端完成

*/

NSString * const WXAppKey = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";

/**

* 微信開放平臺和商戶約定的密鑰

*

* 注意:不能hardcode在客戶端姐刁,建議genSign這個過程由服務(wù)器端完成

*/

NSString * const WXAppSecret = @"db426a9829e4b49a0dcac7b4162da6b6";

/**

* 微信開放平臺和商戶約定的支付密鑰

*

* 注意:不能hardcode在客戶端聂使,建議genSign這個過程由服務(wù)器端完成

*/

NSString * const WXPartnerKey = @"8934e7d15453e97507ef794cf7b0519d";

/**

*? 微信公眾平臺商戶模塊生成的ID

*/

NSString * const WXPartnerId = @"1900000109";

調(diào)用支付的代碼就比較簡單了,如下所示

#pragma mark - 主體流程

- (void)getAccessToken

{

NSString *getAccessTokenUrl = [NSString stringWithFormat:@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%@&secret=%@", WXAppId, WXAppSecret];

NSLog(@"--- GetAccessTokenUrl: %@", getAccessTokenUrl);

self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:getAccessTokenUrl]];

__weak WXPayClient *weakSelf = self;

__weak ASIHTTPRequest *weakRequest = self.request;

[self.request setCompletionBlock:^{

NSError *error = nil;

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData]

options:kNilOptions

error:&error];


if (error) {

[weakSelf showAlertWithTitle:@"錯誤" msg:@"獲取 AccessToken 失敗"];

return;

} else {

NSLog(@"--- %@", [weakRequest responseString]);

}

NSString *accessToken = dict[AccessTokenKey];

if (accessToken) {

NSLog(@"--- AccessToken: %@", accessToken);

__strong WXPayClient *strongSelf = weakSelf;

[strongSelf getPrepayId:accessToken];

} else {

NSString *strMsg = [NSString stringWithFormat:@"errcode: %@, errmsg:%@", dict[errcodeKey], dict[errmsgKey]];

[weakSelf showAlertWithTitle:@"錯誤" msg:strMsg];

}

}];

[self.request setFailedBlock:^{

[weakSelf showAlertWithTitle:@"錯誤" msg:@"獲取 AccessToken 失敗"];

}];

[self.request startAsynchronous];

}

- (void)getPrepayId:(NSString *)accessToken

{

//token傳入到此鏈接

NSString *getPrepayIdUrl = [NSString stringWithFormat:@"https://api.weixin.qq.com/pay/genprepay?access_token=%@", accessToken];

NSLog(@"--- GetPrepayIdUrl: %@", getPrepayIdUrl);

NSMutableData *postData = [self getProductArgs];

// 文檔: 詳細(xì)的訂單數(shù)據(jù)放在 PostData 中,格式為 json

self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:getPrepayIdUrl]];

[self.request addRequestHeader:@"Content-Type" value:@"application/json"];

[self.request addRequestHeader:@"Accept" value:@"application/json"];

[self.request setRequestMethod:@"POST"];

[self.request setPostBody:postData];

__weak WXPayClient *weakSelf = self;

__weak ASIHTTPRequest *weakRequest = self.request;

[self.request setCompletionBlock:^{

NSError *error = nil;

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[weakRequest responseData]

options:kNilOptions

error:&error];

//獲取到了支付參數(shù)

if (error) {

[weakSelf showAlertWithTitle:@"錯誤" msg:@"獲取 PrePayId 失敗"];

return;

} else {

NSLog(@"--- %@", [weakRequest responseString]);

}

NSString *prePayId = dict[PrePayIdKey];

if (prePayId) {

NSLog(@"--- PrePayId: %@", prePayId);

// 調(diào)起微信支付

//將支付參數(shù)傳入到sdk,喚起微信客戶端

PayReq *request? = [[PayReq alloc] init];

request.partnerId = WXPartnerId;

request.prepayId? = prePayId;

request.package? = @"Sign=WXPay";? ? ? // 文檔為 `Request.package = _package;` , 但如果填寫上面生成的 `package` 將不能支付成功

request.nonceStr? = weakSelf.nonceStr;

request.timeStamp = [weakSelf.timeStamp longLongValue];

// 構(gòu)造參數(shù)列表

NSMutableDictionary *params = [NSMutableDictionary dictionary];

[params setObject:WXAppId forKey:@"appid"];

[params setObject:WXAppKey forKey:@"appkey"];

[params setObject:request.nonceStr forKey:@"noncestr"];

[params setObject:request.package forKey:@"package"];

[params setObject:request.partnerId forKey:@"partnerid"];

[params setObject:request.prepayId forKey:@"prepayid"];

[params setObject:weakSelf.timeStamp forKey:@"timestamp"];

request.sign = [weakSelf genSign:params];

// 在支付之前街佑,如果應(yīng)用沒有注冊到微信,應(yīng)該先調(diào)用 [WXApi registerApp:appId] 將應(yīng)用注冊到微信

[WXApi safeSendReq:request];

} else {

NSString *strMsg = [NSString stringWithFormat:@"errcode: %@, errmsg:%@", dict[errcodeKey], dict[errmsgKey]];

[weakSelf showAlertWithTitle:@"錯誤" msg:strMsg];

}

}];

[self.request setFailedBlock:^{

[weakSelf showAlertWithTitle:@"錯誤" msg:@"獲取 PrePayId 失敗"];

}];

[self.request startAsynchronous];

}

//這是微信官方給的demo,直接調(diào)用getAccessToken方法即可完成支付



銀聯(lián)支付:

支付流程:

(1)注冊申請就不是前端的事了,直接介入sdk

(2)從自己的服務(wù)端獲取流水號

(3)然后調(diào)用銀聯(lián)sdk,不用跳轉(zhuǎn),銀聯(lián)sdk直接是內(nèi)嵌的

(4)支付完成之后會回調(diào)代理方法


銀聯(lián)支付在客戶端實現(xiàn)起來最簡單的这难,現(xiàn)在介紹一下客戶端如何實現(xiàn) ,以及實現(xiàn)代碼

- (void)viewDidLoad {

[super viewDidLoad];

//開始支付

//第一個參數(shù)是流水號赖草,又后臺返回給我們 第二個參數(shù)傳00,01乎折,00標(biāo)示正式環(huán)境骂澄,01標(biāo)示測試環(huán)境,第三個參數(shù)是支付完成回到的控制器矩桂,第四個參數(shù)是設(shè)置代理

[UPPayPlugin startPay:@"57855654" mode:@"01" viewController:self.navigationController delegate:self];

// Do any additional setup after loading the view, typically from a nib.

}

//監(jiān)聽支付結(jié)果

- (void)UPPayPluginResult:(NSString *)result

{

}

//銀聯(lián)支付將復(fù)雜操作全部放在了后臺,我們使用相當(dāng)方便



當(dāng)然下面才是最常用的网沾,它集成所有支付功能于一身:Ping++

支付流程:

4癞蚕,ping++,支持支付寶支付辉哥,微信支付桦山,銀聯(lián)支付,百度錢包支付醋旦,applepay

(1)根據(jù)呢需要介入的支付方式去對應(yīng)的支付平臺申請賬號和參數(shù)

(2)(恨不得直接上代碼了)恒水,傳說中的7行代碼搞定支付


Ping++有著前所未有的簡單,號稱7行代碼搞定支付

NSDictionary* dict = @{? ? @"channel" : channel, // 渠道 alipay, wx, upacp, bfb

@"amount"? : amount? // 金額};

NSData* data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];

NSString *bodyData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

[postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];

[postRequest setHTTPMethod:@"POST"];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:postRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;

NSString* charge = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];? ? // ...

[Pingpp createPayment:charge viewController:viewController appURLScheme:kUrlScheme withCompletion:^(NSString *result, PingppError *error) {? ?

?if ([result isEqualToString:@"success"]) {? ? ? ? // ...

} else {? ? ??

? NSLog(@"PingppError: code=%lu msg=%@", error.code, [error getMsg]);

}

}];

}];

//AppDelegate添加這行代碼適用于監(jiān)聽支付結(jié)果的

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

[Pingpp handleOpenURL:url withCompletion:^(NSString *result, PingppError *error) {? ? ? ? if ([result isEqualToString:@"success"]) {? ? ? ? ? ? // ...

} else {? ? ? ? ? ? NSLog(@"PingppError: code=%lu msg=%@", error.code, [error getMsg]);

}

}];? ? return? YES;

}

綜上所述饲齐,你可以跟你的個人需求來選擇接入支付方式

第三方支付钉凌,終究還是第三方,第三方站著公司和開發(fā)者的角度上考慮問題捂人,減少開發(fā)難度和成本御雕,不必要如此擔(dān)心。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末滥搭,一起剝皮案震驚了整個濱河市酸纲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瑟匆,老刑警劉巖闽坡,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡无午,警方通過查閱死者的電腦和手機(jī)媒役,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪迟,“玉大人酣衷,你說我怎么就攤上這事〈卧螅” “怎么了穿仪?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長意荤。 經(jīng)常有香客問我啊片,道長,這世上最難降的妖魔是什么玖像? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任紫谷,我火速辦了婚禮,結(jié)果婚禮上捐寥,老公的妹妹穿的比我還像新娘笤昨。我一直安慰自己,他們只是感情好握恳,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布瞒窒。 她就那樣靜靜地躺著,像睡著了一般乡洼。 火紅的嫁衣襯著肌膚如雪崇裁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天束昵,我揣著相機(jī)與錄音拔稳,去河邊找鬼。 笑死妻怎,一個胖子當(dāng)著我的面吹牛壳炎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逼侦,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼匿辩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了榛丢?” 一聲冷哼從身側(cè)響起铲球,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晰赞,沒想到半個月后稼病,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體选侨,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年然走,在試婚紗的時候發(fā)現(xiàn)自己被綠了援制。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡芍瑞,死狀恐怖晨仑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拆檬,我是刑警寧澤洪己,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站竟贯,受9級特大地震影響答捕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屑那,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一拱镐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧齐莲,春花似錦痢站、人聲如沸磷箕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岳枷。三九已至芒填,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間空繁,已是汗流浹背殿衰。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留盛泡,地道東北人闷祥。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像傲诵,于是被迫代替她去往敵國和親凯砍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 項目中要用到支付功能拴竹,需要支付寶悟衩,微信,銀聯(lián)三大支付栓拜,所以打算總結(jié)一下座泳,寫兩篇文章惠昔,方便以后的查閱, 大家在做的時...
    Ke_Wang閱讀 24,100評論 17 121
  • 筆者最近的項目中使用到了支付的功能挑势,也遇到了一些坑镇防。在這里跟大家分享一下。 相關(guān)配置 1.向支付寶申請, 與支付寶...
    YanniLiu閱讀 615評論 0 3
  • iOS支付 iOS支付分為兩類潮饱,第三方支付和應(yīng)用內(nèi)支付(內(nèi)購)营罢。 第三方支付包括:支付寶支付、微信支付饼齿、銀聯(lián)支付饲漾、...
    請輸入賬號名閱讀 6,196評論 3 22
  • 周澤楷盯著腳尖看,白色的鞋尖沾上了一點泥缕溉。 “時間快到了考传。”江波濤拍了拍他的肩膀证鸥,他起身把手槍裝進(jìn)槍匣里僚楞,回頭看了...
    紀(jì)堂_閱讀 541評論 0 0
  • 地圖+爬蟲https://zhuanlan.zhihu.com/p/21883516 顏色 線條 k w r y ...
    maocy閱讀 633評論 0 0