Adaptateur REST API Magento
Compatible Magento 2, sans modification
Dernière mise à jour : 5 September 2026
Une REST API pour STOAR compatible sans modification, qui reproduit le format protocolaire de Magento 2 — mêmes chemins d'URL, même syntaxe de requête searchCriteria[…], mêmes noms de champs en réponse, même flux d'authentification. Les bibliothèques clientes Magento existantes dialoguent avec STOAR sans être modifiées.
L'adaptateur est la première implémentation d'un framework d'adaptateurs API extensible : les mêmes données sont exposées sous différentes déclinaisons éditeur (Magento aujourd'hui, Shopify / WooCommerce / adaptateurs sur mesure ensuite) sans dupliquer la logique métier des commandes.
Sommaire #
- Démarrage rapide
- Authentification
- Points de terminaison
- Syntaxe des critères de recherche
- Correspondance des champs (Magento ↔ STOAR)
- Structure de la réponse
- Exemple réel
- Structure des erreurs
Démarrage rapide #
# 1. Get an admin token
TOKEN=$(curl -s -X POST https://app.stoar.ai/rest/V1/integration/admin/token \
-H 'Content-Type: application/json' \
-d '{"username":"[email protected]","password":"your-password"}' \
| tr -d '"')
# 2. List the most recent 5 orders
curl -s "https://app.stoar.ai/rest/V1/orders?searchCriteria[pageSize]=5" \
-H "Authorization: Bearer $TOKEN" \
| jq '.items[] | {entity_id, increment_id, status, grand_total}'
# 3. Fetch a single order
curl -s "https://app.stoar.ai/rest/V1/orders/123" \
-H "Authorization: Bearer $TOKEN" \
| jq
Authentification #
En coulisses, l'adaptateur utilise les jetons d'accès personnels Laravel Sanctum, mais le flux exposé suit exactement le contrat Magento : POST des identifiants, réception d'une chaîne de jeton, envoi via Authorization: Bearer ….
| Type de jeton | Point de terminaison | TTL | Ability | Cas d'usage |
|---|---|---|---|---|
| Admin | POST /rest/V1/integration/admin/token |
4 h | magento:admin |
Opérations backend (lister les commandes, rembourser, annuler) |
| Client | POST /rest/V1/integration/customer/token |
1 h | magento:customer |
Intégrations boutique |
Tous les points de terminaison /rest/V1/orders/* exigent magento:admin. Un jeton client présenté sur ces points de terminaison renvoie 403.
Format du jeton
Un point de terminaison de jeton renvoie en cas de succès le jeton brut sous forme de scalaire JSON entre guillemets — le contrat Magento à la lettre :
HTTP/1.1 200 OK
Content-Type: application/json
"abc123def456…"
Utilise-le sur les requêtes suivantes :
Authorization: Bearer abc123def456…
Les jetons sont stockés dans personal_access_tokens (la table standard de Sanctum) et peuvent être révoqués à tout moment en supprimant la ligne correspondante, ou via $user->tokens()->delete() dans le code.
Points de terminaison #
Tous les chemins sont relatifs à /rest/V1 (préfixe Magento repris tel quel).
POST /rest/V1/integration/admin/token
Émet un jeton admin à partir des identifiants admin_users. Le nom d'utilisateur est comparé à la colonne email ou name.
Requête
POST /rest/V1/integration/admin/token
Content-Type: application/json
{ "username": "[email protected]", "password": "secret" }
Réponse (200)
"3|EsTmpYnjA…"
Erreurs
400— identifiants invalides, utilisateur inactif ou champs manquants
POST /rest/V1/integration/customer/token
Émet un jeton client à partir des identifiants stoar_shop_customers. Le nom d'utilisateur est l'adresse e-mail.
Requête
POST /rest/V1/integration/customer/token
Content-Type: application/json
{ "username": "[email protected]", "password": "secret" }
Réponse (200) — même structure que le jeton admin.
Erreurs
400— e-mail/mot de passe invalides, client inactif, champs manquants
GET /rest/V1/orders
Liste les commandes avec la prise en charge complète des requêtes searchCriteria[…] de Magento — voir Syntaxe des critères de recherche ci-dessous.
Authorization : jeton admin Bearer.
Réponse (200)
{
"items": [
{ /* full order object — see Response shape */ }
],
"search_criteria": {
"filter_groups": [...],
"sort_orders": [...],
"page_size": 20,
"current_page": 1
},
"total_count": 150
}
Valeurs par défaut
pageSizevaut 20 par défaut, plafonné à 500currentPagevaut 1 par défaut- Aucun filtre → toutes les commandes, les plus récentes d'abord (tri
id DESC)
GET /rest/V1/orders/{id}
Récupère une commande unique avec toutes ses relations : lignes, paiements, historiques de statut, adresses de facturation et de livraison.
Authorization : jeton admin Bearer.
Réponse (200) — voir Structure de la réponse.
Erreurs
404—{ "message": "No such entity with %fieldName = %fieldValue", "parameters": ["entity_id", "99999"] }
POST /rest/V1/orders/{id}/cancel
Annule une commande en attente ou payée. Déclenche le même flux que l'interface d'administration : passe le statut à cancelled, écrit une ligne d'historique de statut et libère les réservations de stock (lorsque la commande porte un session_id).
Authorization : jeton admin Bearer.
Requête : corps vide.
Réponse (200) — true
Erreurs
404— id de commande inconnu422— la commande est dans un état qui interdit l'annulation (p. ex.delivered,refunded)
GET /rest/V1/orders/{id}/comments
Liste l'historique de statut de la commande (Magento appelle ces entrées des « comments »).
Authorization : jeton admin Bearer.
Réponse (200)
{
"items": [
{
"entity_id": 42,
"parent_id": 123,
"comment": "Payment confirmed",
"status": "paid",
"created_at": "2026-04-10T12:00:00+00:00",
"is_customer_notified": false,
"is_visible_on_front": false,
"extension_attributes": { "old_status": "pending", "changed_by": "system" }
}
],
"search_criteria": { "filter_groups": [], "sort_orders": [], "page_size": 1, "current_page": 1 },
"total_count": 1
}
POST /rest/V1/orders/{id}/comments
Ajoute un commentaire à l'historique de statut sans modifier le statut de la commande.
Authorization : jeton admin Bearer.
Requête
{
"statusHistory": {
"comment": "Customer phoned to confirm delivery slot",
"is_customer_notified": false,
"is_visible_on_front": false
}
}
statusHistory.status est facultatif — s'il est omis, le statut de commande existant est conservé.
Réponse (200) — true
Erreurs
400—statusHistory.commentmanquant404— id de commande inconnu
POST /rest/V1/order/{id}/refund
Note — Magento utilise la forme singulière
/order/, et NON/orders/. L'adaptateur la reproduit à l'identique.
Émet un remboursement. STOAR délègue à la méthode existante Order::processRefund(), qui appelle Stripe via StripeService::processRefund(). La commande passe à refunded (remboursement total) ou reste dans son état payé courant avec refunded_amount cumulé (remboursement partiel).
Authorization : jeton admin Bearer.
Requête — remboursement total (omettre le corps ou arguments) :
{}
Requête — montant explicite :
{ "arguments": { "amount": 50.00 } }
Requête — par ligne (style Magento) :
{
"items": [
{ "order_item_id": 456, "qty": 1 },
{ "order_item_id": 457, "qty": 2 }
]
}
Lorsque items[] est fourni, le montant du remboursement est calculé à partir du price * qty enregistré pour chaque ligne. arguments.amount, s'il est fourni, prime sur ce calcul.
Réponse (200) — id d'avoir (entier). STOAR n'a pas d'entité avoir distincte : l'id de la commande est renvoyé à la place.
Erreurs
404— id de commande inconnu422— commande non remboursable (pas de payment intent Stripe, statut différent de paid/processing/shipped/delivered)
Syntaxe des critères de recherche #
Le point de terminaison GET /rest/V1/orders accepte l'intégralité de la grammaire search-criteria de Magento.
Structure
searchCriteria[filter_groups][N][filters][M][field|value|condition_type]
searchCriteria[sortOrders][N][field|direction]
searchCriteria[pageSize]
searchCriteria[currentPage]
Logique des filtres
- Les filtres d'un même
filter_groups[N]sont combinés par OR - Les
filter_groups[N]distincts sont combinés par AND
Exemple — commandes dont le status vaut paid OU shipped, ET dont le customer_email contient @example.com :
GET /rest/V1/orders
?searchCriteria[filter_groups][0][filters][0][field]=status
&searchCriteria[filter_groups][0][filters][0][value]=paid
&searchCriteria[filter_groups][0][filters][0][condition_type]=eq
&searchCriteria[filter_groups][0][filters][1][field]=status
&searchCriteria[filter_groups][0][filters][1][value]=shipped
&searchCriteria[filter_groups][0][filters][1][condition_type]=eq
&searchCriteria[filter_groups][1][filters][0][field]=customer_email
&searchCriteria[filter_groups][1][filters][0][value]=%[email protected]
&searchCriteria[filter_groups][1][filters][0][condition_type]=like
Opérateurs pris en charge
condition_type |
Signification | Exemple |
|---|---|---|
eq |
égal à | value=paid&condition_type=eq |
neq |
différent de | value=cancelled&condition_type=neq |
gt |
supérieur à | value=100&condition_type=gt |
gteq |
≥ | value=2026-01-01&condition_type=gteq |
lt |
inférieur à | |
lteq |
≤ | |
from |
début de plage (alias de gteq) |
|
to |
fin de plage (alias de lteq) |
|
like |
LIKE SQL ; les jokers % sont à ta charge |
value=%25%40example.com&condition_type=like |
in |
liste séparée par des virgules | value=paid,shipped,delivered&condition_type=in |
nin |
NOT IN | |
null |
IS NULL | (aucune value requise) |
notnull |
IS NOT NULL | |
finset |
correspondance de sous-chaîne au mieux |
Opérateurs non pris en charge ou champs inconnus → 400 avec un message explicatif.
Ordres de tri
searchCriteria[sortOrders][0][field]=created_at
searchCriteria[sortOrders][0][direction]=DESC
searchCriteria[sortOrders][1][field]=grand_total
searchCriteria[sortOrders][1][direction]=ASC
direction accepte ASC ou DESC (ASC par défaut). Plusieurs ordres de tri se composent de gauche à droite.
Pagination
searchCriteria[pageSize]=25 # max 500
searchCriteria[currentPage]=2 # 1-indexed
La réponse renvoie les valeurs réellement appliquées :
"search_criteria": { "page_size": 25, "current_page": 2 }
Correspondance des champs (Magento ↔ STOAR) #
L'adaptateur n'expose que les noms de champs Magento. En interne, chacun correspond à une colonne STOAR ou à une valeur calculée. Les champs absents de cette liste ne peuvent servir ni dans filter_groups ni dans sortOrders — toute tentative renvoie 400.
Filtrables / triables
| Champ Magento | Source STOAR | Remarques |
|---|---|---|
entity_id |
id |
|
increment_id |
id |
traité comme numérique au filtrage (le préfixe ORD- n'est utilisé qu'à l'affichage) |
status |
status |
|
state |
status |
STOAR fusionne le state de Magento dans status |
customer_id |
customer_id |
|
customer_email |
customer_email |
|
customer_firstname |
customer_info->first_name |
résolu via JSON_EXTRACT MariaDB |
customer_lastname |
customer_info->last_name |
idem |
grand_total |
total_amount |
|
subtotal |
subtotal |
|
tax_amount |
tax_amount |
|
shipping_amount |
shipping_amount |
|
discount_amount |
discount_amount |
|
coupon_code |
coupon_code |
|
currency_code |
currency |
|
order_currency_code |
currency |
|
created_at |
created_at |
|
updated_at |
updated_at |
En réponse uniquement (champs en lecture)
Ces champs apparaissent dans la réponse JSON mais ne peuvent servir de champs de filtre ou de tri :
total_paid,total_refunded— dérivés des lignesOrderPayment+refunded_amountcustomer_is_guest—customer_id === nullitems[],billing_address,shipping_address,payment,status_histories[]- Tous les totaux
base_*— STOAR est monodevise, doncbase_grand_total === grand_total
Dérivation du state
status STOAR |
state Magento |
|---|---|
pending |
new |
paid, processing, shipped, delivered |
processing |
cancelled |
canceled |
refunded |
closed |
Structure de la réponse #
Une réponse de commande complète (tronquée par souci de concision) :
{
"entity_id": 123,
"increment_id": "ORD-000123",
"state": "processing",
"status": "paid",
"customer_id": 45,
"customer_email": "[email protected]",
"customer_firstname": "Jane",
"customer_lastname": "Doe",
"customer_group_id": 0,
"customer_is_guest": false,
"base_currency_code": "EUR",
"currency_code": "EUR",
"order_currency_code": "EUR",
"grand_total": 115.0,
"base_grand_total": 115.0,
"subtotal": 100.0,
"base_subtotal": 100.0,
"tax_amount": 10.0,
"base_tax_amount": 10.0,
"shipping_amount": 5.0,
"base_shipping_amount": 5.0,
"discount_amount": 0.0,
"base_discount_amount": 0.0,
"total_paid": 115.0,
"total_refunded": 0.0,
"base_total_paid": 115.0,
"base_total_refunded": 0.0,
"shipping_description": "Standard",
"shipping_incl_tax": 5.0,
"base_shipping_incl_tax":5.0,
"created_at": "2026-04-10T09:00:00+00:00",
"updated_at": "2026-04-10T09:30:00+00:00",
"is_virtual": false,
"weight": 0,
"store_id": 1,
"coupon_code": null,
"items": [
{
"item_id": 456,
"order_id": 123,
"product_id": 789,
"product_type": "simple",
"sku": "WID-1-A",
"name": "Widget",
"qty_ordered": 2.0,
"qty_invoiced": 0.0,
"qty_shipped": 0.0,
"qty_refunded": 0.0,
"qty_canceled": 0.0,
"price": 50.0,
"base_price": 50.0,
"price_incl_tax": 55.0,
"row_total": 100.0,
"row_total_incl_tax":110.0,
"tax_amount": 10.0,
"tax_percent": 10.0,
"discount_amount": 0,
"extension_attributes": { "variant_id": 12 }
}
],
"billing_address": {
"entity_id": null,
"parent_id": 123,
"address_type": "billing",
"email": "[email protected]",
"firstname": "Jane",
"lastname": "Doe",
"street": "1 Test St",
"city": "Berlin",
"country_id": "DE",
"postcode": "10115",
"region": null,
"telephone": "+49…"
},
"shipping_address": { /* same shape, address_type="shipping" */ },
"payment": {
"entity_id": null,
"parent_id": 123,
"method": "stripe",
"base_amount_paid": 115.0,
"base_amount_refunded": 0.0,
"cc_trans_id": "pi_test_…",
"extension_attributes": {
"payments": [
{ "id": 1, "gateway": "stripe", "amount": 115.0, "currency": "eur",
"status": "succeeded", "reference": "pi_test_…", "archived_at": null,
"created_at": "2026-04-10T09:05:00+00:00" }
]
}
},
"status_histories": [
{
"entity_id": 1,
"parent_id": 123,
"comment": null,
"status": "pending",
"created_at": "2026-04-10T09:00:00+00:00",
"extension_attributes": { "old_status": null, "changed_by": "System" }
},
{
"entity_id": 2,
"parent_id": 123,
"comment": "Payment confirmed via webhook",
"status": "paid",
"created_at": "2026-04-10T09:05:00+00:00",
"extension_attributes": { "old_status": "pending", "changed_by": "System" }
}
],
"extension_attributes": {
"lookup_token": "abc…",
"tracking_number": null,
"tracking_url": null,
"tracking_carrier": null,
"shipment_status": null,
"admin_notes": null,
"customer_notes": null
}
}
Exemple réel #
Voici une réponse réelle capturée en production pour GET /rest/V1/orders/10126 — une commande payée de USD $936.98 avec deux lignes de produits simples. Les données personnelles (e-mail, téléphone, jeton de consultation, adresse postale exacte) ont été anonymisées ; tout le reste est fidèle à l'original.
Requête
GET /rest/V1/orders/10126
Authorization: Bearer 1|vYuVLH4wvkSFfhwAVHGhzVMkOVbKkw8S5gKjVU5o9212c81b
Réponse (200)
{
"entity_id": 10126,
"increment_id": "ORD-010126",
"state": "processing",
"status": "paid",
"customer_id": 5794,
"customer_email": "[email protected]",
"customer_firstname": "Jane",
"customer_lastname": "Doe",
"customer_group_id": 0,
"customer_is_guest": false,
"base_currency_code": "USD",
"currency_code": "USD",
"order_currency_code": "USD",
"grand_total": 936.98,
"base_grand_total": 936.98,
"subtotal": 936.98,
"base_subtotal": 936.98,
"tax_amount": 0,
"base_tax_amount": 0,
"shipping_amount": 0,
"base_shipping_amount": 0,
"discount_amount": 0,
"base_discount_amount": 0,
"total_paid": 0,
"total_refunded": 0,
"base_total_paid": 0,
"base_total_refunded": 0,
"shipping_description": "Free Shipping",
"shipping_incl_tax": 0,
"base_shipping_incl_tax":0,
"created_at": "2025-06-03T04:56:43+00:00",
"updated_at": "2025-06-03T04:56:43+00:00",
"is_virtual": false,
"weight": 0,
"store_id": 1,
"coupon_code": null,
"items": [
{
"item_id": 30219,
"order_id": 10126,
"product_id": 112238,
"product_type": "simple",
"sku": "RELOOP_TERMINALMIX8_025-DEF",
"name": "Reloop Terminal Mix 8",
"qty_ordered": 3,
"qty_invoiced": 0,
"qty_shipped": 0,
"qty_refunded": 0,
"qty_canceled": 0,
"price": 299,
"base_price": 299,
"price_incl_tax": 299,
"base_price_incl_tax": 299,
"original_price": 299,
"base_original_price": 299,
"row_total": 897,
"base_row_total": 897,
"row_total_incl_tax": 897,
"base_row_total_incl_tax":897,
"discount_amount": 0,
"base_discount_amount": 0,
"discount_percent": 0,
"tax_amount": 0,
"base_tax_amount": 0,
"tax_percent": 0,
"amount_refunded": 0,
"base_amount_refunded": 0,
"row_weight": 0,
"created_at": "2025-06-03T04:56:43+00:00",
"updated_at": "2025-06-03T04:56:43+00:00",
"is_qty_decimal": false,
"no_discount": false,
"parent_item_id": null,
"extension_attributes": { "variant_id": 95589 }
},
{
"item_id": 30220,
"order_id": 10126,
"product_id": 51706,
"product_type": "simple",
"sku": "SK8-SOCK-027-DEF",
"name": "Premium Skateboard Socks",
"qty_ordered": 2,
"qty_invoiced": 0,
"qty_shipped": 0,
"qty_refunded": 0,
"qty_canceled": 0,
"price": 19.99,
"base_price": 19.99,
"price_incl_tax": 19.99,
"base_price_incl_tax": 19.99,
"original_price": 19.99,
"base_original_price": 19.99,
"row_total": 39.98,
"base_row_total": 39.98,
"row_total_incl_tax": 39.98,
"base_row_total_incl_tax":39.98,
"discount_amount": 0,
"base_discount_amount": 0,
"discount_percent": 0,
"tax_amount": 0,
"base_tax_amount": 0,
"tax_percent": 0,
"amount_refunded": 0,
"base_amount_refunded": 0,
"row_weight": 0,
"created_at": "2025-06-03T04:56:43+00:00",
"updated_at": "2025-06-03T04:56:43+00:00",
"is_qty_decimal": false,
"no_discount": false,
"parent_item_id": null,
"extension_attributes": { "variant_id": 33857 }
}
],
"billing_address": {
"entity_id": null,
"parent_id": 10126,
"address_type": "billing",
"email": null,
"firstname": "Jane",
"lastname": "Doe",
"middlename": null,
"prefix": null,
"suffix": null,
"street": "1 Example Street",
"city": "Phoenix",
"country_id": "US",
"postcode": "85001",
"region": "AZ",
"region_code": "AZ",
"region_id": null,
"telephone": "+1-555-0100",
"fax": null,
"company": null,
"customer_address_id": null
},
"shipping_address": {
"entity_id": null,
"parent_id": 10126,
"address_type": "shipping",
"email": null,
"firstname": "Jane",
"lastname": "Doe",
"middlename": null,
"prefix": null,
"suffix": null,
"street": "1 Example Street",
"city": "Phoenix",
"country_id": "US",
"postcode": "85001",
"region": "AZ",
"region_code": "AZ",
"region_id": null,
"telephone": "+1-555-0100",
"fax": null,
"company": null,
"customer_address_id": null
},
"payment": {
"entity_id": null,
"parent_id": 10126,
"base_amount_authorized": 936.98,
"base_amount_paid": 0,
"base_amount_refunded": 0,
"base_shipping_amount": 0,
"base_shipping_captured": 0,
"base_shipping_refunded": 0,
"billing_address_id": null,
"cc_avs_status": null,
"cc_cid_status": null,
"cc_exp_month": null,
"cc_exp_year": null,
"cc_last4": null,
"cc_number_enc": null,
"cc_owner": null,
"cc_status": null,
"cc_status_description": null,
"cc_trans_id": null,
"created_at": null,
"updated_at": null,
"method": "payid",
"po_number": null,
"protection_eligibility": null,
"quote_payment_id": null,
"extension_attributes": { "payments": [] }
},
"status_histories": [],
"extension_attributes": {
"lookup_token": "REDACTED-FOR-DOCS",
"tracking_number": null,
"tracking_url": null,
"tracking_carrier": null,
"shipment_status": null,
"admin_notes": null,
"customer_notes": null
}
}
Ce que cet exemple révèle du contrat
Quelques points de cette réponse réelle méritent d'être signalés, car ils peuvent surprendre les intégrateurs :
| Champ | Observé | Pourquoi cela peut sembler « faux » |
|---|---|---|
total_paid, payment.base_amount_paid |
0 |
Le status de la commande est paid, mais son journal d'audit OrderPayment est vide. L'adaptateur calcule total_paid comme la somme des lignes OrderPayment réussies et non archivées — il ne déduit pas le montant payé du seul statut de la commande. Les commandes antérieures à l'audit des paiements renverront 0 ici même si elles sont payées. |
payment.method |
"payid" |
Il s'agit de la clé de passerelle STOAR, pas d'un nom de méthode canonique Magento. Les valeurs possibles incluent stripe, bank_transfer, cash_on_delivery, payid, invoice, ainsi que toute passerelle personnalisée enregistrée via GatewayRegistry. |
status_histories |
[] |
Les journaux de statut ont été introduits après la création de certaines commandes historiques : les commandes anciennes renvoient donc un tableau vide. Les commandes nouvellement créées comportent toujours au moins une entrée (le statut initial pending). |
qty_invoiced, qty_shipped, qty_refunded, qty_canceled |
0 pour toutes les lignes |
STOAR n'a pas d'entités Invoice/Shipment distinctes : les compteurs de traitement par ligne sont toujours rapportés à 0. Utilise plutôt les champs total_refunded et status au niveau de la commande. |
coupon_code |
null |
Renseigné uniquement si la commande a été passée avec un code de réduction. Sans rapport avec les remises issues des règles panier. |
customer_id + customer_is_guest: false |
tous deux renseignés | Lorsque la commande a été passée par un client connecté. Les commandes invité renvoient customer_id: null et customer_is_guest: true. |
weight |
0 |
STOAR ne suit pas le poids par commande ; le champ n'est présent que pour la compatibilité avec les clients Magento. |
store_id |
1 |
STOAR est monoboutique ; ce champ vaut toujours 1. |
extension_attributes.lookup_token |
masqué | C'est le jeton « magic link » propre à chaque commande, utilisé par les pages de suivi de commande invité. Ne l'expose jamais dans du code client ni dans des journaux publics — sa seule possession suffit à consulter la commande sans authentification. |
Structure des erreurs #
Toute erreur /rest/V1/* suit l'enveloppe Magento :
{
"message": "Human message with %fieldName placeholders",
"parameters": ["fieldName", "fieldValue"],
"trace": "…stack trace…"
}
parameters s'aligne sur les marqueurs %1, %2 ou %fieldName présents dans message, afin que les clients localisés puissent y substituer des valeurs.
trace n'est inclus que lorsque APP_DEBUG=true.
| HTTP | Déclencheur | Exemple |
|---|---|---|
| 400 | entrée incorrecte — champ de filtre inconnu, condition_type non pris en charge, échec de validation |
{ "message": "Unsupported condition_type: zorp" } |
| 401 | jeton manquant ou invalide | { "message": "Consumer is not authorized to access %resources", "parameters": ["Magento_Sales::sales"] } |
| 403 | jeton avec la mauvaise ability (p. ex. jeton client sur un point de terminaison admin) | { "message": "The consumer does not have access to the requested resource." } |
| 404 | id de commande inconnu | { "message": "No such entity with %fieldName = %fieldValue", "parameters": ["entity_id", "99999"] } |
| 422 | précondition non satisfaite (annulation impossible, remboursement impossible) | { "message": "Order 5 cannot be cancelled in status 'delivered'." } |
| 500 | erreur serveur inattendue | { "message": "Internal server error." } (le mode debug affiche le message réel) |
Voir aussi #
- Référence REST Adobe Commerce — la spécification amont que reproduit cet adaptateur