大部分内容,来自大佬【凤凰牌老熊】博客:http://doc.cocolian.cn/essay/,外加我乱加的一些标签和乱找的一些注解。

文章目录

  • 支付网关的设计
    • 功能概述
    • 支付(API)网关
      • 支付宝
      • 微信支付
      • PayPal
  • 设计原则

支付网关的设计

在支付系统中,支付网关和支付渠道的对接是最核心的功能。

  • 其中支付网关是对外提供服务的接口,所有需要渠道支持的资金操作都需要通过网关分发到对应的渠道模块上。一旦定型,后续就很少,也很难调整。
  • 支付渠道模块是接收网关的请求,调用渠道接口执行真正的资金操作。

每个渠道的接口,传输方式都不尽相同,所以在这里,支付网关相对于支付渠道模块的作用,类似设计模式中的wrapper,封装各个渠道的差异,对网关呈现统一的接口。而网关的功能是为业务提供通用接口,一些和渠道交互的公共操作,也会放置到网关中。

支付网关在支付系统参考架构图中的位置如下图所示:

功能概述

支付系统对其他系统,特别是交易系统,提供的支付服务包括

  1. 签约
  2. 支付
  3. 退款
  4. 充值
  5. 转帐
  6. 解约

有些地方还会额外提供签约并支付的接口,用于支持在支付过程中绑卡。

每个服务实现的流程也是基本类似(包括下单,取消订单,退单,查单等操作)。每个操作实现,都包括:

  1. 参数校验
  2. 支付路由
  3. 生成订单
  4. 风险评估
  5. 调用渠道服务
  6. 更新订单
  7. 发送消息

这7步

对于一些比较复杂的渠道服务,还会涉及到异步同通知处理的步骤。

一般来说,支付主流程会涉及到如下模块:

  1. 商户侧应用发起支付请求
    注意,这个请求一般是从服务器端发起的。比如用户在手机端提交“立即支付”按钮后,商户的服务器端会先生成订单,然后请求支付网关执行支付。
  2. 支付请求被发送到支付(API)网关上
    网关对这个请求进行一些通用的处理,比如QPS1控制、验签等,然后根据支付请求的场景(网银、快捷、外卡等),调用对应的支付产品。
  3. 支付产品对用户请求进行预处理
    包括执行参数校验、根据支付路由寻找合适的支付通道、评估交易风险、生成订单、调用通道落地执行支付、响应通道的结果并将交易结果通知到商户侧。
  4. 支付产品调用支付通道执行支付
    这个请求并不是直接落地到通道上,而是通过支付通道前置来封装,由支付通道前置来完成和通道的交付。 支付产品是按照可以提供的支付服务来设计的。
  5. 支付通道前置,(以下在不引起混淆的情况下,都简称支付通道)负责和支付通道之间的通讯
    调用支付通道接口完成最终的支付操作。

不同类型的支付产品,其对外提供的接口也会有区别。 后续分类别介绍各种支付产品的设计。 这里重点介绍支付API网关设计、支付产品的整体流程实现。 而软件架构的设计,是基于微服务架构来描述的。

支付(API)网关

支付网关是直接对接业务系统的接口,它本身并不执行任何支付相关的业务逻辑。它将支付产品接口中和业务无关的功能提取出来,在这里统一实现。这样在具体产品接口中,就无需考虑这些和业务无关的逻辑。支付网关设计还和对外接口参数有关。我们看一下业内几个主流的支付平台的接口设计。

支付宝

对外接口采用统一参数的方式,参考APP请求参数说明。 接口参数分为三层: 公共参数、业务参数、还有业务扩展参数。 其中公共参数是各个请求接口中公用的。

公共参数

