概述

iOS支付宝支付集成

详细

支付宝和微信都是业界的老大哥,相信大家都有所觉得文档、SDK都是各种坑吧(纯粹吐槽而已),本文先整理支付宝支付集成。

一、准备工作

1、向支付宝”签约" 成为支付宝的”商户”, 签约完成后, 支付宝会提供一些必要的数据给我们(商户ID-partner,帐号ID-支付宝帐号)

注意:签约成为支付宝商户,需要提供公司营业执照[http://act.life.alipay.com/shopping/before/help/index.html](http://act.life.alipay.com/shopping/before/help/index.html)

2、获取支付相关的 '私钥' 和 '密钥'

[https://doc.open.alipay.com/doc2/detail?treeId=44&articleId=103242&docType=1](https://doc.open.alipay.com/doc2/detail?treeId=44&articleId=103242&docType=1)

3、下载支付的SDK

[https://doc.open.alipay.com/doc2/detail?treeId=54&articleId=103419&docType=1](https://doc.open.alipay.com/doc2/detail?treeId=54&articleId=103419&docType=1)

二、集成支付宝SDK步骤

1、从官方Demo中把红色标注的文件添加进入项目中,记得选copy;

2、

点击项目名称,点击“Build Phases”选项卡,在“Link Binary with Librarles” 选项中,新增“AlipaySDK.framework”和“SystemConfiguration.framework” 两个系统库文件。如果项目中已有这两个库文件,可不必再增加;

添加下图中的库:

  1. localhost:alipay mac$ ls
  2. APAuthV2Info.h Order.h libssl.a
  3. APAuthV2Info.m Order.m openssl
  4. AlipaySDK.bundle Util
  5. AlipaySDK.framework libcrypto.a
  6. 导入系统库
  7. SystemConfiguration.framework

3、

添加Pch文件新建pch成功后,在pch文件中添加#import然后按照下图所示,进行修改pch的文件路径

也可以不设置,我这个是我需要设置#import <UIKit/UIKit.h> #import <Foundation/Foundation.h>,也可以不用使用,只在当前文件里添加相对应的使用即可,但是这样针对整个项目来说方便些

4、

修改SDK路径完成以上两步之后,会发现出现了一个经典的错误,找不到:#include解决这个问题,需要在Header Search Path中配置SDK中的点a(libssl.a/libcrypto.a)文件所在的路径,找到之后设置好正确的路径

点击项目名称,点击“Build Settings”选项卡,在搜索框中,以关键字“search” 搜索,对“Header Search Paths”增加头文件路径:“$(SRCROOT)/项目名称/IntegratedAlipay/AlipayFiles”(注意:不包括引号,如果不是放到项目根目录下,请在项目名称后面加上相应的目录名);

根据你文件位置,我的是:

“$(SRCROOT)/QTXStudent/Classes/Alipay/AlipayFiles”

5、 为URL Types 添加支付宝回调scheme

点击项目名称,点击“Info”选项卡,在URL types里面添加一项,Identifier可以不填,URL schemes必须和appScheme的值相同,用于支付宝处理回到应用的事件;

为URL Types 添加支付宝回调scheme

6、在工程项目的plist文件中添加

iOS 9以后的系统需要添加支付宝分享的scheme到白名单中,scheme名为alipayshare

按如下形式添加即可:

7、在AppDelegate中处理事件回调:

  1. /**
  2. 这里处理微信/支付宝支付完成之后跳转回来
  3. */
  4. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
  5. {
  6. //如果极简 SDK 不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给 SDK
  7. if ([url.host isEqualToString:@"safepay"]) {
  8. //跳转支付宝钱包进行支付,处理支付结果
  9. [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
  10. NSLog(@"支付宝客户端支付结果result = %@",resultDic);
  11. if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
  12.  
  13. // 发通知带出支付成功结果
  14. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnSucceedPayNotification object:resultDic];
  15. } else {
  16.  
  17. // 发通知带出支付失败结果
  18. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnFailedPayNotification object:resultDic];
  19. }
  20.  
  21. }];
  22. }
  23.  
  24. if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回 authCode
  25. [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
  26. NSLog(@"支付宝网页版result = %@",resultDic);
  27. if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
  28.  
  29. // 发通知带出支付成功结果
  30. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnSucceedPayNotification object:resultDic];
  31. } else {
  32.  
  33. // 发通知带出支付失败结果
  34. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnFailedPayNotification object:resultDic];
  35. }
  36. }];
  37. }
  38.  
  39. return YES;
  40. }
  41.  
  42. // NOTE: 9.0以后使用新API接口
  43. - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
  44. {
  45.  
  46. //如果极简 SDK 不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给 SDK
  47. if ([url.host isEqualToString:@"safepay"]) {
  48. //跳转支付宝钱包进行支付,处理支付结果
  49. [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
  50. NSLog(@"支付宝客户端支付结果result = %@",resultDic);
  51. if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
  52.  
  53. // 发通知带出支付成功结果
  54. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnSucceedPayNotification object:resultDic];
  55. } else {
  56.  
  57. // 发通知带出支付失败结果
  58. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnFailedPayNotification object:resultDic];
  59. }
  60. }];
  61. }
  62.  
  63. if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回 authCode
  64. [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
  65. NSLog(@"支付宝网页版result = %@",resultDic);
  66. if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
  67.  
  68. // 发通知带出支付成功结果
  69. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnSucceedPayNotification object:resultDic];
  70. } else {
  71.  
  72. // 发通知带出支付失败结果
  73. [[NSNotificationCenter defaultCenter] postNotificationName:ZLAliReturnFailedPayNotification object:resultDic];
  74. }
  75. }];
  76. }
  77.  
  78. return YES;
  79. }

