个人随笔
目录
用AI生成的第三方超市支付码对接设计文档
2026-04-14 17:19:18

一、文档概述

1.1 文档目的

本文档用于规范我方支付系统与第三方超市系统的支付码对接流程,明确核心业务逻辑、数据库表设计、接口定义、加密签名规则及对账机制,确保对接过程合规、安全、高效,支撑线下超市扫码支付、退款、对账等全场景业务落地。

1.2 业务场景

我方系统为用户提供支付码,用户在第三方超市消费时,出示我方支付码,超市收银系统扫码后调用我方接口完成扣款,我方系统负责用户余额校验、扣款、交易记录留存及退款、对账等操作,不介入超市自身订单生成、商品管理等业务。

1.3 角色定义

  • 我方系统:支付能力提供方,负责用户账户管理、支付码生成与核验、交易风控、扣款/退款、流水记录、对账清算,提供接口供超市系统调用。

  • 第三方超市系统:收单侧商户系统,负责商品订单生成、扫码读取支付码、发起支付/退款请求、接收支付结果、完成对账,调用我方接口实现支付功能。

  • 用户:我方系统注册用户,通过我方系统生成支付码,在超市完成消费支付。

二、数据库表设计(必选+辅助)

核心原则:我方系统不存储超市订单详情,仅留存支付相关流水记录,确保交易可追溯、可对账、可退款,所有金额字段均以“分”为单位存储,避免浮点精度误差。

2.1 必选表(核心表,缺一不可)

2.1.1 支付流水表(payment_trade)

用途:存储每一笔超市扫码支付的完整交易记录,作为支付、查询、对账、退款的核心依据。

字段名 字段类型 是否必填 字段说明
id bigint 主键,我方系统唯一支付流水号(自增/雪花算法生成)
out_trade_no varchar(64) 第三方超市系统的订单号,唯一标识超市侧订单,用于关联对账、查询、退款
auth_code varchar(32) 用户出示的支付码(脱敏存储,如仅存后4位,前几位用*代替),用于核验支付有效性
user_id varchar(64) 我方系统用户ID,关联用户账户,明确扣款对象
total_amount int 交易总金额(单位:分),避免浮点误差
status varchar(16) 交易状态:WAIT(支付中)、PAID(支付成功)、FAIL(支付失败)、CANCEL(交易取消)、REFUND(全额退款)
pay_time datetime 支付成功时间,支付失败则为空
refund_amount int 累计已退款金额(单位:分),初始值为0,退款后累计更新
refund_status varchar(16) 退款状态:NO_REFUND(无退款)、REFUNDING(退款中)、REFUNDED(全额退款)、PART_REFUND(部分退款)
channel varchar(32) 渠道标识,如“SUPERMARKET_XX”(XX为超市编码),区分不同合作超市
store_id varchar(32) 超市门店编号,可选,用于超市分门店对账
terminal_id varchar(32) 超市收银机终端号,可选,用于定位具体收银设备交易
subject varchar(128) 交易标题,默认“超市消费”,可由超市传入商品描述
create_time datetime 交易创建时间(超市发起支付请求的时间)
update_time datetime 交易状态更新时间,每次状态变更自动更新
remark varchar(256) 备注,存储支付失败原因、异常说明等

2.1.2 退款流水表(payment_refund)

用途:存储每一笔退款交易记录,关联支付流水,支撑退款查询、对账及财务凭证留存。

字段名 字段类型 是否必填 字段说明
id bigint 主键,我方系统唯一退款流水号(自增/雪花算法生成)
refund_no varchar(64) 我方系统生成的退款单号,唯一标识一笔退款
trade_id bigint 关联支付流水表的主键(id),绑定对应的支付交易
out_trade_no varchar(64) 第三方超市的原订单号,与支付流水表一致,用于对账
out_refund_no varchar(64) 第三方超市系统的退款单号,唯一标识超市侧退款请求
refund_amount int 退款金额(单位:分),可支持部分退款(不超过原交易金额)
status varchar(16) 退款状态:PROCESSING(退款中)、SUCCESS(退款成功)、FAIL(退款失败)
refund_time datetime 退款成功时间,退款失败则为空
reason varchar(256) 退款原因,由超市传入(如“用户退货”“多收金额”)
create_time datetime 退款请求创建时间
update_time datetime 退款状态更新时间,每次状态变更自动更新

2.2 辅助表(按需可选,提升业务完整性)

2.2.1 用户账户表(user_account)

