在线商店

如何通过 API 将自定义商店接入 easySales

如何通过 API 将自定义商店接入 easySales

通过 API 把任意自定义或尚未支持的商店平台接入 easySales:需要的两个凭据、推送产品与库存、送入订单,以及把变化取回去。

什么时候需要这么做

easySales 为常见的商店平台提供现成的连接器。如果你用的是自定义的东西——自研的店铺,或者我们还没有做集成的平台——你可以自己通过 API 把它接进来。

这是一项开发工作。你要写代码把自己的商品目录推送到 easySales 并把订单送过来,而 easySales 会在有变化时回调你的店铺。这里的任何一步都不需要安装插件。

连接是怎么运作的

这里涉及两个凭据,把它们弄混是第一次集成返回 403 最常见的原因。

凭据 从哪里来 如何发送 缺失时
访问令牌 POST /oauth/token,使用你在 API设置 中创建的 OAuth 客户端 Authorization: Bearer <token> 请求头 401
网站令牌 连接向导的配置步骤 请求体中website_token 字段,不是请求头 403 Invalid website token
两个凭据,以及各自的用途

每一次写入都需要两个。访问令牌证明是谁在调用;网站令牌说明数据属于哪家店铺

第 1 步 — 添加网站

进入整合方式 → 网站,点击连结网站,填写表单,然后选择 API 图块以及它下面的 API V2 版本。

easySales 中的连结网站表单,API 图块已选中并带有绿色对勾,下方是 API V2 版本图块,标题为选择您的网站使用的平台版本。
先选 API 图块,再选它下面的 API V2。
字段 作用
网站名称 你自己的标签。以后靠它区分不同的店铺。
网址 你的店铺地址,带上正确的协议。
国家 决定下一个字段提供哪些增值税税率。不可更改。
增值税价格 对未带税率的产品所应用的增值税。从列表中选择,不能手输。
运输增值税 订单未带税率时,对配送所应用的增值税。
语言 / 货币 店铺的语言,以及你的价格所使用的货币。两者都不可更改。
新订单自定义状态 可选。让每一笔导入的订单落到你自己的某个状态里。
库存来源 权威库存数值所在的位置。默认是 easySales。
隐式封装类型 为这些订单生成运单时使用的默认值。
发票系列 当你的请求没有提供发票系列时所使用的开票系列。
连接表单

第 2 步 — 复制网站令牌

向导的配置步骤会显示一个 60 个字符的令牌。旧文章从未提到过它,而每一次写入调用都需要它。

easySales 连接向导中 API V2 的配置步骤,显示只读的 60 个字符的生成网站令牌,以及一个复制到剪贴板的按钮。
网站令牌。每一次写入调用都在请求体里带上它。

用按钮复制,不要手动重打,并把它作为机密保存在你的应用里。点击保存创建网站。

店铺现在会出现在整合方式 → 网站下,卡片上带着同一个令牌——以后就到那里再找它。

easySales 的网站界面,显示一个已连接的 API V2 店铺卡片,包含其网址、增值税、网站令牌和积极的开关。
一个已连接的 API 店铺。卡片上的令牌就是你代码里发送的那个。

第 3 步 — 创建 OAuth 客户端

进入设定值 → API设置。OAuth 凭据就在这里。

easySales 的 API设置 界面,列出一个 OAuth 客户端及其客户 ID、名称和被遮蔽的密钥,下方是一个个人访问令牌。
设定值 → API设置。上面是 OAuth 客户端,下面是个人访问令牌。

点击创建新客户,按将要发起调用的系统给它命名,并把授权类型设为 Website Grant

easySales API设置 中的创建客户端表单,名称已填写,授权类型设为 Website Grant,并显示 Website Grant 使用 website_token 获取访问令牌的说明。
Website Grant——用你的网站令牌换取访问令牌的那一个。

Website Grant 正是为这件事而设计的:它用你的网站令牌换取访问令牌,不需要浏览器跳转,也不需要用户操作。保存后复制出现的客户 ID密钥

