发表时间:2022-03-24来源:网络
不管是支付宝支付,还是微信支付,还是银联支付等,大部分的支付流程都是相似的,学会了其中的思想,那么其他支付方式也就很简单了。
1、A网站以POST请求方式提交参数给支付宝接口,在支付宝端进行支付处理。
POST请求方式一定程度下保证了安全性,即在url上看不到参数,但可以在浏览器开发者工具中可以看到参数,为防止篡改,则可以采用一些加密协议,如:https、加签名、加密手段(MD5加盐、base64、DES、sha1)等。
在加密中又可以分为对称加密(base64、des等)与非对称加密(RSA公钥与私钥的互换)。
那么在支付宝中主要使用什么方式进行加密呢? 加签名和RSA非对称加密。
2、在支付宝接口中,把支付的结果通知给A网站(成功/失败),以便更新订单的状态信息。
那么支付宝怎么把支付结果返回给A网站呢?有两种通知/回调方式:1、同步通知(同步回调) 2、异步通知(异步回调)
同步通知:当A网站以post请求方式将参数提交给支付宝接口,支付宝会返回同步通知给A网站,意味着A网站需要提供一个接口给支付宝,而同步通知实际上是:本地浏览器的重定向操作,告知A网站支付成功还是失败,不做订单状态的更改。
异步通知:为了安全性考虑,一般需要进行订单状态的更改时,使用异步通知,即支付宝服务器使用httpclient技术调用A网站的接口进行通知,A网站解析报文,判断到底是支付成功还是支付失败。异步通知包含补偿机制,即:支付宝把结果异步通知给A网站,若A网站未及时响应给支付宝,则支付宝会进行补偿重发,类似与MQ。所以在网络存在延迟的情况下,需要解决支付回调的幂等性问题,解决方式跟MQ很相似——使用全局ID。
简而言之:
回调方式:同步回调、异步回调
回调场景: 告诉商户支付通知结果
同步回调: 整个支付流程完毕,使用同步方式将参数重定向给商户平台,一般场景用于展示结果。
异步回调: 第三方支付接口发一个后台通知给商户平台,一般场景用户修改订单信息。
在支付环境可能产生的问题:
安全性问题、支付回调的幂等性问题(如充值1毛钱,可以购买500元的商品漏洞——html篡改数据),分布式事务问题(解决数据的双方一致性问题,因为A网站和支付宝并不使用同一个数据库),若A网站不能及时收到支付宝的异步通知,则支付宝会重试补偿,则应该在A网站内做幂等性判断即可。
使用支付宝沙箱:https://openhome.alipay.com/platform/appDaily.htm
初次访问需要进行认证,选择自研开发者:
认证成功后进入沙箱环境,下载JAVA版本的SDK&Demo https://docs.open.alipay.com/270/106291/
下载后导入Demo到Eclipse(plus:貌似Demo并不是一个Maven工程)
导入后修改AlipayConfig.java文件(app_id、RSA2、公钥,测试环境下修改网关等信息)
在支付领域,数据安全肯定是首要的任务,加密种类可分为:单向加密、对称加密、非对称加密。
最安全的肯定是RSA:公钥与私钥的互换,效率不如单向加密和对称加密高,但安全性很好,要想破解,必须知道公钥和私钥两把密钥,属于非对称加密。
单向加密:如MD5、SHA等不可逆【不能解密,只能加密】,主要用来验证数据传输的过程中,是否被篡改过。
对称加密:一方通过密钥将信息加密后,把密文传给另一方,另一方通过这个相同的密钥将密文解密,转换成可以理解的明文。
明文 密钥 密文 【可以加密,又可以解密】
常用对称加密方案 DES、AES、Base64
非对称加密:在支付领域一般都使用RSA非对称加密。在通信双方,如果使用非对称加密,一般遵从这样的原则:公钥加密,私钥解密。同时,一般一个密钥加密,另一个密钥就可以解密。
因为公钥是公开的,如果用来解密,那么就很容易被人解密消息。因此,私钥也可以认为是个人身份的证明。
如果通信双方需要互发消息,那么应该建立两套非对称加密的机制(即两对公私钥密钥对),发消息的一方使用对方的公钥进行加密,接收消息的一方使用自己的私钥解密。
每个人生成一个“私钥-公钥”对,这个私钥需要每个人自行进行保护!公钥可以随便分享,后面详细说,同时,生成的这个“私钥-公钥”对还有个强大的功能就是,使用私钥加密的信息,只能由该私钥对应的公钥才能解密,使用公钥加密的信息,只能由该公钥对应的私钥才能解密!
初次使用支付宝沙箱环境,默认RSA2(SHA256)密钥是未启用状态,需要手动配置应用公钥!
使用tomcat运行项目,进入web页面,如下显示:
点击付款,使用账号密码登录。注意:不要使用真实环境登录,而是用沙箱账号密码登录
沙箱账号密码可以在这查看:
登录密码和支付密码默认都为111111
支付成功后,跳转到你所填写的同步通知地址,实际为浏览器重定向。
若重定向后显示:
trade_no:20180916xxxxxxxxx
out_trade_no:20180916xxx
total_amount:100000
则表示测试成功
演示完成,下面我们使用断点方式,debug运行看看底层是如何运行的。
首先我打开google浏览器,打开开发者工具,当我们点击付款时候,访问的是alipay.trade.page.pay.jsp,在项目中找到该jsp
在13行打一个断点,点击页面按钮
return_url代表同步通知本地浏览器重定向的url,而notify_url代表异步通知url,精彩在后头。
为什么他要这么做呢?实际上他在29行-33行把参数封装为json格式,并把result动态生成为一个表单,我拷贝表单在本地生成.html文件运行试试看。
此处有一个scirpt标签,当页面加载时候提交表单,表单的action为alipaydev.com,提交方式为POST请求,且内部封装了两个隐藏域,value为刚才的debug所示的封装后的json,并提交给支付宝服务器,双击1.html,运行结果为:
接下来,登录账户付款。
分别在notify_url.jsp和return_url.jsp打一个断点
发现断点先进入notify_url.jsp(异步通知/异步回调),①接收支付宝传递过来的参数,②验证签名,防止被篡改,如果验证签名失败,则有重试机制,直到A系统返回"success"给支付宝,支付宝才不会重试。实际上同步通知和异步通知代码基本一样,最后返回结果。需要考虑网络延迟的情况下,A系统与支付宝系统双方数据一致性问题
所以需要A系统还需要做一个幂等性问题的判断,在网络延迟的情况下,需要使用全局id处理幂等性问题,全局id可以参考订单ID
1、引入依赖,该依赖包含了支付宝所需的sdk
com.github.1991wangliang alipay-sdk 1.0.02、支付服务需要提供两个接口
1、创建token接口
2、使用token进行支付
数据库支付表结构,非正式,仅供参考
CREATE TABLE `payment_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) DEFAULT NULL, `typeid` int(2) DEFAULT NULL, `orderid` varchar(50) DEFAULT NULL, `price` decimal(10,0) DEFAULT NULL, `source` varchar(10) DEFAULT NULL, `state` int(2) DEFAULT NULL, `created` datetime DEFAULT NULL, `updated` datetime DEFAULT NULL, `platformorderid` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
token接口如何创建?
详细的支付流程:
生成支付令牌,支付令牌,假设有效期15分钟
1、请求时,向支付表创建一条支付信息
2、生成支付token,存到redis中,key为支付token,value为支付表的id,并设置有效期为15分钟
3、返回支付token给客户端
4、使用支付token,向redis查找对应支付表的id
5、使用支付表的id,获取支付信息
6、封装支付宝form表单提交参数
具体代码实现:
public ResponseBase createToken(@Re PaymentInfo paymentInfo) { //1.创建支付请求信息 Integer insertResultCount = paymentInfoDao.savePaymentType(paymentInfo); if(insertResultCount上一篇:简述开发java程序的主要步骤,最全Java知识总结
下一篇:java运行五个步骤
皓盘云建最新版下载v9.0 安卓版
53.38MB |商务办公
ris云客移动销售系统最新版下载v1.1.25 安卓手机版
42.71M |商务办公
粤语翻译帮app下载v1.1.1 安卓版
60.01MB |生活服务
人生笔记app官方版下载v1.19.4 安卓版
125.88MB |系统工具
萝卜笔记app下载v1.1.6 安卓版
46.29MB |生活服务
贯联商户端app下载v6.1.8 安卓版
12.54MB |商务办公
jotmo笔记app下载v2.30.0 安卓版
50.06MB |系统工具
鑫钜出行共享汽车app下载v1.5.2
44.7M |生活服务
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-02-15
2022-02-14