用途:存储我方系统用户的账户信息及余额,用于扣款、退款操作(若我方系统已有用户体系,可复用现有表)。

字段名 字段类型 是否必填 字段说明
user_id varchar(64) 主键,我方系统用户唯一ID,与支付流水表user_id关联
balance int 用户账户余额(单位:分),初始值为0,支付扣款、退款到账时更新
status varchar(16) 账户状态:NORMAL(正常)、FROZEN(冻结)、DISABLED(禁用),冻结/禁用时无法支付
create_time datetime 账户创建时间
update_time datetime 账户信息更新时间(如余额、状态变更)

2.2.2 商户信息表(merchant_info)

用途:存储合作超市的商户信息,用于接口鉴权、渠道区分、对账等。

字段名 字段类型 是否必填 字段说明
merchant_id varchar(32) 主键,我方系统分配给超市的唯一商户号,用于接口鉴权
merchant_name varchar(64) 超市名称,用于用户账单展示、对账备注
app_secret varchar(128) 商户密钥,用于接口签名、鉴权,需加密存储
channel varchar(32) 渠道标识,与支付流水表channel一致
callback_url varchar(256) 超市提供的支付结果异步回调地址,我方系统推送交易终态
status varchar(16) 商户状态:NORMAL(正常)、DISABLED(禁用),禁用时无法调用接口

2.2.3 对账文件记录表(reconciliation_file)

用途:存储每日对账文件的生成信息,用于对账文件管理、查询、追溯。

字段名 字段类型 是否必填 字段说明
id bigint 主键,自增
merchant_id varchar(32) 关联商户信息表,对应具体超市
reconciliation_date date 对账日期(T+1,即前一日交易)
file_type varchar(16) 文件类型:DETAIL(明细文件)、SUMMARY(汇总文件)
file_url varchar(256) 对账文件下载地址(临时有效,如24小时)
file_md5 varchar(64) 文件MD5校验值,用于超市校验文件完整性
create_time datetime 文件生成时间(每日凌晨生成前一日文件)

三、核心业务流程

整体流程围绕“支付-查询-退款-对账”闭环展开,核心为线下被扫支付,不涉及我方系统订单生成,仅负责支付相关操作。

3.1 支付流程(核心流程)

  1. 用户在我方系统生成一次性支付码(内部流程,无需对外接口,支付码需设置有效期,如30秒);

  2. 用户在超市收银台出示支付码,超市收银系统通过扫码枪读取支付码码值(auth_code);

  3. 超市系统生成自身订单(out_trade_no),调用我方“付款码支付接口”,传入核心参数并通过appsecret完成签名;

  4. 我方系统接收请求后,先进行接口鉴权(验证商户号有效性)及签名验证(通过appsecret校验签名合法性);

  5. 我方系统核验支付码有效性(是否过期、是否挂失、是否绑定有效用户);

  6. 核验通过后,查询用户账户余额,判断余额是否充足;

  7. 余额充足:扣减用户账户余额,在支付流水表插入一条记录(status=PAID,pay_time=当前时间),返回支付成功结果;

  8. 余额不足/支付码无效:在支付流水表插入一条记录(status=FAIL,remark=失败原因),返回支付失败结果;

  9. 我方系统将支付终态(成功/失败)主动推送至超市提供的回调地址(异步回调),作为同步接口的兜底机制;

  10. 超市系统接收支付结果/回调通知,完成收银闭环,向用户展示支付结果。

3.2 支付结果查询流程(异常处理流程)

  1. 当超市调用“付款码支付接口”超时、返回“支付中”(WAIT),或收银机断网、设备故障时,超市系统调用我方“支付结果查询接口”,传入参数并通过appsecret签名;

  2. 我方系统接收请求,完成签名验证及商户鉴权后,通过“超市订单号(out_trade_no)”或“我方支付流水号(id)”查询支付流水表;

  3. 返回该笔交易的最终状态(PAID/FAIL)、交易金额、支付时间等信息;

  4. 超市系统根据查询结果,更新自身订单状态,避免单边账(用户扣款成功、超市未确认)。

3.3 退款流程(售后流程)

  1. 用户退货/超市多收金额,超市系统生成自身退款订单(out_refund_no);

  2. 超市系统调用我方“退款接口”,传入原支付订单号、退款金额、退款原因等参数并通过appsecret签名;

  3. 我方系统接收请求,进行商户鉴权、签名验证,查询原支付流水记录(确认交易已成功,且未全额退款);

  4. 验证通过后,在退款流水表插入一条记录(status=PROCESSING);

  5. 我方系统将退款金额原路退回用户账户,更新用户账户余额;

  6. 更新退款流水表状态为SUCCESS(退款成功),更新支付流水表的refund_amount(累计退款金额)和refund_status(退款状态);

  7. 返回退款结果给超市系统,同时可通过异步回调推送退款终态;

  8. 若退款失败(如用户账户异常),更新退款流水表状态为FAIL,返回失败原因,超市可重新发起退款。