参数 类型 必填 最大长度 描述 示例值
app_id String 32 支付宝分配给开发者的应用 ID。 2014072300007148
method String 128 接口名称。 alipay.trade.app.pay
format String 40 仅支持 JSON。 JSON
charset String 10 请求使用的编码格式,APP 支付建议使用 UTF-8 格式,如使用 gbk、gb2312 等格式会有 系统繁忙,请稍后再试 的报错。 utf-8
sign_type String 10 商户生成签名字符串所使用的签名算法类型,目前支持 RSA2 和 RSA,推荐使用 RSA2。 RSA2
sign String 256 商户请求参数的签名串,详情参见 签名。 详见示例
timestamp String 19 发送请求的时间,格式 yyyy-MM-dd HH:mm:ss。 2014-07-24 03:07:50
version String 3 调用的接口版本,固定为:1.0。 1.0
notify_url String 256 支付宝服务器主动通知商户服务器里指定的页面 http/https 路径。建议商户使用 https。 https://api.xx.com/receive_notify.htm
biz_content String - 业务请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档。 -

业务相关的参数,通过特定的规则拼接再biz_content上。最后将参数生成签名,放到sign字段中。

支付宝的接口混合json格式和query string格式,在参数命名上,既有下划线方式的,也有驼峰的。英文单词的使用也不太规范。期待后续版本能做的更好。

微信支付

和支付宝不一样,微信支付是采用XML格式来作为报文传输。在其接口文档说明中, 对XML报文格式有详细的描述。当然,也使用签名字符串来保证接口的安全,签名结果放在sign标签下。

在接口设计上,和支付宝还有一些差距。有些参数命名不一致,比如商户号,有些接口中叫mch_id,有些接口是partnerid。

PayPal

PayPal是标准的Restful设计,将支付中涉及到的对象,如Payment, Order, Credit Card等,以资源的形式,支持通过Restful API来操作。

