快速开始
平台自带一个零依赖的 Node.js API 服务。在项目根目录执行下面命令即可启动,无需安装任何 npm 包:
# 启动 API + 静态站点服务(默认 8787 端口)
node api/server.js
# 或用 npm script
npm start
# 跑一遍全链路冒烟测试(26 项)
npm test
服务同时承担静态站点托管与 API 响应。健康检查:
GET /api/health
// 响应
{ "code": 0, "data": { "status": "ok", "service": "yunbuild-api", "version": "2.6.0" } }
所有响应统一为 { code, data, message } 结构。code = 0 表示成功;非 0 时读取 message。管理接口需在请求头携带 Authorization: Bearer <token>。
接口总览
1. 创建订单
用户选好模板或套餐后,先调用此接口生成订单,再拿订单号去发起支付。
POST /api/orders
Content-Type: application/json
{
"itemType": "template", // template 或 plan
"itemId": "t01-lanqi-tech",
"payChannel": "mock", // mock | custom | wechat | alipay
"coupon": "YUNBUILD200",
"customer": {
"name": "王先生", "phone": "13800138000",
"email": "wang@company.com", "company": "某某科技"
},
"remark": "需要部署协助"
}
// 201 响应
{ "code": 0, "data": {
"orderNo": "YB20261029A1B2C3", "amount": 1099,
"listPrice": 1299, "discount": 200, "status": "pending"
} }
| 字段 | 类型 | 必填 | 说明 |
itemType | string | 是 | template 单套模板 / plan 套餐订阅 |
itemId | string | 是 | 模板 ID 或套餐 ID(personal / business / unlimited / private) |
customer.name | string | 是 | 联系人姓名 |
customer.phone | string | 是 | 手机号或固定电话,接口会做格式校验 |
payChannel | string | 否 | 默认 mock |
coupon | string | 否 | 优惠码,内置 YUNBUILD200 / VIP500 / FIRST100 |
2. 发起支付
用订单号换取支付链接或二维码。渠道不同,返回的字段也不同。
POST /api/pay/create
{ "orderNo": "YB20261029A1B2C3", "channel": "mock" }
// 200 响应(沙盒)
{ "code": 0, "data": {
"success": true, "mode": "mock",
"payUrl": "http://127.0.0.1:8787/site/pay-mock.html?orderNo=...",
"expiresIn": 900
} }
// 真实网关返回 qrCode 字段时,前端用它渲染二维码
{ "data": { "success": true, "mode": "wechat", "qrCode": "weixin://wxpay/bizpayurl?pr=..." } }
沙盒模式下,确认支付走下面这个接口(真实网关请走异步回调,勿在前端调用):
POST /api/pay/confirm
{ "orderNo": "YB20261029A1B2C3" }
// 支付成功后自动置为 delivered 并生成 licenseKey
3. 异步支付回调
第三方支付完成后会回调此地址。自定义网关使用 HMAC-SHA256 校验请求头 X-YB-Signature。
POST /api/pay/notify/{channel}
// channel: custom | wechat | alipay
{ "orderNo": "YB20261029A1B2C3", "tradeNo": "4200001234" }
// 成功响应
{ "code": "SUCCESS", "message": "OK" }
幂等提醒:回调可能重复到达。服务内部已做状态判断,重复回调会返回已支付状态,不会重复发放授权码。微信 / 支付宝的证书解密与验签请按 api/gateways.js 中的注释接入。
4. 授权码校验与源码下载
POST /api/license/verify
{ "key": "YB-1A2B-3C4D-5E6F-7A8B" }
// → { valid: true, itemName: "...", holder: "...", expiresAt: null }
GET /api/download/t01-lanqi-tech?key=YB-1A2B-3C4D-5E6F-7A8B
// → application/zip,实时打包该模板全部源码 + LICENSE.txt
下载接口会校验授权码状态与该订单是否包含此模板。全站通授权可下载全部模板。演示环境默认开启 allowDemoDownload,上线前请在 data/config.json 中改为 false。
支付网关配置
在「管理后台 → 支付配置」中可视化填写,或直接编辑 data/config.json。所有密钥只保存在服务端,接口读取时会自动脱敏。
{
"siteBaseUrl": "https://your-domain.com",
"enableMockPay": true,
"allowDemoDownload": false,
"gateways": {
"custom": { "enabled": true, "endpoint": "https://api.your-pay.com/create",
"secret": "your-hmac-secret", "timeout": 10 },
"wechat": { "enabled": false, "appId": "", "mchId": "",
"apiV3Key": "", "privateKeyPath": "" },
"alipay": { "enabled": false, "appId": "", "privateKey": "" }
}
}
自定义网关协议
平台向你的 endpoint 发送 POST 请求,携带订单信息与 HMAC 签名;你的服务返回 payUrl(跳转收银台)或 qrCode(扫码内容)之一即可。
// 请求头
Content-Type: application/json
X-YB-Signature: <HMAC-SHA256(secret, rawBody)>
// 你的服务响应
{ "payUrl": "https://pay.your-domain.com/cashier/xxx", "tradeNo": "P20261029001" }
// 或
{ "qrCode": "weixin://wxpay/bizpayurl?pr=xxxxx", "tradeNo": "P20261029001" }
微信支付 v3 与支付宝 RSA2 的签名与证书接入步骤,已逐条写在 api/gateways.js 的 wechatPay() / alipayPay() 注释里,按步骤补齐即可切换生产环境。
部署指南
方式一:平台自带服务(推荐演示与小型站点)
把整个项目目录放到服务器,node api/server.js 用 pm2 或 systemd 守护,前面挂 Nginx 反代并配置 HTTPS 即可。
方式二:纯静态托管模板站点
每套模板都是纯静态文件,可单独上传到 Nginx、对象存储、Vercel、Netlify 或 CDN,不需要 Node 环境。后台默认使用浏览器本地存储,适合单端维护;多端协同请把 assets/js/main.js 中的读写逻辑改为调用你的服务端接口。
方式三:容器化
FROM node:20-alpine
WORKDIR /app
COPY . .
EXPOSE 8787
CMD ["node", "api/server.js"]
生产环境检查清单:① 修改默认管理员密码;② 关闭 allowDemoDownload;③ 配置 HTTPS 与反向代理;④ 把 data/*.json 迁移到数据库并做好备份;⑤ 关闭 enableMockPay。
错误码
| HTTP | 含义 | 处理建议 |
200 / 201 | 成功 | 读取 data 字段 |
401 | 未登录或登录已过期 / 回调签名失败 | 重新登录,或检查网关密钥 |
403 | 无权限 / 授权码无效 | 核对授权码与订单归属 |
404 | 资源不存在 | 检查模板 ID、订单号或路径 |
409 | 订单状态冲突 | 订单已支付或已关闭,勿重复提交 |
422 | 参数校验失败 | 按 message 修正字段 |
429 | 请求过于频繁 | 默认限流 180 次 / 分钟 / IP |
502 | 支付网关调用失败 | 检查网关配置与网络连通性 |