3.4 对账流程(财务闭环流程)

  1. 每日凌晨,我方系统生成前一日(T-1)的对账文件(明细文件+汇总文件),明细文件包含所有支付、退款交易详情,汇总文件包含交易总额、退款总额、净收入等;

  2. 我方系统将对账文件存储至安全服务器,生成下载地址,同时在对账文件记录表插入一条记录;

  3. 超市系统通过“对账文件下载接口”,传入对账日期、文件类型并通过appsecret签名,获取对账文件下载地址;

  4. 超市系统下载文件,通过MD5校验值验证文件完整性,将文件内容与自身订单记录、收银记录进行对账;

  5. 若对账一致,双方确认当日交易无误;若对账不一致,通过支付流水表、退款流水表排查差异(如单边账、金额不符),进行差错处理。

四、接口设计(必选+辅助)

核心原则:所有接口均采用HTTPS协议传输,无需Token鉴权,仅通过「商户号+appsecret签名」实现接口安全校验;接口请求/响应均采用JSON格式,编码为UTF-8;所有金额参数均以“分”为单位,日期时间格式统一为“yyyy-MM-dd HH:mm:ss”;接口超时时间统一设置为30秒,超市系统需做好超时重试机制(建议重试2次,间隔1秒)。

4.1 接口通用规则

4.1.1 通用请求参数(所有接口必传)

参数名 参数类型 是否必填 参数说明
merchant_id String 我方系统分配给超市的唯一商户号(对应商户信息表merchant_id)
timestamp Long 当前时间戳(毫秒级),用于防重放,请求时间与我方系统时间差不超过5分钟
nonce_str String 随机字符串(长度16-32位),由超市系统生成,用于防重放、防篡改
sign String 签名值,通过appsecret按照指定规则生成(详见4.1.2签名规则)

4.1.2 签名规则(所有接口统一)

签名目的:验证请求数据的完整性和合法性,防止数据被篡改、伪造请求,仅通过appsecret实现,无需额外Token。

  1. 参数排序:将请求中所有非空参数(含通用请求参数+接口专属参数)按照参数名ASCII码升序排列(字典序);

  2. 拼接字符串:将排序后的参数以“key=value”形式拼接,用“\&”连接,例如:merchant_id=123\&nonce_str=abc\&timestamp=1690000000000\&out_trade_no=CS20260414001;

  3. 补充密钥:在拼接字符串末尾拼接“\&appsecret=XXX”(XXX为商户信息表中的app_secret,需加密存储,双方严格保密);

  4. 生成签名:将上述拼接好的字符串进行MD5加密(32位小写),得到的结果即为sign值;

  5. 验证规则:我方系统接收请求后,按相同规则重新计算签名,与请求中的sign值对比,不一致则拒绝处理请求。

4.1.3 通用响应参数(所有接口统一返回)

参数名 参数类型 是否必返 参数说明
code String 响应码:200-请求成功;非200-请求失败(具体失败码见各接口说明)
message String 响应信息:成功返回“success”,失败返回具体失败原因(如“签名验证失败”“支付码已过期”)
data Object 响应数据:请求成功时返回接口专属数据,失败时为null
sign String 响应签名:我方系统用appsecret按4.1.2规则生成,超市系统可验证响应数据完整性

4.2 必选接口(核心接口,支撑支付、退款、对账核心流程)

4.2.1 付款码支付接口(核心支付接口)

接口用途:超市系统扫码获取支付码后,调用该接口完成用户扣款,是核心交易接口。

接口信息 请求方式:POST;接口地址:/api/v1/payment/scan-pay;请求格式:JSON;超时时间:30秒
专属请求参数 参数名 参数类型 是否必填 参数说明
out_trade_no String 超市系统订单号(对应支付流水表out_trade_no),唯一,长度不超过64位
auth_code String 用户支付码码值(对应支付流水表auth_code),无需脱敏,原样传入
total_amount Integer 交易总金额(单位:分),大于0,对应支付流水表total_amount
subject String 交易标题,默认“超市消费”,可传入商品描述,长度不超过128位(对应支付流水表subject)
store_id String 超市门店编号(对应支付流水表store_id),可选,用于分门店对账
terminal_id String 收银机终端号(对应支付流水表terminal_id),可选,用于定位具体收银设备