#mermaid-svg-UtjsakEAIn2AOBYs .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-UtjsakEAIn2AOBYs .label text{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .node rect,#mermaid-svg-UtjsakEAIn2AOBYs .node circle,#mermaid-svg-UtjsakEAIn2AOBYs .node ellipse,#mermaid-svg-UtjsakEAIn2AOBYs .node polygon,#mermaid-svg-UtjsakEAIn2AOBYs .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-UtjsakEAIn2AOBYs .node .label{text-align:center;fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .node.clickable{cursor:pointer}#mermaid-svg-UtjsakEAIn2AOBYs .arrowheadPath{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-UtjsakEAIn2AOBYs .flowchart-link{stroke:#333;fill:none}#mermaid-svg-UtjsakEAIn2AOBYs .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-UtjsakEAIn2AOBYs .edgeLabel rect{opacity:0.9}#mermaid-svg-UtjsakEAIn2AOBYs .edgeLabel span{color:#333}#mermaid-svg-UtjsakEAIn2AOBYs .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-UtjsakEAIn2AOBYs .cluster text{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-UtjsakEAIn2AOBYs .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-UtjsakEAIn2AOBYs text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-UtjsakEAIn2AOBYs .actor-line{stroke:grey}#mermaid-svg-UtjsakEAIn2AOBYs .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-UtjsakEAIn2AOBYs .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-UtjsakEAIn2AOBYs #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-UtjsakEAIn2AOBYs .sequenceNumber{fill:#fff}#mermaid-svg-UtjsakEAIn2AOBYs #sequencenumber{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs #crosshead path{fill:#333;stroke:#333}#mermaid-svg-UtjsakEAIn2AOBYs .messageText{fill:#333;stroke:#333}#mermaid-svg-UtjsakEAIn2AOBYs .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-UtjsakEAIn2AOBYs .labelText,#mermaid-svg-UtjsakEAIn2AOBYs .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-UtjsakEAIn2AOBYs .loopText,#mermaid-svg-UtjsakEAIn2AOBYs .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-UtjsakEAIn2AOBYs .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-UtjsakEAIn2AOBYs .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-UtjsakEAIn2AOBYs .noteText,#mermaid-svg-UtjsakEAIn2AOBYs .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-UtjsakEAIn2AOBYs .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-UtjsakEAIn2AOBYs .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-UtjsakEAIn2AOBYs .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-UtjsakEAIn2AOBYs .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .section{stroke:none;opacity:0.2}#mermaid-svg-UtjsakEAIn2AOBYs .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-UtjsakEAIn2AOBYs .section2{fill:#fff400}#mermaid-svg-UtjsakEAIn2AOBYs .section1,#mermaid-svg-UtjsakEAIn2AOBYs .section3{fill:#fff;opacity:0.2}#mermaid-svg-UtjsakEAIn2AOBYs .sectionTitle0{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .sectionTitle1{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .sectionTitle2{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .sectionTitle3{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-UtjsakEAIn2AOBYs .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .grid path{stroke-width:0}#mermaid-svg-UtjsakEAIn2AOBYs .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-UtjsakEAIn2AOBYs .task{stroke-width:2}#mermaid-svg-UtjsakEAIn2AOBYs .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .taskText:not([font-size]){font-size:11px}#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-UtjsakEAIn2AOBYs .task.clickable{cursor:pointer}#mermaid-svg-UtjsakEAIn2AOBYs .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-UtjsakEAIn2AOBYs .taskText0,#mermaid-svg-UtjsakEAIn2AOBYs .taskText1,#mermaid-svg-UtjsakEAIn2AOBYs .taskText2,#mermaid-svg-UtjsakEAIn2AOBYs .taskText3{fill:#fff}#mermaid-svg-UtjsakEAIn2AOBYs .task0,#mermaid-svg-UtjsakEAIn2AOBYs .task1,#mermaid-svg-UtjsakEAIn2AOBYs .task2,#mermaid-svg-UtjsakEAIn2AOBYs .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutside0,#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutside2{fill:#000}#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutside1,#mermaid-svg-UtjsakEAIn2AOBYs .taskTextOutside3{fill:#000}#mermaid-svg-UtjsakEAIn2AOBYs .active0,#mermaid-svg-UtjsakEAIn2AOBYs .active1,#mermaid-svg-UtjsakEAIn2AOBYs .active2,#mermaid-svg-UtjsakEAIn2AOBYs .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-UtjsakEAIn2AOBYs .activeText0,#mermaid-svg-UtjsakEAIn2AOBYs .activeText1,#mermaid-svg-UtjsakEAIn2AOBYs .activeText2,#mermaid-svg-UtjsakEAIn2AOBYs .activeText3{fill:#000 !important}#mermaid-svg-UtjsakEAIn2AOBYs .done0,#mermaid-svg-UtjsakEAIn2AOBYs .done1,#mermaid-svg-UtjsakEAIn2AOBYs .done2,#mermaid-svg-UtjsakEAIn2AOBYs .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-UtjsakEAIn2AOBYs .doneText0,#mermaid-svg-UtjsakEAIn2AOBYs .doneText1,#mermaid-svg-UtjsakEAIn2AOBYs .doneText2,#mermaid-svg-UtjsakEAIn2AOBYs .doneText3{fill:#000 !important}#mermaid-svg-UtjsakEAIn2AOBYs .crit0,#mermaid-svg-UtjsakEAIn2AOBYs .crit1,#mermaid-svg-UtjsakEAIn2AOBYs .crit2,#mermaid-svg-UtjsakEAIn2AOBYs .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-UtjsakEAIn2AOBYs .activeCrit0,#mermaid-svg-UtjsakEAIn2AOBYs .activeCrit1,#mermaid-svg-UtjsakEAIn2AOBYs .activeCrit2,#mermaid-svg-UtjsakEAIn2AOBYs .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-UtjsakEAIn2AOBYs .doneCrit0,#mermaid-svg-UtjsakEAIn2AOBYs .doneCrit1,#mermaid-svg-UtjsakEAIn2AOBYs .doneCrit2,#mermaid-svg-UtjsakEAIn2AOBYs .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-UtjsakEAIn2AOBYs .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-UtjsakEAIn2AOBYs .milestoneText{font-style:italic}#mermaid-svg-UtjsakEAIn2AOBYs .doneCritText0,#mermaid-svg-UtjsakEAIn2AOBYs .doneCritText1,#mermaid-svg-UtjsakEAIn2AOBYs .doneCritText2,#mermaid-svg-UtjsakEAIn2AOBYs .doneCritText3{fill:#000 !important}#mermaid-svg-UtjsakEAIn2AOBYs .activeCritText0,#mermaid-svg-UtjsakEAIn2AOBYs .activeCritText1,#mermaid-svg-UtjsakEAIn2AOBYs .activeCritText2,#mermaid-svg-UtjsakEAIn2AOBYs .activeCritText3{fill:#000 !important}#mermaid-svg-UtjsakEAIn2AOBYs .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-UtjsakEAIn2AOBYs g.classGroup text .title{font-weight:bolder}#mermaid-svg-UtjsakEAIn2AOBYs g.clickable{cursor:pointer}#mermaid-svg-UtjsakEAIn2AOBYs g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-UtjsakEAIn2AOBYs g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-UtjsakEAIn2AOBYs .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-UtjsakEAIn2AOBYs .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-UtjsakEAIn2AOBYs .dashed-line{stroke-dasharray:3}#mermaid-svg-UtjsakEAIn2AOBYs #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs .commit-id,#mermaid-svg-UtjsakEAIn2AOBYs .commit-msg,#mermaid-svg-UtjsakEAIn2AOBYs .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-UtjsakEAIn2AOBYs g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-UtjsakEAIn2AOBYs g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-UtjsakEAIn2AOBYs g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-UtjsakEAIn2AOBYs .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-UtjsakEAIn2AOBYs .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-UtjsakEAIn2AOBYs .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-UtjsakEAIn2AOBYs .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-UtjsakEAIn2AOBYs .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-UtjsakEAIn2AOBYs .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-UtjsakEAIn2AOBYs .edgeLabel text{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-UtjsakEAIn2AOBYs .node circle.state-start{fill:black;stroke:black}#mermaid-svg-UtjsakEAIn2AOBYs .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-UtjsakEAIn2AOBYs #statediagram-barbEnd{fill:#9370db}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-state .divider{stroke:#9370db}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-UtjsakEAIn2AOBYs .note-edge{stroke-dasharray:5}#mermaid-svg-UtjsakEAIn2AOBYs .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-UtjsakEAIn2AOBYs .error-icon{fill:#522}#mermaid-svg-UtjsakEAIn2AOBYs .error-text{fill:#522;stroke:#522}#mermaid-svg-UtjsakEAIn2AOBYs .edge-thickness-normal{stroke-width:2px}#mermaid-svg-UtjsakEAIn2AOBYs .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-UtjsakEAIn2AOBYs .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-UtjsakEAIn2AOBYs .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-UtjsakEAIn2AOBYs .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-UtjsakEAIn2AOBYs .marker{fill:#333}#mermaid-svg-UtjsakEAIn2AOBYs .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-UtjsakEAIn2AOBYs {color: rgba(0, 0, 0, 0.75);font: ;}

