DocumentationAPI RESTAPI Commandes

API Commandes

Récupérez et gérez les commandes importées de tous les canaux de vente avec mises à jour de statut et filtrage.

7 min de lecture

Sur cette page

Vue d'ensemble

Les commandes arrivent dans Kataio depuis tous les canaux de vente connectés. L'API Commandes fournit un accès en lecture aux données de commandes et permet de mettre à jour les statuts. Les changements de statut sont automatiquement synchronisés vers le canal d'origine.

Lister les commandes

GET https://app.kataio.com/api/v1/orders?page=1&limit=20&status=PROCESSING&channelId=ch_01...
Authorization: Bearer {accessToken}

Paramètres de requête

  • page / limit — Pagination (par défaut : page 1, limit 20)
  • status — Filtrer : PENDING, PROCESSING, PARTIALLY_SHIPPED, SHIPPED, DELIVERED, CANCELLED, RETURNED
  • channelId — Filtrer par canal d'origine
  • customerId (depuis v2.3) — Filtrer par client canonique (UUID).
  • customerEmail (depuis v2.3) — Filtrer par email (insensible à la casse). Utile pour les commandes invitées sans fiche client.
  • createdAtGte / createdAtLte (depuis v2.3) — Bornes inférieure / supérieure ISO 8601 sur createdAt. Alias cohérent de dateFrom / dateTo.
  • search — Recherche par numéro de commande ou nom du client
  • dateFrom / dateTo — Filtrer par plage de dates (ISO 8601). Équivalent à createdAtGte / createdAtLte ; les deux sont acceptés.
  • sortBy — Trier par : createdAt, total, orderNumber
  • sortOrder — asc ou desc

Réponse (200)

