商户对接文档

易支付 MD5 签名 · 下单、notify 入账、return 用户回跳。后台「商户账号」获取 pid 与 API 密钥。

一句话:notify_url 用 POST 收通知、验签后入账;return_url 用 GET 把用户带回你的网站。两个都要配,不能混用。
网关必须用 https://;轮询组编码传 channel,不要写在 type 里。
网关:http://jd.xiaoil.com 完整 Markdown 返回首页
对接必懂:第 4 步 notify POST = 入账发货;第 5 步 return GET = 用户看成功页。详细说明见 完整 Markdown 文档

1. 准备工作

项目说明
pid商户号,后台「商户账号」列表第一列
API 密钥创建商户时生成,用于签名与验签 notify
channel支付通道码;建议在商户中绑定默认通道
网关本站根地址,如 http://jd.xiaoil.com
安全:密钥仅放服务端;notify_url 必须为可公网访问的 HTTPS 地址。
网关:对接地址必须用 https://。用 http:// 遇 Nginx 强制 HTTPS 会返回 301 HTML,formPost 下单失败。

1B. channel 与 type(易错)

参数选通道?说明
channel✅ 是通道码轮询组编码(如 ahpay
type❌ 否可选,可省略;不要把组编码写进 type

1C. 轮询组

多个通道可加入同一组。对接时 channel=组编码,平台自动轮询组内启用通道。页面跳转同样支持:/pay/{组编码}?…

组须启用、组内有启用通道;商户若配置了白名单须已授权该组。

2. 签名算法(MD5)

  1. 参与签名参数:除 signsign_type 外,且值非空。
  2. 按 key ASCII 升序,拼接 key=value&...(不 URL 编码)。
  3. 末尾直接追加 API 密钥,MD5 小写 32 位 → sign

示例待签串:

money=1.00&name=测试商品&notify_url=https://merchant.example.com/notify&out_trade_no=20260101120000&pid=1001&type=jd{您的API密钥}

3. 接口一览

能力方法路径
创建订单POST/api/epay/submit/api/channel/submit
查询订单GET/POST/api/epay/query/api/channel/query
页面跳转GET/pay/{通道码或组编码}?pid&…
收银台GET/pay/cashier?trade_no=

请求体支持 application/x-www-form-urlencodedmultipart/form-dataapplication/json

响应:{"code":1,"msg":"success",...} 成功;code:-1 失败。

4. 创建订单

POST http://jd.xiaoil.com/api/epay/submit

请求参数

参数必填说明
pid商户号(可用 mch_id)
out_trade_no商户订单号,不可重复
money金额,如 1.00
signMD5 签名
name商品名称
channel条件通道码或轮询组编码;未绑默认通道时必填
notify_url强烈建议POST 异步通知 → 入账用这个
return_url需回跳时必传GET 浏览器跳转 → 只展示,不入账
client_ip条件付款人 IP;开启收银台风控时 API 下单必填
type不参与选通道,可省略

成功响应

{
  "code": 1,
  "msg": "success",
  "trade_no": "JD202601011234567890",
  "out_trade_no": "20260101120000",
  "payurl": "http://jd.xiaoil.com/pay/cashier?trade_no=JD...",
  "qrcode": "https://wepay.jd.com/...",
  "money": "1.00",
  "pay_amount": "1.00",
  "countdown_seconds": 900,
  "expires_at": "2026-01-01T12:15:00Z"
}
建议:将用户跳转至 payurl 使用自带收银台;或自行用 qrcode 生成二维码并轮询查单。

4A. 三种对接方式

方式做法
API 调用(formPost)POST /api/epay/submit → 跳转 payurl
页面跳转浏览器打开 /pay/{编码}?…
自建扫码页qrcode + 轮询 /api/cashier/poll

4B. 完整对接流程

  1. 商户服务端 POST /api/epay/submit,获得 payurltrade_no
  2. 引导用户打开 payurl 收银台完成支付
  3. 平台 POST notify_url → 商户验签、幂等入账,响应 success
  4. 收银台检测到成功 → 浏览器 GET 跳转 return_url(带签名参数)

入账以 notify 为准;return 仅用于用户回跳展示。

4C. return_url 与 notify_url(重要)

notify_urlreturn_url
方式POST 服务端GET 浏览器跳转
用途验签入账、发货用户支付成功页
是否必传强烈建议需回跳商户站时必传
勿只传 notify:return_url 时收银台会 GET 打开 notify 地址,多数接口只收 POST 会失败。请同时配置两者。

跳转优先级:return_url →(无则)notify_url →(均无)/pay/success

5. 查询订单

GET/POST http://jd.xiaoil.com/api/epay/query

参数:pidsign,以及 out_trade_notrade_no 二选一。

trade_status含义
WAIT_BUYER_PAY待支付
TRADE_SUCCESS支付成功
TRADE_FAILED失败/超时
TRADE_REFUND已退款

6. 页面跳转下单

GET http://jd.xiaoil.com/pay/{通道码}?pid=&out_trade_no=&money=&name=&sign=&sign_type=MD5

验签通过后创建订单并跳转收银台,适合浏览器直接打开。

7. 收银台

订单倒计时:金融充值 900 秒、保证金 5400 秒、安徽农信 1800 秒(以通道配置为准),超时 TRADE_FAILED

8. 异步通知与同步跳转

平台 POSTnotify_urlapplication/x-www-form-urlencoded)。字段:pid, trade_no, out_trade_no, type, name, money, pay_amount, trade_status, sign。验签后响应正文含 success(HTTP 200),失败重试约 5 次。