webhooks 网勾
payout item 花销项目
payouts 花销
orders 订单
captures
authorization 授权
refund 退款
SaleTransactions 销售交易
Payments 付款
create webhook 创建网勾
show webhook details 展示网勾详情
list all webhooks 列出所有网勾
update webhook 更新网勾
delete webhook 删除网勾
show payout item details 展示花销项目详情
cancel unclaimed payout item 取消无人认领的花销项目
create payouts 创建花销
show batch payout details 展示批量的花销详情
show order details 展示订单详情
authorize order 批准订单
capture order 捕获订单
void an order 废除一个订单
show captured payment details 展示捕获的付款详情
refund captured payment 退还捕获的付款
show authorization details 展示授权详情
capture an authorization 获取一个授权
void an authorization 废除一个授权
reauthorization payment 重新授权支付
show refund details 展示退款详情
show sale details 展示销售详情
refund sale 销售退款
create payment 创建付款
execute approved payment 实施核实的付款
show payment details 展示付款详情
update payment 更新付款(记录)
list payments 列出付款(记录)
Paypal-Services
Billing Agreements 账单协议
create agreement 创建协议
update agreement 更新协议
agreement details 协议详情
bill agreement balance 协议账单余额
cancel agreement 取消协议
re-active agreement 重新激活协议
set agreement balance 设置协议余额
suspend agreement 终止协议
list agreement transactions 列出协议交易记录
execute agreement 执行协议
Billing Plans 计费计划
Identity 身份
Invoice 发票
Payment Experience 支付经历
Payments 付款
Payouts 支出
Vault 金库
webhook 网勾
created plan 创建计划
更新计划
计划详情
列出计划
TokenService
OpenId connect
create invoice 创建发票
generate QR code 生成二维码
list merchant invoice 列出商户发票
serach for invoice 搜索发票
create web experience profile 创建web支付经历简介
show web experience details 展示web支付经历详情
list web experience profiles 列出创建web支付经历简介
update web experience profiles 更新web支付经历简介
delete web experience profile 删除web支付经历简介
show credit card 出示信用卡
list vaulted credit cards 列出金库中的信用卡
show vaulted credit card details 列出金库中的信用卡详情
update vaulted credit card 更新金库中的信用卡
delete vaulted credit card 删除金库中的信用卡
event notification 事件提醒

