从ping++和某支付来看支付服务设计

golang cyanprobe 3年前 (2021-12-11) 1911次浏览 已收录 0个评论

前言:

最近在做一个独立于中台的聚合支付服务, 来聚合海外的三方支付, 类似于ping++, 中台接入这个聚合支付服务, 使国际区域上的业务接入不再依赖中台做集成。

由于这个聚合服务也相当于一个三方支付SDK, 所以要接入三方服务, 聚合成为类似于ping++这种服务, 我写的也相当于三方聚合服务。

内容:

1.大概流程

流程图大概如下:

2.服务实现

由于接入了某三方,同时聚合服务作为三方可参考ping++的设计 二者对比, 引起了一些思考。

 

Q1:首先回调鉴权, 某三方服务是使用 平台 secret key hmac 加盐的方式实现,而ping++ 是使用RSA(商户公钥)的形式, 二者的区别是什么?

A1: 区别在于使用RSA验签,可以确认秘钥泄露责任。 secret key 加盐, 平台是有泄露风险的,这样就可以模拟回调造成商户损失, 此时无法确认责任方是平台还是用户自己,而使用rsa就没有这个问题。

 

Q2: ping++请求鉴权采用rsa + secret 形式, 某三方采用secret key 形式, 有何区别是否有风险

A2: 除了A1的原因, 某三方是无其他风险的, 取决于https可以防范中间人攻击, secret是否明文无所谓

 

Q3: 如何实现沙盒机制?

A3: 沙盒的设计可以分为支付网关(支付宝, stripe)和基于livekey testkey (ping++)的设计

  • 基于key, 三方平台自带沙盒环境 和 生产环境, 订单上分离,可以看成是一个项目两个库,在网关区分写入到哪里。
  • 基于支付网关, 可以想象成同一项目,部署两个环境。

作为业务接入方期望在生产调用沙盒环境, 可以配置多个回调(如测试mode 配置商户生产和测试两个环境地址,商户通过标识来判断支付类型), 这也是三方平台使用eventId 的原因(因为每个回调要对应单独的通知状态)。

还有一种简单的方式,直接在创建charge时传入回调地址。

 

Q4: chargeId, fefundId, eventId 的必要性?

A4:  chargeId 为三方关联支付渠道的id, 相当于三方平台唯一订单id, 是必要的。

refundId也是必要的, 因为同一笔charge可以多次退款,所以商户需要对回调是哪一笔退款有感知。像某三方支付,对同一refundId请求两次直接报通用内部错误,没有做幂等处理,商户方是无法感知他生成的这笔退款是否发送成功的,这样是有问题的(场景: 请求返回超时了,但实际成功了)。

eventId除了前面已经谈过的多个回调地址原因, 还有基于回调事件唯一性的考量, 还有通晰平台服务链路, 其实是不必要的。

 

Q5: charge是否是有状态的?

A5: charge 是有状态的, refund也是有状态的, charge状态的终点可以是success, 而不必是退款(charge 是维护有退款金额的)

 

 

 


CyanProbe , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:从ping++和某支付来看支付服务设计
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址