概述

开发中支付通常都会集成支付宝支付,下面讲解支付宝的整体流程。

集成支付宝支付的流程

签约

与支付签约,得到获取商户的ID(partner)、账户ID(seller)、私钥privateKey。

下载SDK

文档中心->开发文档->SDK下载

编写支付代码

  • 创建APOrderInfo模型,赋值所有的订单信息
  • 调用APOrderInfo的orderInfoEncoded转成字符串,使用APRSASigner对订单参数进数字签名(其中私钥是客户端使用支付宝提供的工具生成的密钥对。公钥需要上传支付宝对应的应用后台返回支付宝公钥用于校验支付完成的回调数据进行校验)。
  • 调用AlipaySDK的payOrder进行支付。
- (void)pay
{
NSString *pid = @"";
NSString *appID = @""; // 如下私钥,rsa2PrivateKey 或者 rsaPrivateKey 只需要填入一个
// 如果商户两个都设置了,优先使用 rsa2PrivateKey
// rsa2PrivateKey 可以保证商户交易在更加安全的环境下进行,建议使用 rsa2PrivateKey
// 获取 rsa2PrivateKey,建议使用支付宝提供的公私钥生成工具生成,
// 工具地址:https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1
NSString *rsa2PrivateKey = @"MIIEpAIBAAKCAQEAngES3OTqQR/dH5/D64inGWfxrYUZX75JJ1RxIEkjJW+ISTA7SK75CVNaoMTfEQ1twmluIQr0uEAVCWdjY2UuSsl+MoRlufTjDgVY0W94zcG7CcWy6vshWde1xAkyJq23fWyokFvgBERY7G00pkULSnwpofcWgk1xITkNo4ocW0kTgAKlGYyLkKjJ7Sy4MgWpS+4GQm0ABJ/ahzlJ+u4NP4F765Ntk2AUi3mDXs0DgzB6rjonEAyOWbUKpHESqsuzZ/VbIJ+KEhbJzRrUnd3xSO7a4Up0TzALusfH1IPxVdn0E7KTpfYPCmzKyJ8NzY7CCxqMftEcMML/bpxwuymt+wIDAQABAoIBAHpWTHuaBsKr4DMXKcQZh4AFWjvG/XGDTPLVz812s27N35EDdjN9vrb4wggOxsRWSHCp3ypYaEis3VztnyebdO9U+ZA1sOn9cTwu6aknjTqK0L3tQ+3qydTdTxBdKmaGRLcpRY6YhGfpX4yXtZcziF2Aq1+Lh/MV8Q0PNr80NWZ7g9pOnj4xuLaHZyPy60XZu3pjqG18hx07ny0CMn/kjt/a1EDPSGj2Nqrn9ERP8kD0jWQmdXRK2wDBESqyjD65jy4wrX2pqbiphqKBP3NcBdI+sxkAxezKTiwsqcMU/o2tXDEYyBuTPCUQm6/CJgbi6q1Ll0d5KTTfIt4V+YzvYOECgYEAyekr+g/1P0+1oyobBSlr0dLlmXu7QcJsazS23YkTgjNZldyEqRhg8q3oPl4e6HMlxuP71YJySbVaw3o3g5pMg8myLCa0THndpVruwxjtbG4GxCwLgWBJHjJGuLVoCn+ngNPRhjN1n7K1K+R/mWQGAZc7PdQm8B7bs35JtCDTbAsCgYEAyFTVAB9ziLt2dxO9J1Kd1zrh6se1ZdcxLXtBnNIyxuEktvcce9xtmu41N4+0pXF80Gl3IfWmVuMFjA5XpxpGa3f7QMiSm4lYG3Xr00KzcBfsciVIE2ZyrOdpfnoKtxJvZ6imPyJMkswwJxrnE92FDQj98V+l4BoIzAVYvLL+C9ECgYEAvX6zwj2l2uRxQQ/sSfzk7wiyaUjBpubUoAzaLrJOd9y/kDFk49o4aqoilB37fgdLhg1Dtc92eYzWAS272iw+8VSjfmJYxol9JopgGQRVF3Vvrj70EVkPZmKjEwlV+rxxtSuWsg+rrdSnyejqhEhmhqmrdMyeOq+LXDsC6yX/pp8CgYEAikg0d08+euWb0npnmRsoJQdaJqwQBOpT4ecw1UUrE6kZpMpSeRUg+07uoRmrQoBh/aKvP1vHpDY1AAZubsRuU4SQhJluybo2fU4aqMtj/T4mUmx1oh6Xjc53PXyUpOYuzEjX6MCORs53dqbVVxsT2nmYgOLbJyQRanNOW4LaZeECgYADEXDfjOIqmSdeZvWasFhQmUFMcj+9bYu9E80ps+Px5Ko5gr5fmB0fV4itR6REbk5WS57jb2ilFi4mCHkgOeuj5LtVQQ+TofIfl9vWqx5dj/wq8eG1KynijUZhcG5ONgJ+3gB6KM5KsOMf3IVi3WiFOzVha+T8cE530EG8VrYVZw==";
NSString *rsaPrivateKey = @""; /*
*生成订单信息及签名
*/
//将商品信息赋予AlixPayOrder的成员变量
APOrderInfo* order = [APOrderInfo new]; // NOTE: app_id设置
order.app_id = appID; // NOTE: 支付接口名称
order.method = @"alipay.trade.app.pay"; // NOTE: 参数编码格式
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 = (rsa2PrivateKey.length > 1)?@"RSA2":@"RSA";// NOTE: 商品数据
order.biz_content = [APBizContent new];
order.biz_content.body = @"我是测试数据";
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); NSString *signedString = nil;
APRSASigner* signer = [[APRSASigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)];
if ((rsa2PrivateKey.length > 1)) {
signedString = [signer signString:orderInfo withRSA2:YES];
} else {
signedString = [signer signString:orderInfo withRSA2:NO];
} // NOTE: 如果加签成功,则继续执行支付
if (signedString != nil) {
//应用注册scheme,在AliSDKDemo-Info.plist定义URL types
NSString *appScheme = @"alisdkdemo"; // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
orderInfoEncoded, signedString]; // NOTE: 调用支付结果开始支付
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
}];
}
} #pragma mark -
#pragma mark ==============产生随机订单号============== - (NSString *)generateTradeNO
{
static int kNumber = 15;
NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSMutableString *resultStr = [[NSMutableString alloc] init];
srand((unsigned)time(0));
for (int i = 0; i < kNumber; i++)
{
unsigned index = rand() % [sourceStr length];
NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
[resultStr appendString:oneStr];
}
return resultStr;
}

