首先本篇为作者原创,仅供学习使用,以后会不断完善,精炼。阅读之前请参考  上一篇

上一篇 中详细说明了结合官方支付宝SDK,对工程环境进行的一些配置,实现了支付,本篇重点说明一下,注意事项和原理,主要作为自己的笔记使用,在这里分享给大家。

实现主要流程:

在支付宝 demo 中给出了签名的lib工具库,因为订单需要签名成一个字符串,然后交给支付接口,签名涉及到商户方的私钥,所以将这个签名的过程交给后台去完成,在调用支付宝支付接口前,我们把必要的参数传给后台服务器,然后服务器那边签名好后返回给我们签名后的字符串,我们传给支付宝SDK支付API就能唤起支付宝支付控件或者打开支付宝钱包进行支付了。参考

下面是一些解说,以及注意事项:

我的上篇笔记中,详细的说明了基于  手机控件支付开发包(IOS版)3.1.3 SDk的使用环境配置,我的Xcode是7.2版本。对于上一篇中有的地方我要做一些补充与说明:

在Appdelegate 中添加一个方法的说明

//添加方法

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{

[[AlipaySDK defaultService]

processOrderWithPaymentResult:url

standbyCallback:^(NSDictionary *resultDic) {

NSLog(@"result = %@",resultDic);//返回的支付结果 //【由于在跳转支付宝客户端支付的过程中,商户 app 在后台很可能被系统 kill 了,所以 pay 接 口的 callback 就会失效,请商户对 standbyCallback 返回的回调结果进行处理,就是在这个方法 里面处理跟 callback 一样的逻辑】

}];

return YES;

}

下面是一些请求参数,这里是Order类中的参数说明:

//下面的参数不可空

@property(nonatomic, copy) NSString * partner;            //签约的支付宝账号对应的支付宝唯一用户号。以2088开头的16位纯数字组成。

@property(nonatomic, copy) NSString * seller;             //卖家支付宝账号(邮箱或手机号码格式)或其对应的支付宝唯一用户号(以2088开头的纯16位数字)。

@property(nonatomic, copy) NSString * tradeNO;            //商户网站唯一订单号

@property(nonatomic, copy) NSString * productName;        //商品的标题

@property(nonatomic, copy) NSString * productDescription; //商品的描述

@property(nonatomic, copy) NSString * amount;             //总金额  该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。

@property(nonatomic, copy) NSString * notifyURL;          //服务器异步通知页面路径 支付宝服务器主动通知商户网站里指定的页面http路径

//以下的信息是支付的基本的配置信息(固定不变)

@property(nonatomic, copy) NSString * service;            //借口名称、不可空

@property(nonatomic, copy) NSString * paymentType;        //支付类型。默认值为:1(商品购买)。

@property(nonatomic, copy) NSString * inputCharset;       //参数编码字符集 商户网站使用的编码格式,固定为utf-8。

@property(nonatomic, copy) NSString * itBPay;             //未付款交易的超时时间 设置未付款交易的超时时间,一旦超时,该笔交易就会自动被关闭。当用户输入支付密码、点击确认付款后(即创建支付宝交易后)开始计时。取值范围:1m~15d,或者使用绝对时间(示例格式:2014-06-13 16:00:00)。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。该参数数值不接受小数点,如1.5h,可转换为90m。

@property(nonatomic, copy) NSString * showUrl;            //

//下面的参数是可空的

@property(nonatomic, copy) NSString * rsaDate;            //

@property(nonatomic, copy) NSString * appID;              //客户端号  标识客户端。

@property(nonatomic, readonly) NSMutableDictionary * extraParams;

注意:

(1)对于上面的一些属性是支付宝官网demo中的Order.h类中声明的,我们也可以在我们的订单类中声明一些自己产品相关的其他的属性字段,但是一定不能给支付宝业务逻辑中定义的不可空属性字段重名,参考  业务字段有 { service、partner、_input_charset、sign_type、sign、notify_url、app_id、appenv、out_trade_no、subject、payment_type、seller_id、total_fee、body、goods_type、rn_check、it_b_pay、extern_token、out_context }

