商业层 JS SDK
一个 JavaScript 库包装器, 使其能快速且容易地与 商业层 API。 。 。 .
此软件包来自
commercelayer-sdk单相并列@commercelayer/provisioning-sdk两者均由API自己出版的图案的同一发电机生产.
什么是商业层?
商业层 是一个多市场商业API和订单管理系统,它允许您在任何网站,移动应用程序,聊天机,可穿戴,语音,或IoT设备中加入全局购物能力,轻松地. 用你已经掌握和热爱的最好的工具来整理你的堆叠. 通过一个快速的 企业级的 安全的API.
目录
开始
要开始商业层 JS SDK 你需要安装它 获得允许你执行API呼叫的证书 并将SDK导入到应用程序代码中 以下各节解释了如何实现这一目标.
如果你想读,也可以读 此教程 从商业层的博客.
安装
商业层 JS SDK 可作为 无 财务报告和审定财务报表 线条 下列命令可以安装的软件包:
npm install @commercelayer/sdk
// or
yarn add @commercelayer/sdk
认证
所有对商业层 API 的请求必须使用 OAuth2 证书 无记名符. 因此,在开始使用SDK之前,你需要获得有效的访问符. 请检查 我们的文件 关于现有授权流量的更多信息.
随便用吧 商业层,一个 JavaScript 库,可以帮助您包装我们的认证 API.
导入
SDK提供两种导入样式. 默认条目是捆绑客户端 - 使用它,除非你有具体的理由不使用。 选择性的(可动摇树木的)风格生活在一个单独的子道上,并带有下文所描述的重要告诫.
捆绑客户端( 默认)
import { CommerceLayer } from '@commercelayer/sdk'
const cl = CommerceLayer({
accessToken: 'your-access-token',
apiVersion: '2026-05'
})
const orderList = await cl.orders.list()
const skuList = await cl.skus.list()
所有资源存取器都直接在客户对象上提供. 这可以增加你最后的捆绑大小, 但每个呼叫都被限定为特定客户实例, 这样你就可以安全创建和使用 多个客户同时拥有不同的访问符 (多租户应用程序、无服务器连接再利用等):
const clUS = CommerceLayer({ accessToken: usToken, apiVersion: '2026-05' })
const clEU = CommerceLayer({ accessToken: euToken, apiVersion: '2026-05' })
const [usOrders, euOrders] = await Promise.all([
clUS.orders.list(),
clEU.orders.list()
]) // each request uses its own token
选择性资源进口/single-client(中文(简体) )
import { CommerceLayer, orders, skus } from '@commercelayer/sdk/single-client'
const cl = CommerceLayer({
accessToken: 'your-access-token',
apiVersion: '2026-05'
})
const orderList = await orders.list()
const skuList = await skus.list()
您的捆绑中只包含导入的资源, 因此输出最小 。 权衡:进口资源份额 一个单一的全球 SDK 配置。如果两个请求与不同的访问符同时在飞行中,它们可能会默默使用错误的符号——因此这种样式只支持 一次一个活动符号。 。 。 .
它很适合边缘/ 服务器功能或只使用少数资源和单一符号的webhook处理器 。 当您需要多个并行符时, 请使用上面的捆绑客户端 .
选项
当即时处理一个新的 SDK 客户端时, 您可以通过一些选项来初始化它 :
{
organization?: string // The organization slug
accessToken: string // A valid API access token
apiVersion: ApiVersion // The API version to target, e.g. '2026-05' — required, see API version below
timeout?: number // A custom request timout (<= 15 secs [default])
headers?: RequestHeaders // Custom request headers
userAgent?: string // Custom user-agent useful in certaing contexts but often not allowed by browsers
fetch?: Fetch // A specific fetch implementation
refreshToken?: RefreshToken // A function responsible for token refresh
}
相同的选项可以在 SDK 初始化后更改或在运行时通过,同时执行 API 调用 :
const options = { ... }
// Instantiate the client using desired options
const cl = CommerceLayer(options)
// Change configuration after client cteation
cl.config(options)
// Use runtime configuration without persisting settings
cl.customers.list({}, options)
API 版本
Core API版本,每个请求都针对一个版本. apiVersion 因此为 所需经费 当创建客户端时,并成为每个请求 URL 的一部分 - /api/2026-05/orders。 。 。 .
只有SDK的这个发布所生成的版本被接受;任何其他值都是类型错误. 两者均导出:
import { API_SCHEMA_VERSION, API_SUPPORTED_VERSIONS } from '@commercelayer/sdk'
API_SUPPORTED_VERSIONS // ['2017-08', '2026-05'] — the versions you can target
API_SCHEMA_VERSION // '2026-05' — the version the types describe
这些类型是为 API_SCHEMA_VERSION. 仅存在于较旧版本的资源和领域仍然包括在内,标明 @deprecated 带有它们的最后版本,而更新的添加带 @since - 所以你可以继续瞄准 '2017-08' 在迁移时, 您的编辑会显示变化 .
该版本可以在已有客户端上被更改,也可以为单个请求被推翻:
cl.config({ apiVersion: '2017-08' })
const orderList = await cl.orders.list({}, { apiVersion: '2017-08' })
[大 从7.x升级:
apiVersion是新的和需要的,所以每个CommerceLayer(...)电话需要它.
SDK 使用情况
JavaScript SDK 是一个环绕商业地层 API 的包装器,这意味着您仍然会提出 API 请求,但使用不同的语法 。 目前,我们没有关于我们API支持的每一种资源(大约400+个终点)的全面SDK文档,因此你需要依赖我们的全面 API 参考 当你继续使用这个SDK。 举例来说,如果你想创建命令,请看看 顺序对象 或 创建命令 用于查看所需属性和/或关系的文档。 所有其他支助资源也是如此.
为了告诉你事情是如何运作的 我们会用 SKUs 软件 财务报告和审定财务报表 航运类别 以下示例中的资源。 下面的代码片段显示在进行由我们的REST API提供的标准CRUD操作时如何使用SDK. 请检查我们的 API 参考 完整清单 资源 联合国 属性。 。 。 .
下面的例子假设客户端
cl,按 导入。 。 。 .
创建
如何创建 SKU
// Select the shipping category (it's a required relationship for the SKU resource)
const shippingCategories = await cl.shipping_categories.list({ filters: { name_eq: 'Merchandising' } })
// Attributes passed inline, so each value is checked against the field it sets
const newSku = await cl.skus.create({
code: 'TSHIRTMM000000FFFFFFXL',
name: 'Black Men T-shirt with White Logo (XL)',
description: 'A very beautiful and cozy mens t-shirt',
weight: 500,
unit_of_weight: 'gr',
shipping_category: cl.shipping_categories.relationship(shippingCategories[0].id), // assigns the relationship
})
请检查access-date=中的日期值 (帮助) 创建 SKU。 。 。 .
获取/ 列表
如何获取一个 SKU
// Fetch the SKU by ID
const sku = await cl.skus.retrieve('BxAkSVqKEn')
// Fetch all SKUs and filter by code
const skuList = await cl.skus.list({ filters: { code_eq: 'TSHIRTMM000000FFFFFFXLXX' } })
// Fetch the first SKU of the list
const skuList = (await cl.skus.list()).first()
// Fetch the last SKU of the list
const skuList = (await cl.skus.list()).last()
请检查access-date=中的日期值 (帮助) 获取 SKU。 。 。 .
如何获取 SKU 的收藏
// Fetch all the SKUs
const skuList = await cl.skus.list()
获取资源时,您可以使用 meta 属性以获取 meta 此类信息:
const skuList = await cl.skus.list()
const meta = skuList.meta
请检查access-date=中的日期值 (帮助) 列出全部 SKU。 。 。 .
如何获取 SKU 集并排序结果
// Sort the results by creation date in ascending order (default)
const skuList = await cl.skus.list({ sort: { created_at: 'asc' } })
// Sort the results by creation date in descending order
const skuList = await cl.skus.list({ sort: { created_at: 'desc' } })
请检查access-date=中的日期值 (帮助) 排序结果。 。 。 .
如何收集 SKU 和包括协会
// Include an association (prices)
const skuList = await cl.skus.list({ include: [ 'prices' ] })
// Include an association (stock items)
const skuList = await cl.skus.list({ include: [ 'stock_items' ] })
请检查access-date=中的日期值 (帮助) 包括协会。 。 。 .
如何获取 SKU 的集合并返回特定字段( sparse 字段)
// Request the API to return only specific fields
const skuList = await cl.skus.list({ fields: { skus: [ 'name', 'metadata' ] } })
// Request the API to return only specific fields of the included resource
const skuList = await cl.skus.list({ include: [ 'prices' ], fields: { prices: [ 'currency_code', 'formatted_amount' ] } })
请检查access-date=中的日期值 (帮助) 使用稀有字段。 。 。 .
如何获取 SKU 和过滤数据
// Filter all the SKUs fetching only the ones whose code starts with the string "TSHIRT"
const skuList = await cl.skus.list({ filters: { code_start: 'TSHIRT' } })
// Filter all the SKUs fetching only the ones whose code ends with the string "XLXX"
const skuList = await cl.skus.list({ filters: { code_end: 'XLXX' } })
// Filter all the SKUs fetching only the ones whose name contains the string "White Logo"
const skuList = await cl.skus.list({ filters: { name_cont: 'White Logo' } })
// Filter all the SKUs fetching only the ones created between two specific dates
// (filters combined according to the AND logic)
const skuList = await cl.skus.list({ filters: { created_at_gt: '2018-01-01', created_at_lt: '2018-01-31'} })
// Filters all the SKUs fetching only the ones created or updated after a specific date
// (attributes combined according to the OR logic)
const skuList = await cl.skus.list({ filters: { updated_at_or_created_at_gt: '2019-10-10' } })
// Filters all the SKUs fetching only the ones whose name contains the string "Black"
// and whose shipping category name starts with the string "MERCH"
const skuList = await cl.skus.list({ filters: { name_cont: 'Black', shipping_category_name_start: 'MERCH'} })
请检查access-date=中的日期值 (帮助) 过滤数据。 。 。 .
如何收集 SKU
当您获取到资源时, 就会得到标定结果 。 您可以在类似页面中请求特定的页面或项目:
// Fetch the SKUs, setting the page number to 3 and the page size to 5
const skuList = await cl.skus.list({ pageNumber: 3, pageSize: 5 })
// Get the total number of SKUs in the collection
const skuCount = skuList.meta.recordCount
// Get the total number of pages
const pageCount = skuList.meta.pageCount
PS: 默认的页码是 1个,默认页面大小为 10个,允许的最大页面大小为 第25条。 。 。 .
请检查access-date=中的日期值 (帮助) 标记 工作时.
如何获取光标粘贴的收藏( 如事件存储)
少数资源——例如: 事件存储 ——使用 基于光标 页码而不是页码。 导航 pageAfter (和 pageBefore,并读取下一页的光标 meta.cursor,它只出现在光标粘贴的回复中:
const skuId = 'xYZkjABcde'
// Event stores are fetched as a relationship of a resource
let page = await cl.skus.event_stores(skuId, { pageSize: 10 })
const events = [...page]
// Follow the cursor until there are no more pages
while (page.meta.cursor?.next) {
page = await cl.skus.event_stores(skuId, { pageAfter: page.meta.cursor.next.after })
events.push(...page)
}
PS: 默认页面大小为 10个 最大值为 第25条在光标投放的回复中,抵消字段(
meta.pageCount编号 :meta.recordCount已经NaN财务报告和审定财务报表hasNextPage()返回时false检查meta.cursor.next换句话说 这个pageAfter编号 :pageBefore参数总是在类型级别上被接受;被抵消-被分配的资源只是忽略它们而已.
见 事件存储页 详情请参考.
如何通过 SKU 的集合来移动
要为收藏的每个项目执行函数,请使用 map() 这样的方法 :
// Fetch the whole list of SKUs (1st page) and print their names and codes to console
const skuList = await cl.skus.list()
skuList.map(p => console.log('Product: ' + p.name + ' - Code: ' + p.code))
如何获取资源关系
许多资源与其它资源有关系,您可以直接获取,而不是将上述这些协会包括在内。 这样,对于一对一N关系,可以过滤或排序产生的集合作为标准资源.
// Fetch 1-to-1 related resource: billing address of an order
const billingAddress = await cl.orders.billing_address('xYZkjABcde')
// Fetch 1-to-N related resources: orders associated to a customer
const customerOrders = await cl.customers.orders('XyzKjAbCDe', { fields: ['status', 'number'] })
总的来说:
- API 等端点
/api/customers或者说/api/customers/<customerId>翻译为cl.customers.list()或者说cl.customers.retrieve('<customerId>')还有SDK. - 1比1关系 API 等端点
/api/orders/<orderId>/shipping_address翻译为cl.orders.shipping_address('<orderId>')与SDK,或改为cl.orders.retrieve('<orderId>', { include: ['shipping_address'] })来配合命令. - 1-N关系 API 等
/api/customers/<customerId>?include=orders或者说/api/customers/<customerId>/orders翻译为cl.customers.retrieve('<customerId>', { include: ['orders'] })或者说cl.customers.orders('<customerId>')还有SDK.
请检查access-date=中的日期值 (帮助) 获取关系。 。 。 .
如何计算资源
很多次你只需要数一下有多少资源
某些特征 你可以叫特别的 count
函数通过过滤器以获取结果的总数
资源.
// Get the total number of placed orders
const placedOrders = await cl.orders.count({ filters: { status_eq: 'placed' } })
更新
如何更新现有的 SKU
const sku = {
id: 'xYZkjABcde',
description: 'Updated description...',
image_url: 'https://img.yourdomain.com/skus/new-image.png'
}
cl.skus.update(sku) // updates the SKU on the server
请检查access-date=中的日期值 (帮助) 更新 SKU。 。 。 .
删除
如何删除已有的 SKU
cl.skus.delete('xYZkjABcde') // persisted deletion
请检查access-date=中的日期值 (帮助) 删除 SKU。 。 。 .
逾越全权证书
如有需要,商务层JS SDK允许您更改客户端配置并设置在请求级别. 要做到这一点,只是使用 config() 方法或通过 options 参数并认证 API 调用 :
// Permanently change configuration at client level
cl.config({ organization: 'you-organization-slug', accessToken: 'your-access-token' })
const skuList = await cl.skus.list()
// or
// Use configuration at request level
cl.skus.list({}, { organization: 'you-organization-slug', accessToken: 'your-access-token' })
处理验证错误
Commercial Leater API返回单个资源每个属性的特定错误(附加信息). 您可以检查它们以正确处理验证错误( 如果有的话) 。 要做到这一点,使用 errors 被捕获错误的属性 :
// Log error messages to console:
const attributes = { code: 'TSHIRTMM000000FFFFFFXL', name: '' }
const newSku = await cl.skus.create(attributes).catch(error => console.log(error.errors))
// Logged errors
/*
[
{
title: "can't be blank",
detail: "name - can't be blank",
code: 'VALIDATION_ERROR',
source: { pointer: '/data/attributes/name' },
status: '422',
meta: { error: 'blank' }
},
{
title: 'has already been taken',
detail: 'code - has already been taken',
code: 'VALIDATION_ERROR',
source: { pointer: '/data/attributes/code' },
status: '422',
meta: { error: 'taken', value: 'TSHIRTMM000000FFFFFFXL' }
},
{
title: "can't be blank",
detail: "shipping_category - can't be blank",
code: 'VALIDATION_ERROR',
source: { pointer: '/data/relationships/shipping_category' },
status: '422',
meta: { error: 'blank' }
}
]
*/
请检查access-date=中的日期值 (帮助) 错误 由API返回.
使用截取器
您可以在请求发送到API之前,或由客户端解析并返回答复之前,使用截取器来截取SDK消息并修改它们. 也可以在被 SDK 抛出之前访问错误对象.
截取器是特殊功能,能够处理SDK消息并返回一个(最终)修改后版本,供客户端使用.
const requestInterceptor = (request: RequestObj): RequestObj => {
console.log(request)
return request
}
const responseInterceptor = (response: ResponseObj): ResponseObj => {
console.log(response)
return response
}
const errorInterceptor = (error: ErrorObj): ErrorObj => {
console.log(error)
return error
}
这里有一个如何使用它们的例子:
// Add the interceptors (only one or all if needed)
cl.addRequestInterceptor(requestInterceptor)
cl.addResponseInterceptor(responseInterceptor, errorInterceptor)
const customerList = await cl.customers.list()
// Remove interceptors
// Tt is possible to remove only a specific interceptor: cl.removeInterceptor('request')
cl.removeInterceptors()
Raw 响应读取器
这个 原始响应阅读器 是一个特殊的截取器,它允许在解析并翻译为SDK对象之前,捕捉来自 API 的原始消息.
// Add a RawResponseReader capable of capturing also response headers
const rrr = cl.addRawResponseReader({ headers: true })
const customerList = await cl.customers.list()
cl.removeRawResponseReader()
console.log(rrr.rawResponse)
console.log(rrr.headers)
刷新访问令牌
可能您正在使用一个即将过期的访问符, 特别是当它被用于许多API电话时. 在此情况下,您可以定义一个特殊功能,当一个调用因过期而失效时,该功能会负责刷新符号.
async function myRefreshTokenFunction(espiredToken: string): Promise<string> {
// Get a new access token using for example our js-auth library
return (await getAccessToken()).accessToken
}
cl.config({ refreshToken: myRefreshTokenFunction })
// If needed you can later retrieve the new access token
const newToken = cl.currentAccessToken
贡献者指南
-
叉头 此寄存器 (学习如何做到这一点) 读取 GitHub 文档) (中文(简体) ).
-
像这样砍掉叉子仓库:
git clone https://github.com/<your username>/commercelayer-sdk.git && cd commercelayer-sdk -
从寄存器根安装工作空间 :
pnpm install -
做你的改变。 此软件包大多来自 API 方案—— 任何您在其中编辑的内容
gen/将被覆盖。 更改生成器或sdk.config.ts转而运行pnpm generate并承担结果. -
创建牵引请求( E)学着怎么做) (中文(简体) ). Lint,类型,测试套件和生成输出的检查都是可自动复制的.
-
有人会照顾你的拉力请求 并提供一些反馈.
需要帮忙吗?
- 联合 商业层的迪斯科德社区。 。 。 .
- 让我们继续 布鲁斯基, (中文(简体) ), X (原Twitter) (中文(简体) ),或 链接。 。 。 .
- 有虫子吗? 创建一个 问题 。在此仓库上.
许可证
此寄存器在 麻省理工学院 执照.