{
  "data": [
    {
      "id": "ord_01...",
      "orderNumber": "ORD-2026-001542",
      "status": "PROCESSING",
      "channelId": "ch_01...",
      "channelName": "Boutique Shopify FR",
      "channelType": "SHOPIFY",
      "customer": {
        "name": "Marie Dupont",
        "email": "marie.dupont@example.com",
        "phone": "+33 6 12 34 56 78"
      },
      "shippingAddress": {
        "line1": "15 Rue de la Paix",
        "line2": "Apt 3B",
        "city": "Paris",
        "postalCode": "75002",
        "country": "FR"
      },
      "items": [
        {
          "productId": "prod_01...",
          "name": "Chemise Oxford Bleue - Taille M",
          "sku": "CHM-OXF-BLU-M",
          "quantity": 2,
          "unitPrice": 49.90,
          "lineTotal": 99.80
        }
      ],
      "subtotal": 99.80,
      "shippingCost": 5.90,
      "tax": 21.14,
      "total": 126.84,
      "currency": "EUR",
      "createdAt": "2026-03-14T16:23:00.000Z",
      "updatedAt": "2026-03-15T09:00:00.000Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 156,
    "totalPages": 8
  }
}

Obtenir une commande

GET https://app.kataio.com/api/v1/orders/ord_01...
Authorization: Bearer {accessToken}

Retourne l'objet commande complet tel que montré ci-dessus, incluant tous les articles, les informations client, l'adresse de livraison et l'historique complet des statuts.

Créer une commande

Envoyez une commande dans Kataio depuis votre propre checkout, marketplace ou back-office. Requiert le scope write:orders.

POST https://app.kataio.com/api/v1/orders
Authorization: Bearer {accessToken}
Content-Type: application/json
Idempotency-Key: ord_2026-04-22_CNB-AB12CD

{
  "customerName": "Marie Dupont",
  "customerEmail": "marie.dupont@example.com",
  "externalReference": "CNB-AB12CD",
  "initialStatus": "PROCESSING",
  "currency": "EUR",
  "items": [
    { "sku": "CHM-OXF-BLU-M", "quantity": 2, "unitPrice": 49.90 }
  ],
  "shippingAddress": { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
  "billingAddress":  { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
  "paymentMetadata": { "stripePaymentIntentId": "pi_3OaBcDxxx", "stripeChargeId": "ch_3OaBcDxxx" },
  "notes": "Livraison urgente — client VIP"
}

Corps de la requête

  • customerName (requis) — nom affiché.
  • customerId (depuis v2.3) — UUID du client canonique. Prioritaire sur customerEmail si les deux sont fournis.
  • customerEmail — crée ou met à jour automatiquement un client et le lie à la commande. Depuis v2.3 : l'upsert émet customer.created.
  • items[].sku, items[].quantity, items[].unitPrice (requis) — les lignes sont résolues par SKU (les SKU de variantes sont acceptés).
  • items[].name (depuis v2.3, optionnel) — surcharge le nom affiché de la ligne (ex. nom localisé depuis votre boutique). Persisté sur l'item et renvoyé à chaque lecture.
  • currency — ISO 4217, EUR par défaut.
  • externalReference — votre propre numéro de commande (ex. CNB-AB12CD). Unique par tenant — les doublons retournent 409. Renvoyé sur chaque lecture.
  • initialStatus — enregistre la commande directement en PROCESSING, SHIPPED, etc. Par défaut PENDING. Utilisez PROCESSING lorsque le paiement a déjà été encaissé côté checkout (Stripe, etc.) pour éviter un aller-retour.
  • shippingAddress / billingAddress — objets JSON libres ; la facturation reprend la livraison si omise.
  • paymentMetadata — JSON libre pour les identifiants PSP (ex. stripePaymentIntentId). Conservé et renvoyé tel quel.
  • notes — notes internes.

Idempotence

Passez un header Idempotency-Key (chaîne libre ≤255 caractères) pour rendre POST /orders sûr à rejouer. La première requête est traitée normalement et la réponse est mise en cache pendant 24 heures. Les requêtes suivantes avec la même clé rejouent la réponse à l'identique (statut 201 + header Idempotent-Replay: true). Même clé + corps différent → 409 Conflict ; générez une nouvelle clé si vous vouliez créer une autre commande.

Workers en file d'attente : générez une clé d'idempotence par commande logique (ex. ord_{votreOrderId}) et réessayez en cas d'échec réseau avec la même clé. La seconde tentative rejouera la réponse d'origine sans créer de doublon — même si la réponse de la première requête s'est perdue en route.

Réponse (201)

{
  "data": {
    "id": "894c736a-7471-4848-b094-24bddf471730",
    "externalId": "CNB-AB12CD",
    "externalReference": "CNB-AB12CD",
    "status": "PROCESSING",
    "totalAmount": "99.80",
    "currency": "EUR",
    "customerName": "Marie Dupont",
    "customerEmail": "marie.dupont@example.com",
    "shippingAddress": { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
    "billingAddress":  { "line1": "15 Rue de la Paix", "city": "Paris", "zip": "75002", "country": "FR" },
    "paymentMetadata": { "stripePaymentIntentId": "pi_3OaBcDxxx", "stripeChargeId": "ch_3OaBcDxxx" },
    "itemCount": 1,
    "createdAt": "2026-04-22T10:15:03.000Z"
  }
}

Erreurs

  • 400 — erreur de validation (items manquants, statut invalide, etc.).
  • 409 — externalReference en doublon ou conflit Idempotency-Key. Le corps de la réponse nomme l'id de la commande existante.

Mettre à jour le statut d'une commande

Faites progresser une commande dans son cycle de vie. La mise à jour du statut est synchronisée vers le canal de vente d'origine.

PATCH https://app.kataio.com/api/v1/orders/ord_01.../status
Authorization: Bearer {accessToken}
Content-Type: application/json

{
  "status": "SHIPPED",
  "trackingNumber": "COLISSIMO-FR-9876543210",
  "trackingUrl": "https://www.laposte.fr/outils/suivre-vos-envois?code=9876543210",
  "note": "Expédié via Colissimo le 15/03/2026"
}

Transitions de statut

  • PENDING → PROCESSING ou CANCELLED
  • PROCESSING → PARTIALLY_SHIPPED (via les expéditions), SHIPPED ou CANCELLED
  • PARTIALLY_SHIPPED → SHIPPED (dernier colis) ou CANCELLED
  • SHIPPED → DELIVERED ou RETURNED
  • DELIVERED → RETURNED
  • CANCELLED et RETURNED sont terminaux.

Modifier les lignes d'une commande

Depuis v2.12. Remplace les lignes d'une commande qui n'a pas commencé sa préparation : autorisé tant que le statut est PENDING ou PROCESSING sans colis ni retour (409 sinon). C'est un remplacement complet — les lignes avec un id sont mises à jour, celles sans id ajoutées, les lignes existantes absentes supprimées — un seul appel est donc idempotent pour votre intégration.

PUT /api/v1/orders/{id}/items
{
  "items": [
    { "id": "c3d4e5f6-7890-abcd-ef12-345678901234", "sku": "BACFERM-640", "quantity": 2, "unitPrice": 129.9 },
    { "sku": "OEILLET-INOX", "quantity": 22, "unitPrice": 0.6 }
  ],
  "shippingAmount": 5.9,
  "discountAmount": 0
}
  • items[] — obligatoire, même format que Créer une commande (sku, quantity, unitPrice, et en option name, description, metadata) plus un id optionnel. Un id inconnu répond 400.
  • shippingAmount, discountAmount, taxAmount — optionnels ; par défaut les valeurs actuelles de la commande. Sans taxAmount, la TVA est recalculée depuis le taxRate de la commande (null si elle n'en a pas).
  • Sous-total et total sont recalculés, les réservations de stock suivent le delta par ligne, le total dépensé du client bouge de la différence.
  • Retourne 200 avec la commande complète (même format que GET /orders/{id}). Émet order.updated.

Expéditions (livraison partielle)

Depuis v2.12. Une commande peut partir en plusieurs colis. Chaque colis est une expédition qui liste les lignes et quantités qu'il contient. Tant qu'il reste des quantités non expédiées, la commande est PARTIALLY_SHIPPED ; le colis qui expédie la dernière unité la passe en SHIPPED. Marquer une commande SHIPPED via PATCH /orders/{id}/status fonctionne toujours et crée une expédition pour tout ce qui reste.

POST /api/v1/orders/{id}/shipments
{
  "carrier": "Colissimo",
  "trackingNumber": "6A12345678901",
  "trackingUrl": "https://www.laposte.fr/outils/suivre-vos-envois?code=6A12345678901",
  "shippedAt": "2026-09-20T09:30:00.000Z",
  "notes": "Fragile",
  "items": [
    { "orderItemId": "c3d4e5f6-7890-abcd-ef12-345678901234", "quantity": 2 }
  ]
}
  • items — obligatoire, au moins une ligne. quantity ne peut pas dépasser la quantité restante de la ligne (400 Cannot ship 3 of SKU — only 2 remaining).
  • carrier, trackingNumber, trackingUrl, shippedAt (par défaut maintenant), notes — optionnels. Transporteur et suivi sont recopiés sur la commande (dernier colis).
  • Retourne 201 avec l'expédition ; 409 sur une commande annulée, retournée ou livrée.
GET    /api/v1/orders/{id}/shipments
DELETE /api/v1/orders/{id}/shipments/{shipmentId}

Supprimer un colis recalcule le statut (PARTIALLY_SHIPPED s'il reste d'autres colis, PROCESSING sinon). GET /orders/{id} renvoie shipments[] et une shippedQuantity sur chaque ligne.

Webhooks : chaque colis émet order.shipment_created (charge utile = l'expédition plus orderId, externalId, orderStatus) ; order.status_changed est émis à chaque transition et order.shipped une seule fois, quand la commande devient SHIPPED.

Synchronisation bidirectionnelle : Lorsque vous marquez une commande comme SHIPPED avec un numéro de suivi, Kataio pousse cette mise à jour vers le canal de vente. Le client reçoit une notification d'expédition de la plateforme où il a acheté.
Transitions invalides : Tenter une transition de statut invalide (par ex. SHIPPED → PROCESSING) retourne une erreur 422 Unprocessable Entity. L'API applique un flux de statut strict pour maintenir l'intégrité des données.