响应数据(data)

参数名 参数类型 说明
trade_id Long 我方系统支付流水号(对应支付流水表id)
out_trade_no String 超市系统订单号(与请求参数一致)
status String 交易状态:PAID(支付成功)、FAIL(支付失败)
pay_time String 支付成功时间(status=PAID时返回,否则为null)
balance Integer 用户支付后账户余额(单位:分,status=PAID时返回)

常见失败响应码

400-参数缺失/格式错误;401-商户号无效/商户已禁用;403-签名验证失败;405-支付码已过期/无效/挂失;406-用户账户冻结/禁用;407-用户余额不足;500-我方系统异常

4.2.2 支付结果查询接口(异常处理接口)

接口用途:当支付接口超时、返回支付中,或设备故障时,超市系统调用该接口查询交易最终状态,避免单边账。

接口信息 请求方式:GET;接口地址:/api/v1/payment/query;请求格式:JSON;超时时间:30秒
专属请求参数(二选一) 参数名 参数类型 是否必填 参数说明
out_trade_no String 二选一 超市系统订单号(对应支付流水表out_trade_no)
trade_id Long 二选一 我方系统支付流水号(对应支付流水表id)

响应数据(data)

参数名 参数类型 说明
trade_id Long 我方系统支付流水号
out_trade_no String 超市系统订单号
total_amount Integer 交易总金额(单位:分)
status String 交易最终状态:PAID(支付成功)、FAIL(支付失败)
pay_time String 支付成功时间(status=PAID时返回,否则为null)
refund_status String 退款状态(对应支付流水表refund_status)
remark String 备注(支付失败时返回失败原因)

常见失败响应码

400-参数缺失/格式错误(未传二选一参数);401-商户号无效/禁用;403-签名验证失败;404-交易不存在;500-我方系统异常

4.2.3 退款接口(售后接口)

接口用途:超市系统发起退款请求(用户退货、多收金额等场景),调用该接口完成退款,原路退回用户账户。

接口信息 请求方式:POST;接口地址:/api/v1/payment/refund;请求格式:JSON;超时时间:30秒
专属请求参数 参数名 参数类型 是否必填 参数说明
out_trade_no String 原支付对应的超市系统订单号(对应支付流水表out_trade_no)
out_refund_no String 超市系统退款单号(对应退款流水表out_refund_no),唯一,长度不超过64位
refund_amount Integer 退款金额(单位:分),大于0,不超过原交易总金额(对应退款流水表refund_amount)
reason String 退款原因(如“用户退货”“多收金额”),长度不超过256位(对应退款流水表reason)

响应数据(data)

参数名 参数类型 说明
refund_no String 我方系统退款单号(对应退款流水表refund_no)
out_refund_no String 超市系统退款单号(与请求参数一致)
out_trade_no String 原支付对应的超市系统订单号
refund_amount Integer 退款金额(单位:分)
status String 退款状态:SUCCESS(退款成功)、FAIL(退款失败)、PROCESSING(退款中)
refund_time String 退款成功时间(status=SUCCESS时返回,否则为null)

常见失败响应码

400-参数缺失/格式错误;401-商户号无效/禁用;403-签名验证失败;404-原交易不存在;405-原交易未支付/已全额退款;406-退款金额超过原交易金额;407-用户账户异常;500-我方系统异常

4.2.4 对账文件下载接口(财务闭环接口)

接口用途:超市系统每日调用该接口,下载前一日的对账文件(明细+汇总),完成对账操作。

接口信息 请求方式:GET;接口地址:/api/v1/reconciliation/download;请求格式:JSON;超时时间:30秒
专属请求参数 参数名 参数类型 是否必填 参数说明
reconciliation_date String 对账日期,格式“yyyy-MM-dd”,仅支持下载前一日(T-1)的文件(对应对账文件记录表reconciliation_date)
file_type String 文件类型:DETAIL(明细文件)、SUMMARY(汇总文件)(对应对账文件记录表file_type)

响应数据(data)

参数名 参数类型 说明
file_url String 对账文件下载地址(临时有效,24小时内有效,对应对账文件记录表file_url)
file_md5 String 文件MD5校验值(用于验证文件完整性,对应对账文件记录表file_md5)
file_size

(注:文档部分内容可能由 AI 生成)

 5

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2