接口简介
所有接口统一通过 /api/index.php 访问,使用 act 参数区分操作类型。
POST/api/index.php
支持的操作
| act 参数 | 功能 |
|---|---|
get_categories | 获取分类列表 |
get_products | 获取商品列表 |
get_product | 获取单个商品 |
create_order | 提交订单 |
query_order | 查询订单 |
所有请求均为 POST,参数使用
application/x-www-form-urlencoded 提交,返回统一 JSON。鉴权参数
每个请求必须携带以下 4 个参数,缺一不可。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
uid | int | 是 | 用户编号 |
api_key | string | 是 | API 密钥 |
timestamp | int | 是 | Unix 时间戳(秒级),误差 ≤ 300 秒 |
sign | string | 是 | 签名,算法见下 |
签名算法
签名 = md5(api_key + timestamp),两个字符串直接拼接后取 MD5(小写 32 位)。
// api_key = "abc123", timestamp = 1726123456 $sign = md5("abc123" . "1726123456");
多语言示例
// PHP $sign = md5($api_key . time()); // Python import time, hashlib sign = hashlib.md5((api_key + str(int(time.time()))).encode()).hexdigest() // Node.js const crypto = require('crypto'); const sign = crypto.createHash('md5').update(api_key + Math.floor(Date.now()/1000)).digest('hex');
若账号开启了「IP 白名单」,来源 IP 必须提前加入白名单。多个 IP 支持英文逗号、分号、空格或换行分隔。
返回格式
{
"code": 0, // 0 = 成功,-1 = 失败
"msg": "success", // 提示信息
"data": { ... } // 业务数据
}
| 字段 | 类型 | 说明 |
|---|---|---|
code | int | 0 表示成功,-1 表示失败 |
msg | string | 成功或失败的文字提示 |
data | mixed | 业务数据,仅部分接口返回 |
获取分类 POST
拉取上游商城的所有启用分类,用于对接方在本地自动建立对应分类。
POST/api/index.php?act=get_categories
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
act | string | 是 | 固定值 get_categories |
uid | int | 是 | 用户编号 |
api_key | string | 是 | API 密钥 |
timestamp | int | 是 | Unix 时间戳 |
sign | string | 是 | 签名 |
返回示例
{
"code": 0,
"msg": "success",
"data": [
{
"id": "cat_a8f3b2",
"tag": "cat_a8f3b2",
"name": "会员专区",
"sort": 1
}
],
"total": 1
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
data[].id | string | 分类标识码 |
data[].tag | string | 与 id 一致 |
data[].name | string | 分类名称 |
data[].sort | int | 排序值,越小越靠前 |
total | int | 分类总数 |
获取商品列表 POST
拉取本商城上架中的商品列表,支持分类、关键词筛选与分页。
POST/api/index.php?act=get_products
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
act | string | 是 | 固定值 get_products |
uid | int | 是 | 用户编号 |
api_key | string | 是 | API 密钥 |
timestamp | int | 是 | Unix 时间戳 |
sign | string | 是 | 签名 |
category | string | 否 | 分类标识 |
keyword | string | 否 | 关键词 |
page | int | 否 | 页码,默认 1 |
per_page | int | 否 | 每页数量,默认 50,最大 100 |
返回示例
{
"code": 0,
"msg": "success",
"data": [
{
"id": 1,
"name": "美团会员月卡",
"description": "官方直充,秒到账",
"price": 15.00,
"original_price": 20.00,
"vip_price": 12.00,
"image": "https://xxx.com/xxx.jpg",
"category": "cat_a8f3b2",
"category_id": "cat_a8f3b2",
"category_name": "会员专区",
"input_title": "下单QQ",
"stock": 100,
"status": 1,
"tags": "热卖,限时"
}
],
"total": 1,
"page": 1,
"per_page": 50
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
id | int | 商品 ID |
name | string | 商品名称 |
price | float | 现价 |
vip_price | float | 会员价,0 表示无 |
image | string | 商品主图,完整 URL |
category_id | string | 分类标识码 |
category_name | string | 分类中文名 |
stock | int | 库存,-1 表示无限 |
status | int | 1 上架,0 下架 |
获取单个商品 POST
按商品 ID 获取商品的完整详情。
POST/api/index.php?act=get_product
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
act | string | 是 | 固定值 get_product |
uid | int | 是 | 用户编号 |
api_key | string | 是 | API 密钥 |
timestamp | int | 是 | Unix 时间戳 |
sign | string | 是 | 签名 |
product_id | int | 是 | 商品 ID |
返回示例
{
"code": 0,
"msg": "success",
"data": {
"id": 1,
"name": "美团会员月卡",
"price": 15.00,
"stock": 100
}
}
字段与商品列表中的单个商品一致。
提交订单 POST
使用指定用户编号的余额下单,成功后扣余额、减库存、写入订单。
POST/api/index.php?act=create_order
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
act | string | 是 | 固定值 create_order |
uid | int | 是 | 用户编号 |
api_key | string | 是 | API 密钥 |
timestamp | int | 是 | Unix 时间戳 |
sign | string | 是 | 签名 |
product_id | int | 是 | 商品 ID |
input1 | string | 是 | 主输入内容 |
quantity | int | 否 | 数量,默认 1,最大 99 |
input2 | string | 否 | 附加输入 2 |
input3 | string | 否 | 附加输入 3 |
input4 | string | 否 | 附加输入 4 |
note | string | 否 | 订单备注 |
callback_url | string | 否 | 状态回调地址 |
返回示例
{
"code": 0,
"msg": "下单成功",
"order_no": "202609121200001234",
"total_price": 15.00,
"card_content": "卡密内容"
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
order_no | string | 订单号 |
total_price | float | 订单总金额 |
card_content | string | 卡密内容,多张用 \n 分隔 |
api_result | string | 工具型商品返回的上游解析结果 |
display_type | string | 建议展示类型 |
查询订单 POST
根据订单号查询订单的当前状态。
POST/api/index.php?act=query_order
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
act | string | 是 | 固定值 query_order |
uid | int | 是 | 用户编号 |
api_key | string | 是 | API 密钥 |
timestamp | int | 是 | Unix 时间戳 |
sign | string | 是 | 签名 |
order_no | string | 是 | 要查询的订单号 |
返回示例
{
"code": 0,
"msg": "success",
"data": {
"order_no": "202609121200001234",
"product_name": "美团会员月卡",
"quantity": 1,
"total_price": 15.00,
"status": 3,
"status_text": "已完成",
"card_content": ["卡密1"]
}
}
订单状态
| status | 含义 |
|---|---|
0 | 待处理 |
1 | 已支付 |
2 | 处理中 |
3 | 已完成 |
4 | 已取消 / 失败 |
主动推送
下单时传 callback_url,订单状态变化时系统会主动推送到该地址。下游需返回字符串 ok。
订单状态推送
请求方式:POST application/x-www-form-urlencoded
| 参数 | 类型 | 说明 |
|---|---|---|
order_no | string | 本站订单号 |
out_trade_no | string | 下游订单号 |
product_id | int | 商品 ID |
quantity | int | 购买数量 |
total_price | float | 订单金额 |
status | int | 订单状态 |
status_text | string | 状态文字 |
card_content | string | 卡密内容 |
timestamp | int | 推送时间戳 |
sign | string | 签名 |
签名规则
ksort($params); $str = ''; foreach ($params as $k => $v) { if ($k === 'sign') continue; $str .= $k . '=' . $v . '&'; } $str = rtrim($str, '&') . $api_key; $sign = md5($str);
重试机制
失败后按 5 / 10 / 15 / 20 / 25 分钟间隔重试,最多 5 次。
下游处理示例(PHP)
$post = $_POST; $sign = $post['sign'] ?? ''; unset($post['sign']); ksort($post); $str = ''; foreach ($post as $k => $v) { $str .= $k . '=' . $v . '&'; } $str = rtrim($str, '&') . $api_key; if (md5($str) !== $sign) { echo 'error'; exit; } $order_no = $post['order_no']; $status = intval($post['status']); db_query("UPDATE orders SET status='$status' WHERE order_no='$order_no'"); echo 'ok';
分类同步流程
对接方按以下步骤同步上游商品与分类。
同步步骤
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 调用 get_categories | 获取上游全部分类 |
| 2 | 本地建分类 | 按 name 建同名分类 |
| 3 | 调用 get_products | 分页拉取商品 |
| 4 | 商品归位 | 按 category_id 匹配本地分类 |
示例代码
$cats = api('get_categories'); foreach ($cats['data'] as $c) { $exist = db_get_row("SELECT id FROM categories WHERE name='{$c['name']}'"); if (!$exist) { db_query("INSERT INTO categories (name, tag) VALUES ('{$c['name']}', '{$c['id']}')"); } } $page = 1; while (true) { $products = api('get_products', ['page' => $page, 'per_page' => 100]); if (empty($products['data'])) break; foreach ($products['data'] as $p) { $localCat = db_get_row("SELECT tag FROM categories WHERE name='{$p['category_name']}'"); $catTag = $localCat ? $localCat['tag'] : ''; db_query("INSERT INTO products (name, price, category) VALUES ('{$p['name']}', '{$p['price']}', '{$catTag}')"); } $page++; }
工具接口参数
本系统支持「自定义 API 工具」型商品。第三方系统下单此类商品时,本系统会调用上游 API,将上游返回的已解析结果原样返回。
与卡密商品区别
| 类型 | 返回内容 |
|---|---|
| 卡密商品 | card_content:卡密文本 |
| 工具 / 对接商品 | api_result:上游解析后的成品 |
返回参数
| 字段 | 类型 | 说明 |
|---|---|---|
api_result | string | 上游返回的已解析结果,原样返回 |
display_type | string | 建议展示类型:text / image / audio / video |
示例
{
"code": 0,
"msg": "下单成功",
"order_no": "202609121200001234",
"total_price": 1.00,
"display_type": "video",
"api_result": "https://xxx.com/video/xxx.mp4"
}
处理建议
| display_type | 建议处理 |
|---|---|
text | 直接文本展示 |
image | 按链接展示图片 |
audio | 用播放器加载链接 |
video | 用播放器加载链接 |
状态码 / 错误码
返回码
| code | 说明 |
|---|---|
0 | 请求成功 |
-1 | 请求失败,具体原因见 msg |
常见错误
| msg | 原因 |
|---|---|
| API密钥不能为空 | 未提交 api_key |
| 用户ID不能为空 | 未提交 uid |
| 签名不能为空 | 未提交 sign |
| 时间戳不能为空 | 未提交 timestamp |
| 时间戳已过期 | 与服务器相差超过 300 秒 |
| 用户不存在或API密钥无效 | uid 与 api_key 不匹配 |
| 签名验证失败 | sign 计算错误 |
| IP 不在白名单中 | 来源 IP 未加白 |
| 商品不存在或已下架 | product_id 无效 |
| 余额不足 | 用户余额不足 |
| 订单不存在 | 订单号不存在或不属于该用户 |