iOS 开发之支付

iOS 开发支付篇

随着互联网的发展,电商平台已经成为人们的习惯一种生活方式,电商个人认为站在开发的角度看,也就多了一个购物车和支付,而支付称为很多刚接触电商平台开发人员很向往的一个技术点,那么现在我讲自己了解的当前所有支付方式以及如何使用分享给大家。

支付宝支付:

支付流程 :

(1)先与支付宝签约,获取商户id(partner)和账号id(seller)

(2)下载相应的公私钥文件(加密签名使用),在客户端我们可能只需要私钥

(3)下载支付宝sdk

(4)生成订单信息,可以直接客户端或者自己服务端生存都可以,但是大多是服务端生存的。

(5)调用支付宝客户端,有支付宝客户端跟支付宝打交道

(6)支付完毕之后返回结果给客户端和服务端。


//回到本应用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];

// 商品标题

order.productName=pruduct.subject;

// 商品描述

order.productDescription =pruduct.body;

//商品价格

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

order.notifyURL = @"http%3A%2F%2Fwwww.xxx.com"; //回调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)注册微信开放平台,创建应用获取appid,appSecret,申请支付功能,申请成功之后会返回一些参数详情见图

(2)下载微信支付sdk

(3)客户端请求订单,后台与微信后台交互,返回给客户端支付参数;

(4)调用微信客户端,由微信客户端和微信服务器打交道;

(5)客户端和服务端都会收到支付结果;(前台消息不可靠,我们需要去后台验证,如果后台没有收到支付通知,后台去微信服务器验证然后将结果返回给客户端)



//需要的依赖库,环境搭建可以参见文档,或者直接用cocoapods倒入

/**

*  微信开放平台申请得到的 appid, 需要同时添加在 URL schema

*/

NSString * const WXAppId = @"wxd930ea5d5a258f4f";

/**

* 微信开放平台和商户约定的支付密钥

*

* 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成

*/

NSString * const WXAppKey = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";

/**

* 微信开放平台和商户约定的密钥

*

* 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成

*/

NSString * const WXAppSecret = @"db426a9829e4b49a0dcac7b4162da6b6";

/**

* 微信开放平台和商户约定的支付密钥

*

* 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成

*/

NSString * const WXPartnerKey = @"8934e7d15453e97507ef794cf7b0519d";

/**

*  微信公众平台商户模块生成的ID

*/

NSString * const WXPartnerId = @"1900000109";

调用支付的代码就比较简单了,如下所示

#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];

// 文档: 详细的订单数据放在 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];

//获取到了支付参数

if (error) {

[weakSelf showAlertWithTitle:@"错误" msg:@"获取 PrePayId 失败"];

return;

} else {

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

}

NSString *prePayId = dict[PrePayIdKey];

if (prePayId) {

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

// 调起微信支付

//将支付参数传入到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];

// 构造参数列表

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];

// 在支付之前,如果应用没有注册到微信,应该先调用 [WXApi registerApp:appId] 将应用注册到微信

[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,直接调用getAccessToken方法即可完成支付



银联支付:

支付流程:

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

(2)从自己的服务端获取流水号

(3)然后调用银联sdk,不用跳转,银联sdk直接是内嵌的

(4)支付完成之后会回调代理方法


银联支付在客户端实现起来最简单的,现在介绍一下客户端如何实现 ,以及实现代码

- (void)viewDidLoad {

[super viewDidLoad];

//开始支付

//第一个参数是流水号,又后台返回给我们 第二个参数传00,01,00标示正式环境,01标示测试环境,第三个参数是支付完成回到的控制器,第四个参数是设置代理

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

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

}

//监听支付结果

- (void)UPPayPluginResult:(NSString *)result

{

}

//银联支付将复杂操作全部放在了后台,我们使用相当方便



当然下面才是最常用的,它集成所有支付功能于一身:Ping++

支付流程:

4,ping++,支持支付宝支付,微信支付,银联支付,百度钱包支付,applepay

(1)根据呢需要介入的支付方式去对应的支付平台申请账号和参数

(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添加这行代码适用于监听支付结果的

- (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;

}

综上所述,你可以跟你的个人需求来选择接入支付方式

第三方支付,终究还是第三方,第三方站着公司和开发者的角度上考虑问题,减少开发难度和成本,不必要如此担心。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • 项目中要用到支付功能,需要支付宝,微信,银联三大支付,所以打算总结一下,写两篇文章,方便以后的查阅, 大家在做的时...
    Ke_Wang阅读 24,090评论 17 121
  • 笔者最近的项目中使用到了支付的功能,也遇到了一些坑。在这里跟大家分享一下。 相关配置 1.向支付宝申请, 与支付宝...
    YanniLiu阅读 599评论 0 3
  • iOS支付 iOS支付分为两类,第三方支付和应用内支付(内购)。 第三方支付包括:支付宝支付、微信支付、银联支付、...
    请输入账号名阅读 6,176评论 3 22
  • 周泽楷盯着脚尖看,白色的鞋尖沾上了一点泥。 “时间快到了。”江波涛拍了拍他的肩膀,他起身把手枪装进枪匣里,回头看了...
    纪堂_阅读 533评论 0 0
  • 地图+爬虫https://zhuanlan.zhihu.com/p/21883516 颜色 线条 k w r y ...
    maocy阅读 627评论 0 0