前段时间项目需要接入支付宝支付,这份任务被分配到我来完成,折腾了好几天(主要是因为我菜),现在有时间来记录一下整个过程。
整个工作分为以下几步。
一. 登录并创建应用
首先到支付宝开放平台登录要接通支付的支付宝账号,登录之后看到如下页面
点击"网页&移动应用"进行应用创建,创建完成之后到我的应用查看你新创建的应用,会看到应用的唯一编号(APPID)
二. 配置你的应用
1. 为你的应用添加功能
可以根据你的接入需求选择你要添加的功能,我这里添加的是APP支付(这里面的大部分功能都是需要签约的),这里是签约说明
2. 配置密钥
为了保证交易双方(商户和支付宝)的身份和数据安全,开发者在调用接口前,需要配置双方密钥,对交易数据进行双方校验。RSA
密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后,开发者需要在开放平台开发者中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)
支付宝开发平台提供了密钥的生成工具,自行下载使用
点击"生成密钥"即可.
然后进入自己新建的应用进行配置
如下图一样填入你的应用公钥
配置完成后会获得"支付宝公钥"(ALIPAY_PUBLIC_KEY)
三. 集成与开发
接入移动支付需要集成两个 SDK:客户端 SDK 需要集成在商户自己的 APP 中,用于唤起支付宝 APP
并发送交易数据,并在支付宝APP返回商户APP时获得支付结果;服务端SDK需要商户集成在自己的服务端系统中,用于协助解析并验证客户端同步返回的支付结果和异步通知。
官方文档集成和开发
四. 调用接口
为了避免在线上生产环境联调过程中遇到问题,建议在沙箱环境中联调通过后再在线上生产环境进行联调,具体操作步骤见沙箱联调指南。如果需要在线上调用接口,需要参考下面步骤:应用上线后再进行接口调用,不然会出现“无权限错误”的报错信息。
系统交互流程如下图所示:
以 Android 平台为例:
图中虚线标识商户链路,实线标识支付宝链路。第4步调用支付接口:此消息就是本接口所描述的支付宝客户端SDK提供的支付对象 PayTask,将商户签名后的订单信息传进 payv2
方法唤起支付宝收银台,交易数据格式具体参见请求参数说明。第5步支付请求:支付宝客户端 SDK 将会按照商户客户端提供的请求参数发送支付请求。
第8步接口返回支付结果:商户客户端在第4步中调用的支付接口,会返回最终的支付结果(即同步通知),参见客户端同步返回。
第13步用户在支付宝 APP 或 H5 收银台完成支付后,会根据商户在手机网站支付 API 中传入的前台回跳地址 return_url
自动跳转回商户页面,同时在 URL 请求中附带上支付结果参数。同时,支付宝还会根据原始支付 API 中传入的异步通知地址
notify_url,通过 POST 请求的形式将支付结果作为参数通知到商户系统,详情见支付结果异步通知。除了正向支付流程外,支付宝也提供交易查询、关闭、退款、退款查询以及对账等配套 API。
特别注意:
构造交易数据并签名必须在商户服务端完成,商户的应用私钥绝对不能保存在商户 APP 客户端中,也不能从服务端下发。
同步返回的数据,只是一个简单的结果通知,商户确定该笔交易付款是否成功需要依赖服务端收到支付宝异步通知的结果进行判断。
商户系统接收到通知以后,必须通过验签(验证通知中的 sign 参数)来确保支付通知是由支付宝发送的。建议使用支付宝提供的 SDK
来完成,详细验签规则参考异步通知验签。使用SDK快速接入
App支付 API 必须通过支付宝提供的移动端 SDK 来调用。
交易操作
外部商户APP唤起快捷SDK创建订单并支付,具体的接口参数和示例代码可详见alipay.trade.app.pay(app支付接口2.0)
以下大致记录针对alipay.trade.app.pay接口的代码:
服务端
1.APP客户端点击"支付"调用应用服务端,应用服务端通过alipay.trade.app.pay接口传入订单参数
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_con