💳 支付系统 API 文档

接口地址

接口基础地址:https://pay.xiaoil.com

后台地址:/admin/(默认账号:admin,密码:123456)
商户中心:/user/(支持自助注册)

1. 创建订单

POST https://pay.xiaoil.com/submit.php

请求参数

参数必填说明
pid商户ID
type支付方式:alipay(支付宝) / wxpay(微信) / qqpay(QQ钱包)
out_trade_no商户订单号(唯一)
notify_url异步通知地址
return_url支付后跳转地址
name商品名称
money金额(元,保留两位小数)
param自定义参数(原样返回)
sign签名
sign_type签名类型,默认MD5

返回示例

{
    "code": 1,
    "msg": "订单创建成功",
    "data": {
        "trade_no": "20250102123456789012",
        "payurl": "https://pay.xiaoil.com/pay/cashier.php?trade_no=xxx",
        "qrcode": "https://pay.xiaoil.com/pay/cashier.php?trade_no=xxx&qrcode=1"
    }
}
提示:POST请求默认会跳转到支付页面,如需返回JSON请添加参数 format=json 或使用GET请求。

1.1 MAPI接口(API模式)

POST https://pay.xiaoil.com/mapi.php

MAPI接口专门用于API模式对接,直接返回JSON格式的支付二维码或支付链接,不会跳转页面。

请求参数

参数必填说明
pid商户ID
type支付方式:alipay(支付宝) / wxpay(微信) / qqpay(QQ钱包)
out_trade_no商户订单号(唯一)
notify_url异步通知地址
return_url支付后跳转地址
name商品名称
money金额(元,保留两位小数)
clientip客户端IP地址
device设备类型:pc/mobile/wechat/alipay
param自定义参数(原样返回)
sign签名
sign_type签名类型,默认MD5

返回示例

// 返回二维码
{
    "code": 1,
    "trade_no": "20250102123456789012",
    "qrcode": "https://qr.alipay.com/xxx"
}

// 返回支付链接
{
    "code": 1,
    "trade_no": "20250102123456789012",
    "payurl": "https://xxx/pay"
}
提示:MAPI接口始终返回JSON,适合需要自定义收银台页面的场景。返回的 qrcode 可直接生成二维码,payurl 可跳转或嵌入iframe。

2. 查询订单

GET https://pay.xiaoil.com/api/query.php

请求参数

参数必填说明
pid商户ID
trade_no系统订单号(与out_trade_no二选一)
out_trade_no商户订单号
sign签名

返回示例

{
    "code": 1,
    "msg": "查询成功",
    "data": {
        "trade_no": "20250102123456789012",
        "out_trade_no": "商户订单号",
        "type": "alipay",
        "pid": "1001",
        "money": "0.01",
        "realmoney": "0.01",
        "name": "商品名称",
        "status": 1,
        "addtime": "2025-01-02 12:34:56",
        "endtime": "2025-01-02 12:35:00",
        "sign": "xxx",
        "sign_type": "MD5"
    }
}

订单状态说明

status说明
0待支付
1已支付
3已冻结
4已退款

3. 订单状态检查

GET https://pay.xiaoil.com/api/check.php

前端轮询用接口,会主动向支付宝查询订单状态。

请求参数

参数必填说明
trade_no系统订单号

返回示例

// 已支付
{"status": 1}

// 未支付
{"status": 0}

// 订单不存在
{"status": -1, "msg": "order not found"}
提示:此接口无需签名,适合前端JS轮询检查支付状态。如果订单未支付,系统会主动向支付宝查询订单状态并自动更新。

4. 异步通知

支付成功后,系统会向 notify_url 发送POST请求:

通知参数

参数说明
pid商户ID
trade_no系统订单号
out_trade_no商户订单号
type支付方式
name商品名称
money金额
trade_status交易状态:TRADE_SUCCESS
sign签名
sign_type签名类型
重要:商户验签成功后,请返回纯文本 success(不含引号),否则系统会重复通知。

通知验签示例

<?php
// 接收通知参数
$params = $_POST;
$sign = $params['sign'] ?? '';
$key = '你的商户密钥';

// 验证签名
unset($params['sign'], $params['sign_type']);
ksort($params);
$str = '';
foreach ($params as $k => $v) {
    if ($v !== '') {
        $str .= $k . '=' . $v . '&';
    }
}
$calcSign = md5(rtrim($str, '&') . $key);

if ($sign === $calcSign) {
    // 验签成功,处理业务逻辑
    // ...
    echo 'success';
} else {
    echo 'fail';
}
?>