return_url GET 参数(支付成功回跳)

与 notify 相同字段,trade_status=TRADE_SUCCESS,附在 Query 上,用商户密钥验签。示例:

https://merchant.example.com/ok?pid=1001&trade_no=JD...&out_trade_no=...&money=1.00&trade_status=TRADE_SUCCESS&sign=...

入账仍以 notify 为准,return 不可单独作为发货依据。

9. 常见错误

现象 / msg说明
301 HTML网关用了 http://,改 https://
签名错误排序、空值或密钥错误
商户订单号重复out_trade_no 已存在
未指定通道…传 channel=通道码或组编码
未授权此轮询组/通道商户白名单未勾选
轮询组已关闭后台启用轮询组
…client_ip开启风控时 API 须传 client_ip

10. 代码示例(PHP)

function epaySign($params, $key) {
  unset($params['sign'], $params['sign_type']);
  $params = array_filter($params, fn($v) => $v !== '' && $v !== null);
  ksort($params);
  $str = '';
  foreach ($params as $k => $v) {
    $str .= ($str === '' ? '' : '&') . $k . '=' . $v;
  }
  return md5($str . $key);
}
$params = [
  'pid' => '1001',
  'channel' => 'ahpay',  // 通道码或轮询组编码
  'out_trade_no' => 'ORDER' . time(),
  'money' => '1.00', 'name' => '测试',
  'notify_url' => 'https://你的域名/api/pay/notify',
  'return_url' => 'https://你的域名/pay/success',
  'client_ip' => $_SERVER['REMOTE_ADDR'] ?? '',
  'sign_type' => 'MD5',
];
$params['sign'] = epaySign($params, $apiKey);
// POST http://jd.xiaoil.com/api/epay/submit → 跳转 $result['payurl']

notify 入账(PHP)

if (!verifySign($_POST, $apiKey)) exit('sign error');
if ($_POST['trade_status'] === 'TRADE_SUCCESS') { /* 幂等更新订单 */ }
echo 'success';

11. 对接检查清单

12. 常见问题

只传 notify 不传 return? 用户支付后可能 GET 打开 notify 地址导致异常,请传 return_url。

notify 和 return 哪个先到? 不固定;入账只认 notify

用户关页面还会 notify 吗? 会,支付成功即 POST。

payurl 和 qrcode? payurl=本站收银台(自动回跳);qrcode=支付直链+自行查单。

轮询组怎么传? channel=组编码/pay/组编码?…,不要写在 type 里。

type 可以不传吗? 可以,不参与选通道。