概述

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

集成支付宝支付的流程

签约

与支付签约,得到获取商户的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. 1、postman介绍与安装

    postman介绍 官方介绍:Developers use Postman to build modern software for the API-first world. 个人理解postman是 ...

  2. HCW 19 Team Round (ICPC format) H Houston, Are You There?(极角排序)

    题目链接:http://codeforces.com/gym/102279/problem/H 大致题意: 你在一个定点,你有个长度为R的钩子,有n个东西在其他点处,问你能勾到的东西的数量是多少? 思 ...

  3. error C3867: “std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str”: 函数调用缺少参数列表;请使用“&std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str”创建指向成员的指针

    这个问题找了很多没有找到满意的答案.仔细看了一下,是使用了c_str的问题. 我直接把使用string.c_str的地方使用char*代替即解决问题.

  4. vue组件的inheritAttrs属性

    vue官网对于inheritAttrs的属性解释:如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false. 可能不是很好理解,我们可以举个例子来验证一下. ...

  5. java-day19

    获取Stream流方法 根据Collection获取流 根据Map获取流 根据数组获取流 常用方法分为两种:延迟方法和终结方法 逐一处理:forEach 过滤:filter 映射:map 统计个数:c ...

  6. Redis数据结构之字典-dict

    dict是Redis服务器中出现最为频繁的复合型数据结构,除hash使用dict之外,整个Redis数据库中所有的key和value也会组成一个全局字典,还有带过期时间的key集合也是一个字典. zs ...

  7. redis主从复制和哨兵

    摘自:https://www.cnblogs.com/leeSmall/p/8398401.html 一.Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点 ...

  8. Wordpress 文章编辑页面添加 metabox

    add_meta_box($id,$title,$callback,$screen,$context:,$priority); 参数 $id (字符串)(必需)Meta模块的 HTML"ID ...

  9. Servlet - Servlet相关

    1. 概念 Servlet是指任何实现了Servlet接口的类, Servlet运行于支持Java的应用服务器中, Servlet可以响应任何类型的请求, 但大多数情况下, Servlet只用来扩展基 ...

  10. 牛客多校第十场 D Han Xin and His Troops 中国剩余定理

    题意: 韩信有若干个兵,给定你若干个模数和余数,再给你一个1e18以内的范围限制,求解同余方程组,如果无解,输出“他一定在撒谎”,如果最小解超出范围限制,输出“他可能在撒谎”,否则输出最小解 注意:不 ...