开发文档
标准易支付协议,支持 PHP / Java / Python / Node.js / Golang 等多种语言。提供页面跳转、API 接口、二维码获取、订单查询等完整能力,最快 30 分钟完成接入。
1快速开始
接入前请先在商户后台获取 pid(商户ID)和 KEY(商户密钥),所有接口共用这两个凭证。
接口基础地址
https://xpay.nmmp.cn
签名方式
MD5
接口一览
| 接口名称 | 方式 | 地址 | 说明 |
|---|---|---|---|
| 页面跳转支付 | POST | /xpay/epay/submit.php | 用户前台跳转收银台 |
| API 接口支付 | POST | /xpay/epay/mapi.php | 服务端发起,返回 JSON |
| 获取支付二维码 | POST | /api/order/qrcode | 返回 base64 二维码图片 |
| 订单状态查询 | POST | /api/order/status | 查询订单支付状态 |
submit.php 用于用户前台直接跳转支付(浏览器端);mapi.php 用于服务器端发起请求并返回 JSON 数据。两者请求参数完全一致。2签名算法
所有支付请求均需携带 sign 参数,签名方式默认为 MD5。
签名步骤
- 将所有参数(除
sign、sign_type及空值外)按照参数名 ASCII 码从小到大排序(a-z) - 拼接成 URL 键值对格式,如
a=b&c=d&e=f,参数值不要做 URL 编码 - 在拼接字符串末尾直接拼接商户密钥 KEY,进行 MD5 加密,结果转小写即为
sign
多语言示例
PHP
function epaySign($params, $key) { // 过滤空值、sign、sign_type $filtered = []; foreach ($params as $k => $v) { if ($v !== '' && $v !== null && $k !== 'sign' && $k !== 'sign_type') { $filtered[$k] = $v; } } ksort($filtered); // ASCII升序 $str = ''; foreach ($filtered as $k => $v) { $str .= $k . '=' . $v . '&'; } return md5(rtrim($str, '&') . $key); }
Python
import hashlib def epay_sign(params, key): # 过滤空值、sign、sign_type filtered = {k: v for k, v in params.items() if v != '' and v is not None and k not in ('sign', 'sign_type')} # ASCII升序拼接 sign_str = '&'.join(f'{k}={filtered[k]}' for k in sorted(filtered.keys())) # 末尾拼密钥,md5小写 return hashlib.md5((sign_str + key).encode()).hexdigest()
Node.js
const crypto = require('crypto'); function epaySign(params, key) { const keys = Object.keys(params) .filter(k => k !== 'sign' && k !== 'sign_type' && params[k] !== '' && params[k] !== null) .sort(); const str = keys.map(k => k + '=' + params[k]).join('&'); return crypto.createHash('md5').update(str + key).digest('hex'); }
3页面跳转支付
此接口用于用户前台直接发起支付,通过 form 表单 POST 提交后自动跳转到收银台页面。
POST
https://xpay.nmmp.cn/xpay/epay/submit.php
请求参数
| 字段 | 变量名 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
| 商户ID | pid | 是 | 10000 | 商户唯一标识符 |
| 支付方式 | type | 是 | alipay | alipay / wxpay |
| 商户订单号 | out_trade_no | 是 | 202608181200001 | 商户系统内部订单号,需唯一 |
| 商品名称 | name | 是 | VIP会员 | 超过127字节自动截取 |
| 商品金额 | money | 是 | 1.00 | 单位元,最多两位小数 |
| 异步通知 | notify_url | 否 | https://ex.com/notify.php | 服务器异步回调地址 |
| 跳转通知 | return_url | 否 | https://ex.com/return.php | 支付完成后浏览器跳转 |
| 网站名称 | sitename | 否 | 测试网站 | 收银台显示的网站名 |
| 设备类型 | device | 否 | pc | pc / mobile |
| 扩展参数 | param | 否 | uid=123 | 支付后原样返回 |
| 签名 | sign | 是 | 202cb962ac59... | MD5签名结果 |
| 签名类型 | sign_type | 否 | MD5 | 默认MD5 |
4API 接口支付
此接口用于服务器后端发起支付请求,返回 JSON 格式数据。请求参数与页面跳转支付完全一致。
POST
https://xpay.nmmp.cn/xpay/epay/mapi.php
返回结果
JSON Response
{
"code": 1, // 1=成功,其他=失败
"msg": "success", // 失败时返回错误原因
"trade_no": "20260818071512752535", // 平台订单号
"qrcode": "https://xpay.nmmp.cn/api/pay/toapp/...",
"urlscheme": "alipays://platformapi/startapp?...",
"money": "0.01" // 实际支付金额
}qrcode 和 urlscheme 根据支付方式不同可能只返回其中一个。微信可能只返回 trade_no。如需直接获取二维码图片,请使用「获取支付二维码」接口。mapi.php 无 CORS 跨域头,浏览器端直接调用会被拦截。请在服务器端调用,或通过自建 PHP 代理转发。
5获取支付二维码
创建订单后,使用平台订单号调用此接口,可直接获取 base64 编码的二维码图片,无需自行生成。
POST
https://xpay.nmmp.cn/api/order/qrcode
请求参数
| 字段 | 变量名 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
| 平台订单号 | order_id | 是 | 20260818071512752535 | mapi.php 返回的 trade_no |
返回结果
JSON Response
{
"code": 200,
"data": {
"type": "qrcode", // qrcode/jump/text
"qrcode_data": "data:image/png;base64,iVBORw0..."
}
}使用方式
HTML
<!-- 直接将 qrcode_data 赋值给 img src --> <img src="data:image/png;base64,iVBORw0..." alt="支付二维码">
支付宝二维码为 PNG 格式,微信二维码为 JPEG 格式,均以
data:image/...;base64, 开头,可直接用于 <img> 标签。6订单状态查询
主动查询订单支付状态,适用于前端轮询或后端对账场景。
POST
https://xpay.nmmp.cn/api/order/status
请求参数
| 字段 | 变量名 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
| 平台订单号 | order_id | 是 | 20260818071512752535 | mapi.php 返回的 trade_no |
返回结果
JSON Response
{
"code": 200,
"data": {
"status": 1, // 订单状态码
"trade_no": "20260818071512752535",
"money": "0.01",
"pay_time": ""
}
}状态码
| 状态码 | 状态 | 说明 |
|---|---|---|
| 1 | 待支付 | 订单已创建,等待用户支付 |
| 2 | 支付成功 | 用户已完成支付 |
| 3 | 已关闭 | 订单被主动关闭 |
| 4 | 已超时 | 超过支付有效期未支付 |
| 5 | 支付失败 | 支付过程中出现异常 |
7支付结果通知
支付完成后,平台会向商户设置的通知地址发送回调。
- 异步通知(notify_url):服务器端 POST 回调,可靠稳定,推荐使用
- 跳转通知(return_url):浏览器 GET 跳转,仅用于页面展示,不可作为发货依据
通知参数
| 字段 | 变量名 | 必填 | 示例 | 说明 |
|---|---|---|---|---|
| 商户ID | pid | 是 | 10000 | 商户唯一标识符 |
| 平台订单号 | trade_no | 是 | 2026080615134349021 | 平台订单号 |
| 商户订单号 | out_trade_no | 是 | 20160806151343349 | 商户内部订单号 |
| 支付方式 | type | 是 | alipay | alipay / wxpay |
| 商品名称 | name | 是 | VIP会员 | 商品名称 |
| 商品金额 | money | 是 | 1.00 | 支付金额 |
| 支付状态 | trade_status | 是 | TRADE_SUCCESS | 只有此值表示成功 |
| 扩展参数 | param | 否 | uid=123 | 透传参数 |
| 签名 | sign | 是 | 202cb962ac59... | 需校验 |
| 签名类型 | sign_type | 是 | MD5 | 默认MD5 |
收到异步通知后务必:①校验签名;②验证
trade_status 为 TRADE_SUCCESS;③验证金额一致;④处理完成后输出 success,否则平台会重复通知。8支付方式
| 变量值 | 名称 | 说明 |
|---|---|---|
alipay | 支付宝 | 返回 urlscheme,可生成二维码或直接拉起App |
wxpay | 微信支付 | 需通过 /api/order/qrcode 获取二维码 |
9设备类型
device 参数用于指定支付场景,影响收银台页面展示方式。
| 调用值 | 设备 | 说明 |
|---|---|---|
pc | 电脑端 | PC网页扫码支付,展示二维码供手机扫码 |
mobile | 移动端 | 手机浏览器支付,可能直接拉起支付App |
网页展示二维码供用户扫码时建议传
device=pc。该参数主要影响 submit.php 收银台展示形态,不影响 mapi.php 返回字段。10错误码说明
mapi.php 返回 code
| code | 说明 |
|---|---|
1 | 请求成功 |
-1 | 签名验证失败,检查签名算法和密钥 |
-2 | 商户ID不存在或已被禁用 |
-3 | 参数缺失,检查必填参数 |
-4 | 订单号已存在,更换 out_trade_no |
-5 | 支付方式不可用 |
-6 | 金额格式错误 |
二维码/订单查询接口
| code | 说明 |
|---|---|
200 | 请求成功 |
400 | 参数错误,缺少 order_id |
404 | 订单不存在 |
500 | 服务器内部错误 |
11完整示例
PHP 完整接入示例,包含创建订单、获取二维码、处理回调。
create_order.php
<?php $pid = '10000'; $key = '你的商户密钥'; // 组装参数 $params = [ 'pid' => $pid, 'type' => 'alipay', 'out_trade_no' => date('YmdHis') . rand(100,999), 'name' => '测试商品', 'money' => '0.01', 'device' => 'pc', 'sign_type' => 'MD5', ]; // 计算签名 function epaySign($p, $key) { $f = []; foreach ($p as $k => $v) if ($v !== '' && $k !== 'sign' && $k !== 'sign_type') $f[$k] = $v; ksort($f); $s = ''; foreach ($f as $k => $v) $s .= $k.'='.$v.'&'; return md5(rtrim($s,'&') . $key); } $params['sign'] = epaySign($params, $key); // 创建订单 $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => 'https://xpay.nmmp.cn/xpay/epay/mapi.php', CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, ]); $result = json_decode(curl_exec($ch), true); curl_close($ch); if ($result['code'] == 1) { $tradeNo = $result['trade_no']; // 获取二维码(base64) $qr = curl_init('https://xpay.nmmp.cn/api/order/qrcode'); curl_setopt_array($qr, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(['order_id' => $tradeNo]), CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, ]); $qrData = json_decode(curl_exec($qr), true); curl_close($qr); $qrcode = $qrData['data']['qrcode_data'] ?? ''; echo '<img src="' . $qrcode . '">'; } else { echo '失败:' . $result['msg']; }