(2)此外不要在要拼接的参数中加入其他的key用& 连接,支付宝建议不要在请求参数中附带和支付无关的业务系统自身的key相关数据。

(3)商户的请求参数中,所有的key(支付宝关键key或者商户自己的key),其对应的value中都不应该出现支付宝关键key。

使用支付宝的步骤:

首先商户注册得到Partner 商户ID ,seller 账户ID,商户根据自己的商户ID登陆商网,获取自己的私钥和公钥,然后下载SDK,配置好使用环境,最后由程序生成订单信息,调用支付宝支付。下面是官方文档的说法:

  • 构造订单数据并签名
  • 商户客户端根据手机支付宝支付开发包的接口规则,通过程序生成得到签名结果及要传输给手机支付宝支付开发包的数据集合。
  • 发送请求数据
  • 把构造完成的数据集合传递给手机支付宝支付开发包。
  • 手机支付宝支付开发包对请求数据进行处理
  • 手机支付宝支付开发包将请求数据根据业务规则包装后传递给支付宝服务端,服务端得到这些集合后,会先进行安全校验等验证,一系列验证通过后便会处理完成这次发送过来的数据请求。
  • 返回处理的结果数据
  • 对于处理完成的交易,支付宝会以两种方式把数据分别反馈给商户应用和商户服务器。
    • 在手机客户端上,开发包客户端直接把处理的数据结果反馈给商户客户端;
    • 支付宝服务器主动发起通知,调用商户在请求时设定好的页面路径(参数notify_url,如果商户没设定,则不会进行该操作)。
  • 对获取的返回结果数据进行处理
  • 商户在客户端同步通知接收模块或服务端异步通知接收模块获取支付宝返回的结果数据后,可以结合商户自身业务逻辑进行数据处理(如:订单更新、自动充值到会员账号中等)。同步通知结果仅用于结果展示,入库数据需以异步通知为准。

使用支付宝在完成支付后,采用同步通知客户端处理结果,异步主动通知商品集合参数中早已设定好的回调服务器。

注意* 处理客户端回调的方法必须实现,否则会导致在安装有手机支付宝的情况下,支付完毕后无法正常同步返回支付结果。

支付结果的提取,必须通过CompletionBlock获取,禁止开发者私自解析支付结果返回的URL。获取值的Key对应resultStatus、memo与result(result中的值,开发者可以自行解析);

重要方法:

下面的是一些重要的信息,是在支付宝完成支付后的注意事项:

支付宝对商户的请求数据处理完成后,会将处理的结果数据直接通知给商户。这些处理结果数据就是同步通知参数。

同步返回的数据,对于商户在服务端没有收到异步通知的时候,可以依赖服务端对同步返回的结果来进行判断是否支付成功。同步返回的结果中,sign字段描述了请求的原始数据和服务端支付的状态一起拼接的签名信息。验证这个过程包括两个部分:1、原始数据是否跟商户请求支付的原始数据一致(必须验证这个);2、验证这个签名是否能通过。上述1、2通过后,在sign字段中success=true才是可信的。【特别注意,同步结果校验的逻辑,必须放在服务端处理,切记不要放在客户端】【强烈建议商户直接依赖服务端的异步通知,忽略同步返回】

上面仅仅是针对签约 mobile.securitypay.pay 这个服务业务,适用于上面的规则,如果是网页浏览器接入则建议走异步通知方式。

支付结果的返回码实例:

ResultStatus={};memo={};result={partner=""&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"&notify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type=""&_input_charset="utf-8"&it_b_pay="30m"&success="true"&sign_type="RSA"&sign="hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZgSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU="}

返回支付结果,处理逻辑要在商户服务器里处理

返回码也要注意了解一下

在上一篇中的代码中,在  NSString *orderSpec = [order description];  id<DataSigner> signer = CreateRSADataSigner(privateKey);NSString *signedString = [signer signString:orderSpec];对订单信息加密之前需要对 待签名参数集合 进行排序,并且去除 sign、sign_type 两个关键字、待组装的参数中不能有空的 value .参考订单签名规则

对商户的请求数据处理完成后,会将处理的结果数据通过服务器主动通知的方式通知给商户网站。这些处理结果数据就是服务器异步通知参数。

关于返回参数请参考

异步通知商户服务器,是服务器之间的交流,不能像同步通知那样可见。支付宝服务器是使用POST方式向商户服务器发送包含处理结果的通知,商户得到这些信息后必须给支付宝服务器反馈一个7个字符的字符串success,如果商户程序中没有打印出,支付宝服务器会不停地发送异步通知,默认时间是24h22m,一般25小时以内完成8次通知(通知的间隔频率一般是:2m,10m,10m,1h,2h,6h,15h)。

支付宝处理完成支付之后,会将处理结果返回给商户,商户获得返回结果,必须验证签名,验证签名是否是支付宝发来的通知,需要调用走支付宝的通知验证接口(notify_verify) 参考 调用后直接回调两种结果,成功(true)和不成功(对应的错误)。商户注意需要验证处理结果中的一些信息:

商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,并判断total_fee是否确实为该订单的实际金额(即商户订单创建时的金额),同时需要校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),上述有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。 如果商户需要对同步返回的数据做验签,必须通过服务端的签名验签代码逻辑来实现。如果商户未正确处理业务通知,存在潜在的风险,商户自行承担因此而产生的所有损失。

注意:

  • 交易状态TRADE_SUCCESS的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;
  • 交易状态TRADE_FINISHED的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限;
  • 交易成功之后,商户(高级即时到账或机票平台商)可调用批量退款接口,系统会发送退款通知给商户,具体内容请参见批量退款接口文档;
  • 当商户使用站内退款时,系统会发送包含refund_status和gmt_refund字段的通知给商户。

通知交易状态有必要也做一下了解:

退款状态:

关于不可意退款的移动快捷支付:参考

注意事项:对订单信息的签名要放在服务器端,不要放在客户端,通知地址要使用安全的超文本传输协议 https 不要使用 http 协议。要能够保证在客户端没有安装支付宝App 的情况下客户也能够完成支付。