8、 在需要用的地方导入“AlipayHeader.h”,并使用“[AlipayRequestConfig alipayWithPartner:...”方法进行支付;

  1. /**
  2. * 配置请求信息,仅有变化且必要的参数
  3. *
  4. * @param partner 合作者身份ID 以 2088 开头由 16 位纯数字组成的字符串。
  5. * @param sellerID 卖家支付宝账号 以 2088 开头由 16 位纯数字组成的字符串。
  6. * @param outTradeNO 商户网站唯一订单号
  7. * @param subject 商品名称
  8. * @param body 商品详情
  9. * @param totalFee 总金额
  10. * @param notifyURL 服务器异步通知页面路径
  11. * @param itBPay 未付款交易的超时时间
  12. */
  13. + (void)alipayWithPartner:(NSString *)partner
  14. sellerID:(NSString *)sellerID
  15. outTradeNO:(NSString *)outTradeNO
  16. subject:(NSString *)subject
  17. body:(NSString *)body
  18. totalFee:(NSString *)totalFee
  19. notifyURL:(NSString *)notifyURL;

仅含有变化的参数:

  1. + (void)alipayWithPartner:(NSString *)partner
  2. sellerID:(NSString *)sellerID
  3. outTradeNO:(NSString *)outTradeNO
  4. subject:(NSString *)subject
  5. body:(NSString *)body
  6. totalFee:(NSString *)totalFee
  7. notifyURL:(NSString *)notifyURL {
  8.  
  9. [self alipayWithPartner:partner sellerID:sellerID outTradeNO:outTradeNO subject:subject body:body totalFee:totalFee notifyURL:aliNotifyURL service:@"mobile.securitypay.pay" paymentType:@"1" inputCharset:@"utf-8" itBPay:@"30m" privateKey:aliPrivateKey appScheme:aliAppScheme];
  10.  
  11. }

包含所有必要的参数:

  1. + (void)alipayWithPartner:(NSString *)partner
  2. sellerID:(NSString *)sellerID
  3. outTradeNO:(NSString *)outTradeNO
  4. subject:(NSString *)subject
  5. body:(NSString *)body
  6. totalFee:(NSString *)totalFee
  7. notifyURL:(NSString *)notifyURL
  8. service:(NSString *)service
  9. paymentType:(NSString *)paymentType
  10. inputCharset:(NSString *)inputCharset
  11. itBPay:(NSString *)itBPay
  12. privateKey:(NSString *)privateKey
  13. appScheme:(NSString *)appScheme {
  14.  
  15. Order *order = [Order order];
  16. order.partner = partner;
  17. order.sellerID = sellerID;
  18. order.outTradeNO = outTradeNO;
  19. order.subject = subject;
  20. order.body = body;
  21. order.totalFee = totalFee;
  22. order.notifyURL = notifyURL;
  23. order.service = service;
  24. order.paymentType = paymentType;
  25. order.inputCharset = inputCharset;
  26. order.itBPay = itBPay;
  27.  
  28. // 将商品信息拼接成字符串
  29. NSString *orderSpec = [order description];
  30.  
  31. // 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循 RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
  32.  
  33. NSString *signedString = [self genSignedStringWithPrivateKey:aliPrivateKey OrderSpec:orderSpec];
  34.  
  35. // 调用支付接口
  36. [self payWithAppScheme:appScheme orderSpec:orderSpec signedString:signedString];
  37. }

生成signedString:

  1. + (NSString *)genSignedStringWithPrivateKey:(NSString *)privateKey OrderSpec:(NSString *)orderSpec {
  2.  
  3. // 获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循 RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
  4. id<DataSigner> signer = CreateRSADataSigner(privateKey);
  5. return [signer signString:orderSpec];
  6. }

支付:

  1. + (void)payWithAppScheme:(NSString *)appScheme orderSpec:(NSString *)orderSpec signedString:(NSString *)signedString {
  2.  
  3. // 将签名成功字符串格式化为订单字符串,请严格按照该格式
  4. NSString *orderString = nil;
  5. if (signedString != nil) {
  6. orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"", orderSpec, signedString, @"RSA"];
  7. [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { // 网页版
  8. NSLog(@"支付宝支付结果 reslut = %@", resultDic);
  9.  
  10. // 返回结果需要通过 resultStatus 以及 result 字段的值来综合判断并确定支付结果。 在 resultStatus=9000,并且 success="true"以及 sign="xxx"校验通过的情况下,证明支付成功。其它情况归为失败。较低安全级别的场合,也可以只通过检查 resultStatus 以及 success="true"来判定支付结果
  11.  
  12. if (resultDic && [resultDic objectForKey:@"resultStatus"] && ([[resultDic objectForKey:@"resultStatus"] intValue] == 9000)) {
  13.  
  14. // 发通知带出支付成功结果
  15. [ZLNotificationCenter postNotificationName:QTXAliReturnSucceedPayNotification object:resultDic];
  16. } else {
  17.  
  18. // 发通知带出支付失败结果
  19. [ZLNotificationCenter postNotificationName:QTXAliReturnFailedPayNotification object:resultDic];
  20. }
  21. }];
  22. }
  23.  
  24. }

