公共约定
先看完这一节,能省掉大部分对接问题。
| 约定 | 说明 |
|---|---|
| 接口前缀 | https://api.tcozon.top |
| 请求方式 | 全部 POST,Content-Type: application/json |
| 参数命名 | 驼峰(mchId、outTradeNo),不是下划线 |
| 金额单位 | 分,整数。100 表示 ¥1.00,不要传小数或字符串 |
| 字符编码 | UTF-8 |
| 响应结构 | { code, message, data, sign },code="0000" 为成功 |
| 幂等 | 同一商户下 outTradeNo 唯一;重复提交返回原订单,不会重复建单 |
参数名一律驼峰。如果你参考过旧版文档里的 mch_id / out_trade_no 这类下划线写法,那是过时的,会导致参数错误与签名失败。
签名规则
算法 SHA256withRSA,结果 Base64。三步。
- 取除
sign外的所有参数,按参数名 ASCII 升序排序 - 拼成
key=value&key=value,跳过值为空的参数,末尾不留& - 用商户私钥做 SHA256withRSA 签名 → Base64 → 作为
sign提交
mchId=DEMO_MCH_001&nonceStr=72a66a99dc4644e69ee3&outTradeNo=SHOP20260830001&payType=CASHIER&subject=咖啡一杯&totalAmount=100
签名串里用原始值,不要 URL 编码、不要加引号。金额是整数:totalAmount=100,不是 1.00 也不是 "100"。
各语言实现代码见《商户接入指南》第 03 节(Java / PHP / Python / Node)。
验证平台响应
响应与回调都带 sign,用平台公钥按同样规则验签,确认消息确实来自本平台。
收银台下单
推荐用这个。返回一个收银台链接,顾客打开即可选微信或支付宝付款。你不需要处理 openid,也不需要区分渠道。
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mchId | string | 必填 | 平台分配的商户号 |
| outTradeNo | string | 必填 | 你自己的订单号,同一商户下唯一 |
| totalAmount | int | 必填 | 金额,单位分,正整数 |
| payType | string | 必填 | CASHIER 顾客自选 · WX_LITE 仅微信 · ALI_NATIVE 仅支付宝 |
| subject | string | 选填 | 商品描述,显示在付款页 |
| nonceStr | string | 选填 | 随机串,建议每次都带,防重放 |
| sign | string | 必填 | RSA2 签名 |
响应参数
| 字段 | 说明 |
|---|---|
| data.cashierUrl | 收银台链接。发给顾客 / 生成二维码 / 直接跳转均可 |
| data.tradeNo | 平台流水号。查询、退款时可用 |
| data.outTradeNo | 回显你的订单号 |
| sign | 平台签名,可用平台公钥验证 |
{
"mchId": "DEMO_MCH_001",
"outTradeNo": "SHOP20260830001",
"totalAmount": 100,
"payType": "CASHIER",
"subject": "咖啡一杯",
"nonceStr": "72a66a99dc4644e69ee3",
"sign": "GSs+Nn7kiVEQo6OzcBJCm7iwr0SMCohOZEXO5LF7Hzo+..."
}
{
"code": "0000",
"message": "成功",
"data": {
"cashierUrl": "https://api.tcozon.top/checkout.html?t=P5d511fddfca745f0bfb3",
"tradeNo": "P5d511fddfca745f0bfb3",
"outTradeNo": "SHOP20260830001"
},
"sign": "kQ8D3oJi8qJFFf9b99FjadVO0qJkQoin4sC702CoSh/..."
}
收银台链接里不含金额明文,顾客改不了价格。链接可重复打开,付过一次后不会重复扣款。
统一下单
直接指定渠道下单,返回该渠道的拉起参数。需要你自己处理 openid 与拉起逻辑,多数场景建议用上面的收银台下单。
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mchId | string | 必填 | 商户号 |
| outTradeNo | string | 必填 | 商户订单号,唯一 |
| totalAmount | int | 必填 | 金额(分),须 > 0 |
| payType | string | 必填 | 见 payType 枚举 |
| subject | string | 选填 | 商品描述 |
| openid | string | 条件必填 | WX_JSAPI / WX_LITE 必填,须是对应 appid 下的 openid |
| notifyUrl | string | 选填 | 本单回调地址,不传则用商户后台配置的 |
| nonceStr | string | 选填 | 随机串 |
| sign | string | 必填 | RSA2 签名 |
响应参数
| 字段 | 说明 |
|---|---|
| data.tradeNo | 平台流水号 |
| data.outTradeNo | 商户订单号 |
| data.state | 订单状态,下单成功后为 NOTPAY |
| data.payInfo | 拉起支付所需数据。微信 JSAPI/小程序为 wx.requestPayment 的参数 JSON 字符串;支付宝正扫为二维码 URL |
{
"code": "0000",
"data": {
"tradeNo": "P979cb0f420d542c5bee79794eec31d76",
"outTradeNo": "SHOP20260830002",
"state": "NOTPAY",
"payInfo": "https://qr.alipay.com/bax04958be9ibxtajjgo3012"
},
"sign": "..."
}
微信 JSAPI / 小程序的 payInfo 是 JSON 字符串,不是对象。前端拿到后需要先 JSON.parse 再传给 wx.requestPayment。
订单查询
回调没收到、或需要主动对账时调用。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mchId | string | 必填 | 商户号 |
| outTradeNo | string | 必填 | 商户订单号 |
| nonceStr | string | 选填 | 随机串 |
| sign | string | 必填 | RSA2 签名 |
{
"code": "0000",
"data": {
"tradeNo": "P5d511fddfca745f0bfb3",
"outTradeNo": "SHOP20260830001",
"state": "SUCCESS"
},
"sign": "..."
}
申请退款
仅已支付订单可退,支持部分退款,原路退回付款人。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mchId | string | 必填 | 商户号 |
| outTradeNo | string | 必填 | 原订单号 |
| outRefundNo | string | 必填 | 你自己的退款单号,唯一 |
| refundAmount | int | 必填 | 退款金额(分),不能大于原订单金额 |
| nonceStr | string | 选填 | 随机串 |
| sign | string | 必填 | RSA2 签名 |
data 为上游退款返回原文。全额退款成功后订单状态变为 REFUND。
也可以直接在商户后台「我的订单」里点退款,不用写代码。
发货
微信小程序支付的订单,支付成功后需上传发货信息,否则影响资金结算。虚拟商品由平台自动完成;实物商品必须由你提供真实物流单号。
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| mchId | string | 必填 | 商户号 |
| outTradeNo | string | 必填 | 订单号,必须是你自己的订单 |
| logisticsType | int | 条件必填 | 1=快递 2=同城配送 3=虚拟商品 4=用户自提。不传则按你在商户后台配置的发货模式 |
| trackingNo | string | 条件必填 | 物流单号,logisticsType=1 时必填 |
| expressCompany | string | 条件必填 | 物流公司编码(如 SF 顺丰、YTO 圆通、ZTO 中通、JD 京东),logisticsType=1 时必填 |
| itemDesc | string | 选填 | 商品描述,不传用下单时的 subject |
| nonceStr | string | 选填 | 随机串 |
| sign | string | 必填 | RSA2 签名 |
{
"mchId": "DEMO_MCH_001",
"outTradeNo": "SHOP20260830001",
"logisticsType": 1,
"trackingNo": "SF1234567890123",
"expressCompany": "SF",
"nonceStr": "72a66a99dc4644e69ee3",
"sign": "..."
}
{
"mchId": "DEMO_MCH_001",
"outTradeNo": "SHOP20260830001",
"logisticsType": 3,
"nonceStr": "72a66a99dc4644e69ee3",
"sign": "..."
}
响应 data 含 ok(是否成功)与 message。接口幂等:同一订单重复发货不会重复上报。
实物商品不要按虚拟发货上报。那是向微信提供不实信息,可能导致小程序被处罚。销售实物请在商户后台把发货模式设为「实物商品」,平台就不会自动按虚拟发货处理,等你提供真实单号。
支付结果通知
顾客付款成功后,平台 POST 一个 JSON 到你配置的回调地址。这是你给订单发货 / 开通服务的触发点。
通知报文
| 字段 | 类型 | 说明 |
|---|---|---|
| mchId | string | 商户号 |
| outTradeNo | string | 你的订单号 |
| tradeNo | string | 平台流水号 |
| totalAmount | int | 订单金额(分) |
| state | string | 订单状态,成功通知为 SUCCESS |
| sign | string | 平台签名,必须用平台公钥验证 |
{
"mchId": "DEMO_MCH_001",
"outTradeNo": "SHOP20260830001",
"tradeNo": "P5d511fddfca745f0bfb3",
"totalAmount": 100,
"state": "SUCCESS",
"sign": "..."
}
你必须做三件事
| 步骤 | 做什么 | 为什么 |
|---|---|---|
| 验签 | 用平台公钥验证 sign | 防止伪造回调骗取发货 |
| 校验金额 | 核对 totalAmount 与本地订单一致 | 防止金额被篡改 |
| 返回 SUCCESS | 响应体纯文本 SUCCESS(不是 JSON) | 没收到会重试,并标记为通知失败 |
回调必须做幂等。网络重试可能让同一笔回调到达多次。先查自己的订单状态,已处理过就直接返回 SUCCESS,不要重复发货。
沙盒接口
沙盒模式下所有流程与生产完全一致(同样的签名、回调、手续费计算),只是不产生真实扣款。联系运营开通后即可使用。
下单流程不变(还是调 /v1/pay/cashier),顾客付款环节改用下面两个接口模拟。
模拟支付成功。订单置为 SUCCESS,并向你的回调地址发送与生产完全一致的通知。幂等:重复调用不会重复发通知。
模拟支付失败。订单置为 CLOSED,用于测试你的失败分支。
curl -X POST "https://api.tcozon.top/v1/pay/sandbox/pay?t=P5d511fddfca745f0bfb3" # 响应 { "code": "0000", "data": { "state": "SUCCESS", "amount": 100, "sandbox": true } }
沙盒接口只对沙盒订单生效。对生产订单调用会返回「非沙盒订单不可模拟支付」。沙盒订单不计入经营数据。
payType 枚举
| 值 | 渠道 | 是否需要 openid | 说明 |
|---|---|---|---|
| CASHIER | 顾客自选 | 否 | 推荐。收银台下单专用,顾客在收银台选微信或支付宝 |
| WX_LITE | 微信小程序 | 是 | 小程序内支付;用收银台下单时表示「仅微信」 |
| WX_JSAPI | 微信公众号 | 是 | 微信内 H5 支付 |
| ALI_NATIVE | 支付宝正扫 | 否 | 返回二维码链接;用收银台下单时表示「仅支付宝」 |
本平台为间连模式,上游不支持 WX_H5(微信直连 H5)与 ALI_H5(支付宝手机网站),调用会返回「交易类型不支持」。等价替代:微信走拉起小程序、支付宝走正扫链接——收银台已自动处理,无需你关心。
订单状态
| state | 含义 | 说明 |
|---|---|---|
| NOTPAY | 待支付 | 已下单,顾客尚未付款 |
| SUCCESS | 已支付 | 付款成功,此时会发出回调 |
| CLOSED | 已关闭 | 下单失败、超时未付或被主动关单 |
| REFUND | 已退款 | 全额退款完成 |
错误码
| code | 含义 | 怎么处理 |
|---|---|---|
| 0000 | 成功 | — |
| 2001 | 参数错误 | 看 message,通常是必填项缺失或金额格式不对 |
| 2002 | 商户不存在或已禁用 | 核对 mchId;若被禁用请联系运营 |
| 3001 | 签名验证失败 | 检查:私钥是否用对、是否跳过 sign 与空值、排序是否 ASCII 升序、值是否被 URL 编码、金额是否整数分、编码是否 UTF-8 |
| 4001 | 未登录或登录已过期 | 商户后台重新登录 |
| 4004 | 订单不存在 | 核对 outTradeNo 及其归属商户号 |
| 5001 | 上游渠道处理失败 | message 含渠道原因,可重试;持续失败请联系我们 |
| 9999 | 系统内部错误 | 请联系我们并提供 outTradeNo |
微信发货规则
走微信小程序支付(WX_LITE,含收银台的「仅微信」)的订单,微信要求支付成功后上传发货信息,否则影响该小程序的资金结算。
两种模式
| 你卖的是 | 怎么发货 | 你要做什么 |
|---|---|---|
| 虚拟商品 / 服务 默认模式 |
平台在支付成功后自动按虚拟发货上传 | 什么都不用做。也可在商户后台或调发货接口手动补发 |
| 实物商品 | 需要真实物流单号,平台不会自动上传 | ①在商户后台把发货模式设为「实物商品」 ②发货后调发货接口或在后台填单号 |
卖实物却按虚拟发货上报,是向微信提供不实信息。请务必把发货模式设对——设成实物后平台就不再自动处理,等你提供真实单号。
在商户后台操作
商户后台 →「发货管理」,能看到所有需发货的订单、切换发货模式、逐单发货或一键虚拟发货。每笔订单的发货状态也会显示在「我的订单」里。
| 状态 | 含义 | 要做什么 |
|---|---|---|
| (无标记) | 非微信小程序支付,不涉及发货 | 无 |
| 📦 待发货 | 虚拟模式:平台处理中;实物模式:等你发货 | 虚拟无需处理;实物请尽快填单号 |
| 📦 已发货 | 微信已确认收到 | 无 |
| 📦 发货异常 | 上传失败 | 在发货管理页看原因并重试;处理不了联系运营 |