支付宝App支付的一些问题
前言、
本文基于Hbuilder,使用mui、PHP进行开发
一、说明
最近做一个App支付的功能。大致流程是这样的:(官方文档有更详细的说明)
描述:
1.开始支付,发起签名申请(签名必须在服务器端进行)
2.服务器端接口返回签名后的订单信息
3.根据接口返回的订单签名信息,调用支付宝App进行支付
4.输入支付密码确认付款【无须操作】
5.支付后返回支付结果【无须操作】
6.商家App接到支付结果,然后传递给接口
7.接口中根据支付结果进行验签
8.接口中确认完成之后返回给商家App支付完成。
9.支付宝异步通知支付结果
10.接口新增处理异步支付结果 需要外网可访问的地址
其中1、3在自己的App中操作;2、9、10需要在服务器端进行;第六步我并没有进行操作,直接进入支付结果页面,在支付结果页面判断订单的支付状态
因为在支付成功的同时支付宝会立刻异步发送信息给服务器端,即第九步,然后我在这里处理了支付单和订单状态,这样6、7、8就不需要操作了,直接进入结果页判断就行了。
需要注意的是关于App的支付宝对接,有两个版本,一个是老版本(移动支付),一个是新版本(支付宝App支付)。有新版当然要用新版的了。
二、服务器端订单信息签名
可以使用支付宝给的sdk快速接入,App支付服务端DEMO&SDK,不嫌麻烦也可以自己写。。。。。
里面有demo,网上也很多。最终处理完之后,返回的是一个请求字符串,具体参数:请求参数说明
推荐GitHub上的PHP签名模板:支付宝App支付新版
生成的请求字符串:
app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22IQJZSRC1YMQB5HU%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http%3A%2F%2Fdomain.merchant.com%2Fpayment_notify&sign_type=RSA2×tamp=2016-08-25%2020%3A26%3A31&version=1.0&sign=cYmuUnKi5QdBsoZEAbMXVMmRWjsuUj%2By48A2DvWAVVBuYkiBj13CFDHu2vZQvmOfkjE0YqCUQE04kqm9Xg3tIX8tPeIGIFtsIyp%2FM45w1ZsDOiduBbduGfRo1XRsvAyVAv2hCrBLLrDI5Vi7uZZ77Lo5J0PpUUWwyQGt0M4cj8g%3D
三、根据签名拉起支付宝进行付款
HBuilder 基座已实现H5 plus的支付API,现已支持支付宝App支付(移动快捷支付)和微信支付。我们只需要在HBuilder中配置上就好了,具体配置查看: HBuilder支付插件配置
plus API使用步骤:
1. 调用plus.payment.getChannels()获取系统支持的支付通道
// 获取Hbuilder内置的支付通道 plus.payment.getChannels(function(channels){ for (var i in channels) { if (channels[i].id == "wxpay") { wxChannel=channels[i]; }else if(channels[i].id == "alipay"){ aliChannel=channels[i]; } } },function(e){ alert("获取支付通道失败:"+e.message); return 0; });
2. 调用plus.payment.request()发起支付请求。
//拉起支付 plus.payment.request(aliChannel,res.data.orderstr,function(result){ alert('支付成功'); console.log(JSON.stringify(result));//将会同步返回支付结果数据,根据自己需求进行处理,是否回传服务器 },function(error){ alert('支付失败'); console.log(JSON.stringify(error));//可查看状态码,失败信息 }); //说明:aliChannel是上面取到的对应内置支付通道信息,res.data.orderstr就是订单信息签名之后返回的请求字符串
四、异步接收支付通知
在用户输入密码并且成功支付的同时,支付宝就会发送异步数据到你设置的 notifyUrl 中,
这里还需要验证签名:
$aop = new AopClient; $aop->alipayrsaPublicKey = '请填写支付宝公钥,一行字符串'; $flag = $aop->rsaCheckV1($_POST, NULL, "RSA2");
AopClient类中的一个方法 rsaCheckV1()就完成解签,之后需要进行一系列数据验证就完成了。
五、出现的问题及问题排查办法
大部分问题:APP支付FAQ
关于:交易订单处理失败,请稍后再试 ALI38173 ,ALI38173出现肯定是因为(二)中的签名参数错误或签名格式,仔细检查对比参数:请求参数说明
我的错误是:最后生成的字符串用htmlspecialchars进行转义了,实际不需要转义,按照GitHub中的文档编写完全没有问题。
解决办法:复制官方文档中生成好的串,直接放在app中拉起支付,确认是服务器端还是App端出错。
附上一个错误排查方案:https://blog.csdn.net/sinat_32575213/article/details/79695142
六、结束
文中出现的链接:
/* 移动支付(老版):https://docs.open.alipay.com/59/104352/
支付宝App支付(新版):https://docs.open.alipay.com/204/105297/
App支付服务端DEMO&SDK:https://docs.open.alipay.com/54/106370
GitHub支付宝App支付新版(推荐):https://github.com/dcloudio/H5P.Server/tree/master/payment/alipayrsa2
订单签名参数说明:https://docs.open.alipay.com/204/105465/
HBuilder支付插件配置:http://ask.dcloud.net.cn/article/71 (这里面的支付宝的签名链接参数是老版本的,只看配置就ok)
APP支付FQA:https://support.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.JUPUDC&treeId=193&articleId=105849&docType=1#s8 */
其他文档:(只看上面的文档就足够了,下面文档有bug,仅供参考)
支付宝APP支付-php后台签名以及验签:https://blog.csdn.net/kunpeng1987/article/details/73649710
Dcloud中mui 微信支付和支付宝支付接口完美实现付款代码(PHP支付宝demo):https://www.erdangjiade.com/php/2475.html
支付宝官方文档,生成RSA密匙:https://docs.open.alipay.com/291/105971/