PayPal的定位以及设计目标和国内第三方支付平台不同,它以支持国际营收为主。对国内应用来说,其易用性和支付宝、微信支付相比还稍逊一些,不过Paypal一直是支付API设计的典范。

对电商支付平台来说,其定位更接近于一个聚合支付。聚合多种支付方式,为公司各个业务提供支持。 在这里,支付网关和支付产品的设计尤为关键。合理的接口设计能够大大降低支付渠道对接的开发工作量。一般支付产品不会超过10个,而根据公司的规模,对接的支付渠道超过100个都有可能。

设计原则

如上所述,支付网关支付产品支付渠道 的职责分工为:

  1. 按照支付能力来划分支付产品。
  2. 同一支付能力的公共支付流程,在支付产品中实现。 支付产品提供的是和渠道无关的、和支付能力流程相关的功能。
  3. 在各支付产品中,其和支付能力无关的公共功能,在支付网关上实现。

按照这个分工,在 支付网关 上实现的主要功能:

  1. API路由。在聚合支付场景下,当有多个支付产品可以提供支持时,使用支付网关可以让接入方对接时无需考虑支付产品的部署问题。
  2. 接口安全: 熔断、限流与隔离。 这对支付服务来说尤为重要。 这是微服务架构的基本功能,本文不做描述。

如下功能,是在 支付产品 中提供:

  1. 风控拦截: 风控是和支付产品有关,不同产品的风控措施、处理对策也是不同的,所以风控是在产品层实现。
  2. 支付路由: 路由也是和产品有关。不同产品路由策略也不同。
  3. 参数校验: 这也是和支付产品相关的,不同的产品接口其参数也不同。
  4. 支付流程: 生成交易记录、落地渠道执行支付、同步和异步通知等操作。

如下功能,可以在产品层或者 网关 层实现:

  1. 身份验证: 确认付款方、收款方、渠道是否有执行当前操作的权限。 在那一层实现取决于这些信息是否有提炼为公共行为。
  2. 验签: 对接口参数进行签名并验证其签名。这是为了避免接口被盗刷和篡改的必要手段。如果对各个接口采用统一的签名规则,则可以在网关层实现。

  1. QPS = req/sec = 请求数/秒 ↩︎