9、

在本头文件中设置aliPartnerID、aliSellerAccount、aliNotifyURL、aliAppScheme和aliPrivateKey的值(所有的值在支付宝回复的邮件里面:注意,建议除appScheme以外的字段都从服务器请求);

这时候,我们支付就直接一句话搞定:

  1. // 支付宝支付
  2. [AlipayRequestConfig alipayWithPartner:aliPartnerID sellerID:aliSellerAccount outTradeNO:[self generateTradeNO] subject:@"测试" body:@"支付宝支付" totalFee:@"0.01" notifyURL:aliNotifyURL]; // notifyURL: 回调url@"http://www.xxx.com"
  3.  
  4. [ZLNotificationCenter addObserver:self selector:@selector(paySucceed) name:ZLAliReturnSucceedPayNotification object:nil];
  5. [ZLNotificationCenter addObserver:self selector:@selector(payFailed) name:ZLAliReturnFailedPayNotification object:nil];

10、建议除appScheme以外的字段都从服务器请求!

建议除appScheme以外的字段都从服务器请求!建议除appScheme以外的字段都从服务器请求!

PS:重要的事情说三遍!!!

上面的第七步和第八步建议不要使用,直接用第九步去替代!建议除appScheme以外的字段都从服务器请求!

如果后台给你一个接口返回那些参数了,你就不用客户端去加密算法,只负责请求后台拿到这些参数再去请求支付宝即可.

