Les acheteurs passent des commandes dans leur portail commercial. Les fournisseurs gèrent les factures. Ils peuvent proposer en option paiements clients hébergés par Stripe après avoir confirmé le total final. Les demandes de commande et le crédit commercial restent disponibles. Utilisez l'API pour récupérer les commandes dans votre ERP ou système de comptabilité et pour maintenir leur statut à jour.
Statuts des commandesLien vers cette section#
| Statut | Signification |
|---|---|
new | Passée |
pending | En attente |
acknowledged | Consultée et en cours de préparation |
processed | Prête pour l'expédition |
dispatched | Expédiée par le fournisseur |
completed | Fournisseur marqué comme terminé |
cancelled | Annulée avec une raison visible par le client |
Le personnel peut sauter les étapes intermédiaires de préparation. Le fait de revenir en arrière ou de rouvrir une commande terminée ou annulée nécessite un correctionReason interne. L'historique précédent reste. Les corrections n'altèrent jamais l'état de paiement. Lisez revision et envoyez expectedRevision avec les mises à jour pour rejeter les modifications obsolètes.
Créer une commande pour un clientLien vers cette section#
POST/api/v1/orders/previewclé d'écriture
Exige orders.create et l'accès au client. Envoyez customerAccountId et lines contenant productId et un entier qty (1 à 1 000 000). Choisissez chaque produit ordinaire une seule fois, au maximum 100 lignes. Une ligne peut inclure un configuration optionnel contenant les clés de mesure et de choix retournées ; différentes configurations d'un même produit restent séparées. Un lineKey optionnel donne à chaque ligne de prévisualisation une identité stable. Un additionalDiscountBp supplémentaire nécessite une autorisation de tarification et discountReason. Les lectures de commande configurées incluent un configuration instantané immuable avec les entrées, la spécification, la version, le fractionnement et les frais. La prévisualisation retourne total, fingerprint, les prix actuels du client et la devise. Les comptes en pause, les produits indisponibles et les quantités inférieures au minimum sont refusés. Un catalogue uniquement prix accepte toujours une commande entrée ici ; les acheteurs ne peuvent pas en envoyer un eux-mêmes tant que cela est désactivé.
POST/api/v1/ordersclé d'écriture
Envoyez le même client et les mêmes lignes, expectedTotal depuis la prévisualisation, expectedBasket défini sur son empreinte, et un UUID frais requestKey. Les poNumber facultatifs (60 caractères) et les notes visibles par le client (2 000 caractères) sont pris en charge. Réutilisez exactement la même demande et la même clé après une réponse incertaine : une tentative de réessai réussie retourne la commande originale au lieu d'en créer une autre. Les prix modifiés nécessitent une autre revue. Le résultat est placed avec orderId et reference, ou prices_changed, empty ou unavailable.
Le personnel agit sous son propre identifiant. Le panier du client reste intact. Les contacts par courriel du client peuvent recevoir une copie ; cela ne génère pas de paiement. Le représentant commercial a par défaut les droits de création ; les mises à jour de traitement et de livraison nécessitent la permission séparée orders.process.
Livraison et suiviLien vers cette section#
PATCH/api/v1/orders/{id}/deliveryclé d'écriture
Requiert orders.process. Envoyez deliveryMethod : unspecified, courier, own_delivery ou collection. Les courierName facultatifs (100 caractères), trackingReference (120 caractères) et trackingUrl (1 000 caractères) sont visibles par le client. Les liens de suivi doivent utiliser HTTPS sans identifiants de connexion intégrés. Les détails facultatifs omis les effacent. Envoyez expectedRevision depuis la commande actuelle. Il y a un enregistrement de livraison par commande ; les intégrations de transporteurs et les envois fractionnés ne sont pas incluses. Les détails de transporteur vides n'impliquent jamais une livraison interne.
Liste des commandesLien vers cette section#
GET/api/v1/orders
Commandes les plus récentes en premier. La liste couvre les 200 commandes les plus récentes correspondant à vos filtres. Pour récupérer de nouvelles commandes, interrogez avec status=new.
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
status | chaîne | non | L'un des statuts ci-dessus. |
customer | chaîne | non | Identifiant client ou code de compte. |
limit | entier | non | 1 à 100. Valeur par défaut 100. |
offset | entier | non | Lignes à ignorer. Valeur par défaut 0. |
curl "https://tradecatalog.app/api/v1/orders?status=new" \
-H "Authorization: Bearer $TRADECATALOG_API_KEY"
const res = await fetch('https://tradecatalog.app/api/v1/orders?status=new', {
headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: orders } = await res.json()
{
"data": [
{
"id": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
"reference": "SO-000142",
"status": "new",
"total": 31460,
"currency": "GBP",
"poNumber": "PO-88231",
"createdAt": "2026-09-27T07:48:12.000Z",
"customer": "Oakfield Joinery"
}
],
"nextOffset": null
}
| Champ | Type | Description |
|---|---|---|
id | chaîne | Identifiant de la commande. |
reference | chaîne | Numéro de commande vu par les acheteurs, comme SO-000142. |
status | chaîne | Voir statuts. |
total | entier | Montant total de la commande selon les prix (voir taxLabel), en unités mineures de currency. |
currency | chaîne | Date à laquelle la commande a été passée. |
poNumber | chaîne ou null | Numéro de commande du client. |
createdAt | chaîne | Date à laquelle la commande a été passée. |
customer | chaîne | Nom du client. Obtenez le code de compte à partir de GET /orders/{id}. |
Obtenir une commandeLien vers cette section#
GET/api/v1/orders/{id}
La commande avec ses lignes et son historique des statuts.
| Nom | Dans | Type | Requis | Description |
|---|---|---|---|---|
id | chemin | chaîne | oui | Identifiant de la commande. |
curl https://tradecatalog.app/api/v1/orders/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e \
-H "Authorization: Bearer $TRADECATALOG_API_KEY"
const res = await fetch(`https://tradecatalog.app/api/v1/orders/${orderId}`, {
headers: { Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}` },
})
const { data: order } = await res.json()
{
"data": {
"id": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
"customerAccountId": "7d2e4f0a-1b3c-4d5e-8f90-a1b2c3d4e5f6",
"placedBy": "Fq3L0cZ7tN1pW9aYx2Rk",
"reference": "SO-000142",
"poNumber": "PO-88231",
"notes": "Deliver to the Hebden Road site, gate 2.",
"status": "new",
"cancelReason": null,
"currency": "GBP",
"total": 31460,
"createdAt": "2026-09-27T07:48:12.000Z",
"updatedAt": "2026-09-27T07:48:12.000Z",
"customer": { "name": "Oakfield Joinery", "accountCode": "OAK01" },
"lines": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"orderId": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
"productId": "3f8a2c1e-9b4d-4e6f-a7c8-1d2e3f4a5b6c",
"sku": "HX-8510",
"name": "Hex bolt M10 x 50 zinc",
"unitLabel": "Box of 100",
"qty": 20,
"unitPrice": 1573,
"listPrice": 1850,
"priceLabel": "Brand discount −15%",
"lineTotal": 31460
}
],
"events": [
{
"status": "new",
"note": null,
"createdAt": "2026-09-27T07:48:12.000Z",
"actor": "Sam Patel"
}
]
}
}
| Champ | Description |
|---|---|
customerAccountId | L'identifiant du client. |
placedBy | L'identifiant de la personne qui l'a saisie. source distingue les commandes des clients et celles du personnel. |
notes | Les notes de livraison ou d'commande du client. |
cancelReason | La raison de l'annulation, si applicable. |
lines | Ce qui a été commandé à quel prix. Une capture d'écran : les changements de prix ultérieurs n'affectent pas cette valeur. productId est null si le produit a depuis été supprimé. |
lines[].priceLabel | La règle qui a fixé le prix, comme sur Prix. |
lines[].priceLabel est Price on request | Le produit n'a pas de prix : unitPrice et lineTotal sont 0 et la ligne n'est pas dans total. Le fournisseur confirme son prix. |
events | Historique des statuts, du plus ancien au plus récent. actor est le nom de la personne, ou null. |
Mettre à jour ou corriger une commandeLien vers cette section#
PATCH/api/v1/orders/{id}clé d'écriture
Modifie le statut d'une commande. Retourne la commande mise à jour sous la même forme que GET /orders/{id}.
- Les mouvements normaux vers l'avant suivent les étapes de traitement ci-dessus. Les autres mouvements nécessitent une raison de correction privée ; un statut actuel répété ne provoque aucun changement.
- L'annulation nécessite un
note, qui est affiché au client comme raison. - Les changements de statut peuvent envoyer un courriel aux contacts clients, y compris la note publique. Un courriel généré ne prouve pas la livraison.
- Le changement est enregistré dans l'historique de la commande contre la personne ayant effectué la clé.
| Nom | Dans | Type | Requis | Description |
|---|---|---|---|---|
id | chemin | chaîne | oui | Identifiant de la commande. |
status | corps | chaîne | oui | Nouveau statut. |
note | corps | chaîne | non | Jusqu'à 1 000 caractères. Requis lors de l'annulation. |
curl -X PATCH https://tradecatalog.app/api/v1/orders/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e \
-H "Authorization: Bearer $TRADECATALOG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "dispatched", "note": "DPD tracking 1554 2210 0931" }'
const res = await fetch(`https://tradecatalog.app/api/v1/orders/${orderId}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.TRADECATALOG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: 'acknowledged' }),
})
const { data: order } = await res.json()
| Statut | Code | Quand |
|---|---|---|
| 400 | invalid_request | Le mouvement n'est pas autorisé, par exemple « Une commande reçue ne peut pas être marquée comme terminée », ou l'annulation sans note. |
| 403 | insufficient_scope | La clé est en lecture seule. |
| 404 | not_found | Aucune commande de ce type dans cet espace de travail. |
La tentative de PATCH qui a déjà réussi retourne 400 invalid_request, car la commande a évolué. Vérifiez le statut de la commande avant de la considérer comme une erreur.
Non disponibleLien vers cette section#
L'API ne peut pas passer de commandes pour un acheteur, ni modifier les lignes, les quantités ou les prix d'une commande. Les acheteurs passent leurs commandes dans leur portail de commerce ; les modifications d'une commande sont convenues avec le client et facturées dans votre propre système.
Les listes de commandes incluent également paymentStatus : null pour les conditions habituelles de compte, ou le statut de paiement Stripe facultatif. Le statut de livraison est séparé et ne prouve jamais le paiement. La page détaillée de la commande est l'endroit où il faut revoir le total final confirmé et approuver le paiement. L'API ne peut pas créer ou approuver un paiement.
internalNote (2 000 caractères) et correctionReason (1 000 caractères) sont des champs d'historique réservés au personnel. note reste public, y compris les anciennes notes. Envoyez expectedRevision pour rejeter une édition concurrente avec une demande non valide. Les lectures de l'API pour le personnel incluent l'historique privé ; les lectures des outils d'acheteur et du portail excluent les identités du personnel et les champs privés. L'annulation nécessite toujours une raison publique et le retrait ou le remboursement intégral d'un paiement en attente.