补充:

  1. APRSASigner利用私钥对参数签名,其中支付签名分为两种RSA2、RSA区别主要是签名过程使用的单向散列函数不同分别是SHA256、SHA1。建议使用前者。具体信息参考

  2. APRSASigner做签名内部依赖openssl,不过支付宝对签名细节封装成了libcrypto.a libssl.a。集成支付的工程目录

iOS开发系列-支付宝支付的更多相关文章

  1. iOS开发集成支付宝支付、支付宝&微信支付

    支付宝支付: 参考链接:https://www.jianshu.com/p/60175e525c0e https://blog.csdn.net/zhonggaorong/article/detail ...

  2. iOS开发系列--通知与消息机制

    概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...

  3. iOS开发系列--通知与消息机制--转

    来自:http://www.cocoachina.com/ios/20150318/11364.html 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户 ...

  4. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  5. iOS开发系列文章(持续更新……)

    iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...

  6. iOS开发系列--App扩展开发

    概述 从iOS 8 开始Apple引入了扩展(Extension)用于增强系统应用服务和应用之间的交互.它的出现让自定义键盘.系统分享集成等这些依靠系统服务的开发变成了可能.WWDC 2016上众多更 ...

  7. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  8. iOS开发系列--数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  9. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

随机推荐

  1. iptables防DDOS攻击和CC攻击配置

    防范DDOS攻击脚本 #防止SYN攻击 轻量级预防 iptables -N syn-flood iptables -A INPUT -p tcp –syn -j syn-flood iptables ...

  2. XML XPATH simpleXML

    XPath 通过DOM结构定位节点,在数据量很大的情况下速度下降的很厉害.解决方法是XPath.Xpath的作用:用于快速定位节点 position()是节点的位置,节点的位置是从1开始 simple ...

  3. flink学习之十一-window&EventTime实例

    上面试了Processing Time,在这里准备看下Event Time,以及必须需要关注的,在ET场景下的Watermarks. EventTime & Watermark Event t ...

  4. VC++ 2010 创建高级Ribbon界面详解(3)

    3.工具栏 在传统的菜单式界面中,工具栏作为菜单的有益补充,被广泛使用.我们通过将一些常用命令放置到工具栏上,可以让用户直观而快速地访问到常用功能,提高了效率.在Ribbon界面中,工具栏得到了进一步 ...

  5. response和ServletContext和乱码问题

    服务器端以/开始就代表当前项目名客户端必须以 /项目名/资源 才能定位到资源 软件与软件之间,以字符为标准传递,传递字节,接收端自己按原来的编码集编码之后再按照自己的编码集解码编码(如果没有对应字符, ...

  6. MFS分布式文件系统【3】存储节点 CHUNK SERVER 部署

    [root@ky_hs_252 mfs-1.6.27]# mkdir /usr/local/mfs [root@ky_hs_252 mfs-1.6.27]# useradd mfs -s /sbin/ ...

  7. 不走弯路,微信小程序的快速入门?

    微信小程序下载注册地址:https://mp.weixin.qq.com/cgi-bin/wx 微信小程序登开发者平台地址(可以查看小程序APPID):https://mp.weixin.qq.com ...

  8. properties配置文件的基本操作

    对properties的基本操作 public class PropertiesUtil {// 是否是文件public static boolean isFile = false;// 路径publ ...

  9. linux部署tomcat项目

    unzip apache-tomcat-7.0.55-windows- x64.zip     解压zip文件 chmod +x startup.sh shutdown.sh catalina.sh ...

  10. Hadoop–Task 相关

    在MapReduce计算框架中,一个应用程序被划分为Map和Reduce两个计算阶段.他们分别由一个或多个Map Task 和Reduce Task组成. Map Task: 处理输入数据集合中的一片 ...