MMCCCPAY 商户支付接入文档
面向商户技术人员的完整对接指南,涵盖凭证申请、签名算法、下单/查单/回调、指定通道、身份授权、错误排查与代码示例。
1. 文档说明
本文档描述商户如何通过 MMCCCPAY 开放接口完成收款接入。
- V1 协议:MD5 签名,兼容
submit.php、mapi.php、api.php等传统入口。 - V2 协议:RSA 签名,推荐使用
/api/pay/*标准 REST 风格接口,支持退款、关单、转账等扩展能力。
https://pay.mmcccpay.com
2. 快速开始(5 步接入)
- 登录 商户后台,在「接口凭证」获取 商户 ID(pid) 与密钥。
- 选择协议:新系统用 V2 + RSA;已有易支付 V1 代码可直接对接。
- 实现签名:按本文档第 6 节规则生成
sign。 - 调用下单接口:页面跳转用
submit,服务端 API 用create(V2)或mapi(V1)。 - 实现
notify_url异步通知:验签 → 校验金额与订单号 → 幂等更新订单 → 返回success。
2.1 标准支付时序
3. 商户开通与凭证
3.1 需要准备的资料
| 凭证项 | V1 | V2 | 获取位置 |
|---|---|---|---|
| 商户 ID(pid) | 必填 | 必填 | 商户后台 → 接口信息 |
| 商户号 merchant_no | 展示用 | 展示用 | 商户后台 → 基本信息 |
| API Key(MD5 密钥) | 必填 | — | 商户后台 → V1 接口凭证 |
| 商户 RSA 私钥 | — | 必填(签名) | 商户后台生成或自行上传公钥 |
| 平台 RSA 公钥 | — | 必填(验签响应/通知) | 商户后台 → 平台公钥 |
3.2 回调地址要求
notify_url必须公网可访问,建议 HTTPS。- 异步通知由平台服务器以 GET 方式发起,参数放在 URL Query 中(V1/V2 相同)。
- 收到通知后必须返回纯文本
success(小写),否则平台会按策略重试。 return_url仅用于浏览器同步跳转展示,不能作为到账依据,到账以notify_url为准。
4. V1 与 V2 如何选择
| 对比项 | V1(MD5) | V2(RSA) |
|---|---|---|
| 签名算法 | MD5 | SHA256WithRSA |
| 安全性 | 一般,适合内网或历史系统 | 更高,推荐新接入 |
| 时间戳 | 无强制 | 必填 timestamp |
| 页面跳转 | /submit | /api/pay/submit |
| API 下单 | /mapi | /api/pay/create |
| 退款/关单/转账 | V1 部分支持 | 完整支持 |
| SDK | V1 SDK | V2 SDK |
5. 接口地址总览
以下地址均以网关 https://pay.mmcccpay.com 为前缀。
5.1 V2 接口
| 路径 | 方法 | 说明 |
|---|---|---|
/api/pay/submit | POST / GET | 页面跳转支付(表单提交) |
/api/pay/create | POST | API 创建订单(推荐) |
/api/pay/query | POST | 查询订单 |
/api/pay/refund | POST | 退款 |
/api/pay/refundquery | POST | 退款查询 |
/api/pay/close | POST | 关闭订单 |
/api/merchant/info | POST | 商户信息 |
/api/merchant/orders | POST | 商户订单列表 |
/api/transfer/submit | POST | 转账提交 |
/api/transfer/query | POST | 转账查询 |
/api/transfer/balance | POST | 转账余额 |
5.2 V1 接口
| 路径 | 方法 | 说明 |
|---|---|---|
/submit 或 /submit.php | POST / GET | 页面跳转支付 |
/mapi 或 /mapi.php | POST | API 接口支付 |
/api?act=query | GET | 查询商户信息 |
/api?act=order | GET | 查询单个订单 |
/api?act=orders | GET | 批量查询订单 |
/api?act=refund | POST | 退款(需后台开启) |
6. 签名规则(必读)
6.1 公共规则
- 取所有非空参数参与签名。
sign、sign_type不参与签名。- 数组、对象、文件等非标量字段不参与签名。
- 参数名按 ASCII 码升序排序。
- 拼接格式:
key1=value1&key2=value2(值不做 URL 编码)。
6.2 V1 MD5 签名
待签原文 = key1=value1&key2=value2 ...(按规则排序拼接)
sign = md5(待签原文 + API_KEY) // 结果小写,+ 表示字符串直接拼接
示例参数:
{
"pid": 1001,
"type": "alipay",
"out_trade_no": "ORDER20260530001",
"notify_url": "https://merchant.example.com/notify",
"return_url": "https://merchant.example.com/return",
"name": "VIP会员",
"money": "10.00"
}
排序后原文类似:
money=10.00&name=VIP会员¬ify_url=https://merchant.example.com/notify&out_trade_no=ORDER20260530001&pid=1001&return_url=https://merchant.example.com/return&type=alipay
末尾直接拼接 API Key 后 MD5。
6.3 V2 RSA 签名
待签原文 = 同 6.1 规则拼接
sign = Base64( RSA-SHA256(待签原文, 商户私钥) )
请求需带 sign_type=RSA 与 timestamp(Unix 秒级时间戳,参与签名)。
验证平台响应或异步通知时,使用平台 RSA 公钥验签。
6.4 PHP 签名示例
<?php
function epay_build_sign_content(array $params): string {
unset($params['sign'], $params['sign_type']);
ksort($params);
$parts = [];
foreach ($params as $k => $v) {
if ($v === '' || $v === null || is_array($v)) continue;
$parts[] = $k . '=' . $v;
}
return implode('&', $parts);
}
function epay_sign_md5(array $params, string $apiKey): string {
return md5(epay_build_sign_content($params) . $apiKey);
}
function epay_sign_rsa(array $params, string $privateKeyPem): string {
$content = epay_build_sign_content($params);
openssl_sign($content, $signature, $privateKeyPem, OPENSSL_ALGO_SHA256);
return base64_encode($signature);
}
7. 支付方式与设备类型
7.1 支付方式 type
| 值 | 说明 |
|---|---|
alipay | 支付宝 |
wxpay | 微信支付 |
qqpay | QQ 钱包 |
7.2 设备类型 device(V1 mapi / V2 create 可选)
| 值 | 说明 |
|---|---|
pc | 电脑浏览器 |
mobile | 手机浏览器 |
wechat | 微信内浏览器 |
qq | QQ 内浏览器 |
alipay | 支付宝客户端 |
8. 指定通道 channel_id(可选)
V1 的 submit、mapi 与 V2 的 submit、create 均支持可选参数 channel_id:
- 不传:平台按商户分组 → 轮询组 → 通道权重自动选路。
- 传入:强制使用指定通道 ID,且该通道必须在当前商户可用路由内。
- 参与签名:传入时与其他参数一样参与 MD5/RSA 签名。
9. V2 API 创建订单(推荐)
9.1 请求
- URL:
POST https://pay.mmcccpay.com/api/pay/create - Content-Type:
application/x-www-form-urlencoded或application/json
| 字段 | 变量名 | 必填 | 说明 |
|---|---|---|---|
| 商户ID | pid | 是 | 整数 |
| 接口类型 | method | 是 | web / jump / jsapi / app / scan / mini 等 |
| 支付方式 | type | 是 | alipay / wxpay / qqpay |
| 商户订单号 | out_trade_no | 是 | 商户系统唯一单号 |
| 商品名称 | name | 是 | 展示名称 |
| 金额 | money | 是 | 元,最多 2 位小数,如 10.00 |
| 异步通知 | notify_url | 是 | HTTPS 推荐 |
| 同步跳转 | return_url | 否 | 支付完成浏览器跳转 |
| 用户IP | clientip | 否 | 建议传真实 IP |
| 设备 | device | 否 | 见第 7 节 |
| 扩展参数 | param | 否 | 原样回传 |
| 通道ID | channel_id | 否 | 指定通道 |
| 时间戳 | timestamp | 是 | Unix 秒 |
| 签名 | sign | 是 | RSA Base64 |
| 签名类型 | sign_type | 是 | 固定 RSA |
9.2 成功响应
{
"code": 0,
"msg": "success",
"trade_no": "PAY20260530164209956889",
"pay_type": "jump",
"pay_info": "https://pay.mmcccpay.com/payment/PAY20260530164209956889",
"timestamp": "1779179000",
"sign": "...",
"sign_type": "RSA"
}
9.3 pay_type 含义
| pay_type | 商户处理建议 |
|---|---|
| jump | 浏览器跳转 pay_info URL |
| qrcode | 将 pay_info 生成二维码供扫码 |
| html | 输出 HTML 片段自动提交表单 |
| jsapi | 解析 JSON 调起微信/支付宝 JSAPI |
| urlscheme | 小程序 URL Scheme 跳转 |
| identity | 需先跳转身份授权页(见第 12 节) |
9.4 cURL 示例
curl -X POST "https://pay.mmcccpay.com/api/pay/create" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "pid=1001" \
-d "method=jump" \
-d "type=alipay" \
-d "out_trade_no=ORDER20260530001" \
-d "name=测试商品" \
-d "money=10.00" \
-d "notify_url=https://merchant.example.com/notify" \
-d "return_url=https://merchant.example.com/return" \
-d "clientip=127.0.0.1" \
-d "timestamp=1779179000" \
-d "sign_type=RSA" \
-d "sign=YOUR_RSA_SIGN"
10. V2 页面跳转支付
适用于 PC/移动端表单提交,用户浏览器直接跳转到平台收银台或支付页。
- URL:
POST https://pay.mmcccpay.com/api/pay/submit(兼容 GET) - 参数与 create 类似,
method可不传;type可不传(进入收银台选支付方式)
<form action="https://pay.mmcccpay.com/api/pay/submit" method="post">
<input type="hidden" name="pid" value="1001">
<input type="hidden" name="type" value="alipay">
<input type="hidden" name="out_trade_no" value="ORDER20260530001">
<input type="hidden" name="name" value="测试商品">
<input type="hidden" name="money" value="10.00">
<input type="hidden" name="notify_url" value="https://merchant.example.com/notify">
<input type="hidden" name="return_url" value="https://merchant.example.com/return">
<input type="hidden" name="timestamp" value="1779179000">
<input type="hidden" name="sign_type" value="RSA">
<input type="hidden" name="sign" value="YOUR_RSA_SIGN">
<button type="submit">去支付</button>
</form>
11. V2 订单查询
- URL:
POST https://pay.mmcccpay.com/api/pay/query trade_no(平台单号)与out_trade_no(商户单号)二选一
| status | 含义 |
|---|---|
| 0 | 未支付 |
| 1 | 已支付 |
| 2 | 已退款 |
| 3 | 已冻结 |
| 4 | 预授权 |
12. 异步通知与同步跳转
12.1 异步通知 notify_url
用户支付成功后,平台会向商户 notify_url 发起通知。商户必须:
- 验证签名(V1 用 API Key;V2 用平台公钥)。
- 校验
pid为本商户。 - 校验
out_trade_no存在且金额money一致。 - 校验
trade_status == TRADE_SUCCESS(V2 同样使用该值表示成功)。 - 幂等更新本地订单(重复通知不重复发货)。
- 响应纯文本
success。
12.2 通知参数(V1 / V2 通用)
通知以 GET 请求送达,参数在 URL 中。V2 通知额外包含 timestamp、addtime、endtime,验签时使用平台 RSA 公钥。
| 字段 | 说明 |
|---|---|
| pid | 商户 ID |
| trade_no | 平台支付单号 |
| out_trade_no | 商户订单号 |
| type | 支付方式 |
| name | 商品名称 |
| money | 订单金额(元) |
| trade_status | TRADE_SUCCESS 表示支付成功 |
| param | 下单时的扩展参数(如有) |
| sign / sign_type | 签名 |
12.3 PHP 通知处理示例
<?php
// 平台异步通知统一为 GET Query 参数(V1 / V2 相同)
$params = $_GET;
$apiKey = 'YOUR_V1_API_KEY';
$content = epay_build_sign_content($params);
$signOk = hash_equals(md5($content . $apiKey), strtolower($params['sign'] ?? ''));
if (!$signOk || ($params['trade_status'] ?? '') !== 'TRADE_SUCCESS') {
http_response_code(400);
exit('fail');
}
$outTradeNo = $params['out_trade_no'];
$money = $params['money'];
// TODO: 查库、校验金额、幂等更新为已支付
echo 'success';
12.4 同步跳转 return_url
用户支付完成后浏览器跳转至 return_url,参数与通知类似,仅用于展示。务必以异步通知或查单结果为准。
13. 身份授权(JSAPI / 小程序)
当路由到的支付产品需要用户 OpenID / buyer_id,而下单时未传入,平台返回身份承接地址:
{
"code": 0,
"msg": "identity_required",
"pay_type": "identity",
"pay_info": "https://pay.mmcccpay.com/cashier/identity/xxx",
"identity_required": 1,
"identity_url": "https://pay.mmcccpay.com/cashier/identity/xxx",
"resume_token": "xxx"
}
处理流程:
- 收到
identity_required=1或pay_type=identity。 - 引导用户跳转
identity_url完成授权。 - 授权完成后平台继续支付流程,或携带
openid等参数重新下单。
可选身份字段(V2 create):openid、mini_openid、buyer_id、auth_code 等。
14. V1 API 支付 mapi
- URL:
POST https://pay.mmcccpay.com/mapi.php(兼容/mapi) - 请求体:
application/x-www-form-urlencoded(Form Data),参数以表单字段提交,不使用 JSON Body - 签名:MD5,
sign_type=MD5 clientip必填
14.0 cURL 示例
curl -X POST "https://pay.mmcccpay.com/mapi.php" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "pid=1001" \
-d "type=wxpay" \
-d "out_trade_no=ORDER20260530001" \
-d "name=测试商品" \
-d "money=10.00" \
-d "notify_url=https://merchant.example.com/notify" \
-d "return_url=https://merchant.example.com/return" \
-d "clientip=127.0.0.1" \
-d "device=pc" \
-d "sign_type=MD5" \
-d "sign=YOUR_MD5_SIGN"
sign 需按 MD5 规则计算;也可使用 V1 mapi 测试工具 在线调试。
14.1 返回字段(三选一)
| 字段 | 说明 |
|---|---|
| payurl | 跳转链接,直接 location 或 a 标签打开 |
| qrcode | 二维码内容 |
| urlscheme | 小程序 Scheme |
{
"code": 1,
"msg": "success",
"trade_no": "PAY20260530164209956889",
"payurl": "https://pay.mmcccpay.com/payment/PAY20260530164209956889"
}
在线测试工具:submit.php 页面跳转测试 · mapi 接口测试
15. V1 页面跳转 submit
- URL:
https://pay.mmcccpay.com/submit - 支持 GET / POST
type可不传,进入收银台选择支付方式
16. V1 查询类 API(api.php)
16.1 查询订单 act=order
GET https://pay.mmcccpay.com/api?act=order&pid=1001&key=YOUR_API_KEY&out_trade_no=ORDER20260530001
status:1 已支付,0 未支付。
16.2 查询商户 act=query
GET https://pay.mmcccpay.com/api?act=query&pid=1001&key=YOUR_API_KEY
17. 退款(V2)
- URL:
POST https://pay.mmcccpay.com/api/pay/refund trade_no或out_trade_no二选一money退款金额;out_refund_no商户退款单号(建议传)
退款查询:/api/pay/refundquery
18. 订单号说明
| 名称 | 字段 | 说明 |
|---|---|---|
| 商户订单号 | out_trade_no | 商户系统生成,同一商户下唯一 |
| 平台支付单号 | trade_no / pay_no | MMCCCPAY 生成,如 PAY20260530164209956889 |
| 业务单号 | biz_no | 内部业务层单号(查单响应可能返回) |
| 渠道订单号 | api_trade_no | 上游支付渠道单号 |
19. 常见错误与排查
| 现象 | 可能原因 | 处理建议 |
|---|---|---|
| 签名验证失败 | 参数排序、空值、编码、密钥错误 | 对照第 6 节打印待签原文;V2 检查 timestamp 是否参与签名 |
| 商户 API 凭证未开通 | 后台未启用 V1/V2 凭证 | 商户后台 → 接口凭证 → 启用 |
| 支付方式不支持 | type 拼写错误或商户未开通该方式 | 使用 alipay/wxpay/qqpay |
| 通道不可用 | channel_id 无效或路由未配置 | 不传 channel_id 走自动选路,或联系运营配置 |
| 下单成功但无 payurl | 上游通道异常 | 查看返回 msg;联系平台查看通道日志 |
| 收不到异步通知 | notify_url 不可达、未返回 success | 用公网 URL 测试;确保响应 body 为 success |
| 重复通知 | 正常重试机制 | 业务层必须幂等 |
20. 安全规范
- API Key、RSA 私钥仅保存在商户服务器,禁止写入前端 JS 或移动端包体。
- 生产环境 notify_url 使用 HTTPS。
- 回调必须验签 + 校验金额 + 校验商户订单号。
- 勿以后台「同步跳转」作为到账依据。
- 商户订单号
out_trade_no必须全局唯一,禁止重复使用。 - V2 请求校验 timestamp,防止重放(建议 ±300 秒窗口内有效)。
21. 上线检查清单
| 检查项 | 完成 |
|---|---|
| 商户后台凭证已启用,pid / 密钥正确 | □ |
| 签名算法与待签原文本地单元测试通过 | □ |
| notify_url 公网可达且返回 success | □ |
| 订单幂等处理已实现 | □ |
| 金额校验(元,2 位小数)已实现 | □ |
| 小额(0.01~1 元)真实支付联调通过 | □ |
| 查单补单逻辑已验证 | □ |
22. 常见问题 FAQ
22.1 金额单位是什么?
接口参数 money 单位均为元,字符串格式,最多两位小数,如 10.00。
22.2 out_trade_no 可以重复吗?
不可以。同一商户下 out_trade_no 必须唯一,重复提交会视为同一笔业务订单。
22.3 V1 和 V2 能否混用?
可以。同一商户可同时开通 V1 MD5 与 V2 RSA,按系统模块选择即可;通知验签方式与各自协议一致。
22.4 如何测试?
22.5 支付页 URL 是什么?
API 返回的 payurl / pay_info 通常指向平台收银台,格式如:
https://pay.mmcccpay.com/payment/{平台支付单号}