基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

时间:2023-01-21 22:26:51

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

上一篇 中详细说明了结合官方支付宝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中的值,开发者可以自行解析);

重要方法:

基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

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

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

同步返回的数据,对于商户在服务端没有收到异步通知的时候,可以依赖服务端对同步返回的结果来进行判断是否支付成功。同步返回的结果中,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="}

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

返回码也要注意了解一下

基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

在上一篇中的代码中,在  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字段的通知给商户。

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

基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

退款状态:

基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

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

注意事项:对订单信息的签名要放在服务器端,不要放在客户端,通知地址要使用安全的超文本传输协议 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&amp&semi;Demo下载地址)

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

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

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

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

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

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

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

  8. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  9. iOS开发之支付宝集成

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

随机推荐

  1. div&plus;css3绘制基本图形

    基本图形包括:矩形.圆角矩形.圆形.椭圆形.三角形.值线.弧 这些图形的绘制用到了CSS圆角属性,不考虑IE8. 下面的实现在chrome浏览器运行通过. 1.矩形 比较简单,通过CSS设置宽度.高度 ...

  2. Ubuntu14&period;04、win7双系统如何设置win7为默认启动项

    Ubuntu14.04.win7双系统如何设置win7为默认启动项 Ubuntu14.04.win7双系统设置win7为默认启动项方法: 在启动项选择菜单处记住windows 7对应的序号. 从上至下 ...

  3. php 中的&dollar;argv与&dollar;argc

    例如 php test.php as a joke print_r($argv); echo $argc; print_r($argv); array_shift($argv); echo $argc ...

  4. Chapter 21&lowbar;5&period;2 tab扩展

    在Lua中,像这样()的空白捕获具有特殊意义.表示捕获它在目标字符串中的位置,返回一个数字: print(string.match("hello","()ll()&quo ...

  5. 深度学习实践系列(2)- 搭建notMNIST的深度神经网络

    如果你希望系统性的了解神经网络,请参考零基础入门深度学习系列,下面我会粗略的介绍一下本文中实现神经网络需要了解的知识. 什么是深度神经网络? 神经网络包含三层:输入层(X).隐藏层和输出层:f(x) ...

  6. 通过T4模板实现代码自动生成

    1:准备.tt模板 using BBFJ.OA.IBLL; using BBFJ.OA.IDAL; using BBFJ.OA.Model; using System; using System.Co ...

  7. 解决ios safari中按钮圆角问题【原创】

       问题描述 使用html5编写页面在移动app中嵌套,总会涉及到按钮的使用,在android手机浏览器中显示正常,但在ios safari浏览器中会看到按钮显示为圆角样式,设置border-rad ...

  8. 将POST请求转换为DELETE、PUT等请求的方法

    一.在WEB工程的web.xml文件中配置HiddenHttpMethodFilter 二.form 表单中添加一个隐藏域 name="_method" value="D ...

  9. HDU 5127&period;Dogs&&num;39&semi; Candies-STL&lpar;vector&rpar;神奇的题,set过不了 &lpar;2014ACM&sol;ICPC亚洲区广州站-重现赛(感谢华工和北大)&rpar;

    周六周末组队训练赛. Dogs' Candies Time Limit: 30000/30000 MS (Java/Others)    Memory Limit: 512000/512000 K ( ...

  10. java类敏感词过滤类

    package com.fpx.pcs.prealert.process.service.impl; import java.util.HashMap;import java.util.HashSet ...