下面例子是支付宝的拼接方式,请按照当前版本的相对应的拼接方式来.

  1. // 支付宝支付
  2. - (void)alipayPay {
  3.  
  4. NSMutableDictionary *params = [NSMutableDictionary dictionary];
  5. params[@"orderNo"] = self.orderNo; // 订单号
  6. params[@"realAmt"] = [NSString stringWithFormat:@"%.2lf", self.realAmt]; // 金额
  7.  
  8. __weak __typeof(self) weakSelf = self;
  9. [QTXHttpTool post:QTX_aliPay_url params:params success:^(id json) {
  10. QTXLog(@"支付宝支付返回参数接口 请求成功-%@", json);
  11.  
  12. if ([json[@"success"] isEqual:@(YES)]) {
  13.  
  14. // 返回生成订单信息及签名
  15. NSString *signedString = json[@"data"][@"sign"];
  16. NSString *orderInfoEncoded = json[@"data"][@"orderInfo"];
  17.  
  18. // NOTE: 如果加签成功,则继续执行支付
  19. if (signedString != nil) {
  20. // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
  21. // NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@&sign_type=RSA", orderInfoEncoded, signedString];
  22. NSString *orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
  23. orderInfoEncoded, signedString, @"RSA"];
  24.  
  25. // NOTE: 调用支付结果开始支付
  26. [[AlipaySDK defaultService] payOrder:orderString fromScheme:XHHAppScheme callback:^(NSDictionary *resultDic) {
  27. QTXLog(@"reslut = %@",resultDic);
  28.  
  29. if ([resultDic[@"resultStatus"] intValue] == 9000) {
  30.  
  31. [QTXNotificationCenter addObserver:self selector:@selector(paySucceed) name:QTXWXReturnSucceedPayNotification object:nil];
  32. } else {
  33.  
  34. [QTXNotificationCenter addObserver:self selector:@selector(payFailed) name:QTXWXReturnFailedPayNotification object:nil];
  35. }
  36. }];
  37.  
  38. }
  39.  
  40. } else {
  41. [MBProgressHUD showError:[NSString stringWithFormat:@"%@", json[@"errorMessage"]]];
  42. }
  43.  
  44. } failure:^(NSError *error) {
  45.  
  46. [MBProgressHUD showError:@"暂无网络,稍后再试"];
  47. QTXLog(@"支付宝支付返回参数接口 请求失败-%@", error);
  48. }];
  49.  
  50. }

11、支付宝集成失败相关问题

1. 报错 AL159

查看金额是否是两位小数,切不可拼接"元"

2. 报错“创建交易异常,请重新创建后再付款”

返回的状态码是“6001”,取消支付

当是用公司注册支付宝App时分配的商户账号登陆的支付宝,进行支付测试的。支付宝那边检测到是商户而不是普通的支付账号,商户支付给商户自己,所以支付失败!

三、其他补充

1、压缩文件截图

2、Alipay 包截图

目前是项目中直接操作, 在AlipayHeader.h文件里补充上你们项目的aliPartnerID, aliSellerAccount, aliNotifyURL, 具体可参考代码, 项目则能够直接运行!

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

