iOS之“支付宝支付”开发流程
来源:互联网 发布:淘宝上有两个稻香村 编辑:程序博客网 时间:2024/04/28 18:12
支付宝快捷支付的主要步骤:
- 先与支付宝签约,获得商户ID(partner)和账号ID(seller);
- 下载相应的公钥私钥文件(加密签名用);
- 下载支付宝SDK;
- 生成订单信息;
- 调用支付宝客户端,由支付宝客户端跟支付宝安全服务器打交道;
- 支付完毕后返回支付结果给商户客户端和服务。
而iOS客户端需要做的是:
- 调用支付宝支付接口;
- 处理支付宝返回的支付结果。
在调用支付宝支付接口前,还需要先生成一个订单,下载的支付宝文档中描述时,是将这步也放在客户端来做了,但也可以在服务器端生成这个订单(支付宝会在支付成功后通知服务器端,所以在服务器端生成订单的话,开发者掌握所有订单,而且也会更安全)。
- 生成订单(可以在iOS客户端内生成,也可以在服务器端生成);
- 调用支付宝支付接口,发送订单;
- 处理支付宝返回的支付结果。
支付宝支付的安全问题,需要在生成订单和处理支付结果的时候做一个安全性校验:即生成订单时对数据签名,收到支付结果时对数据进行签名验证,以检验数据是否被篡改过(支付宝目前只支持采用RSA加密方式做签名验证)。简单地说,就是在生产订单时,需要使用私钥生成签名值;在处理返回的支付结果时,需要使用公钥验证返回结果是否被篡改。
支付宝iOS SDK的官方下载地址:
https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId=4#ps-tabinfo-hash
压缩包里有两个相关文档:
《支付宝钱包支付接口开发包2.0标准版.pdf》
《支付宝钱包支付接口开发包2.0标准版接入与使用规则.pdf》
集成支付宝支付的主要流程:
将需要的文件,静态库等拖入工程中,这里有include,libs,Utilities,libcrypto.a,libssl.a文件(如果只需要发送订单和处理支付返回结果,只需要添加AlipaySDK.bundle和AlipaySDK.framework)。如下图:
设置Head Search Paths 和 Library Search Paths
即:targets->Build Setting ->Search Paths->Always Search User Paths和 Library Search Paths,注意:Always Search User Paths 和 Library Search Paths的路径一定要根据这个地址能找到对应的头文件。
设置partner、seller、RSA private key、RSA public key
一般是设置在-info文件中。
支付成功后,回到应用程序中
需要设置回调的标示,同样在-info文件中,添加个节点:
发送订单的方法:
- (void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;
如果手机内没安装支付宝的app,会直接展现支付宝web支付界面,通过callback返回支付结果;如果手机内安装了支付宝的app,会跳转到支付宝的app支付,然后通过openURL的回调返回支付结果。
- 调用支付宝
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { if ([resultDic[@"resultStatus"] intValue] == 9000) { //支付成功 } else{ NSString *resultMes = resultDic[@"memo"]; resultMes = (resultMes.length<=0?@"支付失败":resultMes); NSLog(@"%@",resultMes); } }];
支付宝的SDK只给了一个处理返回结果的方法,没有提供处理openURL的方法:
if ([url.host isEqualToString:@"safepay"]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); }]; }
SDK提供了处理openURL返回结果的方法:
- (void)processOrderWithPaymentResult:(NSURL *)resultUrl standbyCallback:(CompletionBlock)completionBlock;
两个回调block都统一定义为typedef void(^CompletionBlock)(NSDictionary *resultDic)。
resultStatus状态码对应的信息:
- 9000:订单支付成功
- 8000:正在处理中
- 4000:订单支付失败
- 6001:用户中途取消
- 6002:网络连接出错
result是订单信息,以及签名验证信息。
代码过程展示:
- 在AppDelegate中:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { //跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); }]; return YES;}- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { [self parseURL:url application:application]; return YES;}//签名验证- (void)parseURL:(NSURL *)url application:(UIApplication *)application { AlixPay *alixpay = [AlixPay shared]; AlixPayResult *result = [alixpay handleOpenURL:url]; if (result) { //是否支付成功 if (9000 == result.statusCode) { /* *用公钥验证签名 */ id<DataVerifier> verifier = CreateRSADataVerifier([[NSBundle mainBundle] objectForInfoDictionaryKey:@"RSA public key"]); if ([verifier verifyString:result.resultString withSign:result.signString]) { UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:result.statusMessage delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alertView show]; }//验签错误 else { UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"签名错误" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alertView show]; } } //如果支付失败,可以通过result.statusCode查询错误码 else { UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:result.statusMessage delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alertView show]; } } }
- 在需要支付的页面选中商品调用支付宝安全支付
- (void)payTreasurePay { /* *商户的唯一的parnter和seller。 *签约后,支付宝会为每个商户分配一个唯一的 parnter 和 seller。 */ //如果partner和seller数据存于其他位置,请改写下面两行代码 NSString *partner = @"商户的parnter"; NSString *seller = @"商户的seller"; //partner和seller获取失败,提示 if ([partner length] == 0 || [seller length] == 0) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"缺少partner或者seller" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alert show]; return; } /* *生成订单信息及签名 */ //将商品信息赋予AlixPayOrder的成员变量 AlixPayOrder *order = [[AlixPayOrder alloc] init]; order.partner = partner; order.seller = seller; order.tradeNO = @"订单ID"; //订单ID(由商家自行制定) order.productName = @"商品标题"; //商品标题 order.productDescription = @"商品描述"; //商品描述 order.amount = [NSString stringWithFormat:@"%.2f",2.5]; //商品价格 order.notifyURL = @"http://www.xxx.com"; //回调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,用于安全支付成功后重新唤起商户应用 NSString *appScheme = URLScheme; //将商品信息拼接成字符串 NSString *orderSpec = [order description]; NSLog(@"orderSpec = %@",orderSpec); //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode NSString *privateKey = @"私钥"; id<DataSigner> signer = CreateRSADataSigner(privateKey); NSLog(@"prikey = %@",privateKey); 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) { NSString *resultStatus=resultDic[@"resultStatus"]; if([resultStatus isEqualToString: @"9000"]){ [self alert:@"恭喜" msg:@"您已成功支付啦!"]; }else{ [self alert:@"提示" msg:@"支付失败,可在待付款订单中查看"]; } [self.navigationController popToRootViewControllerAnimated:YES]; }]; /* //获取安全支付单例并调用安全支付接口 AlixPay * alixpay = [AlixPay shared]; int ret = [alixpay pay:orderString applicationScheme:appScheme]; if(ret == 9000){ [self alert:@"恭喜" msg:@"您已成功支付啦!"]; }else{ [self alert:@"提示" msg:@"支付失败,可在待付款订单中查看"]; } [self.navigationController popToRootViewControllerAnimated:YES]; if (ret == kSPErrorAlipayClientNotInstalled) { UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您还没有安装支付宝快捷支付,请先安装。" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alertView show]; } else if (ret == kSPErrorSignError) { NSLog(@"签名错误!"); } */ }}- (void)alert:(NSString *)title msg:(NSString *)msg{ UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alter show];}
注:
RSA加密算法,除了可加解密外,还可用来作签名校验。简单的说,RSA会生成一个私钥和一个公钥,私钥应该独自保管,公钥可以分发出去。做签名验证时,可以用私钥对需要传输的数据做签名加密,生成一个签名值,之后分发数据,接收方通过公钥对签名值做校验,如果一致则认为数据无篡改。
支付宝demo(包括ios,android,wp)下载地址:
http://download.csdn.net/download/pearlhuzhu/5736965
解决在iOS9上调用支付宝不可回调的问题以及支付宝的嵌入流程:
http://blog.csdn.net/baby_hua/article/details/51004405
- iOS之“支付宝支付”开发流程
- iOS开发之支付宝集成流程
- iOS 支付宝支付开发流程
- iOS 支付宝开发流程
- iOS开发之支付宝支付
- ios 支付宝支付流程
- ios 支付宝支付流程
- iOS支付宝支付流程
- iOS开发支付集成之支付宝支付
- iOS开发支付集成之支付宝支付
- iOS开发支付集成之支付宝支付
- iOS开发支付集成之支付宝支付
- iOS开发支付集成之支付宝支付
- iOS之“微信支付”开发流程
- ios支付宝支付开发
- iOS开发-支付宝支付
- IOS开发--支付宝支付
- iOS开发支付宝支付
- 有效处理Java异常三原则
- Apache的Order Allow,Deny 详解
- HDOJ 1048 The Hardest Problem Ever(加密解密类)
- Sqlite全面学习(二)
- css样式
- iOS之“支付宝支付”开发流程
- 【转】ACM及其他OJ系统基本输入输出规则
- eclipse搭建java+python+go+c++开发环境
- 本文为自己所学的Collection小结,因为时间问题只提到一些本人觉得需要注意的方法,如需详细学习Collection仍需找其他资料
- 2016游戏安全技术竞赛题PC第一题逆向分析详解
- logcat无限输出Socket deconnection
- Xcode快捷键
- TodayWidget使用及创建
- 搭建可用http访问的svn(windows)