聚合支付对接文档
协议与易支付 V1 完全一致:一个下单地址、一套 MD5 签名、一个异步回调。支持易支付协议的系统改三个字段即可接入,自研项目照下面的示例十来行写完。
第 1 步 · 拿凭据
开通后你会收到 商户 ID(PID)与 64 位商户密钥(KEY),以及属于你的收银台地址。
第 2 步 · 拼签名
参数按名升序拼 k=v&k=v,末尾直接接 KEY,做一次 MD5 小写。
第 3 步 · 收回调
用户付完,我们 GET 你的 notify_url,验签后返回 success 即完成。
01通用规则
| 传输方式 | HTTP / HTTPS,GET 或 POST 均可(推荐 POST,不易被劫持与缓存) |
| 数据格式 | 表单键值对(application/x-www-form-urlencoded) |
| 字符编码 | UTF-8 |
| 签名算法 | MD5,结果小写 32 位 |
| 金额单位 | 元,字符串,最多两位小数(10.10,不要传 10.1 之外的格式) |
| 接口地址 | https://vorbynsnty.kdns.fr/ypay/submit.php(下单)https://vorbynsnty.kdns.fr/ypay/mapi.php(查单) |
商户 ID 与密钥在「开通邮件」里;如果你是通过第三方系统接入,把上面这两个地址分别填到「接口地址 / 网关地址」即可,程序会自动拼后面的路径。
02签名算法(最关键的一步)
九成「签名错误」都出在下面四条里,逐条对:
| # | 规则 | 容易踩的坑 |
|---|---|---|
| 1 | 参与签名的只有发送的全部业务参数,排除 sign、sign_type,以及值为空串的参数 | 把 sign_type 也拼进去了;或把值为空的可选参数留成 key= 参与计算 |
| 2 | 按参数名 ASCII 升序排序(a→z) | 按提交顺序拼;大写的参数名排在小写前面 |
| 3 | 拼成 a=b&c=d&e=f,参数值不做 URL 编码,也不加引号 | 先 urlencode 再签名(中文商品名、回调地址里的 : / 会炸) |
| 4 | 末尾直接接商户密钥再 MD5:md5(拼接串 + KEY),小写 | 写成 &key=KEY、或把 KEY 放前面、或用了大写 MD5 |
// 待签名参数(sign / sign_type 不参与) money=10.10 name=VIP会员 notify_url=https://your.site/notify.php out_trade_no=ORD20261108001 pid=1001 return_url=https://your.site/return.php type=alipay // 按 ASCII 升序拼成一串(值不编码),末尾直接接 KEY money=10.10&name=VIP会员¬ify_url=https://your.site/notify.php&out_trade_no=ORD20261108001&pid=1001&return_url=https://your.site/return.php&type=alipay你的64位商户密钥 // 对这个整体做 MD5,取小写
03页面跳转支付(主流程)
用户点「去支付」时,浏览器直接跳到下面这个地址,我们接住后 302 到收银台(支付宝 / 微信)。
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
pid | 是 | String | 商户 ID,开通时下发(形如 1001) |
type | 是 | String | alipay 支付宝 / wxpay 微信支付 |
out_trade_no | 是 | String | 你的商户订单号,同一笔不要重复,建议「业务前缀 + 时间 + 随机」 |
money | 是 | String | 金额(元),两位小数,如 10.10 |
name | 是 | String | 商品名称,超过 127 字节会被截断 |
notify_url | 是 | String | 异步回调地址,必须公网可访问,不要带参数以外的登录态 |
return_url | 否 | String | 付款完成后用户浏览器跳回的地址(仅用于展示,不作为到账依据) |
sign | 是 | String | 按第 02 节算出的 32 位 MD5 |
sign_type | 否 | String | 固定 MD5 |
GET /ypay/submit.php ?pid=1001 &type=alipay &out_trade_no=ORD20261108001 &money=10.10 &name=VIP会员 ¬ify_url=https://your.site/notify.php &return_url=https://your.site/return.php &sign=8f14e45fceea167a5a36dedd4bea2543 &sign_type=MD5
04异步通知(到账的唯一依据)
用户付款成功后,我们的服务器会以 GET 方式请求你填的 notify_url。收到后先验签、再改单、最后返回纯文本 success。
| 参数 | 说明 |
|---|---|
pid | 商户 ID |
trade_no | 本平台订单号 |
out_trade_no | 你的商户订单号(用它找到本地订单) |
type | alipay / wxpay |
name | 商品名称(原样返回) |
money | 实际支付金额,务必与本地订单金额比对 |
trade_status | 只有 TRADE_SUCCESS 才是支付成功 |
sign / sign_type | 按第 02 节同规则验签 |
success(纯文本,不要带 HTML),否则我们会按退避策略重复通知,最长 6 次。
回调可能重复、也可能延迟,因此你的处理必须幂等:已处理的订单直接返回 success。回调没到时,用第 05 节的查单接口补一次,不要只依赖回调。
05查单(掉单补查)
GET https://vorbynsnty.kdns.fr/ypay/mapi.php ?pid=1001 &key=你的64位商户密钥 &out_trade_no=ORD20261108001
| 返回字段 | 说明 |
|---|---|
code | 1 查询成功;-1 参数或密钥错误 |
status | 1 = 已支付,0 = 未支付 |
out_trade_no / trade_no | 商户订单号 / 平台订单号 |
money / name | 金额与商品名 |
payment_time | 支付完成时间(未支付时为空) |
查单用 key 直接校验(不走 sign),所以这个接口只能在你自己的服务器上调用,别把密钥放进前端代码。
06代码示例
以 PHP 为例(大多数发卡 / 虚拟商品系统都是 PHP);Node.js 与 Python 只差一个排序拼接。
// 1) 发起支付:拼参数 → 排序 → 签名 → 跳转
$pid = '1001';
$key = '你的64位商户密钥';
$p = array(
'pid' => $pid,
'type' => 'alipay',
'out_trade_no' => 'ORD' . date('YmdHis') . mt_rand(1000, 9999),
'money' => '10.10',
'name' => 'VIP会员',
'notify_url' => 'https://your.site/notify.php',
'return_url' => 'https://your.site/return.php',
);
ksort($p); // ① ASCII 升序
$s = array();
foreach ($p as $k => $v) { $s[] = $k . '=' . $v; } // ② 值不做 urlencode
$p['sign'] = md5(implode('&', $s) . $key); // ③ 末尾直接接 KEY
$p['sign_type'] = 'MD5';
header('Location: https://vorbynsnty.kdns.fr/ypay/submit.php?' . http_build_query($p));
exit;
// 2) 收回调:验签 → 比金额 → 幂等改单 → 输出 success
$key = '你的64位商户密钥';
$g = $_GET; // 我们也可能用 POST,生产环境请合并 $_GET + $_POST
$sign = $g['sign'] ?? '';
unset($g['sign'], $g['sign_type']);
$g = array_filter($g, function ($v) { return $v !== ''; });
ksort($g);
$a = array();
foreach ($g as $k => $v) { $a[] = $k . '=' . $v; }
if (!hash_equals(md5(implode('&', $a) . $key), $sign)) { exit('fail'); }
if (($g['trade_status'] ?? '') !== 'TRADE_SUCCESS') { exit('fail'); }
// 这里务必校验:订单存在、金额一致、未处理过
// $order = find_order($g['out_trade_no']);
// if (!$order || $order['money'] != $g['money'] || $order['paid']) exit('success');
// mark_paid($order['id'], $g['trade_no']);
echo 'success';
Node.js 签名:
const crypto = require('crypto');
const sign = crypto.createHash('md5')
.update(Object.keys(p).sort().map(k => `${k}=${p[k]}`).join('&') + key)
.digest('hex');
Python 签名:
import hashlib
raw = '&'.join('%s=%s' % (k, p[k]) for k in sorted(p) if p[k] != '')
sign = hashlib.md5((raw + key).encode('utf-8')).hexdigest()
07排错对照表
| 现象 | 原因 | 怎么解 |
|---|---|---|
| 页面显示「签名错误」 | 签名串与我们的算法不一致,或密钥不是这一对 | 按第 02 节逐条核对;确认用的是开通邮件里那串 64 位 KEY,不是商户后台的登录密码 |
| 页面显示「商户不存在」 | PID 不属于这个网关 | 核对 PID;我们每个商户的 PID 是独立的,别填到别的平台 |
| 显示「在线支付暂未开通」 | 该商户名下没有可用通道 | 联系客服开通通道,或换 type 试另一通道 |
| 钱付了,订单还是待支付 | 回调没到 / 验签失败 / 没返回 success | 先看服务器访问日志有没有打到 notify_url;用第 05 节查单补单;仍不行把订单号发客服 |
| 回调到了但被重复处理 | 没有做幂等 | 已支付的订单直接 return success,不要重复发货 / 加余额 |
| 金额对不上 | 用了 float 直接比较,或传了 10.1 这类格式 | 金额统一用「分」为整数存储,或按字符串比较两位小数 |
08费率与结算
| 费率 | 标准 3.0%,月流水 5 万以上 2.8%,20 万以上 2.5% 起(以开通时确认为准) |
| 计费方式 | 按实际成功收款金额计费,退款部分不计费 |
| 结算周期 | T+1 自动结算到约定的支付宝 / 微信 / 银行卡 |
| 最低结算 | 单次结算不低于 10 元,未达累计到下个结算日 |
| 对账 | 每笔订单可查平台订单号与支付时间;需要日账单可向客服索取 |
09商户查询接口(对账用)
除下单与回调外,我们还开放了一组 只读查询接口,供你在自己的后台或脚本里拉账户、订单和结算数据,
不必登录收银台后台。地址统一为 https://vorbynsnty.kdns.fr/api.php?r=接口名。
鉴权:uid + sign
每个接口都必须带 uid(你的商户 ID)和 sign,签名规则与下单完全相同:
除 sign / sign_type 外的非空参数,按参数名 ASCII 升序拼成 k=v&k=v(值不 urlencode),
末尾直接接你的 64 位密钥,MD5 取小写。GET 与 POST(表单或 JSON)都支持,参数一并参与签名。
// PHP 示例:查账户概览
$uid = '1001';
$key = '你的64位商户密钥';
$p = array('uid' => $uid);
ksort($p);
$str = urldecode(http_build_query($p)); // 值不做 urlencode,所以 decode 回来
$sign = md5($str . $key);
$url = 'https://vorbynsnty.kdns.fr/api.php?r=agg%2Fapi%2Faccount'
. '&uid=' . $uid . '&sign=' . $sign;
echo file_get_contents($url);
接口一览
| 接口 | 作用 | 主要参数 |
|---|---|---|
agg/api/account |
账户概览:费率、已开通通道、累计 / 今日流水、可结算与待结算金额 | uid sign |
agg/api/stats |
经营汇总:今日 / 昨日 / 本月 / 累计四组收入、退款、手续费、应结金额 | uid sign |
agg/api/query |
单笔订单查询,返回状态、支付时间、手续费与应结金额 | trade_no 或 out_trade_no |
agg/api/orders |
订单列表,分页 + 按状态 / 通道 / 日期筛选 | page limit state type start_date end_date |
agg/api/settle |
结算流水:按支付日期聚合,含当日笔数、收入、退款、手续费、应结金额与结算状态 | page limit start_date end_date |
订单字段
| 字段 | 说明 |
|---|---|
out_trade_no | 平台订单号(我们系统生成,回调里也会带) |
trade_no | 商户订单号,即你下单时传的 out_trade_no |
type / type_name | 通道标识与中文名:alipay 支付宝、wxpay 微信支付、qqpay QQ 钱包 |
money / refund | 订单金额 / 已退款金额 |
fee / settle_money | 按你的费率算出的手续费 / 实际应结金额 |
state / state_name | 0 未支付、1 支付完成、2 已退款 |
created_at / paid_at | 下单时间 / 支付完成时间(未支付为空) |
返回示例
{
"uid": "1001",
"code": "VB5C1338CBF8",
"name": "示例商户",
"rate": 3.0,
"state": "正常",
"expire_at": "2027-11-08 23:59:59",
"channels": ["微信支付", "支付宝"],
"cashier_url": "https://vorbynsnty.kdns.fr/ypay/public/index.php?s=/cashier/VB5C1338CBF8",
"total": { "count": 128, "income": 6800.00, "refund": 60.00, "fee": 202.20, "net": 6537.80 },
"today": { "count": 6, "income": 320.00, "refund": 0.00, "fee": 9.60, "net": 310.40 },
"settleable": 6227.40,
"pending": 310.40,
"server_time": "2026-11-09 07:40:00",
"ok": true
}
结算口径
T+1:当天的成功收款计入 pending(待结算),次日进入 settleable(可结算),由平台统一打款。
手续费按 money - refund 乘你的费率计算,退款部分不计费。
agg/api/settle 返回的每日记录里,昨天及更早的日期标记为「已结算」,当天的标记为「待结算」。
错误码
| code | 含义 | 怎么处理 |
|---|---|---|
param | 缺少必填参数(如 uid、订单号) | 检查参数是否传全,空值会被签名忽略 |
sign_missing | 没带 sign | 补签名 |
sign_error | 签名不匹配 | 参数排序、剔除空值与 sign、末尾直接拼 KEY、MD5 小写,四步逐一核对 |
merchant | uid 不存在 | 核对商户 ID |
disabled / expired | 商户被停用 / 已到期 | 联系平台恢复或续期 |
order | 订单不存在 | 确认订单号是否属于该商户 |
这组接口是只读的:不能下单、不能退款、不能改配置。退款与提现请在收银台后台操作,或联系客服。 查询接口有频率限制,轮询对账建议 5 分钟一次,不要每秒拉全量。
10平台性质与底层渠道
Vorbyn Pay 是一套聚合支付技术工具:它把你的订单统一起来,转发给上游支付渠道完成收款, 再把渠道的回调结果通知给你。本平台不持牌、不清算、不沉淀资金——钱从付款人直接进入渠道账户, 由渠道方完成清算与结算。我们负责的是下单、签名、验签、对账与排障。
实际收款与结算由谁完成
| 渠道 | 角色 | 官网 | 说明 |
|---|---|---|---|
| 码支付 | 实际收款方 微信 / 支付宝 |
mzf.net.cn | 易支付标准协议(MD5 签名)。收款、清算、结算都在码支付侧完成。 |
| 星益聚合收银台 | 聚合层收银台 v1.45 |
/ypay/ | 给每个商户分配收银台地址、收款码与通道;底层通道同样指向码支付。 |
你能在渠道后台看到什么
开通后,除了本平台的商户中心,你还会拿到上面两个渠道后台的登录方式(在商户中心「渠道说明」里), 用它可以自己核对每一笔订单、到账金额与结算记录。两边数据不一致时,以渠道后台为准——平台页面只是汇总展示。
合规边界
| 平台做什么 | 聚合下单、签名验签、异步通知、订单对账、技术支持 |
| 平台不做什么 | 不持牌、不清算、不设资金池、不做二次清算、不代收代付 |
| 禁止业务 | 赌博博彩、色情内容、诈骗、虚拟币交易、洗钱与跑分、枪支毒品等违法场景 |
| 风控 | 提交申请即自动审核;运营中发现违规,直接关停账户并保留移交证据的权利 |
对完文档还有卡点?
把报错原文、订单号和你的签名串发过来,我们直接告诉你差在哪一步。