开放平台(Open API)接入指南

在线文档(推荐)https://docs.rizzitgo.com — API 参考与本文同步更新
适用对象:外部合作方 / 第三方开发者
语言版本:中文(本文) · English

本指南说明如何接入本系统的 /open-api/* 开放接口。开放接口与 C 端 /app-api、管理端 /admin-api 物理隔离,统一采用 OAuth2 client_credentials(客户端模式) 鉴权,并按 scope(授权范围)控制每个应用可调用的接口集合。


1. 概述与架构

调用时序:

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)。
expires_in 令牌剩余有效期,单位秒。
userType 用户类型,开放平台令牌固定为 OPEN_API

3. 接入流程

  1. 联系平台运营,提交:合作方名称、联系人(姓名/邮箱/电话)、回调来源 IP(可选,用于 IP 白名单)、需要的接口范围(scope)。
  2. 运营在管理后台「开放平台 / 合作方应用」创建应用,下发:
    • clientId(客户端编号)
    • clientSecret(客户端密钥,仅展示一次,请妥善保存)
    • 授权 scope 列表(如 goods:detail:read
    • tenant-id(租户编号)
  3. 合作方使用 clientId + clientSecret 换取 access_token,再携带令牌调用业务接口。

上线前自检清单:


4. 环境与域名

环境 网关域名 说明
沙箱 / 测试 api-qa.rizzitbuy.com 联调使用,数据与生产隔离。
生产 api.rizzitgo.com 正式环境。

生产网关域名为 api.rizzitgo.com(文档示例已采用),测试/沙箱网关域名为 api-qa.rizzitbuy.com{租户编号}{clientId}{clientSecret} 等占位符请替换为运营下发的实际值。


5. 获取访问令牌

请求参数:

参数 位置 必填 说明
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 查询商品详情(试点)

请求参数(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=微店

响应示例:

{
  "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
  },
  "msg": ""
}

7.2 查询商品质检详情

请求参数(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 查询商品质检图片列表

请求示例:

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 按时间分页查询质检数据

请求参数(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 图片识别搜索商品列表

请求参数(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 商品链接解析

请求参数(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 优惠券随机兑换(按邮箱发券)

请求参数(application/json):

字段 类型 必填 说明
code string 兑换码
email string 收券会员邮箱,需与平台会员账号一致(精确匹配)
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":"user@example.com","requestId":"REQ-20260604-0001"}'

响应字段:

字段 类型 说明
code string 兑换码
email string 收券会员邮箱
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": "user@example.com",
    "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": ""
}

业务错误:邮箱为空返回「邮箱不能为空」;按邮箱查不到会员返回「会员不存在」;兑换码不存在/已过期/已作废、超过每人或每日(含 IP)限兑次数等,沿用兑换码模块既有错误码与提示。兑换码的限领/限兑/有效期等限制在后台配置,请按运营约定的额度调用。


8. 撤销令牌(可选)

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. 安全与限制


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. 常见问题(FAQ)


13. 在线接口文档

网关 Knife4j 聚合的 Swagger 中包含 /open-api/** 分组,可在线查看每个接口的入参/出参定义,便于联调。


14. 文档版本

版本 日期 变更说明
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