前端
置灰按钮
禁止多次点击提交按钮。
弹出提示框
在移动手机端,基本都是跳转到支付成功页面,但是pc电脑端,一般都是弹出一个提示框,有两个按钮1.支付成功,完成支付2.支付失败,因为异常。
为什么手机端是直接跳转成功页面,而电脑是弹出提示框,因为手机屏幕比较小,弹出提示框,不好操作。电脑屏幕比较大。
但是,本质作用都是一样,就是为了避免重复点击提交按钮,避免停留在当前页面但是因为刷新当前页面导致重复提交请求。
跳转到成功页面
即支付成功之后,跳转到支付成功页面。而不是一直在提交支付页面,因为可能会多次点击提交按钮。
还有可能是刷新页面,导致多次请求。当然,一般情况下,请求数据都是post提交。如果是get提交,那么就可能导致刷新当前页面的时候,重复提交。所以,如果跳转到成功页面,那么即使刷新当前页面,也没有关系。
这里的跳转成功页面,不是说真的支付成功,而是针对你的提交支付操作,已经成功了。具体是否成功,得看后台的处理和判断。
最佳实践和应用场景
比如,我们手机app扫码支付的时候,基本上都是跳转到支付成功页面。这种情况,都是微信h5。
基于token + 缓存
首先,要注意的是,这种解决方案是前端和后台结合。怎么个结合法?就是后台会生成token,并且会给到前端。
具体步骤是
1.客户端请求
2.后台生成token,给token到前端
3.客户端再次请求
4.后台从缓存取数据
几个问题
1.客户端的两次请求时机?
第一次是扫码。第二次是点击提交按钮。
2.缓存保存的是什么数据?
key/value,具体来说是token/order。即在后台使用token唯一标识order。
3.用什么存储?
缓存中间件。memcache或redis。
本质
本质是为了解决步骤3多次提交的时候,后台读的数据,始终是从缓存读,且读的数据是同一个数据。
后台
核心是检验数据是否存在。这里有两个核心的点。1.第一,数据。2.第二,校验。
数据?客户端必须提供1.客户端唯一id 2.数据唯一id。具体解释一下,我们本质是要确定哪个用户的哪个数据?怎么确定?userId/商家id,唯一确定用户。orderId唯一确定当前用户的数据,特别注意,这个orderId是客户端的订单id,服务器端会生成自己的orderId。我们必须确保二者在数据库里唯一,怎么确保?组合唯一索引约束。
如何校验?本质就是校验数据在数据库里是否存在。具体来说就是,sql:where merchantId=? and orderId=?。当然,我们也可以不校验,但是不校验的话,写入数据的时候,如果重复,就会报错。
上面的其实有点问题,就是存在一种情况,因为上面的是1.先读2后写,这里包含了两步操作,所以必然存在原子性问题。
就是在读和写之间,数据已经存在。那怎么办?
还能怎么解决。唯一的解决方法就是加锁。1.如果是单进程,就普通锁。2.如果是集群,那么就分布式锁。作用都是确保读和写是原子操作。
本质
核心是两点
1.数据库的组合唯一索引约束
2.校验数据在数据库里是否存在
聚合支付-扫码支付
聚合支付-扫码支付,本质上是二维码,没有真正的商家,即店家是没有自己的商家系统的。具体看这篇文章 juejin.cn/post/684490…
所以,聚合支付-扫码支付,校验数据在数据库里是否存在的时候,是检验商家号+支付公司订单号。即sql:select ... where merchantId=? and orderId=?
区别在哪里呢?如果商家有自己的商家系统,且请求数据的时候,传了商家订单号给上游,那么orderId就是客户端传过来的订单号;没有的话,就是支付公司自己的订单号。就这么简单!