首先,郑重的说明一下,本人是纯服务端开发人员,不懂安卓和ios开发,在实际开发配合中,也只负责给安卓和ios的同事提供服务端调取的接口以及处理支付宝的异步回调。所以这篇文章只是介绍服务端的开发过程,不会涉及到安卓和ios客户端的处理过程,如果你只想了解客户端处理过程,可以不用往下看了,goodbye!!!
在看这篇文章之前,希望你先看上一篇文章支付宝支付(一)—H5手机网站支付2.0(alipay.trade.wap.pay) ,涉及到的部分准备工作这里就不再重复了,有疑问的看上一篇文章或者查阅官方文档。
一、APP支付产品介绍
APP支付适用于商家在 App 应用中集成支付宝支付功能。 商家APP调用支付宝提供的 SDK,SDK 再调用支付宝APP内的支付模块。
注意:如果用户已安装支付宝 APP,商家 APP 会跳转到支付宝中完成支付,支付完后跳回到商家APP内,最后展示支付结果。如果用户没有安装支付宝 APP,商家 APP 内会调起支付宝网页支付收银台,用户登录支付宝账户,支付完后展示支付结果。 目前支持手机系统有:iOS(苹果)、Android(安卓)。
1、应用场景
(1)用户已安装支付宝支付流程
步骤1:用户在商家 App 中选择商品下单、确认购买,进入支付环节,选择支付宝,用户点击确认支付,如图1;
步骤2:进入到支付宝页面,调起支付宝支付,出现确认支付界面,如图2;
步骤3:用户确认收款方和金额,点击立即支付后出现输入密码界面,如图3;
步骤4:输入正确密码后,支付宝端显示支付结果,如图 4; 5.自动回跳到商家 App 中,商家根据付款结果个性化展示订单处理结果,如图 5。
(2)用户未安装支付宝支付流程
步骤1:用户在商家 App 中选择商品下单、确认购买,进入支付环节,选择支付宝,用户点击确认支付,如图 6;
步骤2:用户未安装支付宝客户端,则调起支付宝网页支付收银台,用户登录支付宝账户,如图 7;
步骤3:登录成功后,进入确认付款页面,如图 8;
步骤4:用户点击确认付款,进入支付密码页面,如下图 9; 5.用户输入密码,完成支付,展示支付结果,如图 10。
例如我们常用的饿了么 app、优酷 app、携程 app。
2、准入条件
-
申请前必须拥有经过实名认证的支付宝账户;
-
企业或个体工商户可申请;
-
需提供真实有效的营业执照,且支付宝账户名称需与营业执照主体一致;
-
网站能正常访问且页面显示完整,网站需要明确经营内容且有完整的商品信息;
-
网站必须通过ICP备案。如为个体工商户,网站备案主体需要与支付宝账户主体名称一致;
-
如为个体工商户,则团购不开放,且古玩、珠宝等奢侈品、投资类行业无法申请本产品。
3、计费模式
-
费率按单笔计算;
-
一般行业费率:0.6%;自2018年5月9日起,特殊行业新签约费率从 1.2% 调整为 1%,特殊行业范围包括:休闲游戏;网络游戏点卡、渠道代理;游戏系统商;网游周边服务、交易平台; 网游运营商(含网页游戏)。
4、使用说明
APP支付产品包含的接口和描述如下:
API英文名 | API中文名 | 完整文档 |
alipay.trade.query | 交易查询接口 | 查看文档 |
alipay.trade.close | 交易关闭接口 | 查看文档 |
alipay.trade.refund | 交易退款接口 | 查看文档 |
alipay.trade.fastpay.refund.query | 交易退款查询接口 | 查看文档 |
alipay.trade.app.pay | app 支付接口 2.0 | 查看文档 |
alipay.data.dataservice.bill.downloadurl.query | 查询账单下载地址接口 | 查看文档 |
二、准备工作
还是先上官方文档入口
前四个步骤这里就不再重复了,有兴趣有疑问的查看上一篇文章支付宝支付(一)—H5手机网站支付2.0(alipay.trade.wap.pay)
1、创建应用并获取APPID
2、配置应用环境
3、配置沙箱环境
4、服务端实现(集成并且配置SDK)
5、调用接口
为了避免在线上生产环境联调过程中遇到问题,建议在沙箱环境中联调通过后再在线上生产环境进行联调,具体操作步骤见 沙箱联调指南。如果需要在线上调用接口,需要参考下面步骤:应用上线后再进行接口调用,不然会出现“无权限错误”的报错信息。
系统交互流程如下图所示:
以 Android 平台为例: 图中虚线标识商户链路,实线标识支付宝链路。
-
第4步调用支付接口:此消息就是本接口所描述的支付宝客户端SDK提供的支付对象 PayTask,将商户签名后的订单信息传进 payv2 方法唤起支付宝收银台,交易数据格式具体参见请求参数说明。
-
第5步支付请求:支付宝客户端 SDK 将会按照商户客户端提供的请求参数发送支付请求。
-
第8步接口返回支付结果:商户客户端在第4步中调用的支付接口,会返回最终的支付结果(即同步通知),参见客户端同步返回。
-
第13步用户在支付宝 APP 或 H5 收银台完成支付后,会根据商户在手机网站支付 API 中传入的前台回跳地址 return_url 自动跳转回商户页面,同时在 URL 请求中附带上支付结果参数。同时,支付宝还会根据原始支付 API 中传入的异步通知地址 notify_url,通过 POST 请求的形式将支付结果作为参数通知到商户系统,详情见支付结果异步通知。
除了正向支付流程外,支付宝也提供交易查询、关闭、退款、退款查询以及对账等配套 API。
特别注意:
-
构造交易数据并签名必须在商户服务端完成,商户的应用私钥绝对不能保存在商户 APP 客户端中,也不能从服务端下发。
-
同步返回的数据,只是一个简单的结果通知,商户确定该笔交易付款是否成功需要依赖服务端收到支付宝异步通知的结果进行判断。
-
商户系统接收到通知以后,必须通过验签(验证通知中的 sign 参数)来确保支付通知是由支付宝发送的。建议使用支付宝提供的 SDK 来完成,详细验签规则参考异步通知验签。
三、服务端具体封装和操作过程
前三个步骤这里就不再重复了,有兴趣有疑问的查看上一篇文章支付宝支付(一)—H5手机网站支付2.0(alipay.trade.wap.pay)
1、将支付宝通用参数独立配置在一个属性文件中方便管理
2、读取配置文件信息
3、加载接入参数并初始化AlipayClient
4、利用sdk封装app支付代码
通用模块,就在demo里面的 AliPayUtil.java 里面
/** * alipay.trade.app.pay:原生手机APP支付测试(外部商户APP唤起快捷SDK创建订单并支付) * @param alipayInfo * @return */ public static String alipayTradeAppPay(String out_trade_no, String total_amount){ try { //(1)封装bizmodel信息 AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); model.setOutTradeNo(out_trade_no); model.setSubject("支付宝APP支付"); model.setBody("支付宝APP支付"); model.setProductCode("QUICK_MSECURITY_PAY"); model.setTotalAmount(total_amount); model.setTimeoutExpress(staticAliPayProperties.getAli_timeout_express()); //(2)设置请求参数 //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest(); alipayRequest.setNotifyUrl(staticAliPayProperties.getAli_notify_url()); alipayRequest.setBizModel(model); //(3)请求 //这里和普通的接口调用不同,使用的是sdkExecute String form = alipayClient.sdkExecute(alipayRequest).getBody(); System.out.println("********************* 返回结果为:"+form); return form; } catch (AlipayApiException e) { e.printStackTrace(); return null; } }
APP支付、PC电脑网站支付和H5手机网站支付的区别重点看我标黄部分
5、模拟支付请求
步骤1:控制层 AliPayController.java 写请求方法 alipayTradeAppPay
步骤2:调取的接口和实现类
注意:
(1)这里我随机生成了商户订单号 out_trade_no,交易金额 total_amount 写死了,正常业务处理中,我们是根据你的业务实际情况处理
(2)里面涉及到的其他的工具类,最后的demo里面会提供。当然,你也可以自己随机商城,保持不重复的原则即可
(3)实际操作中,在调取之前,我们需要处理具体的业务逻辑,因为本文只总结支付宝相关的,就不补充了。例如:订单金额计算处理;商户订单和支付宝订单的关联和存储,商户订单和支付宝订单可能是多对一的关系;支付宝订单需要保存,因为在回调的时候你需要根据支付宝订单的 out_trade_no 识别支付宝通知的订单结果;你可以把它存储在redis或者持久化到数据库中。
步骤3:模拟支付请求
这里,我是写了一个html页面,通过前端请求到后台调取控制层方法模拟实际支付请求的
注意:因为本人只是服务端开发人员,并不懂安卓和ios原生开发,所以这里我只是模拟告诉你了服务端的调取过程。在实际开发过程中,我提供了该服务端的接口给了安卓和ios开发的同事,他们拿到我返回的支付宝调取结果之后直接调取原生的sdk就ok了。也就是说针对我们服务端人员来说,我们只需要给他们提供一个调取接口,返回支付宝的服务端调取结果给他们,然后处理好支付的同步和异步回调通知就完全ok了。
6、运行查看测试结果
点击“原生手机APP支付”按钮,其他按钮功能开发后面有时间会发博文介绍,不过demo里面已经有了,你也可以自己先测试,请求后控制台日志显示
详细调取内容如下:
alipay_sdk=alipay-sdk-java-3.3.87.ALL&app_id=2021000116673834&biz_content=%7B%22body%22%3A%22%E6%94%AF%E4%BB%98%E5%AE%9DAPP%E6%94%AF%E4%BB%98%22%2C%22out_trade_no%22%3A%2220200810180747519478446%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3A%22%E6%94%AF%E4%BB%98%E5%AE%9DAPP%E6%94%AF%E4%BB%98%22%2C%22timeout_express%22%3A%2230m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Ftrt.wgzvip.com%2Fapi%2FaliReturnPay%2FreturnPayAsynchronous&sign=F1BTreBDeHs%2FYtrmh9FfjzOloaSGxy0lkolmCyXWr6HxJRBELjcoBe6l3zbwsEkDTfCeHYnd9G%2Bll0PFrefwy0OIiAmJQLja6tQznBsmX2CgMgIPlFUYnZaY1MluBjeeux%2BTwV16UUQX%2BTavKexwwOSXHxYNq49Jh18WPa1%2FicqlkcSe2VAI%2FI30Oe0r4z2yE067NonwyUOmvq8KljpFGveqXAtVH0akYmYvdq6oGJdIVM1sA2NXZKtPl9q7ZHjhGouOLzuoqRg2ttIjanv3rpw7WZxn7bbTfjwxE1gBfWhUWI87H3GvlIVFSYpDmeRNYYyTxqLhXeg89m449fVG4A%3D%3D&sign_type=RSA2×tamp=2020-08-10+18%3A07%3A47&version=1.0
我们可以很清楚的看到,支付宝返回的不再是一个form表单的内容,我们只需要将该结果返给原生APP开发的同事就ok了。
我们看一下我们之前在js里面模拟调取接口的返回结果,如下:
{ "msg": "操作成功", "code": "code_999999", "data": "alipay_sdk=alipay-sdk-java-3.3.87.ALL&app_id=2021000116673834&biz_content=%7B%22body%22%3A%22%E6%94%AF%E4%BB%98%E5%AE%9DAPP%E6%94%AF%E4%BB%98%22%2C%22out_trade_no%22%3A%2220200810180747519478446%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3A%22%E6%94%AF%E4%BB%98%E5%AE%9DAPP%E6%94%AF%E4%BB%98%22%2C%22timeout_express%22%3A%2230m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Ftrt.wgzvip.com%2Fapi%2FaliReturnPay%2FreturnPayAsynchronous&sign=F1BTreBDeHs%2FYtrmh9FfjzOloaSGxy0lkolmCyXWr6HxJRBELjcoBe6l3zbwsEkDTfCeHYnd9G%2Bll0PFrefwy0OIiAmJQLja6tQznBsmX2CgMgIPlFUYnZaY1MluBjeeux%2BTwV16UUQX%2BTavKexwwOSXHxYNq49Jh18WPa1%2FicqlkcSe2VAI%2FI30Oe0r4z2yE067NonwyUOmvq8KljpFGveqXAtVH0akYmYvdq6oGJdIVM1sA2NXZKtPl9q7ZHjhGouOLzuoqRg2ttIjanv3rpw7WZxn7bbTfjwxE1gBfWhUWI87H3GvlIVFSYpDmeRNYYyTxqLhXeg89m449fVG4A%3D%3D&sign_type=RSA2×tamp=2020-08-10+18%3A07%3A47&version=1.0", "success": true }
也就是说原生的同事调取该接口后,只要把data的结果拿去调取他们自己的sdk就行了
四、同异步结果处理
这部分的异步回调设置和处理与H5手机网站支付一样,不再重复啰嗦了,有疑问的查看上一篇文章支付宝支付(一)—H5手机网站支付2.0(alipay.trade.wap.pay)
注意:APP支付中同步回调不再需要服务端设置了,为什么不需要你自己好好想想就知道了,我服务端怎么可能能决定你的手机APP跳转的页面,这个需要客户端自己处理,安卓和ios的客户端人员他们自己的sdk可以接收到支付宝的同步通知,他们自己处理就ok了,不需要我们操心,我们只需要处理好异步通知结果就行了,最终的支付结果以支付宝异步通知和服务端主动查询支付宝订单结果为准。
五、demo示例下载
查看上一篇文章支付宝支付(一)—H5手机网站支付2.0(alipay.trade.wap.pay)
最后附上官方提供的常见问题参考答案:https://opensupport.alipay.com/support/helpcenter/89