第 4 步 — 获取访问令牌

POST https://easy-sales.com/oauth/token
Content-Type: application/json

{
  "grant_type":    "website",
  "client_id":     "your-client-id",
  "client_secret": "your-client-secret",
  "website_token": "your-60-character-website-token",
  "scope":         "add-products update-products update-stock add-orders update-orders read-orders"
}

返回的是标准的 OAuth 响应体:

{
  "token_type":    "Bearer",
  "expires_in":    31536000,
  "access_token":  "eyJ0eXAiOiJKV1Qi...",
  "refresh_token": "def50200a1b2c3..."
}

在之后的每一次调用中,把它作为 Authorization: Bearer <access_token> 发送。

第 5 步 — 推送你的商品目录

下面所有请求的基础地址是 https://easy-sales.com/api/v2

顺序很重要。 类别和特性必须先存在,产品才能引用它们,否则产品调用会被拒绝。

  1. POST /categories/save — 你的类别
  2. POST /characteristics/save — 你的属性
  3. POST /products/save — 你的产品
POST https://easy-sales.com/api/v2/products/save
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "website_token": "your-60-character-website-token",
  "product": {
    "product_website_id": "10231",
    "sku": "TS-BLK-M",
    "name": "Black T-shirt, size M",
    "sale_price": 79.99,
    "full_price": 99.99,
    "stock": 24,
    "type": "simple",
    "tax_rate": 21,
    "url": "https://my-shop.example.com/p/ts-blk-m",
    "images": ["https://my-shop.example.com/img/ts-blk-m.jpg"],
    "categories": ["cat-778"],
    "characteristics": [{ "id": "char-12", "value": "Black" }]
  }
}
字段 是否必填 说明
product_website_id 该产品在你店铺中的自有 ID
sku 在每个网站内唯一;upsert 的主键
name
sale_price 客户实际支付的价格
stock 必须是数字
type simplecomplex
full_price 折扣前价格,如果你会展示的话
tax_rate 必须是该网站所属国家的有效税率
categories 你自己的类别 ID——每一个都必须已经存在
characteristics 你自己的属性 ID——每一个都必须已经存在
images 我们可以抓取的 URL 数组
weight, handling_time, description, url 用于快递、配送时效估算和市场平台刊登
产品字段

第 6 步 — 保持库存同步

库存是必须保持最新的那一项,而且它是最适合频繁调用的低成本接口。每次最多发送 100 行:

PATCH https://easy-sales.com/api/v2/stocks/bulk
Authorization: Bearer <access_token>

{
  "website_token": "your-60-character-website-token",
  "data": [
    { "sku": "TS-BLK-M", "stock": 24 },
    { "sku": "TS-BLK-L", "stock": 0 }
  ]
}

每个 SKU 都必须已经存在于这个网站上;未知的会被拒绝,而不会被创建。

第 7 步 — 把订单送进来

POST https://easy-sales.com/api/v2/orders/save
Authorization: Bearer <access_token>

{
  "website_token": "your-60-character-website-token",
  "order": {
    "order_id": "SO-100244",
    "order_date": "2026-09-09 14:31:00",
    "order_total": 179.98,
    "status": "new",
    "payment_mode": "card",
    "shipment_tax": 21,
    "billing_address":  { "country": "RO", "city": "Cluj-Napoca", "street": "Str. Memorandumului 4" },
    "shipping_address": { "country": "RO", "city": "Cluj-Napoca", "street": "Str. Memorandumului 4" },
    "order_products": [
      { "product_website_id": "10231", "sku": "TS-BLK-M", "name": "Black T-shirt, size M",
        "quantity": 2, "price": 79.99, "total": 159.98 }
    ]
  }
}

再次提交相同的 order_id,订单会被更新而不是重复创建,这让重试是安全的。

第 8 步 — 把变化取回去