5. 签名算法

签名采用MD5方式,步骤如下:

  1. 将参数按key字母升序排序
  2. 拼接成 key=value& 格式(排除sign、sign_type和空值)
  3. 去掉末尾的 &,拼接商户密钥
  4. 对整个字符串进行MD5加密

PHP示例

<?php
function createSign($params, $key) {
    ksort($params);
    $str = '';
    foreach ($params as $k => $v) {
        if ($k != 'sign' && $k != 'sign_type' && $v !== '') {
            $str .= $k . '=' . $v . '&';
        }
    }
    return md5(rtrim($str, '&') . $key);
}

// 示例
$params = [
    'pid' => '1001',
    'type' => 'alipay',
    'out_trade_no' => '202501021234',
    'notify_url' => 'https://example.com/notify',
    'name' => '测试商品',
    'money' => '0.01',
];
$key = '你的商户密钥';
$params['sign'] = createSign($params, $key);
$params['sign_type'] = 'MD5';
?>

签名字符串示例

// 排序后的参数
money=0.01&name=测试商品¬ify_url=https://example.com/notify&out_trade_no=202501021234&pid=1001&type=alipay

// 拼接密钥后
money=0.01&name=测试商品¬ify_url=https://example.com/notify&out_trade_no=202501021234&pid=1001&type=alipay你的商户密钥

// MD5加密得到签名

6. 错误码

code说明
1成功
-1缺少必要参数
-2商户不存在或已禁用 / 商户收款功能已关闭
-3签名验证失败
-4支付方式不存在
-5暂无可用支付通道
-6风控拦截(IP频率/金额限制等)

7. 对接示例

PHP发起支付

<?php
// 签名函数
function createSign($params, $key) {
    ksort($params);
    $str = '';
    foreach ($params as $k => $v) {
        if ($k != 'sign' && $k != 'sign_type' && $v !== '') {
            $str .= $k . '=' . $v . '&';
        }
    }
    return md5(rtrim($str, '&') . $key);
}

// 构建参数
$params = [
    'pid' => '1001',
    'type' => 'alipay',
    'out_trade_no' => date('YmdHis') . mt_rand(1000, 9999),
    'notify_url' => 'https://你的网站/notify.php',
    'return_url' => 'https://你的网站/return.php',
    'name' => '测试商品',
    'money' => '0.01',
];
$key = '你的商户密钥';
$params['sign'] = createSign($params, $key);
$params['sign_type'] = 'MD5';

// 方式1:跳转支付
header('Location: https://pay.xiaoil.com/submit.php?' . http_build_query($params));

// 方式2:获取支付链接
$result = json_decode(file_get_contents('https://pay.xiaoil.com/submit.php?' . http_build_query($params)), true);
if ($result['code'] == 1) {
    $payUrl = $result['data']['payurl'];
    $qrcodeUrl = $result['data']['qrcode'];
}
?>

前端轮询检查支付状态

<script>
// 轮询检查支付状态
var tradeNo = '订单号';
var checkTimer = setInterval(function() {
    fetch('https://pay.xiaoil.com/api/check.php?trade_no=' + tradeNo)
        .then(response => response.json())
        .then(data => {
            if (data.status == 1) {
                clearInterval(checkTimer);
                alert('支付成功!');
                // 跳转到成功页面
                location.href = '/success.php?trade_no=' + tradeNo;
            }
        });
}, 3000); // 每3秒检查一次
</script>

异步通知处理

<?php
// notify.php - 异步通知处理

// 签名函数
function createSign($params, $key) {
    ksort($params);
    $str = '';
    foreach ($params as $k => $v) {
        if ($k != 'sign' && $k != 'sign_type' && $v !== '') {
            $str .= $k . '=' . $v . '&';
        }
    }
    return md5(rtrim($str, '&') . $key);
}

// 接收参数
$params = $_POST;
$sign = $params['sign'] ?? '';
$key = '你的商户密钥';

// 验证签名
$calcSign = createSign($params, $key);
if ($sign !== $calcSign) {
    exit('fail');
}

// 验证交易状态
if ($params['trade_status'] !== 'TRADE_SUCCESS') {
    exit('fail');
}

// 获取订单信息
$outTradeNo = $params['out_trade_no'];
$money = $params['money'];

// TODO: 查询本地订单,验证金额,更新订单状态
// ...

// 返回成功
echo 'success';
?>

返回首页 | 管理后台 | 商户中心