1 概述
聚合支付收款分为线上和线下业务场景,本文中的商户收银台接口设计主要是指线上业务场景,线下业务场景聚合收款方式后续会进行单独设计和分析。
主流的线上支付渠道有微信支付,支付宝支付,云闪付。这三种支付渠道都有各自的线上收款产品APP支付、H5支付、小程序支付、扫码支付、公众号支付 。dtpay聚合支付系统商户收银台接口产品主要整合支付渠道不同的线上收款场景,让线上商户快速接入各渠道支付场景。
2 线上聚合收银台技术架构
系统采用SpringCloud,SpringCloudAalibaba微服务架构,系统采用容器化(Docker,K8S)部署,以下是技术架构使用的技术栈
3 商户线上聚合收银台接口
商户聚合收银台接口采用接口对接或SDK方式给到商户自助对接,收银台接口系统各参与方有商户系统、dtpay商户线上聚合收银台接口系统、支付渠道方。商户不需要对接各支付渠道的支付产品,通过聚合收银台快速完成收款方式的对接。
4 收银台接口设计
收银台接口主要涵盖以下接口统一下单支付接口、支付通知接口、支付查询接口
4.1 统一支付下单支付接口设计
4.1.1 请求方式
POST/JSON
4.1.2 请求参数
字段 | 名称 | 类型 | 长度 | 必输 | 备注 |
---|---|---|---|---|---|
mercOrderNo | 商户订单号 | String | 32 | 是 | 商户自己生成的唯一的订单号,商户订单号+商户号唯一 |
subject | 订单名称 | String | 100 | 是 | 订单名称、订单说明两者必填其一 |
body | 订单说明 | String | 200 | 否 | 订单名称、订单说明两者必填其一 |
tradeType | 交易类型 | String | 2 | 是 | 01-支付 02-代付 03-提现 |
tradeAmt | 订单金额 | String | 12 | 是 | 交易金额(单位元,带两位小数,例:1.23,最大整数16位) |
feeType | 币种 | String | 否 | 默认是CNY:人民币,当前版本暂不支持其它币种。 | |
tradeTime | 提交支付时间 | String | 14 | 是 | 格式[yyyyMMddHHmmss] ; |
orderPeriod | 订单有效时间 | String | 14 | 是 | 订单有效期(单位分钟) |
notifyUrl | 后台通知地址 | String | 200 | 是 | 支付成功时,后台通知商户的地址,必须为http/https协议地址 |
returnUrl | 前台通知地址 | String | 200 | 是 | 支付成功是,前台页面跳转的提示页面,为空不发前台通知,必须为http/https协议地址 |
refererUrl | 客户端地址 | String | 200 | 否 | 重定向地址,可直接跳转到商户页面(不会附加参数返回) |
termType | 终端接入类型 | String | 8 | 是 | 固定值:wap,pc,app |
paywayCode | 支付方式 | String | 20 | 是 | alipay-支付宝 wxpay-微信支付 unionpay-银联支付例如:当微信支付时传值 wxpay |
sceneCode | 场景编号 | String | 20 | 是 | h5-H5支付app-APP支付scan-扫码支付jspay-公众号支付ebank-网银支付gateway-网关支付例如:当支付场景为H5支付时传值“h5”注:当支付方式选“ebank”即网银支付时,场景编号传送值为“ebank”; |
ip | 客户端IP(外网IP) | String | 32 | 是 | |
merchantId | 商户编号 | String | 8 | 否 | |
storeId | 门店编号 | String | 8 | 否 | |
payeeId | 收银员编号 | String | 8 | 否 | |
remark | 备注 | String | 100 | 否 | |
attach | 附加信息 | String | 128 | 否 | |
deviceInfo | 应用类型 | String | 16 | 否 | 如果是应用于苹果app,应用里值为IOS_SDK;如果是应用于安卓app,应用里值为AND_SDK;如果是应用于手机网站,应用里值为WAP_SDK,微信h5必输 |
mchAppName | 应用名 | String | 256 | 否 | 如果是用于苹果或安卓app应用中,传分别对应在AppStore和安卓分发市场中的应用名(如:王者荣耀)如果是用于手机网站,传对应的网站名(如:天猫官网)微信h5必输 |
mchAppId | 应用标识 | String | 128 | 否 | 如是是用于苹果或安卓app应用中,苹果传IOS应用中唯一标识(如:com.tencent.wzryIOS),安卓传包名(如:com.tencent.tmgp.sgame)如果是用于手机网站,传网站首页URL地址,必须保证公网能正常访问(如:www.itbeien.cn)>微信h5必输 |
bankCode | 网银银行编码 | String | 20 | 否 | 网银支付必传,见银行代码 |
payType | 支付卡类型 | String | 1 | 否 | 1 借记卡 2 贷记卡 3借/贷记卡均可使用。网银支付传此参数,不传默认为1,即 借记卡 |
quickPayAttach | 快捷支付参数 | String | 否 | 快捷支付直连时必输 |
4.1.3 同步响应参数
字段 | 名称 | 类型 | 长度 | 必输 | 备注 |
---|---|---|---|---|---|
mercOrderNo | 商户订单号 | String | 是 | 商户自己生成的唯一的订单号 | |
tradeType | 交易类型 | String | 是 | 01-支付 11-充值 02-代付 03-提现 | |
tradeAmt | 交易金额 | String | 是 | 交易金额 | |
tradeTime | 支付提交时间 | String | 是 | 订单提交时间,格式[yyyyMMddHHmmss] ; | |
feeType | 币种 | String | 是 | 默认是CNY:人民币,当前版本暂不支持其它币种。 | |
termType | 终端接入类型 | String | 是 | 固定值:wap,pc,app | |
orderId | 平台订单号 | String | 32 | 是 | 平台订单号,可以理解成支付平台返回号 |
codeUrl | 二维码链接 | String | 128 | 否 | 二维码链接 扫码必输 |
imgUrl | 二维码图片 | String | 128 | 否 | 二维码图片 |
payInfo | 公众号支付信息 | String | 128 | 否 | 公众号支付信息 |
mwebUrl | H5支付地址 | String | 128 | 否 | H5支付地址 |
bankType | 付款银行 | String | 16 | 否 | 银行类型 |
resultHtml | 支付form | String | 否 | 网银支付返回必输,格式为form表单 |
4.1.4 响应报文实例
{
"orderId":"2024061812582900001378",
"signature":"5974FF8536CC614F6C2XXXXXXXXXXXX",
"termType":"wap",
"mercOrderNo":"D20180315125826",
"tradeType":"01",
"codeUrl":"https://www.itbeien.cn/qr/5519dddb",
"respDesc":"处理成功",
"feeType":"CNY",
"mercNo":"ORG1520825458796",
"tradeTime":"20240618125826",
"interfaceCode":"pay",
"respCode":"000000"
}
4.2 支付通知接口
商户回调接口使用HTTPS协议可以保证数据传输的安全性,所以建议商户提供的回调接口采用HTTPS协议。商户交易完成后,由聚合收银台异步推送至商户。商户接受处理成功后,需返回给平台success。
4.2.1 通知结果参数列表
字段 | 名称 | 类型 | 长度 | 必输 | 备注 |
---|---|---|---|---|---|
mercOrderNo | 商户订单号 | String | 是 | 商户自己生成的唯一的订单号 | |
tradeType | 交易类型 | String | 是 | 01-支付 11-充值 02-代付 03-提现 | |
tradeAmt | 交易金额 | String | 是 | 交易金额 | |
tradeTime | 支付提交时间 | String | 是 | 订单提交时间,格式[yyyyMMddHHmmss] ; | |
feeType | 币种 | String | 是 | 默认是CNY:人民币,当前版本暂不支持其它币种。 | |
termType | 终端接入类型 | String | 是 | 固定值:wap,pc,app | |
orderId | 平台订单号 | String | 32 | 是 | 平台订单号,可以理解成支付平台返回号 |
tradeEndTime | 交易完成时间 | String | 是 | 支付平台保证精确的支付交易完成时间。 | |
payStatus | 支付状态 | String | 是 | p0001 :提交订单 p0002:支付中 p0000 :支付成功 p0004:支付失败 p0005:已取消 p0006:过期已作废 | |
bankType | 付款银行 | String | 16 | 否 | 银行类型 |
4.2.2 支付异步通知参数示例
{
"tradeAmt":"0.01",
"charset":"UTF-8",
"orderId":"2024061812582900001378",
"signature":"0B5E5BAD0C447582A99618EEB0A35567",
"termType":"wap",
"mercOrderNo":"D20180315125826",
"feeType":"CNY",
"locale":"CN",
"tradeEndTime":"20240618125846",
"version":"1.0",
"mercNo":"ORG1520825458796",
"tradeTime":"20240618125828",
"signType":"MD5",
"payStatus":"p0000",
"tradeType":"01"
}
4.2.3 通知结果反馈
聚合收银台通过 notifyUrl 通知商户,商户做业务处理后,需要以字符串的形式反馈处理结果,内容如下:
返回结果 | 结果说明 |
---|---|
success | 处理成功 |
fail | 处理不成功 |
4.2.4 补单机制
注意:聚合收银台通知交互模式,如果聚合收银台收到商户的应答不是纯字符串success或超过5秒后返回时,聚合收银台认为通知失败,聚合收银台会通过一定的策略(通知频率为10/10/10/10/10,单位:秒)间接性重新发起通知,尽可能提高通知的成功率,但平台不保证通知最终能成功。由于存在重新发送后台通知的情况,因此同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。聚合收银台推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回纯字符串success。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重复插入数据造成的数据混乱。
5 加入项目实战
欢迎关注我的视频号,视频号有相关技术和业务视频可学习支付业务/文旅行业数字化。探讨技术(系统架构、微服务、容器化、云原生)