前言
今天分享一点关于支付相关的内容,也是好早就有粉丝私信提过的,很遗憾,一直拖到现在才写。
大家比较好奇微信支付、支付宝支付在企业实战中究竟是什么样,就是网上的在线课程学的那些吗。
因为没有类似的经验,所以不少人对支付功能比较好奇。
刚好我所在的公司本身也是支付服务商,我谈不上特别清楚,但还算比较了解。
先开门见山,本篇没有支付功能的代码实战,因为这东西没你想的那么难,除了微信支付宝提供了原生工具类,其他开源的工具也挺多,你纯粹可以当成支付版的CRUD一样操作。
我将以面试官的角度来提问一些支付相关的问题,并做出回答,让你对企业中支付的全貌有个大概的认知,这里面有一个问题是我面试别人问过的,xdm看完了可以猜一猜是哪个。
正文
1、你知道直连模式和服务商模式吗
网上的课程一般给你演示的都是直连模式,而企业中有不少是申请成为了服务商,因为里面有佣金提成。
我粗俗地解释,直连模式,就是说你是一个会做生意的老板,自己会搞钱,搞到钱存到自己的一个商户号里。
服务商模式,就是说你是一个会做生意的老板,但是自己不搞钱只提供做生意的渠道,其他老板用你的渠道,搞到钱了让你洗一洗,你分别转到他们各自的商户号里去,而你收取一点点服务费。
然后我们对照上面的话再稍微专业点解释,直连模式就是你得自己接入支付功能,啥都要你自己做,服务商模式就是啥都不需要你做,你就提供个商户号,剩下的支付接入功能服务商给你全部搞定。
如果面试官问你这个问题,你只要意思稍微到了就行,别人就知道你是做过的。
2、服务商模式下,你们如何控制多个子商户结算和退款的
假如你有自己的一家公司,专门提供支付服务,而且申请成为了服务商,那么你就有自己的一个appid和mchid,统称为
服务商账户
。然后张三和李四也有各自的公司,但他们是做电商的,需要接入支付功能,找到了你,此时他们需要提供自己公司申请的appid和mchid,交给你去配置,这个统称为
子商户账户
。好了,接下来你作为服务商,该如何配置服务商账户和子商户账户呢?我这里贴出一个微信的小例子,你们可以参考下(文中的参数都是模拟的并非真实配置)。
wechat:
pay:
# 服务商
appId: wx49f94d5f00f349f13
mchId: 1550391234
mchKey: miyao145bijv0974kf64833ld8wpi
keyPath: classpath:wx-cert-dev/apiclient_cert.p12
existsSub: false
# 子商户
subConfigs:
- subAppId: wx50f05d5f11f560h24
subMchId: 1511405678
typeId: zhangsan
- subAppId: wx61g16e6g22d781i35
subMchId: 1623519012
typeId: lisi
# 回调地址
external:
pay-notify-url: https://xxxx/gateway/pay/api/payOrder/notify
refund-notify-url: https://xxxx/gateway/pay/api/refund/notify
其实配置的方式有很多,我这里只是展示其中一种,xdm也可以照搬的。
这样配置了以后,如何读取呢,很简单,就用SpringBoot的
@ConfigurationProperties
注解来读取即可。这种方式是在SpringBoot项目启动时,
读取yml
中服务商和子商户的配置,加载到map
中,然后在支付接口使用时,直接从map中获取即可,就相当于放到了缓存中。而配置中声明的
typeId就是区分子商户的标识
,xdm可以根据业务场景去自定义即可。这样,不论是支付下单还是退款,都能直接读取到对应子商户的配置,从而支付下单或原路退回。
本篇主要不是讲功能的,所以不在这里面的细节上过多赘述。
如果有面试官问这个问题,你只需要说出配置和读取的思路就行。
3、先业务下单还是支付下单
如果面试官问了这个问题,就属于是送分题了。
肯定是先业务下单,因为支付功能是基于业务的基础上进行的,如果业务订单不记录下来,后面整个流程都没头没尾,一些业务相关的数据你也获取不到,状态也更新不了。
所以要先记录下业务订单,包含订单号、业务类型、业务状态等属性,哪怕支付下单失败,你也有业务订单的痕迹可查。
4、下单后不支付怎么处理
这个问题有多种答案,不同公司会有不同的做法,我这里分享一下我的做法。
下单后如果不支付,这笔订单就不做处理,再次下单时生成一笔新的订单,原来的那个订单就当做废订单。
对于中小企业而言,这种方案我觉得最简单,废订单的量也不会有你想象的那么多。
另外,微信支付不能用重复的订单号再次下单,会报错,所以这个方案也顺便规避了这个问题。
如果有面试官问这个问题,可以参考我这个做法来回答,这也是我待过的两家互联网公司都用过的方案。
5、你们有支付中心吗,如何处理回调的
面试官问这个问题,大概率是想知道你们有没有对支付服务做解耦。
微信和支付宝下单成功后,都会通过回调通知返回给你,这种情况下,说明肯定支付成功了。
正常而言,只需要配置回调地址即可,但是在分布式的环境中,支付服务一般是独立出来的,也就是会搭建一个支付中心,我们假定是微服务的架构,支付中心是pay服务,那么其他服务用到支付接口都是调pay服务的接口。
所以回调接口肯定是要写在pay服务里面的,这里就会有一个问题,pay服务收到了回调通知,如何告诉其他业务服务呢?
这里就要引入MQ,比如RabbitMQ,在回调中更新支付订单状态后,要通过它来转发到其他业务服务,其他业务服务消费MQ之后,继续处理自己的业务逻辑。
这样就做到了解耦,只要回答出这一点,也能说明是接入过支付功能的。
6、你们如何处理重复回调的问题
微信和支付宝是有概率犯病的,虽然很小,但确实有,我就遇到过。
这个时候你可能会想到,我在业务逻辑上做判断不就好了,如果已经更新过状态了,就不再处理了。
理论上可以,但实战的话依然会有很多现实问题。
首先,你如何保证回调中的业务逻辑处理有多少,真实业务场景下,不单单只会更新一下状态,你可能还会做一些入库、发消息、rpc调用等等一系列操作,这都是基于业务决定的,你很难说每次都能用同样的办法解决。
另外,我有在工作中通过日志平台观察过重复回调的时间间隔,微信或支付宝的重复回调几乎都是同1秒发生的,是不是感到有点熟悉,有点类似于处理高并发的问题了对吗。
如果你们是分布式架构,且业务量达到一定规模,那么这个问题一旦发生,你单纯靠代码判断是不保险的。
所以,最简单可靠的办法还是把回调中处理业务逻辑的代码都抽取到一个方法中,然后对这个方法上
分布式锁
。如果面试官问到你这个问题,你就说用分布式锁即可。
7、回调中第三方业务处理失败,如何退款的
这个问题对于完全没在企业中接入过支付功能的xdm来说,就是比较难回答的了,因为牵扯到第三方,那说明回调中很可能还要走rpc调用来完成某些业务确认操作。
我曾经专门写过一篇真实发生的关于微信支付退款逻辑不严谨导致重大事故的文章,里面有讲过这个流程,有兴趣的可以自己找找看。
记住,千万别张口就说程序自动退款,这是非常不严谨的,牵扯到钱的东西,都是要谨慎的,如果是服务商模式,更是如此,因为那都是客户的钱。
我这里把其中一些重点罗列出来:
1)、支付时,要先支付下单,回调中再进行rpc业务确认(先付钱再给票),因为你是服务商,要优先维护客户的利益,试想如果先给了票,结果人家不给钱直接跑了,那客户不就亏了么;
2)、回调中,如果rpc业务确认失败,就将这笔订单记录到一张异常记录表中,这张记录表的作用就是专门处理rpc调用失败需要进行退款的订单数据;
3)、定时任务扫描异常记录表,比如15分钟一次,将这些确认失败的订单费用都原路退回;
4)、执行退费逻辑之前,还得先rpc调一下第三方的查询确认状态接口,对方没有那么你必须要求他们提供,只有保证对方明确可以退,你才能再走微信或支付宝的退费接口,否则可能导致多退。因为会存在一种情况,就是第三方自己其实确认成功了,但是网络问题超时或他们程序漏洞导致返回给你是失败的,那么你以为可以退,结果退了后这钱是短款,你就得承担损失了。
这个流程还是蛮复杂的,不想清楚很容易把自己搞死,所以在接入支付功能时,一定要自己画一画,把整个逻辑理清楚,然后再开始编码。
8、你知道微信支付宝退款的时限吗
这个很多人反而不知道,因为网上的教程是不会告诉你的,往往是真实企业中维护过支付功能才会知道,因为你经常要处理一些退费,那么此时就很可能遇到这个问题。
微信和支付宝的政策是不同的,而且可能会变,所以如果要面试的公司是要求懂支付功能的,你最好分别到微信和支付宝的官方文档中查看下最新的规定。
我这里找了下分享给各位:
微信支付
支付宝支付
9、你了解聚合支付吗
一般互联网公司接入支付接口,聚合支付大概率是跑不掉的。
简单理解就好,以国内目前的情况来说,大多数情况也就是微信和支付宝的聚合。
为了更好理解,我这里举个好懂的例子,就是大家去医院看病的时候,是不是有时候医生会给你打印出一个凭条,凭条上会有个二维码,然后你直接扫码进行支付就可以了对吧。
其实这就是一种聚合支付,这个二维码本质就是一个链接,链接里面会有对方提供给你的参数,你扫码的时候也就是读取这些参数的过程,拿到参数后就可以去展示订单详情,然后进行后续的支付等等。
你不管用微信或支付宝哪个载体去扫码,实际上就是走的哪个渠道,前端是可以传递渠道信息给服务端的,如果是小程序那更简单,直接会自动识别并唤起对应的小程序订单详情界面。
这里面微信支付的话,还需要在微信公众平台中配置一个转发链接,除此以外也没什么其他操作了,聚合支付其实没有那么复杂。
大家以后如果有幸在生活中接触到聚合支付的场景,完全可以把聚合码拍下来,然后回去上网搜索草料二维码,用解码器把这个聚合码解析出来,你就能看见到底是个什么玩意儿了。
10、对账你了解多少
正常来讲,面试官一般不会问这个的,因为没啥必要,除非这个公司专门招需要懂得对账的工程师。
如果真问到你了,你可以稍微聊聊,别一问三不知就行。
企业级的支付功能,是肯定要有对账的,尤其是给客户提供支付服务,对账平台也是其中重要的一环,要帮助客户财务平账。
你可以告诉面试官,你们是接入的第三方对账平台,这个回答是最简单的,变相告诉对方你见过用过,这就可以了。
你如果说对账平台是你们自己做的,对方若是个懂行的,估计会问你更多细节,所以我不推荐面试中主动这么回答。
简单来讲,对账的方法是调微信、支付宝、第三方(如果有)的账单接口,拉取到账单然后进行订单的比对,计算出长款多少,短款多少,财务主要关心的是短款,因为短款表示客户亏钱了,那么财务就要追踪这些款项丢失的原因,如果是长款,财务可问可不问,因为是多收的钱,对于财务来讲没所谓,有人找来就人工退掉,没人找来不就白赚么。
总而言之,对账的目的是为了辅助财务查账,通过对账平台,财务可以清晰直观地看到每天的对账结果。
总结
如果哪一天有面试官问你这些东西,你只要回答了,别人立马就知道你是正儿八经做过支付的。
最后回归到开头我问的那个问题,xdm知道我以前面试别人问的是其中哪个问题么,我可以透露下,我不会问很复杂的,但是一个问题就能知道对方是不是真的做过。
好了,今天的小知识你学会了吗?
公众号 --> 【Java分享客栈】
如果喜欢请点赞+关注↑↑↑,持续分享干货哦!