(Over 接上一篇

基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)的更多相关文章

  1. 基于微信的SDK的学习与使用——实现产品支付

    声明本篇博客为作者原创,本篇是继支付宝支付之后本人又学习的第二种支付实现,本篇着重于原理与注意事项的学习. 参考  参考 微信支付的开发文档相比支付宝的比较简单,但是使用功能丝毫也不含糊,我觉得简单易 ...

  2. Cordova webapp实战开发:(6)如何写一个iOS下获取APP版本号的插件?

    上一篇我们学习了如何写一个Andorid下自动更新的插件,我想还有一部分看本系列blog的开发人员希望学习在iOS下如何做插件的吧,那么今天你就可以来看看这篇文字了. 本次练习你能学到的 学习如何获取 ...

  3. IOS --支付宝SDK 分解讲解

    开发在手机端的时候(客户端),我们主要负责客户端(手机端)的开发,所以那些繁琐的到支付宝官网填写商户信息可以留给后台去弄,后台只要把: 1回调地址, 2app的ID, 3商户的私钥(privateKe ...

  4. iOS app支付宝接口调用的一点总结(补充支付宝SDK&Demo下载地址)

    由于app内需要用到支付功能,选择了当前最流行的支付宝进行支付.在进行内嵌支付宝功能开发时,被它狠狠的耍了一把. 根据支付宝开发文档,参考demo代码.将相关支付功能加到了自己的代码中.一些根据文档来 ...

  5. 转:iOS app支付宝接口调用的一点总结(补充支付宝SDK&Demo下载地址)

    iosiOSIOS文档服务器测试电话 由于app内需要用到支付功能,选择了当前最流行的支付宝进行支付.在进行内嵌支付宝功能开发时,被它狠狠的耍了一把. 根据支付宝开发文档,参考demo代码.将相关支付 ...

  6. iOS开发——高级篇——如何集成支付宝SDK

    一.什么是支付宝 第三方支付平台 和内购非常相似内购是用户将钱付款给苹果,之后苹果分成给商户支付宝是用户将钱付款给支付宝,之后支付宝将钱转入我们的账户 使用支付宝前提购买的物品必须是和应用程序无关的. ...

  7. Django学习——Django测试环境搭建、单表查询关键字、神奇的双下划线查询(范围查询)、图书管理系统表设计、外键字段操作、跨表查询理论、基于对象的跨表查询、基于双下划线的跨表查询

    Django测试环境搭建 ps: 1.pycharm连接数据库都需要提前下载对应的驱动 2.自带的sqlite3对日期格式数据不敏感 如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3 ...

  8. Django学习——图书相关表关系建立、基于双下划线的跨表查询、聚合查询、分组查询、F查询、Q查询、admin的使用、使用脚本调用Django、Django查看源生sql

    0 图书相关表关系建立 1.5个表 2.书籍表,作者表,作者详情表(垂直分表),出版社表,书籍和作者表(多对多关系) 一对一 多对多 本质都是一对多 外键关系 3.一对一的关系,关联字段可以写在任意一 ...

  9. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

随机推荐

  1. iOS 私有库的使用

    最近项目说要用私有库 主要过程 创建两个库:  索引库   组件库 组件库  用git操作  比如更新代码 push   打tag等 索引库  存放组件的描述信息 也就是 .spec文件 这个文件和 ...

  2. H5实现多图片预览上传,可点击可拖拽控件介绍

    版权声明:欢迎转载,请注明出处:http://blog.csdn.net/weixin_36380516 在做图片上传时发现一个蛮好用的控件,支持多张图片同时上传,可以点击选择图片,也可以将图片拖拽到 ...

  3. VS2012+Win7站点公布具体步骤

    VS2012+Win7站点公布详细步骤 本机环境: 本文分三个部分介绍Web项目公布的常规方法,大神级别能够略过,主要是为了方便一些刚開始学习的人. 第一部分:VS2012把项目公布到文件系统. 第二 ...

  4. 如何与强势的人相处zz

    要和强势的人相处良好,须知道强势的人有两个很显著的特点:一.以自我观点为中心.二.怕别人否定自己.强势的主要作用也有两个:一.支配别人.二.掩盖自卑. 首先,要区分一下强势的人和特立独行的人,这两类人 ...

  5. [Phoenix] 四、加盐表

    摘要: 在密码学中,加盐是指在散列之前将散列内容(例如:密码)的任意固定位置插入特定的字符串.这个在散列中加入字符串的方式称为“加盐”.其作用是让加盐后的散列结果和没有加盐的结果不相同,在不同的应用情 ...

  6. Grid++Report设置显示固定行数

    一.要实现的功能打印的报表显示固定的行数,并且设置字段的文字可以自动换行二.设置步骤1.鼠标左键单击“明细网格”栏,在右侧属性窗口中设置“追加空白行”属性值为:是:“追加空白行在后”属性值为:是.2. ...

  7. mybatis入门(四)

    mybatis入门 需求:根据id查询用户的信息 mysql数据库: CREATE TABLE `user` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `us ...

  8. android——array中设置选项

    Android中,R.array是提取XML资源文件中String数组的方法.具体定义和提取的方法如下: 1)在R.array中定义字符数组 <?xml version="1.0&qu ...

  9. Gym - 100187A A - Potion of Immortality —— 贪心

    题目链接:http://codeforces.com/gym/100187/problem/A 题解: 光题意就想了很久:在最坏情况下的最小兔子数.其实就是至少用几只兔子就一定能找出仙药(答案存在的话 ...

  10. 转:Windows下WSH/JS实现SVN服务器钩子脚本阻止提交空日志信息和垃圾文件

    http://blog.csdn.net/caikanxp/article/details/8279921 如何强制用户在提交SVN时填写日志信息? 如果用户使用的都是TortoiseSVN客户端,可 ...