【学习笔记】- 支付网关的设计相关推荐

  1. C语言程序设计学习笔记:P1-程序设计与C语言

    本系列博客用于记录学习浙江大学翁恺老师的C语言程序设计,系列笔记链接如下: C语言程序设计学习笔记:P1-程序设计与C语言 C语言程序设计学习笔记:P2-计算 C语言程序设计学习笔记:P3-判断 C语 ...

  2. 5、赛灵思-Zynq UltraScale+ MPSoC学习笔记:Petalinux 的设计流程及定制Linux系统

    5.赛灵思-Zynq UltraScale+ MPSoC学习笔记:Petalinux 的设计流程及定制Linux系统 声明:本文是学习赛灵思 Zynq UltraScale+ MPSoC 5EV过程中 ...

  3. 10月15日计算机视觉基础学习笔记——分割网络的设计

    文章目录 前言 一.分割器的设计 1.优化:减小 feature map 2.上采样 up sampling 二.经典分割模型的涨点方法 前言 本文为10月15日计算机视觉基础学习笔记--分割网络的设 ...

  4. Altium Designer入门学习笔记4:PCB设计中各层的含义

    Altium Designer入门学习笔记4:PCB设计中各层的含义 阻焊层:solder mask,是指板子上要上绿油的部分:因为它是负片输出,所以实际上有solder mask的部分实际效果并不上 ...

  5. Unity DOTS 学习笔记2 - 面向数据设计的基本概念(上)

    上一章,我们安装了ECS套件,也进行了一些介绍,但是比较笼统.没有一些基础知识储备,很难开始编写代码.本章首先翻译和整理了部分Unity官方的DOTS知识,需要对面向数据有更深刻的认识. DOD知识准 ...

  6. 《Python零基础快乐学习之旅》学习笔记13——模块的设计与应用

    文章目录 第13章 模块的设计与应用 13.1 将自建的函数存储在模块中 13.1.1 准备工作 13.1.2 创建函数内容的模块 13.2 应用函数模块 13.2.1 import 语句 13.2. ...

  7. 支付网关的设计:核心模块的功能需求、软件架构设计以及注意要点

    2019独角兽企业重金招聘Python工程师标准>>> 在支付系统中,支付网关和支付渠道的对接是最核心的功能.其中支付网关是对外提供服务的接口,所有需要渠道支持的资金操作都需要通过网 ...

  8. C++ Qt学习笔记 (1) 简易计算器设计

    最近开始学习c++ qt, 按照教材上的例程设计一个简易的桌面计算器: Qt是一个基于C++语言的跨平台应用程序和UI开发框架,主要包含一个类库,和跨平台开发及国际化的工具,最初由挪威的Trollte ...

  9. 天线学习笔记——串馈网络设计

    供个人学习记录使用,如有错误欢迎提出! 参考文献:A Unified Synthesis Method for Series-Fed Networks Under qual/Unequal Distr ...

最新文章

  1. 按下enter键在各个文本框中切换焦点_你真的了解Enter键吗?请先学习本文后再回答...
  2. 免秘登陆linux_linux普通用户免秘钥登陆操作
  3. 关于zbar的libzbar.a不支持ipnone5的64bit问题
  4. OpenCV用于快速边缘检测的结构化森林
  5. Vue使用Vuex一步步封装并使用store
  6. 【渝粤题库】陕西师范大学189101 消费者行为学Ⅰ 作业(高起专)
  7. java 同步 lock_关于java:同步是否像Lock.lock()一样驻留并发线程?
  8. 【MAC】Mac下配置perl的DBD::MySQL模块
  9. oracle分析函数大全非常详细
  10. html 获取当前url,js获取当前页面url信息的方法
  11. 转载:常见的15种音频格式
  12. 计算机设置密码命令,win7设置电脑开机密码的命令和方法
  13. Linux玩dota2需要什么显卡,dota2最低配置要求 玩dota2需要什么电脑配置
  14. 7天带你搞定一个图表框架echarts(六)
  15. 5、实现登陆功能:如果用户名输入“tom”,密码“123”,提示登陆成功,否则提示输入错误,请重新输入!您还有XX次机会。 三次输入错误后将不可以再输入,并提示对不起,你的账号将被锁定
  16. *关键字retry:很像goto语句,跳到标记处
  17. oCPC实践录 | 广告冷启动问题的思考与总结
  18. CSS布局—网格布局Grid(一)
  19. 团队和做的直观图_直观,可靠的日期和时间处理,终于出现在Java中
  20. 重构实践:基于腾讯云Elasticsearch搭建QQ邮箱全文检索

热门文章

  1. UE4中Ultra Dynamic Sky插件蓝图实现昼夜交替
  2. “Word页码从第三页开始”详细的图文步骤教程
  3. git prune 分支清除
  4. 列举几个计算机网络应用的实例,计算机网络必备知识,举几个计算机网络应用的实例(一文搞懂)...
  5. matlab 练习3
  6. 树莓派uefi引导linux卡死,树莓派4B 折腾Windows 10 ARM版前传之运行UEFI引导
  7. JFrame时间输出、计时器
  8. python怎么暂停运行_如何暂停长时间运行的循环?
  9. 计算机机房建设几级资质是什么,机房建设需要哪些资质和建设过程要求
  10. 模拟客户端与服务器端通讯——UDP通讯