Commandes en JSON : schéma ph.order/1.2
Payload versionné de commandes ph.order/1.2 : schéma JSON publié, règles de compatibilité et exemples de livraison.
Lorsqu'une vente est confirmée, la commande est livrée dans l'intégration (webhook, SFTP ou e-mail) avec ce JSON canonique et versionné. Cette page est la spécification exacte du format ph.order/1.2.
Règles de format
- Toutes les clés sont toujours présentes ; les clés ne sont jamais omises.
- null signifie « donnée inconnue » ; il ne doit pas être interprété comme 0 (certains canaux ne détaillent pas les impôts par ligne).
- Les montants sont des nombres avec jusqu'à 2 décimales.
- tax_rate est un décimal : 0.21 équivaut à 21 %.
- channel est le code interne du canal (p. ex. ebay, wllp) et channel_name son nom visible (p. ex. Ebay, Wallapop).
- total_gross est le prix de vente pour le vendeur, commission du vendeur incluse : channel_fees_gross (ce que le canal lui retient sur ce montant) et buyer_fees_gross (ce que l'acheteur paie au canal en plus du prix, jamais dans total_gross) sont informatifs ; shipping_gross (transport) l'est aussi, et il peut être inclus ou non dans total_gross selon le canal (les lines donnent le détail de la marchandise).
Exemple de payload
{
"schema": "ph.order/1.2",
"order_id": "123456789",
"channel": "ebay",
"channel_name": "Ebay",
"created_at": "2026-06-18T10:32:00+00:00",
"status": "accepted",
"currency": "EUR",
"original_currency": "EUR",
"exchange_rate": 1.0,
"customer": {
"foreign_id": "a1b2c3d4",
"first_name": "Toni",
"last_name": "Bosch",
"company_name": null,
"email": "toni.bosch@example.com",
"tax_number": "12345678Z",
"phone": "+34600000000",
"address": {
"street": "Carrer Major 1",
"city": "Campdevànol",
"province": "Girona",
"postal_code": "17530",
"country": "ES"
}
},
"lines": [
{
"external_id": "ITEM-001",
"title": "Faro delantero izquierdo",
"quantity": 1,
"line_net": 100.00,
"line_tax": 21.00,
"line_gross": 121.00,
"tax_rate": 0.21
}
],
"shipping_gross": 10.00,
"channel_fees_gross": 13.00,
"buyer_fees_gross": null,
"total_net": 100.00,
"total_tax": 21.00,
"total_gross": 131.00,
"carrier": "Correos",
"tracking_code": "AB123456789ES",
"tracking_url": "https://tracking.example.com/AB123456789ES",
"payment_method": "card",
"source_account": null
}
Champs
| Champ | Type | Description |
|---|---|---|
schema | string | Identifiant du schéma et de sa version, « ph.order/MAJEUR.MINEUR » (aujourd'hui ph.order/1.2). Ne considérer que le majeur. |
order_id | string | Identifiant unique de la commande. |
channel | string | Code interne du canal de vente (p. ex. ebay, wllp). |
channel_name | string | Nom visible du canal de vente (p. ex. Ebay, Wallapop). |
created_at | string | null | Date et heure de création de la commande, au format ISO 8601. |
status | string | État de la commande (p. ex. accepted). Liste de valeurs ouverte. |
currency | string | null | Devise des montants de la commande au format ISO 4217 (p. ex. EUR). |
original_currency | string | null | Devise dans laquelle l'acheteur a payé, au format ISO 4217. Si elle diffère, la commande a été convertie et ses montants sont en currency. |
exchange_rate | number | null | Unités de original_currency que valait une unité de currency lors de la conversion de la commande (p. ex. 0.8346 livre par euro) ; 1 si elle n'a pas été convertie. |
customer | object | Données de l'acheteur (objet ; voir les champs plus bas). |
lines | array | Lignes de la commande, une par article (liste d'objets ; voir les champs plus bas). |
shipping_gross | number | null | Montant de l'expédition, impôts inclus. |
channel_fees_gross | number | null | Commission que le canal retient au vendeur pour la commande (informatif ; incluse dans total_gross, le canal la déduit du versement). |
buyer_fees_gross | number | null | Frais que l'acheteur paie au canal en plus du prix, p. ex. la protection de l'acheteur (informatif ; ne fait pas partie de total_gross). |
total_net | number | null | Base imposable totale de la commande (hors impôts). |
total_tax | number | null | Montant total des impôts de la commande. |
total_gross | number | null | Prix de vente pour le vendeur, impôts et commission du vendeur inclus (le transport peut être inclus ou non selon le canal). |
carrier | string | null | Transporteur de l'expédition. |
tracking_code | string | null | Code de suivi de l'expédition. |
tracking_url | string | null | URL de suivi de l'expédition. |
payment_method | string | null | Méthode de paiement (p. ex. card). Liste de valeurs ouverte. |
source_account | string | null | Compte d'origine sur le canal de vente, le cas échéant. |
customer.foreign_id | string | null | Identifiant de l'acheteur sur le canal d'origine. |
customer.first_name | string | null | Prénom de l'acheteur. |
customer.last_name | string | null | Nom de l'acheteur. |
customer.company_name | string | null | Raison sociale de l'acheteur, s'il s'agit d'une entreprise. |
customer.email | string | null | Adresse e-mail de l'acheteur. |
customer.tax_number | string | null | Identification fiscale de l'acheteur (NIF/CIF/VAT). |
customer.phone | string | null | Téléphone de l'acheteur. |
customer.address | object | Adresse de livraison de l'acheteur (objet ; voir les champs plus bas). |
customer.address.street | string | null | Rue et numéro de l'adresse de livraison. |
customer.address.city | string | null | Localité de l'adresse de livraison. |
customer.address.province | string | null | Province ou région de l'adresse de livraison. |
customer.address.postal_code | string | null | Code postal de l'adresse de livraison. |
customer.address.country | string | null | Pays de l'adresse de livraison, au format ISO 3166-1 alpha-2 (p. ex. ES). |
lines[].external_id | string | null | Identifiant de l'article dans le catalogue (SKU ou référence). |
lines[].title | string | null | Titre ou description de l'article. |
lines[].quantity | integer | null | Unités de l'article dans cette ligne. |
lines[].line_net | number | null | Base imposable de la ligne (hors impôts). |
lines[].line_tax | number | null | Montant des impôts de la ligne. |
lines[].line_gross | number | null | Montant de la ligne, impôts inclus. |
lines[].tax_rate | number | null | Taux d'imposition de la ligne en décimal (0.21 = 21 %). |
Compatibilité et versions
Pour ne pas avoir à retoucher l'intégration dans les versions futures, il convient de construire le lecteur en suivant ces règles :
- Versionnage : le champ schema est ph.order/MAJEUR.MINEUR (aujourd'hui ph.order/1.2). Ne considérer que le MAJEUR (le 1) et accepter n'importe quelle version mineure.
- Versions publiées : 1.0, le schéma initial. 1.1 ajoute buyer_fees_gross et fixe channel_fees_gross comme la commission que le canal facture au vendeur sur tous les canaux ; sur Wallapop, il contenait la protection de l'acheteur, qui passe à buyer_fees_gross. 1.2 ajoute original_currency et exchange_rate : une commande payée dans une autre devise arrive avec ses montants en euros, et ces champs indiquent dans quelle devise l'acheteur a payé et à quel taux.
- On n'ajoute que, on ne retire jamais : au sein de la version majeure 1, les changements sont additifs. De nouveaux champs pourront être ajoutés (toujours présents, avec null lorsqu'ils ne s'appliquent pas), mais un champ existant ne sera jamais supprimé, renommé, ni son type ou son sens modifiés. Seule exception : celle de 1.1 indiquée dans les versions publiées.
- Ignorer les champs non reconnus : le lecteur doit les écarter sans échouer (ne pas valider avec additionalProperties: false).
- Listes de valeurs ouvertes : dans status, channel, payment_method, currency et original_currency, de nouvelles valeurs peuvent apparaître ; traiter une valeur inconnue sans casser (p. ex. comme « autre »).
- Seul un changement de version MAJEURE (ph.order/2.0) exigerait une adaptation, et il serait annoncé à l'avance ; les versions mineures n'exigent aucun changement de la part du consommateur, sauf l'exception de 1.1 indiquée ci-dessus.
Pour valider avec un JSON Schema, un schéma souple pour ph.order/1.x est fourni, qui prend déjà tout cela en compte (accepte les nouveaux champs et n'importe quelle version mineure). Pour coordonner le changement ou demander le schéma et des payloads de test, contacter le responsable chez Portal Hero.