BigCommerce REST API 轉接器
相容於 v2/v3
最後更新:2026年9月5日
一套可直接替換的 STOAR REST API,對應 BigCommerce v2(/api/v2/orders)與 v3(/api/v3/catalog/products)——相同的 URL 路徑、相同的 RFC 2822 日期、相同的 status_id 數字詞彙、v3 相同的 { data, meta.pagination } 外層結構、v2 相同的 X-Pagination-* 標頭、相同的 X-Auth-Token 標頭。現有的 BigCommerce 用戶端函式庫(bigcommerce/api Node SDK、bigcommerce-api-php、BigCommerce Python)無需任何修改即可與 STOAR 溝通。
這是 STOAR 可擴充的 API 轉接器框架的第四個實作(繼 Magento、WooCommerce 與 Shopify 之後)。它證明了這套架構能在單一轉接器下容納兩種版本風格(v2 + v3),而不必重複任何商務邏輯。
目錄 #
快速上手 #
TOKEN="5|abcdef…" # Sanctum personal-access token with bigcommerce:admin ability
# v2 — orders
curl -H "X-Auth-Token: $TOKEN" \
"https://app.stoar.ai/api/v2/orders?limit=5" | jq '.[] | {id, status_id, status, total_inc_tax}'
# v2 — line items for a specific order (separate sub-endpoint)
curl -H "X-Auth-Token: $TOKEN" \
"https://app.stoar.ai/api/v2/orders/10126/products" | jq '.[].name'
# v3 — catalog products with pagination meta envelope
curl -H "X-Auth-Token: $TOKEN" \
"https://app.stoar.ai/api/v3/catalog/products?limit=2&page=1" | jq '.meta.pagination'
# v3 — single product
curl -H "X-Auth-Token: $TOKEN" \
"https://app.stoar.ai/api/v3/catalog/products/789"
Bearer 驗證(-H "Authorization: Bearer $TOKEN")也可作為備援方式使用。
驗證 #
BigCommerce 的標準驗證標頭是 X-Auth-Token: <token>。STOAR 的轉接器同時接受它與 Bearer 備援:
| 方式 | 格式 | 使用情境 |
|---|---|---|
| X-Auth-Token | X-Auth-Token: <sanctum-token> |
所有 BigCommerce 用戶端函式庫的預設方式 |
| Bearer (STOAR 擴充) | Authorization: Bearer <sanctum-token> |
原生 Sanctum——可與其他轉接器互換使用 |
Token 由 STOAR 的 /manager/api-tokens 頁面核發,或以程式方式透過 AdminUser::createToken('label', ['bigcommerce:admin']) 產生。單一 token 可同時帶有每個轉接器的能力(bigcommerce:admin + magento:admin + shopify:admin + woocommerce:admin)。
AuthTokenMiddleware 會在 auth:sanctum 之前執行,並把 X-Auth-Token 提升為 Authorization: Bearer … 標頭。從 STOAR 的角度來看,每個 BC 請求都是一般的 Sanctum 驗證請求。
不支援 OAuth client-credential 流程(真實的 BC 應用會走 /auth/load 與 /oauth2/token)。
端點 #
所有路徑都相對於 /api。v2 端點位於 /api/v2 之下;v3 端點位於 /api/v3 之下。
GET /api/v2/orders
列出訂單——扁平陣列內文 + 分頁標頭。
授權: bigcommerce:admin。
查詢: 見查詢參數。
回應:
HTTP/1.1 200 OK
X-Pagination-Total-Count: 150
X-Pagination-Page-Total: 3
Content-Type: application/json
[
{ /* order object — see Response shape */ }
]
為什麼用標頭而不是外層結構? 這正是 BC v2 的實際慣例。v3 端點使用
{ data, meta }外層結構(見下方的目錄商品)。真實的 BC 用戶端函式庫兩者都能處理。
GET /api/v2/orders/{id}
單筆訂單——裸物件(v2 沒有外層結構)。
錯誤:
{ "status": 404, "title": "The order requested could not be found.", "type": "..." }
GET /api/v2/orders/{id}/products
注意——明細項目位於獨立的端點,不會內嵌在訂單資源中。這是 BC 與 Magento、WooCommerce 及 Shopify(三者都把明細項目內嵌)較大的差異之一。
回應: BC v2 明細項目物件的扁平陣列。
[
{
"id": 30219,
"order_id": 10126,
"product_id": 112238,
"variant_id": 95589,
"name": "Widget",
"sku": "WID-1-A",
"type": "physical",
"base_price": 299,
"price_ex_tax": 299,
"price_inc_tax": 299,
"base_total": 897,
"total_ex_tax": 897,
"total_inc_tax": 897,
"quantity": 3,
"is_refunded": false,
"product_options": [],
"..."
}
]
GET /api/v3/catalog/products
列出目錄商品——v3 外層結構,包含 data + meta.pagination。
查詢: 見查詢參數。
回應(200):
{
"data": [
{ /* product — see Response shape */ }
],
"meta": {
"pagination": {
"total": 150,
"count": 50,
"per_page": 50,
"current_page": 1,
"total_pages": 3,
"links": {
"current": "https://.../api/v3/catalog/products?page=1&limit=50",
"next": "https://.../api/v3/catalog/products?page=2&limit=50"
},
"too_many": false
}
}
}
第 2 頁以後會包含 links.previous;除最後一頁外都會包含 links.next。
GET /api/v3/catalog/products/{id}
單筆商品——v3 外層結構,包含 data(單一物件)+ 空的 meta。
回應:
{
"data": { /* product — see Response shape */ },
"meta": {}
}
查詢參數 #
共通(訂單 + 商品)
| 參數 | 預設值 | 用途 |
|---|---|---|
limit |
50 |
每頁筆數(上限 250) |
page |
1 |
頁碼,從 1 起算 |
僅限 v2 訂單
| 參數 | 範例 | 效果 |
|---|---|---|
status_id |
11 |
BC 數字狀態碼 → 轉換為 Stoar 狀態 |
customer_id |
42 |
依顧客篩選 |
min_id / max_id |
100 |
id 範圍 |
min_date_created / max_date_created |
2025-01-01T00:00:00 |
created_at 範圍 |
sort |
id:desc |
<field>:<asc\|desc>。可用欄位:id、date_created、date_modified、total_inc_tax |
僅限 v3 目錄商品
v3 支援 BC 更豐富的運算子後綴語法:id:in、price:min 等。
| 參數 | 範例 | 效果 |
|---|---|---|
id |
42 |
精確 id |
id:in |
1,2,3 |
id IN 清單 |
id:not_in |
4,5 |
id NOT IN 清單 |
sku |
WID-1 |
精確 sku |
name |
Widget |
精確名稱 |
keyword |
widget |
對名稱做 LIKE 子字串比對 |
is_visible |
true / false |
轉換為 active/inactive |
is_featured |
true / false |
依 is_featured 篩選 |
categories |
5 |
精確分類 id |
price:min |
10 |
price >= |
price:max |
100 |
price <= |
sort |
name、-price、-date_created、id |
前置 - 反轉排序方向 |
未知的運算子或欄位會被靜默忽略——與 BC 的行為一致。
欄位對應(BigCommerce ↔ STOAR) #
訂單(v2)
| BC v2 欄位 | STOAR 來源 | 備註 |
|---|---|---|
id |
id |
數字 |
status_id |
status(已轉換) |
BC 數字碼(1、11、7、3、10、5、4)——見狀態轉換 |
status |
status(已轉換) |
字串標籤("Pending"、"Awaiting Fulfillment"、"Shipped" 等) |
customer_id |
customer_id ?? 0 |
訪客訂單為 0 |
date_created、date_modified |
created_at、updated_at |
RFC 2822 格式(非 ISO 8601) |
date_shipped |
當 status='shipped'/'delivered' 時為 updated_at |
其餘情況為空字串 |
currency_code、default_currency_code |
currency(轉為大寫) |
例如 EUR |
currency_exchange_rate |
恆為 '1.0000000000' |
Stoar 為單一幣別 |
total_inc_tax |
total_amount |
數值 float(非字串——那是 V3/WC 的行為) |
total_ex_tax |
total_amount - tax_amount |
|
total_tax |
tax_amount |
|
subtotal_ex_tax |
subtotal |
|
subtotal_inc_tax |
subtotal + tax_amount |
|
subtotal_tax |
tax_amount |
|
shipping_cost_ex_tax、shipping_cost_inc_tax、base_shipping_cost |
shipping_amount |
|
discount_amount、coupon_discount |
discount_amount |
|
payment_method |
第一筆未封存的 OrderPayment.gateway |
|
payment_status |
當 payment_status='succeeded' 時為 'captured' |
其餘為空 |
refunded_amount |
refunded_amount ?? 0 |
|
staff_notes |
admin_notes |
|
customer_message |
customer_notes |
|
billing_address |
billing_info JSON |
巢狀物件——扁平結構,使用 street_1/street_2 鍵 |
products |
子資源 | 指向 /orders/{id}/products 的 {url, resource} 指標 |
shipping_addresses |
子資源 | {url, resource} 指標(尚未實作) |
coupons |
子資源 | {url, resource} 指標(尚未實作) |
items_total |
sum(items.quantity) |
|
items_shipped |
當 status='shipped'/'delivered' 時為 sum(items.quantity),否則為 0 |
|
customer_locale |
恆為 'en' |
未儲存 |
channel_id |
恆為 1 |
未建模 |
訂單 line_item(v2 /products)
| BC v2 欄位 | Stoar 來源 |
|---|---|
id |
OrderItem.id |
order_id |
OrderItem.order_id |
product_id |
OrderItem.product_id |
variant_id |
OrderItem.variant_id |
name、name_customer、name_merchant |
OrderItem.name |
sku |
優先取規格 SKU,退回商品 SKU |
type |
恆為 'physical' |
base_price、price_ex_tax |
OrderItem.price |
price_inc_tax |
price + (tax_amount / quantity) |
base_total、total_ex_tax |
price * quantity |
total_inc_tax |
(price * quantity) + tax_amount |
total_tax |
OrderItem.tax_amount |
quantity |
OrderItem.quantity |
product_options[] |
一個元素,內含規格名稱(非 Default 時) |
weight、width、height、depth |
恆為 0 |
is_refunded、quantity_refunded、refund_amount |
恆為 false/0(Stoar 只在訂單層級追蹤退款) |
目錄商品(v3)
| BC v3 欄位 | STOAR 來源 | 備註 |
|---|---|---|
id |
id |
|
name、description、sku |
直接沿用 | |
type |
恆為 'physical' |
BC 另有 'digital';Stoar 只有實體商品 |
is_visible |
status === 'active' |
bool |
availability |
active 時為 'available',否則為 'disabled' |
enum |
is_featured |
is_featured |
bool |
inventory_tracking |
簡單商品為 'product',可組態商品為 'variant' |
|
inventory_level |
stock(可組態商品為各規格加總) |
|
inventory_warning_level |
low_stock_threshold ?? 0 |
|
price |
price(原始值) |
數值 float |
sale_price |
special_price ?? 0 |
float |
calculated_price |
min(price, special_price) | float |
weight |
weight ?? 0 |
float |
tax_class_id |
tax_class_id ?? 0 |
|
categories |
[category_id] |
單一整數的陣列(非巢狀物件) |
base_variant_id |
第一個規格的 id | |
images[] |
image_path + gallery_paths |
內嵌陣列 |
variants[] |
內嵌 | 完整的規格物件 |
custom_url |
{url: "/{slug}", is_customized: false, create_redirect: false} |
|
page_title、meta_description、meta_keywords |
meta_title、meta_description、[] |
|
date_created、date_modified |
created_at、updated_at |
ISO 8601(v3 用 ISO;v2 用 RFC 2822) |
condition |
恆為 'New' |
未建模 |
total_sold、view_count、reviews_rating_sum、reviews_count |
恆為 0 |
未彙總 |
related_products |
恆為 [-1] |
BC 用來表示「自動關聯」的慣例 |
brand_id |
恆為 null |
Stoar 沒有品牌模型 |
目錄商品規格(v3)
| BC v3 欄位 | Stoar 來源 |
|---|---|
id |
Variant.id |
product_id |
Variant.product_id |
sku |
Variant.sku |
price、calculated_price |
Variant.price |
inventory_level |
Variant.stock |
weight、calculated_weight |
Variant.weight |
purchasing_disabled |
!Variant.is_active |
image_url |
Variant.image_path ?? "" |
option_values[] |
恆為 [](Stoar 的規格屬性採用不同模型) |
狀態轉換 #
BigCommerce 使用數字的 status_id 代碼,並搭配一個平行的字串 status 欄位。轉換器會把 Stoar 的列舉值拆解成這兩者。
Stoar → BigCommerce(輸出)
Stoar status |
status_id |
status(字串) |
|---|---|---|
pending |
1 | Pending |
paid |
11 | Awaiting Fulfillment |
processing |
7 | Awaiting Pickup |
shipped |
3 | Shipped |
delivered |
10 | Completed |
cancelled |
5 | Cancelled |
refunded |
4 | Refunded |
BigCommerce 篩選 → Stoar(解析)
?status_id=N 會使用同一份對照表轉換。對照表中找不到的代碼(例如 BC 的狀態 2 =「Manually Verified」或 6 =「Declined」)會被靜默略過——與 BC 的「沒有精確對應」行為一致。真實 BC 的完整代碼表約有 14 個項目;STOAR 開放其中能乾淨對應的七個。
商品狀態
BigCommerce 沒有字串型的 status 欄位——它使用 is_visible(bool)+ availability 列舉。啟用中的商品請以 ?is_visible=true 篩選,停用的商品請用 ?is_visible=false。
回應結構 #
v2 訂單——附註解
{
"id": 456,
"customer_id": 45,
"date_created": "Tue, 03 Jun 2025 04:56:43 +0000",
"date_modified": "Tue, 03 Jun 2025 04:56:43 +0000",
"date_shipped": "",
"status_id": 11,
"status": "Awaiting Fulfillment",
"subtotal_ex_tax": 100,
"subtotal_inc_tax": 110,
"subtotal_tax": 10,
"total_ex_tax": 105,
"total_inc_tax": 115,
"total_tax": 10,
"items_total": 2,
"items_shipped": 0,
"payment_method": "stripe",
"payment_status": "captured",
"refunded_amount": 0,
"currency_code": "EUR",
"currency_exchange_rate": "1.0000000000",
"default_currency_code": "EUR",
"billing_address": {
"first_name": "Jane",
"last_name": "Doe",
"company": "",
"street_1": "1 Test St",
"street_2": "",
"city": "Berlin",
"state": "",
"zip": "10115",
"country": "Germany",
"country_iso2": "DE",
"phone": "+49…",
"email": "[email protected]",
"form_fields": []
},
"products": {
"url": "https://.../api/v2/orders/456/products",
"resource": "/orders/456/products"
},
"shipping_addresses": {
"url": "https://.../api/v2/orders/456/shippingaddresses",
"resource": "/orders/456/shippingaddresses"
},
"coupons": {
"url": "https://.../api/v2/orders/456/coupons",
"resource": "/orders/456/coupons"
},
"store_default_currency_code": "EUR",
"channel_id": 1,
"..."
}
v3 目錄商品——節錄
{
"data": {
"id": 789,
"name": "Widget",
"type": "physical",
"sku": "WID-1",
"description": "<p>A great widget</p>",
"weight": 0.5,
"price": 99.99,
"sale_price": 0,
"retail_price": 0,
"calculated_price": 99.99,
"categories": [5],
"is_visible": true,
"is_featured": true,
"availability": "available",
"inventory_tracking": "product",
"inventory_level": 42,
"page_title": "Widget – buy now",
"custom_url": {
"url": "/widget",
"is_customized": false,
"create_redirect": false
},
"images": [
{ "id": 0, "image_file": "products/widget.webp", "is_thumbnail": true, "sort_order": 0, "url_thumbnail": "products/widget.webp", "url_zoom": "products/widget.webp", "..." }
],
"variants": [
{ "id": 12, "product_id": 789, "sku": "WID-RED", "price": 99.99, "inventory_level": 22, "purchasing_disabled": false, "..." }
]
},
"meta": {}
}
實際範例 #
對正式環境呼叫 GET /api/v2/orders/10126。與 Magento、WooCommerce 及 Shopify 文件中使用的是同一筆 Stoar 訂單——這裡以 BC v2 結構呈現。個資已匿名化。
{
"id": 10126,
"customer_id": 5794,
"date_created": "Tue, 03 Jun 2025 04:56:43 +0000",
"date_modified": "Tue, 03 Jun 2025 04:56:43 +0000",
"date_shipped": "",
"status_id": 11,
"status": "Awaiting Fulfillment",
"subtotal_ex_tax": 936.98,
"subtotal_inc_tax": 936.98,
"subtotal_tax": 0,
"shipping_cost_ex_tax": 0,
"shipping_cost_inc_tax": 0,
"shipping_cost_tax": 0,
"total_ex_tax": 936.98,
"total_inc_tax": 936.98,
"total_tax": 0,
"items_total": 5,
"items_shipped": 0,
"payment_method": "payid",
"payment_provider_id":null,
"payment_status": "captured",
"refunded_amount": 0,
"order_is_digital": false,
"currency_id": 1,
"currency_code": "USD",
"currency_exchange_rate": "1.0000000000",
"default_currency_id": 1,
"default_currency_code": "USD",
"staff_notes": "",
"customer_message": "",
"discount_amount": 0,
"coupon_discount": 0,
"shipping_address_count": 1,
"is_deleted": false,
"ebay_order_id": "0",
"cart_id": null,
"billing_address": {
"first_name": "Jane",
"last_name": "Doe",
"company": "",
"street_1": "1 Example Street",
"street_2": "",
"city": "Phoenix",
"state": "AZ",
"zip": "85001",
"country": "United States",
"country_iso2": "US",
"phone": "+1-555-0100",
"email": "",
"form_fields": []
},
"products": {
"url": "https://app.stoar.ai/api/v2/orders/10126/products",
"resource": "/orders/10126/products"
},
"shipping_addresses": {
"url": "https://app.stoar.ai/api/v2/orders/10126/shippingaddresses",
"resource": "/orders/10126/shippingaddresses"
},
"coupons": {
"url": "https://app.stoar.ai/api/v2/orders/10126/coupons",
"resource": "/orders/10126/coupons"
},
"store_default_currency_code": "USD",
"store_default_to_transactional_exchange_rate": "1.0000000000",
"custom_status": "Awaiting Fulfillment",
"channel_id": 1,
"ip_address": "",
"ip_address_v6": "",
"geoip_country": "",
"geoip_country_iso2": "",
"is_email_opt_in": false,
"credit_card_type": null,
"order_source": "www",
"external_source": null,
"external_id": null,
"external_merchant_id":null,
"tax_provider_id": "",
"customer_locale": "en",
"external_order_id": ""
}
整合者應注意的細節
| 欄位 | 實際觀察 | 原因 |
|---|---|---|
date_created、date_modified |
RFC 2822 字串 | v2 特別使用 RFC 2822(Tue, 03 Jun 2025 04:56:43 +0000)。v3 端點使用 ISO 8601——這個不一致來自 BC,我們只是照做。 |
payment_method |
"payid" |
Stoar 的金流商鍵值——並非 BC 標準的方式名稱。 |
payment_status |
已付款訂單為 "captured" |
BC 有自己的狀態詞彙;我們把 succeeded 對應為 captured。 |
total_inc_tax、total_ex_tax 等 |
float(例如 936.98) |
BC v2 以 float 表示金額——與使用兩位小數字串的 WooCommerce/Shopify 不同。 |
country |
"United States" |
完整國名,由 ISO-2 透過一份小型對照表推導(DE/US/GB/AU/AT/CH)。其他國家回傳 ""。 |
products、shipping_addresses、coupons |
{url, resource} 子資源指標 |
BC 用來表示「循此 URL 取得相關資料」的慣例。/orders/{id}/products 已實作;其餘尚未提供。 |
customer_locale |
恆為 "en" |
未儲存在 Stoar 的 Customer 上。 |
channel_id |
恆為 1 |
Stoar 為單一商店;BC 支援多通路。 |
currency_exchange_rate |
恆為 "1.0000000000" |
Stoar 為單一幣別。 |
staff_notes、customer_message |
admin_notes、customer_notes |
BC 的用語。 |
external_*、ebay_order_id、cart_id |
空值/null/"0" | Stoar 沒有市集整合。 |
錯誤結構 #
BigCommerce 採用 RFC 7807 風格的外層結構:
{
"status": 404,
"title": "The order requested could not be found.",
"type": "https://developer.bigcommerce.com/api-docs/getting-started/api-status-codes",
"errors": { "<field>": "..." }
}
type 永遠指向 BC 的狀態碼文件頁面。errors 只在驗證失敗(400)時出現。
| HTTP | 觸發原因 | title |
|---|---|---|
| 400 | 查詢錯誤/驗證失敗 | Invalid query parameters.(附 errors 對照) |
| 401 | 缺少或無效的 token | Not authenticated. |
| 403 | token 能力不符 | Insufficient OAuth scope. |
| 404 | 未知資源 | The {resource} requested could not be found. |
| 422 | 前置條件不符 | 動態訊息 |
| 429 | 超出流量限制 | Too many requests.(附 X-Rate-Limit-Time-Reset-Ms 與 X-Rate-Limit-Requests-Left 標頭) |
| 500 | 非預期的伺服器錯誤 | Internal Server Error |
流量限制 #
保護其他所有轉接器的同一組以 Sanctum token 為鍵的 api-rest 節流機制,同樣保護 BC 路由。門檻值與總開關都可在 /manager/api-settings 設定。觸發時,回應會使用 BC 的 RFC 7807 外層結構:
HTTP/1.1 429 Too Many Requests
X-Rate-Limit-Time-Reset-Ms: 60000
X-Rate-Limit-Requests-Left: 0
Content-Type: application/json
{
"status": 429,
"title": "Too many requests.",
"type": "https://developer.bigcommerce.com/api-docs/getting-started/api-status-codes"
}
X-Rate-Limit-* 標頭符合 BC 的文件行為。真實的 BC 會回傳更多標頭,並使用秒級解析度的時間窗;STOAR 使用 Laravel 的分鐘級時間窗——就用戶端函式庫相容性而言已經足夠接近。
同一個 Sanctum token 在四個轉接器之間共用同一個配額桶——設定介面的完整操作說明請見 Magento 文件的「流量限制」一節。
延伸閱讀 #
app/Api/Adapters/BigCommerce/Support/StatusTranslator.php——雙向詞彙對應- BigCommerce REST API 參考文件——本轉接器所對應的上游規格