你的店铺需要知道订单何时开了发票、生成了运单或改变了状态。订阅一个 webhook,而不是轮询:

GET https://easy-sales.com/api/v2/webhooks
Authorization: Bearer <access_token>
POST https://easy-sales.com/api/v2/webhooks/order-updated
Authorization: Bearer <access_token>

{
  "url":    "https://my-shop.example.com/hooks/easysales",
  "secret": "a-shared-secret-of-at-least-24-characters"
}

每次只能订阅一个事件,因此需要对 order-createdorder-updatedawb-createdinvoice-createddelivery-status-updated 分别调用一次。

每一次推送都有签名,所以在信任内容之前先校验签名。要快速响应——请求会在几秒后超时,并且只会重试有限的次数,所以先确认接收,再去处理。

限制

限制项 数值
请求数 整个 API 每分钟 500 次
令牌请求 每分钟 60 次——请缓存你的令牌
每次批量调用的产品、库存、价格、类别、特性数量 100
每次批量归档调用的产品数量 50
每个账户的网站数量 30
产品描述 65,534 个字符
值得在设计时纳入考虑的限制

出错的时候

代码 含义 常见原因
400 Invalid json 请求体不是合法的 JSON
401 未通过身份验证 访问令牌缺失、过期或格式错误
403 Invalid website token website_token 缺失或错误
403 The website has been deactivated 网站的积极的开关处于关闭状态
422 校验失败 缺少必填字段、SKU 重复,或者类别、特性尚不存在
429 请求过多 超过每分钟 500 次
503 暂时不可用 数据接收出现积压;请在提示的间隔后重试
每个响应码的含义

在我们这边失败的内容也会进入产品 → 网上商店 → 网站错误,附带请求内容和一个重试操作,这通常比重新复现调用更快。

参考文档

完整的接口参考,包含每个字段和每种响应,发布在 https://api.easy-sales.com

常见问题

访问令牌是标识你账户的 OAuth2 bearer 令牌,放在 Authorization 请求头里。网站令牌标识某一家具体的店铺,作为 website_token 放在请求体里。写入调用两者都需要:401 表示访问令牌不对,403 并提示 "Invalid website token" 则表示网站令牌不对。

自定义店铺没有刷新频率,表单上也没有这个字段。系统不会做任何轮询——由你决定何时推送产品、库存和订单,变化则通过 webhook 回传给你。旧文章描述的是一个已经不属于连接流程的字段。

不是。API 类型的网站不做连接测试,因为在你开始发送数据之前,easySales 没有任何东西可以调用。这个标记是在记录创建时设置的。真正的检验是你的产品有没有出现在产品 → 网上商店 → 产品里。

Website Grant。它就是为此而生的:用网站令牌换取访问令牌,不需要跳转,也不需要用户操作,这正是服务器对服务器的集成所需要的。个人访问令牌也能用,但它覆盖整个账户而不是单个店铺,而且只显示一次。

访问令牌、刷新令牌和个人访问令牌的有效期都是一年。网站令牌完全不会过期——它一直有效,直到你点击刷新令牌或者删除该网站。请缓存访问令牌,而不是每次调用都申请新的;令牌接口的频率限制是每分钟 60 次请求。

类别和特性必须先存在,产品才能引用它们。先推送类别,再推送特性,最后推送产品。批量更新库存也是同样的道理:每个 SKU 都必须已经存在于该网站上。

可以,前提是使用 /save 接口。POST /products/save 按 SKU 做 upsert,POST /orders/save 按 order_id 做 upsert,所以重试是安全的,重复推送也不会产生重复数据。而普通的 POST /products 和 POST /orders 接口会用 422 拒绝重复项。

对自定义店铺来说不会。库存只朝一个方向流动,从你的店铺进入 easySales,所以你的店铺始终是权威数据源。回传的是订单层面的信息:状态变化、运单和发票,通过你订阅的 webhook 送达。

本指南对你有帮助吗?