Adaptateur REST API BigCommerce
Compatible v2/v3
Dernière mise à jour : 5 September 2026
Une API REST compatible et directement substituable pour STOAR, qui reproduit BigCommerce v2 (/api/v2/orders) et v3 (/api/v3/catalog/products) — mêmes chemins d'URL, mêmes dates RFC 2822, même vocabulaire numérique status_id, même enveloppe { data, meta.pagination } en v3, mêmes en-têtes X-Pagination-* en v2, même en-tête X-Auth-Token. Les bibliothèques clientes BigCommerce existantes (bigcommerce/api Node SDK, bigcommerce-api-php, BigCommerce Python) dialoguent avec STOAR sans aucune modification.
Il s'agit de la quatrième implémentation du framework d'adaptateurs d'API extensible de STOAR (après Magento, WooCommerce et Shopify). Elle démontre que l'architecture prend en charge deux variantes de version sous un même adaptateur (v2 + v3) sans dupliquer la moindre logique métier.
Sommaire #
- Démarrage rapide
- Authentification
- Points de terminaison
- Paramètres de requête
- Correspondance des champs (BigCommerce ↔ STOAR)
- Traduction des statuts
- Structure des réponses
- Exemple réel
- Structure des erreurs
- Limitation de débit
Démarrage rapide #
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"
L'authentification Bearer (-H "Authorization: Bearer $TOKEN") est également acceptée en repli.
Authentification #
L'en-tête d'authentification canonique de BigCommerce est X-Auth-Token: <token>. L'adaptateur STOAR l'accepte, ainsi qu'un repli Bearer :
| Méthode | Format | Cas d'usage |
|---|---|---|
| X-Auth-Token | X-Auth-Token: <sanctum-token> |
Valeur par défaut de toutes les bibliothèques clientes BigCommerce |
| Bearer (extension STOAR) | Authorization: Bearer <sanctum-token> |
Sanctum natif — interchangeable avec les autres adaptateurs |
Les tokens sont émis depuis la page /manager/api-tokens de STOAR, ou par programme via AdminUser::createToken('label', ['bigcommerce:admin']). Un même token peut porter simultanément les abilities de tous les adaptateurs (bigcommerce:admin + magento:admin + shopify:admin + woocommerce:admin).
Le middleware AuthTokenMiddleware s'exécute avant auth:sanctum et promeut X-Auth-Token en en-tête Authorization: Bearer …. Du point de vue de STOAR, toute requête BC est une requête Sanctum authentifiée ordinaire.
Le flux OAuth client credentials (les vraies applications BC passent par /auth/load et /oauth2/token) n'est pas pris en charge.
Points de terminaison #
Tous les chemins sont relatifs à /api. Les points de terminaison v2 se trouvent sous /api/v2, ceux de la v3 sous /api/v3.
GET /api/v2/orders
Liste les commandes — tableau plat dans le corps + en-têtes de pagination.
Autorisation : bigcommerce:admin.
Requête : voir Paramètres de requête.
Réponse :
HTTP/1.1 200 OK
X-Pagination-Total-Count: 150
X-Pagination-Page-Total: 3
Content-Type: application/json
[
{ /* order object — see Response shape */ }
]
Pourquoi des en-têtes plutôt qu'une enveloppe ? C'est la convention réelle de BC v2. Les points de terminaison v3 utilisent l'enveloppe
{ data, meta }(voir les produits du catalogue ci-dessous). Les vraies bibliothèques clientes BC gèrent les deux.
GET /api/v2/orders/{id}
Commande unique — objet brut (AUCUNE enveloppe en v2).
Erreurs :
{ "status": 404, "title": "The order requested could not be found.", "type": "..." }
GET /api/v2/orders/{id}/products
Remarque — les lignes de commande résident sur un point de terminaison SÉPARÉ ; elles ne sont pas intégrées à la ressource commande. C'est l'une des différences majeures de BC par rapport à Magento, WooCommerce et Shopify (qui intègrent tous les lignes de commande).
Réponse : tableau plat d'objets de ligne 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
Liste les produits du catalogue — enveloppe v3 avec data + meta.pagination.
Requête : voir Paramètres de requête.
Réponse (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
}
}
}
links.previous est présent à partir de la page 2 ; links.next sur toutes les pages sauf la dernière.
GET /api/v3/catalog/products/{id}
Produit unique — enveloppe v3 avec data (objet unique) + meta vide.
Réponse :
{
"data": { /* product — see Response shape */ },
"meta": {}
}
Paramètres de requête #
Communs (commandes + produits)
| Paramètre | Défaut | Objet |
|---|---|---|
limit |
50 |
éléments par page (max. 250) |
page |
1 |
numéro de page, indexé à partir de 1 |
Commandes v2 uniquement
| Paramètre | Exemple | Effet |
|---|---|---|
status_id |
11 |
Code de statut numérique BC → traduit en statut Stoar |
customer_id |
42 |
Filtrer par client |
min_id / max_id |
100 |
plage d'id |
min_date_created / max_date_created |
2025-01-01T00:00:00 |
plage created_at |
sort |
id:desc |
<field>:<asc\|desc>. Champs : id, date_created, date_modified, total_inc_tax |
Produits du catalogue v3 uniquement
La v3 prend en charge la syntaxe plus riche des suffixes d'opérateur de BC : id:in, price:min, etc.
| Paramètre | Exemple | Effet |
|---|---|---|
id |
42 |
id exact |
id:in |
1,2,3 |
id IN liste |
id:not_in |
4,5 |
id NOT IN liste |
sku |
WID-1 |
sku exact |
name |
Widget |
nom exact |
keyword |
widget |
LIKE sur une sous-chaîne du nom |
is_visible |
true / false |
traduit en active / inactive |
is_featured |
true / false |
filtre sur is_featured |
categories |
5 |
id de catégorie exact |
price:min |
10 |
price >= |
price:max |
100 |
price <= |
sort |
name, -price, -date_created, id |
un - en tête inverse le sens |
Les opérateurs ou champs inconnus sont ignorés silencieusement — comme le fait BC.
Correspondance des champs (BigCommerce ↔ STOAR) #
Commande (v2)
| Champ BC v2 | Source STOAR | Remarques |
|---|---|---|
id |
id |
numérique |
status_id |
status (traduit) |
code numérique BC (1, 11, 7, 3, 10, 5, 4) — voir Traduction des statuts |
status |
status (traduit) |
libellé texte (« Pending », « Awaiting Fulfillment », « Shipped », …) |
customer_id |
customer_id ?? 0 |
les commandes invité reçoivent 0 |
date_created, date_modified |
created_at, updated_at |
format RFC 2822 (PAS ISO 8601) |
date_shipped |
updated_at si status='shipped'/'delivered' |
chaîne vide sinon |
currency_code, default_currency_code |
currency (en majuscules) |
p. ex. EUR |
currency_exchange_rate |
toujours '1.0000000000' |
Stoar est monodevise |
total_inc_tax |
total_amount |
float NUMÉRIQUE (PAS une chaîne — c'est le comportement 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 |
premier OrderPayment.gateway non archivé |
|
payment_status |
'captured' si payment_status='succeeded' |
vide sinon |
refunded_amount |
refunded_amount ?? 0 |
|
staff_notes |
admin_notes |
|
customer_message |
customer_notes |
|
billing_address |
JSON billing_info |
objet imbriqué — structure plate avec les clés street_1/street_2 |
products |
sous-ressource | pointeur {url, resource} vers /orders/{id}/products |
shipping_addresses |
sous-ressource | pointeur {url, resource} (non implémenté) |
coupons |
sous-ressource | pointeur {url, resource} (non implémenté) |
items_total |
sum(items.quantity) |
|
items_shipped |
sum(items.quantity) si status='shipped'/'delivered', sinon 0 |
|
customer_locale |
toujours 'en' |
non stocké |
channel_id |
toujours 1 |
non modélisé |
Ligne de commande line_item (v2 /products)
| Champ BC v2 | Source 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 de la variante d'abord, à défaut celui du produit |
type |
toujours '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[] |
un élément portant le nom de la variante (lorsqu'il n'est pas Default) |
weight, width, height, depth |
toujours 0 |
is_refunded, quantity_refunded, refund_amount |
toujours false/0 (Stoar suit les remboursements au seul niveau commande) |
Produit du catalogue (v3)
| Champ BC v3 | Source STOAR | Remarques |
|---|---|---|
id |
id |
|
name, description, sku |
repris tel quel | |
type |
toujours 'physical' |
BC propose aussi 'digital' ; Stoar ne gère que le physique |
is_visible |
status === 'active' |
booléen |
availability |
'available' si actif, sinon 'disabled' |
énumération |
is_featured |
is_featured |
booléen |
inventory_tracking |
'product' pour un produit simple, 'variant' pour un configurable |
|
inventory_level |
stock (somme des variantes pour un configurable) |
|
inventory_warning_level |
low_stock_threshold ?? 0 |
|
price |
price (brut) |
float NUMÉRIQUE |
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] |
tableau d'un seul entier (PAS des objets imbriqués) |
base_variant_id |
id de la première variante | |
images[] |
image_path + gallery_paths |
tableau en ligne |
variants[] |
en ligne | objets de variante complets |
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 (la v3 utilise ISO, la v2 RFC 2822) |
condition |
toujours 'New' |
non modélisé |
total_sold, view_count, reviews_rating_sum, reviews_count |
toujours 0 |
non agrégés |
related_products |
toujours [-1] |
convention BC pour « produits liés automatiquement » |
brand_id |
toujours null |
Stoar n'a pas de modèle de marque |
Variante de produit du catalogue (v3)
| Champ BC v3 | Source 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[] |
toujours [] (les attributs de variante Stoar suivent un autre modèle) |
Traduction des statuts #
BigCommerce utilise des codes status_id NUMÉRIQUES accompagnés d'un champ texte status parallèle. Le traducteur décompose l'énumération Stoar en ces deux valeurs.
Stoar → BigCommerce (rendu)
status Stoar |
status_id |
status (texte) |
|---|---|---|
pending |
1 | Pending |
paid |
11 | Awaiting Fulfillment |
processing |
7 | Awaiting Pickup |
shipped |
3 | Shipped |
delivered |
10 | Completed |
cancelled |
5 | Cancelled |
refunded |
4 | Refunded |
Filtre BigCommerce → Stoar (analyse)
?status_id=N est traduit via la même table de correspondance. Les codes absents de la table (p. ex. le statut BC 2 = « Manually Verified » ou 6 = « Declined ») passent silencieusement — conformément au comportement « pas d'équivalent exact » de BC. La table complète du vrai BC compte environ 14 entrées ; STOAR expose les sept qui se traduisent proprement.
Statut produit
BigCommerce n'a pas de champ texte status — il utilise is_visible (booléen) et l'énumération availability. Filtre avec ?is_visible=true pour les produits actifs et ?is_visible=false pour les inactifs.
Structure des réponses #
Commande v2 — annotée
{
"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,
"..."
}
Produit du catalogue v3 — abrégé
{
"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": {}
}
Exemple réel #
GET /api/v2/orders/10126 en production. Il s'agit de la même commande Stoar que celle présentée pour Magento, WooCommerce et Shopify — rendue ici à la structure BC v2. Données personnelles anonymisées.
{
"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": ""
}
Points de vigilance pour les intégrateurs
| Champ | Observé | Pourquoi |
|---|---|---|
date_created, date_modified |
chaîne RFC 2822 | la v2 utilise spécifiquement RFC 2822 (Tue, 03 Jun 2025 04:56:43 +0000). Les points de terminaison v3 utilisent ISO 8601 — l'incohérence vient de BC, nous la reproduisons. |
payment_method |
"payid" |
clé de passerelle Stoar — ce n'est pas un nom de méthode canonique BC. |
payment_status |
"captured" pour les commandes payées |
BC dispose de son propre vocabulaire de statuts ; nous faisons correspondre succeeded → captured. |
total_inc_tax, total_ex_tax, etc. |
des floats (p. ex. 936.98) |
BC v2 rend les montants sous forme de floats — contrairement à WooCommerce / Shopify qui utilisent des chaînes à 2 décimales. |
country |
"United States" |
nom complet, déduit de l'ISO-2 via une petite table de correspondance (DE/US/GB/AU/AT/CH). Les autres pays renvoient "". |
products, shipping_addresses, coupons |
pointeurs de sous-ressource {url, resource} |
convention BC signifiant « suis cette URL pour récupérer les données liées ». /orders/{id}/products est implémenté ; les autres ne sont pas encore disponibles. |
customer_locale |
toujours "en" |
non stocké sur le Customer Stoar. |
channel_id |
toujours 1 |
Stoar est mono-boutique ; BC gère le multicanal. |
currency_exchange_rate |
toujours "1.0000000000" |
Stoar est monodevise. |
staff_notes, customer_message |
admin_notes, customer_notes |
terminologie BC. |
external_*, ebay_order_id, cart_id |
vide / null / « 0 » | Stoar n'a aucune intégration marketplace. |
Structure des erreurs #
BigCommerce utilise une enveloppe de style 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 pointe toujours vers la page de documentation des codes de statut de BC. errors n'est présent qu'en cas d'échec de validation (400).
| HTTP | Déclencheur | title |
|---|---|---|
| 400 | requête incorrecte / validation | Invalid query parameters. (avec la table errors) |
| 401 | token absent ou invalide | Not authenticated. |
| 403 | token à l'ability incorrecte | Insufficient OAuth scope. |
| 404 | ressource inconnue | The {resource} requested could not be found. |
| 422 | précondition non remplie | message dynamique |
| 429 | limite de débit dépassée | Too many requests. (avec les en-têtes X-Rate-Limit-Time-Reset-Ms et X-Rate-Limit-Requests-Left) |
| 500 | erreur serveur inattendue | Internal Server Error |
Limitation de débit #
Le même throttle api-rest indexé sur le token Sanctum qui protège tous les autres adaptateurs protège les routes BC. Le seuil et l'interrupteur général se configurent sur /manager/api-settings. En cas de déclenchement, la réponse utilise l'enveloppe RFC 7807 de BC :
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"
}
Les en-têtes X-Rate-Limit-* correspondent au comportement documenté par BC. Le vrai BC renvoie davantage d'en-têtes et utilise des fenêtres à la seconde ; STOAR utilise la fenêtre à la minute de Laravel — suffisamment proche pour la compatibilité avec les bibliothèques clientes.
Un même token Sanctum utilisé sur les quatre adaptateurs partage un seul compteur — voir la section Limitation de débit de Magento pour la visite guidée de l'interface de configuration.
Voir aussi #
app/Api/Adapters/BigCommerce/Support/StatusTranslator.php— correspondance bidirectionnelle des vocabulaires- Référence de la REST API BigCommerce — la spécification amont que cet adaptateur reproduit