iOS支付宝支付集成的更多相关文章

  1. iOS 支付宝支付集成获取私钥

    http://doc.open.alipay.com/doc2/apiList?docType=4 登录到支付宝开放平台,下载相关支付宝支付的demo.解压出来有3个文件夹.(服务端demo,客户端 ...

  2. ios 支付宝支付集成

    支付宝支付: 下载官方demo,把需要的framwork下载下来,在自己的工程中,新建文件夹,然后全部塞进去,到build phases中把需要的全部导入,其中xcode7以上需要多导入两个.a文件, ...

  3. 李洪强iOS开发支付集成之支付宝支付

    iOS开发支付集成之支付宝支付 下载支付宝SDK 首先是开发包下载,还是比较难发现的,网上以前文章中的链接都打不开,我找了好久才找到的.最新的地址在这里(注意的是下载出来的SDK包里面并没有传说中的开 ...

  4. 李洪强iOS开发支付集成之银联支付

    iOS开发支付集成之银联支付 银联官网在这里,这里能下载SDK或者是看文档.最新的版本写的简单了很多,看文档一直做下去基本上就没问题了. 首先,SDK在这里下载,里面包含需要的库文件和详细的文档. 银 ...

  5. 李洪强iOS开发支付集成之微信支付

    iOS开发支付集成之微信支付 微信支付也是需要签名的,也跟支付宝一样,可以在客户端签名,也可以在后台签名(当然,为了安全还是推荐在服务器上做签名,逻辑也比较好理解). 1 - 集成前首先要看看文档 开 ...

  6. iOS开发支付集成之微信支付

    这一篇是<iOS开发之支付>这一部分的继支付宝支付集成,银联支付集成第三篇,微信支付.在集成的时候建议都要去下载最新版的SDK,因为我知道的前不久支付宝,银联都更新了一次,微信的不太清楚更 ...

  7. iOS微信支付集成

    概述 iOS微信支付集成 详细 代码下载:http://www.demodashi.com/demo/10735.html 支付宝和微信都是业界的老大哥,相信大家都有所觉得文档.SDK都是各种坑吧(纯 ...

  8. iOS开发支付集成之支付宝支付

    项目中要用到支付功能,需要支付宝,微信,银联三大支付,所以打算总结一下,写两篇文章,方便以后的查阅, 大家在做的时候也能稍微参考下,用到的地方避免再次被坑.这是第二篇支付宝集成,第一篇银联支付在这里. ...

  9. Android最新版支付宝支付集成

    上次集成支付宝支付已经很久了,今天写东西用到了支付宝支付,就大致写一下流程: 去蚂蚁金服下载最新版的Android&IOS端SDK 全部文档 -- 资源下载 -- App支付客户端 下载后解压 ...

随机推荐

  1. waitdialogform z

    namespace DevExpress.Utils { using DevExpress.LookAndFeel; using DevExpress.Skins; using DevExpress. ...

  2. 栅栏加解密python实现(支持密钥加密)

    栅栏加解密是对较短字符串的一种处理方式.给定行数Row,依据字符串长度计算出列数Column,构成一个方阵. 加密过程:就是按列依次从上到下对明文进行排列,然后依照密钥对各行进行打乱.最后以行顺序从左 ...

  3. UIScrollView视差效果动画

    UIScrollView视差效果动画 效果 源码 https://github.com/YouXianMing/Animations // // ScrollImageViewController.m ...

  4. HTML常用标记

    HTML文档由4个主要标记组成,这4个标记是<html>.<head>.<title>和<body>.举例如下: <html> <he ...

  5. Mysql 监控 支持 mysql 多实例自动发现以及主从监控

    在[/usr/local/zabbix327/bin] 目录下新建python文件,并增加执行权限,如下: #!/usr/bin/env /usr/bin/python # _*_ coding:ut ...

  6. go语言之进阶篇面向对象编程

    1.面向对象编程 对于面向对象编程的支持Go 语言设计得非常简洁而优雅.因为, Go语言并没有沿袭传统面向对象编程中的诸多概念,比如继承(不支持继承,尽管匿名字段的内存布局和行为类似继承,但它并不是继 ...

  7. iOS开发-UIApplication和App启动状态

    UIApplication简单从字面上了解就是应用程序,开发的时候有的时候会根据需要调用其中的方法,看起来不起眼,实际在iOS开发UIApplication提供了iOS程序运行期间的控制和协作工作.每 ...

  8. 【架构】SpringCloud 注册中心、负载均衡、熔断器、调用监控、API网关示例

    示例代码: https://github.com/junneyang/springcloud-demo 参考资料: SpringCloud系列 Eureka 一句话概括下spring框架及spring ...

  9. MybatisGen1.0 Mybatis JavaBean Mapper生成工具

    MybatisGen 一:主要技术 1:apache commons dbutils 2:freemarker模板引擎 3:java(1.5+) 二:使用说明 1:配置文件是src/config.pr ...

  10. FM同步数据库中结构已经发生变化的表

    接触Cognos很久了,最近遇到一个小问题. 在FM模型设计的过程中,有一张表jd_f_order.之后为了更全面的分析这个数据,在这个事实表中引入了一个新的字段商品类型字段,结构如图 但是由于jd_ ...