开放平台(Open API)接入指南
在线文档(推荐):https://docs.rizzitgo.com — API 参考与本文同步更新
适用对象:外部合作方 / 第三方开发者
语言版本:中文(本文) · English
本指南说明如何接入本系统的 /open-api/* 开放接口。开放接口与 C 端 /app-api、管理端 /admin-api 物理隔离,统一采用 OAuth2 client_credentials(客户端模式) 鉴权,并按 scope(授权范围)控制每个应用可调用的接口集合。
1. 概述与架构
- 鉴权模型:标准 OAuth2 客户端模式。合作方使用平台下发的
clientId + clientSecret换取短期access_token,再用令牌调用业务接口。开放平台不涉及用户登录、授权码、密码等模式。 - 接口隔离:所有开放接口挂载在
/open-api/**前缀下,由网关独立路由。开放令牌的用户类型固定为OPEN_API,无法访问/admin-api、/app-api,从源头规避越权。 - 权限粒度:每个接口由其所需的
scope控制(如商品详情接口需goods:detail:read)。应用只能调用其被授予的 scope 对应的接口。 - 多租户:请求需携带
tenant-id,且必须与换取令牌时一致。
调用时序:
sequenceDiagram
participant P as 合作方应用
participant GW as API 网关
participant SYS as 系统服务
participant BIZ as 业务服务
P->>GW: POST /open-api/system/oauth2/token<br/>Basic(clientId:clientSecret)
GW->>SYS: 转发取令牌请求
SYS-->>P: access_token(userType=OPEN_API, expires_in)
P->>GW: POST /open-api/goods/detail<br/>Bearer access_token + tenant-id
GW->>BIZ: 校验令牌 + scope 后转发
BIZ-->>P: 业务数据(统一 {code,data,msg})
2. 名词术语表
| 名词 | 说明 |
|---|---|
clientId |
客户端编号,应用的公开标识。 |
clientSecret |
客户端密钥,仅创建/重置时展示一次,等同口令,务必保密。 |
scope |
授权范围,决定可调用哪些接口,多个用空格分隔(如 goods:detail:read)。 |
tenant-id |
租户编号,多租户隔离标识,放入请求头。 |
access_token |
访问令牌,调用业务接口的凭证,有时效(见 expires_in)。 |
externalUserId |
合作方侧用户唯一标识。代购下单/余额支付前须由运营在「开放平台 / 会员绑定」与平台会员绑定。 |
outOrderNo |
合作方侧订单号,同一 clientId 下唯一,用于下单幂等。 |
paymentId |
平台支付流水号。创建代购单或补款支付单后返回,再拿去调用余额支付。 |
expires_in |
令牌剩余有效期,单位秒。 |
userType |
用户类型,开放平台令牌固定为 OPEN_API。 |
3. 接入流程
- 联系平台运营,提交:合作方名称、联系人(姓名/邮箱/电话)、回调来源 IP(可选,用于 IP 白名单)、需要的接口范围(scope)。
- 运营在管理后台「开放平台 / 合作方应用」创建应用,下发:
clientId(客户端编号)clientSecret(客户端密钥,仅展示一次,请妥善保存)- 授权
scope列表(如goods:detail:read) tenant-id(租户编号)
- 合作方使用
clientId + clientSecret换取access_token,再携带令牌调用业务接口。
上线前自检清单:
- 已安全保存
clientSecret(建议放入密钥管理系统,禁止写入前端/客户端代码或日志)。 - 已确认所需
scope均已开通。 - 调用方出口 IP 已加入白名单(若运营启用了白名单)。
- 已实现令牌缓存(按
expires_in复用,避免每次请求都换取令牌)。 - 已实现
401自动重新取令牌、429退避重试。
3.1 Scope 权限列表(完整)
以下是平台当前支持的所有 scope,命名规范为 {domain}:{resource}:{action}。申请令牌时通过 scope 参数指定所需权限(空格分隔多个),未被授予的 scope 对应接口将返回 403。
| # | Scope | 描述 | 对应接口路径 |
|---|---|---|---|
| 1 | goods:detail:read |
商品详情读取 | POST /open-api/goods/detail |
| 2 | goods:qc:read |
商品质检读取 | POST /open-api/goods/qc-detailPOST /open-api/goods/qc-imagesPOST /open-api/goods/qc-page |
| 3 | goods:search:read |
商品搜索读取 | POST /open-api/goods/search-by-imagesPOST /open-api/goods/search-url-parse |
| 4 | promotion:redeem-code:redeem |
优惠券随机兑换 | POST /open-api/promotion/redeem-code/redeem |
| 5 | promotion:member-coupon:read |
用户优惠券查询 | POST /open-api/promotion/member-coupon/page |
| 6 | promotion:member-coupon:extend |
用户优惠券续期 | POST /open-api/promotion/member-coupon/extend |
| 7 | promotion:member-coupon:restore |
用户优惠券恢复 | POST /open-api/promotion/member-coupon/restore |
| 8 | promotion:coupon-exchange-code:read |
优惠券兑换码状态查询 | POST /open-api/promotion/coupon-exchange-code/status |
| 9 | promotion:spreadsheet:read |
推广者电子表格商品查询 | POST /open-api/promotion/spreadsheet/page |
| 10 | pay:order:create |
支付单创建 | POST /open-api/pay/order/create |
| 11 | pay:order:query |
支付单查询 | POST /open-api/pay/order/queryPOST /open-api/pay/order/page |
| 12 | pay:order:shipments |
支付单物流回填 | POST /open-api/pay/order/upload-shipments |
| 13 | pay:exchange-rate:read |
系统汇率列表查询 | POST /open-api/pay/exchange-rate/list |
| 14 | order:bag-order:read |
包裹单查询 | POST /open-api/order/bag-order/queryPOST /open-api/order/bag-order/page |
| 15 | order:order-item:read |
商品订单明细查询 | POST /open-api/order/order-item/page |
| 16 | logistics:track:query |
物流轨迹查询 | POST /open-api/logistics/track/query |
| 17 | logistics:freight-estimate:read |
运费估算 | POST /open-api/logistics/line/freight-estimate |
| 18 | member:auth:discord-login |
Discord 授权登录链接 / 登录状态查询 | POST /open-api/member/auth/discord-authorize-urlPOST /open-api/member/auth/discord-login-status |
| 19 | system:partner-member:read |
合作方会员绑定查询 | POST /open-api/system/partner-member/queryPOST /open-api/system/partner-member/list |
| 20 | order:purchase:quote |
代购单询价 | POST /open-api/order/purchase/quote |
| 21 | order:purchase:create |
代购单创建 | POST /open-api/order/purchase/create |
| 22 | order:purchase:query |
代购单查询 / 待补款列表 | POST /open-api/order/purchase/queryPOST /open-api/order/purchase/supplement/list |
| 23 | order:purchase:supplement-pay |
创建补款支付单 | POST /open-api/order/purchase/supplement/trade-no |
| 24 | pay:wallet:query |
会员余额查询 | POST /open-api/pay/wallet/balance |
| 25 | pay:wallet:pay |
会员余额支付 | POST /open-api/pay/wallet/pay |
| 26 | member:consumption:read |
用户消费信息查询 | POST /open-api/member/consumption/query |
| 27 | promotion:discord-checkin:claim |
Discord 每日签到 | POST /open-api/promotion/discord-checkin |
| 28 | order:invoice:create |
包裹发票生成 | POST /open-api/order/invoice/create |
| 29 | order:invoice:query |
包裹发票查询 | POST /open-api/order/invoice/query |
说明:OAuth2 令牌接口(
/open-api/system/oauth2/token和/token/revoke)本身不需要 scope,仅需clientId + clientSecret认证。scope 列表随业务扩展而增加,请以本文档最新版本为准。
4. 环境与域名
| 环境 | 网关域名 | 说明 |
|---|---|---|
| 沙箱 / 测试 | api-qa.rzdzht.me |
联调使用,数据与生产隔离。 |
| 生产 | api.rizzitgo.com |
正式环境。 |
生产网关域名为
api.rizzitgo.com(文档示例已采用),测试/沙箱网关域名为api-qa.rzdzht.me。{租户编号}、{clientId}、{clientSecret}等占位符请替换为运营下发的实际值。
5. 获取访问令牌
- 方法与路径:
POST /open-api/system/oauth2/token - 认证:HTTP Basic,将
clientId:clientSecret拼接后做 Base64 编码,放入Authorization头(即Authorization: Basic base64(clientId:clientSecret))。 - Content-Type:
application/x-www-form-urlencoded
请求参数:
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
Authorization |
Header | 是 | Basic base64(clientId:clientSecret) |
tenant-id |
Header | 是 | 租户编号 |
grant_type |
Body | 是 | 固定为 client_credentials |
scope |
Body | 否 | 多个用空格分隔;不传则使用应用已授权的全部 scope |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/system/oauth2/token' \
-H 'Authorization: Basic {base64(clientId:clientSecret)}' \
-H 'tenant-id: {租户编号}' \
-d 'grant_type=client_credentials' \
-d 'scope=goods:detail:read'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
access_token |
string | 访问令牌,后续业务请求携带 |
refresh_token |
string | 客户端模式下为空字符串(无刷新令牌,过期后重新换取) |
token_type |
string | 固定 Bearer |
expires_in |
number | 令牌有效期(秒),示例 1800 |
scope |
string | 实际授予的授权范围,多个用空格分隔 |
响应示例:
{
"code": 0,
"data": {
"access_token": "xxxxxxxx",
"refresh_token": "",
"token_type": "Bearer",
"expires_in": 1800,
"scope": "goods:detail:read"
},
"msg": ""
}
说明:开放平台仅支持
client_credentials;传入其它grant_type(如authorization_code/password/refresh_token)会返回400,提示「开放平台仅支持 client_credentials 授权模式」。令牌的userType固定为OPEN_API,无法访问/admin-api、/app-api接口。
6. 调用业务接口
所有业务请求需带:
| Header | 必填 | 说明 |
|---|---|---|
Authorization |
是 | Bearer {access_token} |
tenant-id |
是 | 与换取令牌时一致的租户编号 |
Content-Type |
是(有 body 时) | application/json |
7. 接口参考
7.1 查询商品详情(试点)
- 方法与路径:
POST /open-api/goods/detail - 所需 scope:
goods:detail:read
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
goodsId |
string | 是 | 商品 ID,不能为空,且不能为 0 |
source |
integer | 是 | 商品来源:1=淘宝,2=1688,3=微店 |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/goods/detail' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"goodsId":"123456","source":1}'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
goodsId |
string | 商品 ID |
goodsTitle |
string | 商品标题 |
goodsDetailUrl |
string | 商品详情页地址 |
goodsPicUrl |
string | 商品主图 |
price |
string | 商品价格(元) |
priceInCents |
number | 商品价格(分) |
orginalPrice |
string | 商品原价(元) |
stockNum |
string | 商品库存 |
salesCount |
string | 商品销售数量 |
goodsImageUrlList |
string[] | 商品图片列表 |
postFee |
string | 商品运费(元) |
goodsSource |
integer | 商品来源:1=淘宝,2=1688,3=微店 |
skuList |
object[] | 商品 SKU 列表,元素字段见下表 |
skuSpecInfoList |
object[] | SKU 规格维度(如颜色、尺码),用于选择规格;元素字段见下表 |
skuList 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
skuId |
string | SKU ID |
specId |
string | 1688 规格 ID |
price |
string | SKU 价格(元) |
priceInCents |
number | SKU 价格(分) |
salePrice |
string | SKU 售价(元) |
salePriceInCents |
number | SKU 售价(分) |
quantity |
integer | SKU 库存数量 |
imageUrl |
string | SKU 图片 URL |
propertiesId |
string | SKU 规格 ID |
propertiesName |
string | SKU 规格名称 |
skuSpecInfoList 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
skuSpecName |
string | 规格维度名称,如颜色、尺码 |
skuSpecList |
object[] | 该维度下的规格值:pid、vid、pname、vname、icon |
响应示例:
{
"code": 0,
"data": {
"goodsId": "123456",
"goodsTitle": "示例商品",
"goodsDetailUrl": "https://example.com/item/123456",
"goodsPicUrl": "https://example.com/img/123456.jpg",
"price": "99.00",
"priceInCents": 9900,
"orginalPrice": "129.00",
"stockNum": "1000",
"salesCount": "532",
"goodsImageUrlList": [
"https://example.com/img/1.jpg",
"https://example.com/img/2.jpg"
],
"postFee": "0.00",
"goodsSource": 1,
"skuList": [
{
"skuId": "5001",
"specId": null,
"price": "99.00",
"priceInCents": 9900,
"salePrice": "99.00",
"salePriceInCents": 9900,
"quantity": 100,
"imageUrl": "https://example.com/img/sku-5001.jpg",
"propertiesId": "1627207:28341",
"propertiesName": "颜色:红色;尺码:M"
}
],
"skuSpecInfoList": [
{
"skuSpecName": "颜色",
"skuSpecList": [
{ "pid": "1627207", "vid": "28341", "pname": "颜色", "vname": "红色", "icon": null }
]
}
]
},
"msg": ""
}
7.2 查询商品质检详情
- 方法与路径:
POST /open-api/goods/qc-detail - 所需 scope:
goods:qc:read
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
goodsId |
string | 是 | 商品 ID,不能为空,且不能为 0 |
source |
integer | 是 | 商品来源:1=淘宝,2=1688,3=微店 |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/goods/qc-detail' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"goodsId":"123456","source":1}'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
goodsId |
string | 商品 ID |
qcPathList |
string[] | 质检照片列表 |
length |
string | 长(cm) |
width |
string | 宽(cm) |
height |
string | 高(cm) |
weight |
string | 重量(g) |
volume |
string | 体积(cm³) |
completionTime |
string | 质检完成时间(yyyy-MM-dd HH:mm:ss) |
说明:出于内部信息保护,质检接口不返回质检员/拍照员的 ID 与姓名等员工信息。
响应示例:
{
"code": 0,
"data": {
"goodsId": "123456",
"qcPathList": [
"https://example.com/qc/1.jpg",
"https://example.com/qc/2.jpg"
],
"length": "30",
"width": "20",
"height": "10",
"weight": "500",
"volume": "6000",
"completionTime": "2026-06-02 18:30:00"
},
"msg": ""
}
7.3 查询商品质检图片列表
- 方法与路径:
POST /open-api/goods/qc-images - 所需 scope:
goods:qc:read - 请求参数:同 7.2(
goodsId+source)
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/goods/qc-images' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"goodsId":"123456","source":1}'
响应示例: data 为质检图片地址数组。
{
"code": 0,
"data": [
"https://example.com/qc/1.jpg",
"https://example.com/qc/2.jpg"
],
"msg": ""
}
7.4 按时间分页查询质检数据
- 方法与路径:
POST /open-api/goods/qc-page - 所需 scope:
goods:qc:read
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNo |
integer | 是 | 页码,从 1 开始 |
pageSize |
integer | 是 | 每页条数 |
goodsId |
string | 否 | 按商品 ID 精确过滤 |
source |
integer | 否 | 商品来源:1=淘宝,2=1688,3=微店 |
createTime |
string[] | 否 | 记录创建时间区间 [开始, 结束],格式 yyyy-MM-dd HH:mm:ss |
completionTime |
string[] | 否 | 质检完成时间区间 [开始, 结束],格式 yyyy-MM-dd HH:mm:ss |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/goods/qc-page' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{
"pageNo": 1,
"pageSize": 10,
"completionTime": ["2026-06-01 00:00:00", "2026-06-02 23:59:59"]
}'
响应字段: data.list 为质检详情数组(字段同 7.2),data.total 为总条数。
{
"code": 0,
"data": {
"list": [
{
"goodsId": "123456",
"qcPathList": ["https://example.com/qc/1.jpg"],
"length": "30",
"width": "20",
"height": "10",
"weight": "500",
"volume": "6000",
"completionTime": "2026-06-02 18:30:00"
}
],
"total": 1
},
"msg": ""
}
7.5 图片识别搜索商品列表
- 方法与路径:
POST /open-api/goods/search-by-images - 所需 scope:
goods:search:read
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
imagesUrl |
string | 是 | 图片 URL,需为可公网访问的图片地址(支持常见图片后缀,如 .jpg/.png 等);格式不合法返回「图片链接格式不合法」 |
page |
integer | 是 | 当前页,从 1 开始 |
source |
integer | 是 | 商品来源:1=淘宝,2=1688,3=微店 |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/goods/search-by-images' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"imagesUrl":"https://example.com/img/query.jpg","page":1,"source":1}'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
goodsList |
object[] | 商品列表,元素字段见下表 |
page |
integer | 当前页 |
size |
integer | 页大小 |
totalPage |
integer | 总页数 |
totalCount |
integer | 总条数 |
goodsList 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
goodsId |
string | 商品 ID |
goodsTitle |
string | 商品标题 |
goodsDetailUrl |
string | 商品详情页地址 |
goodsPicUrl |
string | 商品主图 |
goodsSource |
integer | 商品来源:1=淘宝,2=1688,3=微店 |
price |
string | 商品价格(元) |
priceInCents |
number | 商品价格(分) |
originPriceInCents |
number | 商品原价/划线价(分) |
salesCount |
string | 商品销售数量 |
hasDiscount |
boolean | 是否享受优惠活动 |
discountPriceInCents |
number | 优惠后价格(分) |
说明:出于内部信息保护,开放接口不返回会员维度的收藏状态、个性化分享链接等内部字段。
响应示例:
{
"code": 0,
"data": {
"goodsList": [
{
"goodsId": "123456",
"goodsTitle": "示例商品",
"goodsDetailUrl": "https://example.com/item/123456",
"goodsPicUrl": "https://example.com/img/123456.jpg",
"goodsSource": 1,
"price": "99.00",
"priceInCents": 9900,
"originPriceInCents": 9900,
"salesCount": "532",
"hasDiscount": true,
"discountPriceInCents": 8900
}
],
"page": 1,
"size": 20,
"totalPage": 5,
"totalCount": 100
},
"msg": ""
}
7.6 商品链接解析
- 方法与路径:
POST /open-api/goods/search-url-parse - 所需 scope:
goods:search:read - 说明:解析淘宝/天猫、1688、微店及常见代购站(cssbuy、cnfans、hoobuy 等)的短链或长链,提取平台商品 ID 与来源。无法识别的链接返回「商品链接解析失败」。
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
searchUrl |
string | 是 | 待解析的商品链接,支持短链、长链及含杂质的粘贴文本(会自动剔除空格、中文等) |
rno |
string | 否 | 推广码;非空时拼接到响应 targetGoodsDetailUrl 中 |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/goods/search-url-parse' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"searchUrl":"https://detail.tmall.com/item.htm?id=768650559131","rno":"ABC123"}'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
goodsId |
string | 平台商品 ID |
goodsSource |
integer | 商品来源:1=淘宝,2=1688,3=微店,4=其它 |
goodsSourceName |
string | 商品来源名称(taobao/alibaba/weidian) |
goodsDetailUrl |
string | 原平台商品详情页地址 |
targetGoodsDetailUrl |
string | 站内分享链接(rno 非空时含推广码) |
success |
boolean | 是否解析成功 |
searchUrl |
string | 清洗后的输入链接 |
响应示例:
{
"code": 0,
"data": {
"goodsId": "768650559131",
"goodsSource": 1,
"goodsSourceName": "taobao",
"goodsDetailUrl": "https://detail.tmall.com/item.htm?id=768650559131",
"targetGoodsDetailUrl": "https://www.rizzitgo.com/detailPage?goodsId=768650559131&source=1&rno=ABC123",
"success": true,
"searchUrl": "https://detail.tmall.com/item.htm?id=768650559131"
},
"msg": ""
}
7.7 优惠券随机兑换(按邮箱或 Discord 用户 ID 发券)
- 方法与路径:
POST /open-api/promotion/redeem-code/redeem - 所需 scope:
promotion:redeem-code:redeem - 说明:使用平台后台预先配置好的兑换码(可绑定 N 张优惠券模板,并按权重随机命中一张),为指定会员发放优惠券。会员标识为
email与discordUserId二选一(至少传一个);两者都传时只用 Discord,不回落到邮箱。会员必须已存在(邮箱精确匹配,或 Discord 已绑定会员),否则返回「会员不存在」,本接口不会自动创建会员。
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
code |
string | 是 | 兑换码 |
email |
string | 与 discordUserId 二选一 |
收券会员邮箱,需与平台会员账号一致(精确匹配) |
discordUserId |
string | 与 email 二选一 |
Discord 用户 ID(snowflake,对应社交 openid) |
requestId |
string | 否 | 外部请求流水号,用于幂等防重;同一 requestId 在 10 分钟内仅处理一次,重复请求返回「请求重复,请勿重试」 |
按邮箱请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/promotion/redeem-code/redeem' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"code":"E602F4DC626E4948","email":"[email protected]","requestId":"REQ-20260604-0001"}'
按 Discord 用户 ID 请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/promotion/redeem-code/redeem' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"code":"E602F4DC626E4948","discordUserId":"123456789012345678","requestId":"REQ-20260824-0001"}'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
code |
string | 兑换码 |
email |
string | 收券会员邮箱;按 Discord 发券时回填会员邮箱(可空) |
discordUserId |
string | Discord 用户 ID;按 Discord 发券时回显,按邮箱发券时为 null |
prize |
string | 本次中奖/获得的奖品描述,按券折扣自动生成:折扣券为 30% OFF,满减券为 $10 OFF(金额固定美元,由分换算为元);多张时以逗号分隔,无折扣信息时回退为券标题 |
success |
boolean | 兑换是否成功 |
message |
string | 兑换结果描述 |
coupons |
object[] | 本次兑换得到的优惠券列表(随机模式下通常为 1 张),元素字段见下表 |
coupons 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
templateId |
number | 优惠券模板 ID |
title |
string | 优惠券标题 |
couponType |
integer | 优惠券类型:1=运费券,2=商品券,3=全场券 |
discountType |
integer | 优惠类型:1=满元减,2=满元折 |
discountPrice |
number | 优惠金额(单位:分) |
discountPercent |
number | 折扣百分比(discountType=2 时有效,如 80 表示 8 折) |
usePriceCondition |
number | 门槛:满多少金额可用(单位:分,0 表示不限制) |
validStartTime |
string | 生效开始时间 |
validEndTime |
string | 生效结束时间 |
响应示例:
{
"code": 0,
"data": {
"code": "E602F4DC626E4948",
"email": "[email protected]",
"discordUserId": null,
"prize": "30% OFF",
"success": true,
"message": "兑换成功,共获得 1 张优惠券",
"coupons": [
{
"templateId": 1001,
"title": "满100减10",
"couponType": 2,
"discountType": 1,
"discountPrice": 1000,
"discountPercent": null,
"usePriceCondition": 10000,
"validStartTime": "2026-06-01 00:00:00",
"validEndTime": "2026-06-30 23:59:59"
}
]
},
"msg": ""
}
业务错误:
discordUserId都未传返回「邮箱与 Discord 用户 ID 至少传一个」;按邮箱或 Discord 查不到会员(含 Discord 未绑定、会员已删除)返回「会员不存在」;兑换码不存在/已过期/已作废、超过每人或每日(含 IP)限兑次数等,沿用兑换码模块既有错误码与提示。兑换码的限领/限兑/有效期等限制在后台配置,请按运营约定的额度调用。
7.8 用户优惠券查询 / 续期 / 恢复
通过邮箱、会员编号(unionId)或用户 ID 定位会员,查询其优惠券列表;对未使用券续期、对已失效券恢复。三个接口的用户标识规则一致:三选一,优先级 userId > unionId > email。
优惠券状态编码(请求与响应均为字符串,非数字):
| 编码 | 含义 |
|---|---|
UNUSED |
未使用 |
USED |
已使用 |
FINISH |
已核销 |
EXPIRE |
已失效 |
INVALID |
已作废 |
7.8.1 分页查询用户优惠券
- 方法与路径:
POST /open-api/promotion/member-coupon/page - 所需 scope:
promotion:member-coupon:read
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNo |
integer | 否 | 页码,从 1 开始,默认 1 |
pageSize |
integer | 否 | 每页条数,默认 10 |
email |
string | 三选一 | 用户邮箱 |
unionId |
string | 三选一 | 会员编号 |
userId |
number | 三选一 | 用户 ID |
status |
string | 否 | 状态编码精确过滤,如 EXPIRE 查已失效券;不传返回全部 |
code |
string | 否 | 券码模糊匹配 |
templateId |
number | 否 | 优惠券模板 ID |
响应 data 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
list |
object[] | 优惠券列表,元素字段见下表 |
total |
number | 总条数 |
list 元素主要字段:id、templateId、title、code、status(字符串编码)、couponType、discountType、discountPrice、discountPercent、usePriceCondition、validStartTime、validEndTime、useTime、takeTime。
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/promotion/member-coupon/page' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]","status":"EXPIRE","pageNo":1,"pageSize":10}'
7.8.2 续期未使用优惠券
- 方法与路径:
POST /open-api/promotion/member-coupon/extend - 所需 scope:
promotion:member-coupon:extend - 说明:仅
status=UNUSED的券可续期;在原有validEndTime基础上延长(若已过期则从当前时间起算)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
email / unionId / userId |
— | 三选一 | 定位会员 |
couponIds |
number[] | 是 | 优惠券 ID 列表 |
extendDays |
integer | 是 | 延期天数,1~365 |
响应 data: successCount(成功数量)、coupons(含 id、status、validEndTime)。
7.8.3 恢复已失效优惠券
- 方法与路径:
POST /open-api/promotion/member-coupon/restore - 所需 scope:
promotion:member-coupon:restore - 说明:仅
status=EXPIRE的券可恢复;恢复后状态变为UNUSED,并按后台配置重设有效期(默认 15 天)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
email / unionId / userId |
— | 三选一 | 定位会员 |
couponIds |
number[] | 是 | 优惠券 ID 列表 |
响应 data: successCount、coupons(id、status 为 UNUSED、validEndTime)。
业务错误:
1_013_024_000未提供用户标识;1_013_024_001会员不存在;1_013_024_002券不属于该用户;1_013_024_003状态编码无效;1_013_024_004恢复时券非EXPIRE;续期非UNUSED时返回1_013_003_005。
7.9 推广者电子表格商品分页查询
通过推广码 rno 指定推广者,分页查询其电子表格(分享商品列表)。可选按自定义分类、关键字、商品来源、价格区间及排序方式筛选。
- 方法与路径:
POST /open-api/promotion/spreadsheet/page - 所需 scope:
promotion:spreadsheet:read
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNo |
integer | 否 | 页码,从 1 开始,默认 1 |
pageSize |
integer | 否 | 每页条数,默认 10 |
rno |
string | 是 | 推广者分销码 |
categoryCode |
string | 否 | 推广者自定义分类编码;不传则不过滤分类 |
keyword |
string | 否 | 搜索关键字(匹配商品标题) |
source |
integer | 否 | 商品来源:1=淘宝,2=1688,3=微店 |
sort |
integer | 否 | 排序:省略=创建时间倒序;1=销量倒序;2=价格升序;3=价格降序 |
minGoodsPrice |
number | 否 | 最低价格(人民币分) |
maxGoodsPrice |
number | 否 | 最高价格(人民币分) |
响应 data 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
list |
object[] | 商品列表,元素字段见下表 |
total |
number | 总条数 |
list 元素主要字段:
| 字段 | 类型 | 说明 |
|---|---|---|
goodsId |
string | 商品 ID |
goodsTitle |
string | 商品标题(英文) |
localGoodsTitle |
string | 商品标题(中文) |
priceInCents |
number | 商品价格(人民币分) |
priceInUsd |
string | 商品价格(USD,按数据库交易汇率换算,两位小数) |
goodsSource |
integer | 商品来源:1/2/3 |
goodsPicUrl |
string | 商品主图 URL |
goodsImageUrlList |
string[] | 商品图片列表;已异步补全时为多图,未补全时可能仅含主图单元素 |
goodsDetailUrl |
string | 商品详情页 URL(含 rno) |
goodsSaleCount |
integer | 销量 |
goodsSda |
string | 商品绑定的推广码 |
goodsCategoryCode |
string | 推广者自定义分类编码 |
qcInfoList |
object[] | 该商品最新最多 5 组质检信息;无质检时为空数组。元素字段与开放平台商品 QC(/open-api/goods/qc-*)一致:goodsId、skuId、source、goodsName、localGoodsName、specName、localSpecName、imagePath、goodsDetailUrl、qcPathList、length、width、height、weight、volume、completionTime(不含质检员/拍照员信息) |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/promotion/spreadsheet/page' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"rno":"ABC123","categoryCode":"cat_001","pageNo":1,"pageSize":10}'
业务错误:
1_013_025_000未传 rno;1_013_007_000推广者不存在(rno 无效)。
8. 撤销令牌(可选)
- 方法与路径:
POST /open-api/system/oauth2/token/revoke - 认证:同获取令牌(HTTP Basic)
- 参数:
token={access_token}(application/x-www-form-urlencoded)
curl -X POST 'https://api.rizzitgo.com/open-api/system/oauth2/token/revoke' \
-H 'Authorization: Basic {base64(clientId:clientSecret)}' \
-H 'tenant-id: {租户编号}' \
-d 'token={access_token}'
9. 统一响应结构与错误码
所有接口统一返回结构 { code, data, msg }:code = 0 表示成功,其余为失败,msg 为提示信息。
高频错误:
| HTTP / code | 含义 | 处理建议 |
|---|---|---|
401 |
令牌缺失 / 失效 / 过期 | 重新调用 token 接口获取新令牌后重试 |
403 |
scope 不足 / 用户类型不符 | 联系运营开通对应 scope |
429 |
触发限流(按 clientId 维度) | 降低调用频率,指数退避重试,必要时申请提升 QPS |
400 |
参数错误 / 不支持的 grant_type | 检查请求参数与授权类型 |
10. 安全与限制
- IP 白名单:如运营为应用配置了
ipWhitelist(逗号分隔,多个 IP),仅白名单内来源 IP 可调用;为空表示不限制。 - 限流:可按应用配置每秒 QPS(
rateLimitQps,0表示不限)。超限返回429。 - 密钥保管:
clientSecret仅展示一次;切勿写入前端/客户端代码、日志或版本库。如泄漏请立即联系运营在「合作方应用」中「重置密钥」,旧密钥即时失效。 - 令牌缓存与并发刷新:请在客户端缓存
access_token,在expires_in内复用,避免高频换取令牌;建议在过期前留出缓冲(如剩余 < 60s 时提前刷新),并对刷新过程加锁,防止并发重复换取。 - 重试与退避:遇
401自动重新取令牌并重试一次;遇429/网络抖动采用指数退避(如 1s、2s、4s)重试,设上限。 - 多租户:请求务必携带与令牌一致的
tenant-id,避免跨租户访问被拒绝。
11. 代码示例(取令牌 → 调商品详情)
cURL
# 1) 取令牌
TOKEN=$(curl -s -X POST 'https://api.rizzitgo.com/open-api/system/oauth2/token' \
-H 'Authorization: Basic {base64(clientId:clientSecret)}' \
-H 'tenant-id: {租户编号}' \
-d 'grant_type=client_credentials' \
-d 'scope=goods:detail:read' | jq -r '.data.access_token')
# 2) 调商品详情
curl -X POST 'https://api.rizzitgo.com/open-api/goods/detail' \
-H "Authorization: Bearer ${TOKEN}" \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"goodsId":"123456","source":1}'
Java(JDK 11+ HttpClient)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
public class OpenApiDemo {
static final String GATEWAY = "https://api.rizzitgo.com";
static final String TENANT_ID = "{租户编号}";
static final String CLIENT_ID = "{clientId}";
static final String CLIENT_SECRET = "{clientSecret}";
public static void main(String[] args) throws Exception {
HttpClient http = HttpClient.newHttpClient();
// 1) 取令牌
String basic = Base64.getEncoder()
.encodeToString((CLIENT_ID + ":" + CLIENT_SECRET).getBytes());
HttpRequest tokenReq = HttpRequest.newBuilder()
.uri(URI.create(GATEWAY + "/open-api/system/oauth2/token"))
.header("Authorization", "Basic " + basic)
.header("tenant-id", TENANT_ID)
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(
"grant_type=client_credentials&scope=goods:detail:read"))
.build();
HttpResponse<String> tokenResp = http.send(tokenReq, HttpResponse.BodyHandlers.ofString());
System.out.println(tokenResp.body());
// 实际项目中请用 JSON 库解析 data.access_token
String accessToken = "<从 tokenResp 解析 data.access_token>";
// 2) 调商品详情
HttpRequest bizReq = HttpRequest.newBuilder()
.uri(URI.create(GATEWAY + "/open-api/goods/detail"))
.header("Authorization", "Bearer " + accessToken)
.header("tenant-id", TENANT_ID)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
"{\"goodsId\":\"123456\",\"source\":1}"))
.build();
HttpResponse<String> bizResp = http.send(bizReq, HttpResponse.BodyHandlers.ofString());
System.out.println(bizResp.body());
}
}
Python(requests)
import base64
import requests
GATEWAY = "https://api.rizzitgo.com"
TENANT_ID = "{租户编号}"
CLIENT_ID = "{clientId}"
CLIENT_SECRET = "{clientSecret}"
# 1) 取令牌
basic = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
token_resp = requests.post(
f"{GATEWAY}/open-api/system/oauth2/token",
headers={"Authorization": f"Basic {basic}", "tenant-id": TENANT_ID},
data={"grant_type": "client_credentials", "scope": "goods:detail:read"},
)
access_token = token_resp.json()["data"]["access_token"]
# 2) 调商品详情
biz_resp = requests.post(
f"{GATEWAY}/open-api/goods/detail",
headers={
"Authorization": f"Bearer {access_token}",
"tenant-id": TENANT_ID,
"Content-Type": "application/json",
},
json={"goodsId": "123456", "source": 1},
)
print(biz_resp.json())
12. 跨境支付接口
scope:
pay:order:create、pay:order:query、pay:exchange-rate:read
12.1 三种单号说明
| 单号 | 字段 | 来源 | 说明 |
|---|---|---|---|
| 调用方单号 | outOrderNo |
合作方传入 | 合作方系统内唯一标识,create 必填,query 可用 |
| 平台单号 | orderNo |
本平台生成 | 创建成功后返回,query 可用 |
| 渠道单号 | paymentOrderId |
支付渠道返回 | 创建成功后返回,query 可用 |
12.2 查单优先级
query 接口三个单号至少传一个,若传多个按以下优先级查询:
orderNo(平台单号,索引最优)outOrderNo(调用方单号,需配合 OAuth client 隔离)paymentOrderId(渠道单号)
推荐合作方使用 outOrderNo 查单,无需记忆平台或渠道单号。
12.3 创建支付单 — POST /open-api/pay/order/create
请求示例:
{
"outOrderNo": "DG-20260616-001",
"payAmount": 199.00,
"subject": "代购订单 #12345",
"shippingInfo": {
"firstName": "John",
"lastName": "Doe",
"country": "US",
"addressLine": "123 Main St",
"city": "New York",
"zipcode": "10001",
"phone": "4049526852",
"email": "[email protected]",
"callingCodeCountry": "US",
"callingCode": "1"
}
}
| 字段 | 必填 | 说明 |
|---|---|---|
outOrderNo |
是 | 调用方支付单号,同一 OAuth client 下重复提交走幂等 |
payAmount |
是 | USD 金额,最多 2 位小数,如 199.00 表示 $199.00 |
subject |
否 | 订单标题 |
description |
否 | 订单描述 |
shippingInfo |
否 | 收货信息;传入时须含 9 个必填字段(见下表),否则不下发渠道 |
shippingInfo 字段(传入时全部必填):
| 字段 | 说明 |
|---|---|
firstName / lastName |
名 / 姓 |
country |
ISO 3166-1 alpha-2 国家码(如 US;英国用 GB,服务端会映射为渠道所需的 UK) |
addressLine / city / zipcode |
地址 / 城市 / 邮编 |
phone |
电话号码;支持 E.164(如 +14049526852),服务端会拆为国内号 |
email |
邮箱 |
callingCode |
国际电话区号(不含 +,如 US 为 1);不传时服务端按 callingCodeCountry 或 country 自动推导 |
callingCodeCountry |
区号对应国家码;不传时默认取 country |
响应示例:
{
"code": 0,
"data": {
"orderNo": "OP1930268730012345",
"outOrderNo": "DG-20260616-001",
"paymentOrderId": "KML12345678",
"paymentUrl": "https://www.kamelnet.com/pay/xxx",
"payAmount": 199.00,
"payCurrency": "USD"
}
}
幂等:同一 outOrderNo 重复请求,若原单未关闭则直接返回已有订单信息,不会重复创建。
12.4 查询支付单 — POST /open-api/pay/order/query
请求示例(三选一):
{ "outOrderNo": "DG-20260616-001" }
响应示例:
{
"code": 0,
"data": {
"paid": true,
"status": 10,
"paidTime": "2026-06-16T20:30:00",
"orderNo": "OP1930268730012345",
"outOrderNo": "DG-20260616-001",
"paymentOrderId": "KML12345678",
"payAmount": 199.00,
"payCurrency": "USD"
}
}
status |
含义 |
|---|---|
0 |
待支付 |
10 |
已支付 |
20 |
已关闭 |
待支付订单查询时,系统会自动实时向渠道确认支付状态。
12.5 分页查询支付单列表 — POST /open-api/pay/order/page
与
/query的区别:列表接口不会实时向渠道同步状态,仅查本地库,适合批量拉取和报表场景。
请求示例:
{
"pageNo": 1,
"pageSize": 10,
"status": 10,
"outOrderNo": "DG-2026",
"createTime": ["2026-06-01 00:00:00", "2026-06-30 23:59:59"]
}
| 字段 | 必填 | 说明 |
|---|---|---|
pageNo |
是 | 页码,从 1 开始 |
pageSize |
是 | 每页条数,最大 1000 |
status |
否 | 状态过滤:0=待支付 / 10=已支付 / 20=已关闭 |
outOrderNo |
否 | 调用方支付单号,模糊匹配 |
orderNo |
否 | 平台支付单号,精确匹配 |
paymentOrderId |
否 | 渠道单号,精确匹配 |
createTime |
否 | 创建时间区间 [开始, 结束],格式 yyyy-MM-dd HH:mm:ss |
paidTime |
否 | 支付成功时间区间 [开始, 结束] |
响应示例:
{
"code": 0,
"data": {
"list": [
{
"paid": true,
"status": 10,
"paidTime": "2026-06-16T20:30:00",
"orderNo": "OP1930268730012345",
"outOrderNo": "DG-20260616-001",
"paymentOrderId": "KML12345678",
"payAmount": 199.00,
"payCurrency": "USD",
"createTime": "2026-06-16T18:00:00"
}
],
"total": 1
}
}
数据按 OAuth client 隔离,仅返回当前调用方名下的订单。默认按创建时间倒序排列。
12.6 系统汇率列表 — POST /open-api/pay/exchange-rate/list
- 所需 scope:
pay:exchange-rate:read - operationId:
PayExchangeAPI - 请求:无需 Body(可发送空 JSON
{})
返回全部启用币种的后台配置系统汇率。基准货币为 CNY:1 CNY = exchangeRate 该币种。本接口不返回实时汇率,也不按国家/客户溢价策略改写汇率。
换算:金额_外币 = 金额_CNY × exchangeRate(例如 CNY 100、USD exchangeRate = 0.14 → USD 14)。
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/pay/exchange-rate/list' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{}'
响应 data 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | 币种名称 |
abbreviationCode |
string | ISO 代码,如 USD / EUR / CNY |
symbol |
string | 币种符号 |
exchangeRate |
number | 系统汇率(相对 CNY) |
响应示例:
{
"code": 0,
"data": [
{
"name": "人民币",
"abbreviationCode": "CNY",
"symbol": "¥",
"exchangeRate": 1
},
{
"name": "美元",
"abbreviationCode": "USD",
"symbol": "$",
"exchangeRate": 0.140000
}
]
}
13. 代购下单与余额支付
scope:
system:partner-member:read、order:purchase:quote、order:purchase:create、order:purchase:query、order:purchase:supplement-pay、pay:wallet:query、pay:wallet:pay
第三方平台(如 Shopify)代会员下单并扣其余额。金额字段单位均为人民币分。商品价以服务端实时抓取为准,调用方传入的价格会被忽略。
前置条件:运营在管理后台「开放平台 / 会员绑定」把合作方 externalUserId 绑到平台会员。绑定默认会开启补款授权,买手补款时系统可自动扣余额。
推荐调用顺序:
POST /open-api/system/oauth2/tokenPOST /open-api/system/partner-member/query(可选,确认已绑定)POST /open-api/order/purchase/quotePOST /open-api/order/purchase/create(outOrderNo幂等)POST /open-api/pay/wallet/pay(使用上一步返回的paymentId)
补款不是下单必经步骤。授权开启且余额充足时由系统自动扣;失败后再走 supplement/list → supplement/trade-no → wallet/pay。
商品来源 platformChannel:1 淘宝,2 1688,3 微店,5 闲鱼。
13.1 查询会员绑定 — POST /open-api/system/partner-member/query
- 所需 scope:
system:partner-member:read - operationId:
QueryMemberBindAPI
未绑定或已停用会返回业务异常,便于下单前校验。
请求: { "externalUserId": "shopify_10086" }
响应 data: externalUserId、memberUnionId(会员编码,便于人工核对)、bound(true 表示可用)。
curl -X POST 'https://api.rizzitgo.com/open-api/system/partner-member/query' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"externalUserId":"shopify_10086"}'
13.1.1 查询绑定列表 — POST /open-api/system/partner-member/list
- 所需 scope:
system:partner-member:read(与单条查询共用) - operationId:
QueryMemberBindListAPI
无请求参数。根据访问令牌识别当前合作方,返回该合作方下全部绑定关系(含停用)及对应会员钱包余额。无绑定时 data 为空数组。平台会员编号不对外暴露。钱包查询失败时余额按 0 返回,不影响绑定列表。
响应 data[]: externalUserId、memberUnionId、status(0=正常,1=停用)、balance(可用余额,分)、freezePrice(冻结,分)、currencyCode(固定 CNY)。
curl -X POST 'https://api.rizzitgo.com/open-api/system/partner-member/list' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json'
13.2 询价 — POST /open-api/order/purchase/quote
- 所需 scope:
order:purchase:quote - operationId:
PurchaseQuoteAPI
不产生订单。返回应付金额供展示;下单时请把 payAmount 回传为 expectedPayAmount,避免用过期报价成交。
请求:
| 字段 | 必填 | 说明 |
|---|---|---|
externalUserId |
是 | 合作方用户标识 |
items |
是 | 商品行:platformChannel、goodsId、skuId、qty(1–9999),可选 remarks |
响应 data 主要字段: goodsTotalAmount、freightTotalAmount、payAmount、currencyCode(固定 CNY)、shops[](按店铺拆分的明细)。
curl -X POST 'https://api.rizzitgo.com/open-api/order/purchase/quote' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"externalUserId":"shopify_10086","items":[{"platformChannel":1,"goodsId":"654321","skuId":"5001","qty":2}]}'
13.3 创建代购单 — POST /open-api/order/purchase/create
- 所需 scope:
order:purchase:create - operationId:
PurchaseCreateAPI
同一合作方下 outOrderNo 幂等:已创建成功则回放原单(duplicated=true),不会重复下单。
请求:
| 字段 | 必填 | 说明 |
|---|---|---|
outOrderNo |
是 | 合作方订单号,最长 64 |
externalUserId |
是 | 须已绑定 |
items |
是 | 同询价商品行 |
addressId |
否 | 会员收货地址编号;不传则用会员默认地址 |
orderComment |
否 | 订单备注 |
expectedPayAmount |
否 | 询价得到的应付金额(分);与实时价偏差超过阈值则拒单 |
响应 data: outOrderNo、orderNo、paymentId、payAmount、expireTime、duplicated。
curl -X POST 'https://api.rizzitgo.com/open-api/order/purchase/create' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"outOrderNo":"SHOPIFY-20260811-0001","externalUserId":"shopify_10086","expectedPayAmount":24600,"items":[{"platformChannel":1,"goodsId":"654321","skuId":"5001","qty":2}]}'
13.4 查询代购单 — POST /open-api/order/purchase/query
- 所需 scope:
order:purchase:query - operationId:
PurchaseQueryAPI
outOrderNo 与 orderNo 二选一。只返回本合作方创建的订单。
响应 data: paymentId、payAmount、refStatus(0 处理中 / 1 已创建 / 2 创建失败)、orders[] 子订单(按店铺拆分)。
13.5 查询会员余额 — POST /open-api/pay/wallet/balance
- 所需 scope:
pay:wallet:query - operationId:
WalletBalanceAPI
请求: { "externalUserId": "shopify_10086" }
响应 data: balance(可用余额,分)、freezePrice(冻结,分)、currencyCode(CNY)。
13.6 余额支付 — POST /open-api/pay/wallet/pay
- 所需 scope:
pay:wallet:pay - operationId:
WalletPayAPI
扣款前会校验业务单仍可支付,避免订单已取消仍扣余额。已支付的 paymentId 会报错,请改查单确认结果。
请求:
| 字段 | 必填 | 说明 |
|---|---|---|
externalUserId |
是 | 须与下单时一致 |
paymentId |
是 | 创建代购单或补款支付单返回的支付流水号 |
payAmount |
否 | 预期金额(分);与支付单不一致则拒付 |
响应 data: status(0 未支付 / 10 成功 / 20 已退款 / 30 关闭)、paySuccess、payAmount、successTime、balance(扣款后剩余余额)。
curl -X POST 'https://api.rizzitgo.com/open-api/pay/wallet/pay' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"externalUserId":"shopify_10086","paymentId":"P2026081100001","payAmount":24600}'
13.7 查询待补款 — POST /open-api/order/purchase/supplement/list
- 所需 scope:
order:purchase:query - operationId:
PurchaseSupplementListAPI
仅在自动扣款失败时需要。返回代购单与包裹单的待补款费用行。
请求: { "externalUserId": "shopify_10086" }
响应 data: supplementTotalAmount、orders[]。单据类型 bizType:1 代购单,2 包裹单。费用类型 expenseType:102 商品补款,104 运费补款,203 包裹运费补款。记下 orderExpensesNo 用于下一步。
13.8 创建补款支付单 — POST /open-api/order/purchase/supplement/trade-no
- 所需 scope:
order:purchase:supplement-pay - operationId:
PurchaseSupplementTradeNoAPI
代购单补款与包裹补款须分别发起,不要混在同一次请求。返回的 paymentId 再调用 wallet/pay。
请求: { "externalUserId": "shopify_10086", "orderExpensesNoList": ["OE2026081100001"] }
响应 data: paymentId、payAmount、payType(3 补运费 / 6 商品补款 / 7 包裹补款 / 8 商品+运费补款)。
14. 订单与包裹接口
scope:
order:bag-order:read、order:order-item:read
分页列表接口须指定会员:memberId 与 unionId 至少传一个。金额字段(price / actualPrice / freightFee / goodsTotalAmount)单位为人民币分。
14.1 按包裹单号查询 — POST /open-api/order/bag-order/query
- 所需 scope:
order:bag-order:read
请求:
{ "bagOrderNo": "BG20250624001" }
响应 data 主要字段:
| 字段 | 说明 |
|---|---|
exists |
包裹是否存在;不存在时其余字段可能为空 |
bagOrderNo |
包裹单号 |
status |
包裹状态码(见下表) |
statusDesc |
状态描述 |
createTime |
包裹提交时间 |
unionId |
所属会员编码 |
包裹状态 status:
| 值 | 含义 |
|---|---|
0 |
未支付 |
1 |
待审核 |
2 |
待出库 |
3 |
出库中 |
4 |
待补款 |
5 |
待发货 |
6 |
已寄送 |
7 |
已收货 |
8 |
已退包 |
9 |
已取消 |
10 |
已关闭 |
请求示例:
curl -X POST 'https://api.rizzitgo.com/open-api/order/bag-order/query' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"bagOrderNo":"BG20250624001"}'
14.2 分页查询包裹列表 — POST /open-api/order/bag-order/page
- 所需 scope:
order:bag-order:read
| 字段 | 必填 | 说明 |
|---|---|---|
pageNo / pageSize |
是 | 页码从 1 开始 |
memberId |
与 unionId 至少传一个 |
会员 ID |
unionId |
与 memberId 至少传一个 |
会员编码 |
status |
否 | 包裹状态码 |
bagOrderNo |
否 | 包裹单号 |
createTime |
否 | 创建时间区间 [开始, 结束],格式 yyyy-MM-dd HH:mm:ss |
响应 list 元素主要字段: bagOrderNo、outboundOrderNo、status、statusDesc、goodsQty、goodsTotalAmount(分)、estimateWeight、estimateVolume、unionId、createTime。
curl -X POST 'https://api.rizzitgo.com/open-api/order/bag-order/page' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"unionId":"M123456","pageNo":1,"pageSize":10}'
14.3 分页查询商品订单明细 — POST /open-api/order/order-item/page
- 所需 scope:
order:order-item:read
| 字段 | 必填 | 说明 |
|---|---|---|
pageNo / pageSize |
是 | 页码从 1 开始 |
memberId |
与 unionId 至少传一个 |
会员 ID |
unionId |
与 memberId 至少传一个 |
会员编码 |
status |
否 | 订单明细状态码(见下表) |
orderNo |
否 | 订单编号 |
orderItemNo |
否 | 订单明细编号 |
createTime |
否 | 创建时间区间 |
响应 list 元素主要字段: orderNo、orderItemNo、status、unionId、goodsName、localGoodsName、specName、localSpecName、imagePath、qty、price、actualPrice、freightFee、shopName、localShopName、createTime。
常用明细状态 status(完整枚举以 Redoc 与后台状态为准):
| 值 | 含义 |
|---|---|
101 |
未支付 |
105 |
已取消 |
201 |
待接单 |
204 |
代购中 |
206 |
商家已发货 |
305 |
已入库 |
308 |
已发货 |
curl -X POST 'https://api.rizzitgo.com/open-api/order/order-item/page' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"unionId":"M123456","pageNo":1,"pageSize":10}'
15. 物流轨迹查询
- 方法与路径:
POST /open-api/logistics/track/query - 所需 scope:
logistics:track:query
国内(type=1)与国际(type=2)统一入口。国内建议传 carrierName 提高识别率;国际可用 language(如 zh / en / es)指定轨迹翻译语言。
| 字段 | 必填 | 说明 |
|---|---|---|
trackingNo |
是 | 快递单号 / 国际追踪号 |
type |
是 | 1=国内,2=国际 |
carrierName |
否 | 快递公司名称(国内选填) |
language |
否 | 语言偏好(国际轨迹翻译) |
响应 data 通用字段: trackingNo、type、status、trackContent、trackDate、trackItems(currentPosition、content、trackDate、status)。
轨迹状态 status:PENDING 待发出、IN_TRANSIT 运输中、DELIVERING 派送中、DELIVERED 已签收、EXCEPTION 异常。
国内扩展:carrierName、carrierCode、checkStatus、arrivalTime。
国际扩展:logisticsOrderNo、expressNo、lastMileTrackingNo、supplierCode、supplierName、logisticsLineName、trackUrl、shipCountry、country。
curl -X POST 'https://api.rizzitgo.com/open-api/logistics/track/query' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"trackingNo":"YT9876543210","type":1,"carrierName":"圆通快递"}'
15.1 运费估算 — POST /open-api/logistics/line/freight-estimate
- 所需 scope:
logistics:freight-estimate:read - operationId:
FreightEstimateAPI
按目的国与重量估算可用航线运费。只返回 可用 航线;totalFee 为系统运费(人民币分,不含 C 端促销)。本期请求仅支持国家和重量(不计尺寸、省份、邮限类型)。language 不传时航线名称为英文;传入时用谷歌翻译 lineName。
请求:
| 字段 | 必填 | 说明 |
|---|---|---|
countryCode |
是 | 目的国家代码,如 US |
weight |
是 | 包裹重量,单位克 |
language |
否 | 航线名称目标语言,如 en / zh / es;不传默认 en;传入则谷歌翻译 lineName |
响应 data 列表字段:
| 字段 | 说明 |
|---|---|
id |
航线 ID |
lineUUid |
航线 UUID |
lineName |
航线名称(随 language 翻译) |
icon |
航线图标 URL |
referenceTime |
时效 |
totalFee |
系统运费(人民币分) |
billingType |
计费模式:1 按实重,2 按体积重 |
curl -X POST 'https://api.rizzitgo.com/open-api/logistics/line/freight-estimate' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"countryCode":"US","weight":1000}'
响应示例:
{
"code": 0,
"data": [
{
"id": 7785,
"lineUUid": "a1b2c3d4",
"lineName": "US-EMS",
"icon": "https://cdn.rizzitgoo.com/line/ems.png",
"referenceTime": "7-12 days",
"totalFee": 8800,
"billingType": 1
}
]
}
16. Discord 授权登录链接
- 方法与路径:
POST /open-api/member/auth/discord-authorize-url - 所需 scope:
member:auth:discord-login
用于合作方(如 Discord 机器人)向用户下发平台 Discord OAuth 登录链接。redirectUri 必须是 https:// 地址,且与 Discord Developer Portal 已登记的 Redirect 完全一致。
请求:
{ "redirectUri": "https://rizzitgo.com" }
响应 data: authorizeUrl(Discord 授权 URL,可直接发送给用户)。
curl -X POST 'https://api.rizzitgo.com/open-api/member/auth/discord-authorize-url' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"redirectUri":"https://rizzitgo.com"}'
16.1 查询 Discord 登录状态
- 方法与路径:
POST /open-api/member/auth/discord-login-status - 所需 scope:
member:auth:discord-login
按 Discord 用户 ID(snowflake,对应社交用户 openid)查询该账号是否已绑定会员。未登录时仍返回 HTTP 200,loggedIn=false,便于机器人轮询。绑定存在但会员已删除时同样视为未登录。
请求:
{ "discordUserId": "123456789012345678" }
响应 data:
| 字段 | 说明 |
|---|---|
loggedIn |
是否已完成 Discord 登录(已绑定会员) |
memberId |
会员主键;未登录为 null |
unionId |
对外会员编码;未登录或会员已删除为 null |
curl -X POST 'https://api.rizzitgo.com/open-api/member/auth/discord-login-status' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"discordUserId":"123456789012345678"}'
16.2 Discord 每日签到
- 方法与路径:
POST /open-api/promotion/discord-checkin - 所需 scope:
promotion:discord-checkin:claim - 说明:按 Discord 用户 ID 为已绑定会员代兑平台配置的余额兑换码,将签到奖励入账到会员钱包。合作方不传兑换码,码与活动开关由平台运营配置。会员必须已存在且 Discord 已绑定,否则返回「会员不存在」,本接口不会自动创建会员。建议先调
discord-login-status,仅对loggedIn=true的用户签到。
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
discordUserId |
string | 是 | Discord 用户 ID(snowflake,对应社交 openid,与登录状态接口同一值) |
requestId |
string | 否 | 外部请求流水号,用于幂等防重;同一 requestId 在 10 分钟内仅处理一次,重复请求返回「请求重复,请勿重试」 |
curl -X POST 'https://api.rizzitgo.com/open-api/promotion/discord-checkin' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"discordUserId":"123456789012345678","requestId":"REQ-20260904-0001"}'
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
alreadyCheckedIn |
boolean | 今日是否已签到(含本次成功后为 false;今日已领过为 true) |
grantAmount |
number | 本次到账金额(单位:人民币分);今日已签到时为 null |
success |
boolean | 是否成功(首次到账与「今日已签到」均为 true) |
message |
string | 结果描述,如「签到成功」「今日已签到」 |
首次签到成功示例:
{
"code": 0,
"data": {
"alreadyCheckedIn": false,
"grantAmount": 100,
"success": true,
"message": "签到成功"
},
"msg": ""
}
今日已签到示例(仍为业务成功,勿当失败重试):
{
"code": 0,
"data": {
"alreadyCheckedIn": true,
"grantAmount": null,
"success": true,
"message": "今日已签到"
},
"msg": ""
}
「日」按 上海自然日(
Asia/Shanghai)计算。今日已达每人每日上限时不返回错误码,而是code=0且alreadyCheckedIn=true。到账金额由平台配置的余额兑换码决定(常见为 100 分 = 1 CNY),请以grantAmount为准。业务错误:
discordUserId为空返回参数校验失败;Discord 未绑定或会员已删除返回1_013_022_001「会员不存在」;同一requestId10 分钟内重复返回1_013_022_002「请求重复,请勿重试」;活动关闭返回1_013_026_000「Discord 签到活动未开启」;兑换码未配置返回1_013_026_001「Discord 签到兑换码未配置」;其它入账失败返回1_013_026_002「Discord 签到入账失败」。
17. 用户消费信息查询
- 方法与路径:
POST /open-api/member/consumption/query - 所需 scope:
member:consumption:read - operationId:
MemberConsumptionAPI
按会员标识汇总已支付包裹与钱包充值。金额单位均为人民币分。不传 createTime 时统计终身累计;传入时须同时给出开始、结束,且开始不得晚于结束。
时间区间分别作用于:包裹提交时间(create_time)、充值支付成功时间(pay_time)。
会员标识(至少传一个):memberId、unionId、discordOpenId(Discord snowflake,对应社交 openid,与登录状态接口的 discordUserId 为同一值)。传多个时必须指向同一会员,否则返回「用户不存在」。
请求参数(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
memberId |
number | 三选一 | 会员主键 |
unionId |
string | 三选一 | 对外会员编码 |
discordOpenId |
string | 三选一 | Discord Open ID(snowflake) |
createTime |
string[] | 否 | 统计区间 [开始, 结束],格式 yyyy-MM-dd HH:mm:ss;不传则终身累计 |
响应 data 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
memberId |
number | 解析后的会员主键 |
unionId |
string | 对外会员编码 |
discordOpenId |
string | 仅当请求传入 discordOpenId 时回显,否则为 null |
bagOrderCount |
number | 已支付包裹单数(已提交且已支付,排除未支付 / 已取消 / 已关闭) |
bagConsumeAmount |
number | 包裹实付净额(实付减去退款),人民币分 |
totalRechargeAmount |
number | 钱包净充值(含赠送到账,已扣除退款),人民币分;不含 mock / 内部补偿 / 达人渠道 |
rechargeCount |
number | 成功充值笔数(口径同净充值) |
startTime |
string | 统计开始时间;终身累计时为 null |
endTime |
string | 统计结束时间;终身累计时为 null |
按 unionId 查询终身累计:
curl -X POST 'https://api.rizzitgo.com/open-api/member/consumption/query' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{"unionId":"M123456"}'
按 Discord Open ID + 时间区间:
curl -X POST 'https://api.rizzitgo.com/open-api/member/consumption/query' \
-H 'Authorization: Bearer {access_token}' \
-H 'tenant-id: {租户编号}' \
-H 'Content-Type: application/json' \
-d '{
"discordOpenId":"123456789012345678",
"createTime":["2026-01-01 00:00:00","2026-09-03 23:59:59"]
}'
响应示例:
{
"code": 0,
"data": {
"memberId": 1024,
"unionId": "M123456",
"discordOpenId": "123456789012345678",
"bagOrderCount": 12,
"bagConsumeAmount": 88000,
"totalRechargeAmount": 150000,
"rechargeCount": 5,
"startTime": "2026-01-01 00:00:00",
"endTime": "2026-09-03 23:59:59"
},
"msg": ""
}
业务错误:未传任何会员标识,或
createTime不是成对的开始/结束(含开始晚于结束),返回参数校验失败;标识解析失败、Discord 未绑定、会员已删除、多个标识指向不同会员,返回1_004_001_000「用户不存在」。无消费/充值记录时计数字段为0,仍返回成功。
18. 常见问题(FAQ)
- 频繁收到
401? 多半是令牌过期或未缓存。请在expires_in内复用令牌,并在过期前刷新;确认Authorization头为Bearer {access_token}格式。 - 查询消费返回「用户不存在」?
memberId/unionId/discordOpenId至少传一个;任一标识解析失败、Discord 未绑定会员,或多个标识指向不同会员,都会返回该错误。 - Discord 签到返回「会员不存在」? 该 Discord 用户尚未绑定平台会员,或会员已删除。请先引导用户走 Discord 授权登录,再用
discord-login-status确认loggedIn=true后再签到。 - Discord 签到提示今日已签到? 这是成功响应(
code=0,alreadyCheckedIn=true),不要当失败重试。自然日按上海时区计算。 - 收到
403? 说明当前应用未被授予该接口所需的scope,请联系运营开通。 - 收到
429? 触发了按clientId维度的 QPS 限流,请降低频率并退避重试,必要时申请提升配额。 - 跨租户访问被拒? 请确认请求头
tenant-id与换取令牌时一致。 clientSecret泄漏怎么办? 立即联系运营「重置密钥」,旧密钥即时失效,并更新你侧的密钥配置。- 下单报外部用户未绑定? 运营须先在「开放平台 / 会员绑定」录入
externalUserId与会员编码;停用后也不能下单或支付。 - 创建订单因价格偏差被拒? 服务端以实时价为准。请先调
quote,把返回的payAmount作为expectedPayAmount尽快下单;报价过期或阈值过小都会拒单。 - 补款什么时候要调开放接口? 会员已开补款授权且余额充足时系统会自动扣。仅余额不足或授权关闭时,才需要
supplement/list→supplement/trade-no→wallet/pay。
19. 在线接口文档
网关 Knife4j 聚合的 Swagger 中包含 /open-api/** 分组,可在线查看每个接口的入参/出参定义,便于联调。
20. 文档版本
| 版本 | 日期 | 变更说明 |
|---|---|---|
| v2.9 | 2026-09 | 新增 Discord 每日签到 /open-api/promotion/discord-checkin(scope promotion:discord-checkin:claim),按已绑定 Discord 用户代兑余额;今日已签到返回 alreadyCheckedIn=true(上海自然日)。 |
| v2.8 | 2026-09 | 新增用户消费信息查询 /open-api/member/consumption/query(scope member:consumption:read),按 memberId / unionId / discordOpenId 查询已支付包裹数、包裹实付净额与钱包净充值。 |
| v2.7 | 2026-08 | 新增合作方会员绑定列表 /open-api/system/partner-member/list(复用 scope system:partner-member:read),按令牌返回当前合作方全部绑定关系及对应会员钱包余额。 |
| v2.6 | 2026-08 | 新增代购下单与余额支付链路:会员绑定查询、询价、下单、查单、余额查询/支付、待补款列表与补款支付单;对应 scope system:partner-member:read、order:purchase:*、pay:wallet:*。 |
| v2.5 | 2026-08 | 新增运费估算 /open-api/logistics/line/freight-estimate(scope logistics:freight-estimate:read),按国家与重量返回可用航线 id、lineUUid、名称、时效、系统运费与计费模式。 |
| v2.4 | 2026-08 | 新增系统汇率列表 /open-api/pay/exchange-rate/list(scope pay:exchange-rate:read),返回启用币种相对 CNY 的系统汇率。 |
| v2.3 | 2026-08 | 商品详情 /goods/detail 增加 skuList、skuSpecInfoList,返回 SKU 与规格维度。 |
| v2.2 | 2026-08 | 优惠券随机兑换 /promotion/redeem-code/redeem 支持按 Discord 用户 ID 发券:email 与 discordUserId 二选一,都传时以 Discord 为准。 |
| v2.1 | 2026-08 | 新增 Discord 登录状态查询 /member/auth/discord-login-status(复用 scope member:auth:discord-login),按 Discord 用户 ID 查询是否已绑定会员。 |
| v2.0 | 2026-08 | 新增包裹分页 /order/bag-order/page、商品订单明细 /order/order-item/page、物流轨迹 /logistics/track/query、Discord 授权链接 /member/auth/discord-authorize-url;补充对应 scope。 |
| v1.0 | 2026-06 | 首次发布:OAuth2 客户端模式接入、商品详情试点接口。 |
| v1.1 | 2026-06 | 新增商品质检接口:质检详情、质检图片、按时间分页查询质检数据(scope goods:qc:read);token_type 调整为 Bearer。 |
| v1.2 | 2026-06 | 新增图片识别搜索商品接口 /open-api/goods/search-by-images(scope goods:search:read)。 |
| v1.3 | 2026-06 | 新增优惠券随机兑换接口 /open-api/promotion/redeem-code/redeem(scope promotion:redeem-code:redeem),按邮箱为会员发券。 |
| v1.4 | 2026-06 | 新增商品链接解析接口 /open-api/goods/search-url-parse(scope goods:search:read),支持可选推广码 rno。 |
| v1.5 | 2026-06 | 新增用户优惠券查询/续期/恢复接口(scope promotion:member-coupon:read/extend/restore),状态使用字符串编码。 |
| v1.6 | 2026-06 | 新增跨境支付接口:创建支付单、查询支付单(scope pay:order:create/pay:order:query),金额为 USD 两位小数。 |
| v1.7 | 2026-06 | 跨境支付 shippingInfo 补充 callingCode 说明;服务端支持按 country 自动推导区号并拆分 phone。 |
| v1.8 | 2026-06 | 新增支付单分页列表接口 /open-api/pay/order/page(复用 scope pay:order:query),支持状态/单号/时间区间筛选。 |
| v1.9 | 2026-07 | 新增推广者电子表格商品分页接口 /open-api/promotion/spreadsheet/page(scope promotion:spreadsheet:read),按 rno 查询分享商品列表。 |