Comandes en JSON: esquema ph.order/1.2
Payload versionat de comandes ph.order/1.2: esquema JSON publicat, regles de compatibilitat i exemples d'entrega.
Quan es confirma una venda, la comanda s'entrega a la integració (webhook, SFTP o correu) amb aquest JSON canònic i versionat. Aquesta pàgina és l'especificació exacta del format ph.order/1.2.
Regles de format
- Totes les claus estan sempre presents; les claus mai s'ometen.
- null significa «dada desconeguda»; no s'ha d'interpretar com a 0 (alguns canals no desglossen impostos per línia).
- Els imports són nombres amb fins a 2 decimals.
- tax_rate és un decimal: 0.21 equival al 21 %.
- channel és el codi intern del canal (p. ex. ebay, wllp) i channel_name el seu nom visible (p. ex. Ebay, Wallapop).
- total_gross és el preu de venda per al venedor, amb la comissió del venedor inclosa: channel_fees_gross (el que el canal li reté d'aquest import) i buyer_fees_gross (el que el comprador paga al canal a més del preu, mai dins de total_gross) són informatius; shipping_gross (transport) també ho és, i pot estar inclòs o no a total_gross segons el canal (les lines donen el desglossament de la mercaderia).
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
}
Camps
| Camp | Tipus | Descripció |
|---|---|---|
schema | string | Identificador de l'esquema i la seva versió, «ph.order/MAJOR.MENOR» (avui ph.order/1.2). Fixar-se només en el major. |
order_id | string | Identificador únic de la comanda. |
channel | string | Codi intern del canal de venda (p. ex. ebay, wllp). |
channel_name | string | Nom visible del canal de venda (p. ex. Ebay, Wallapop). |
created_at | string | null | Data i hora de creació de la comanda, en format ISO 8601. |
status | string | Estat de la comanda (p. ex. accepted). Llista de valors oberta. |
currency | string | null | Moneda dels imports de la comanda en format ISO 4217 (p. ex. EUR). |
original_currency | string | null | Moneda en què va pagar el comprador, en format ISO 4217. Si és una altra, la comanda s'ha convertit i els seus imports són en currency. |
exchange_rate | number | null | Unitats d'original_currency que valia una unitat de currency en convertir la comanda (p. ex. 0.8346 lliures per euro); 1 si no s'ha convertit. |
customer | object | Dades del comprador (objecte; veure camps més avall). |
lines | array | Línies de la comanda, una per article (llista d'objectes; veure camps més avall). |
shipping_gross | number | null | Import de l'enviament amb impostos inclosos. |
channel_fees_gross | number | null | Comissió que el canal reté al venedor per la comanda (informatiu; inclosa a total_gross, el canal la descompta del cobrament). |
buyer_fees_gross | number | null | Càrrecs que el comprador paga al canal a més del preu, p. ex. la protecció de compra (informatiu; no forma part de total_gross). |
total_net | number | null | Base imposable total de la comanda (sense impostos). |
total_tax | number | null | Import total d'impostos de la comanda. |
total_gross | number | null | Preu de venda per al venedor, impostos i comissió del venedor inclosos (el transport pot estar inclòs o no segons el canal). |
carrier | string | null | Transportista de l'enviament. |
tracking_code | string | null | Codi de seguiment de l'enviament. |
tracking_url | string | null | URL de seguiment de l'enviament. |
payment_method | string | null | Mètode de pagament (p. ex. card). Llista de valors oberta. |
source_account | string | null | Compte d'origen al canal de venda, si aplica. |
customer.foreign_id | string | null | Identificador del comprador al canal d'origen. |
customer.first_name | string | null | Nom del comprador. |
customer.last_name | string | null | Cognoms del comprador. |
customer.company_name | string | null | Raó social del comprador, si és una empresa. |
customer.email | string | null | Correu electrònic del comprador. |
customer.tax_number | string | null | Identificació fiscal del comprador (NIF/CIF/VAT). |
customer.phone | string | null | Telèfon del comprador. |
customer.address | object | Adreça d'enviament del comprador (objecte; veure camps més avall). |
customer.address.street | string | null | Carrer i número de l'adreça d'enviament. |
customer.address.city | string | null | Població de l'adreça d'enviament. |
customer.address.province | string | null | Província o regió de l'adreça d'enviament. |
customer.address.postal_code | string | null | Codi postal de l'adreça d'enviament. |
customer.address.country | string | null | País de l'adreça d'enviament, en format ISO 3166-1 alpha-2 (p. ex. ES). |
lines[].external_id | string | null | Identificador de l'article al catàleg (SKU o referència). |
lines[].title | string | null | Títol o descripció de l'article. |
lines[].quantity | integer | null | Unitats de l'article en aquesta línia. |
lines[].line_net | number | null | Base imposable de la línia (sense impostos). |
lines[].line_tax | number | null | Import d'impostos de la línia. |
lines[].line_gross | number | null | Import de la línia amb impostos inclosos. |
lines[].tax_rate | number | null | Tipus impositiu de la línia en decimal (0.21 = 21 %). |
Compatibilitat i versions
Per no haver de tornar a tocar la integració en futures versions, convé construir el lector seguint aquestes regles:
- Versionat: el camp schema és ph.order/MAJOR.MENOR (avui ph.order/1.2). Fixar-se només en el MAJOR (l'1) i acceptar qualsevol versió menor.
- Versions publicades: 1.0, l'esquema inicial. 1.1 afegeix buyer_fees_gross i deixa channel_fees_gross com la comissió que el canal cobra al venedor a tots els canals; a Wallapop contenia la protecció de compra del comprador, que passa a buyer_fees_gross. 1.2 afegeix original_currency i exchange_rate: una comanda pagada en una altra moneda arriba amb els imports en euros, i aquests camps diuen en quina moneda va pagar el comprador i a quin canvi.
- Només s'afegeix, mai es treu: dins de la versió major 1 els canvis són additius. Es podran afegir camps nous (sempre presents, amb null quan no apliquin), però mai s'eliminarà, es reanomenarà ni es canviarà el tipus o el significat d'un camp existent. Única excepció: la de 1.1 indicada a les versions publicades.
- Ignorar els camps no reconeguts: el lector els ha de descartar sense fallar (no validar amb additionalProperties: false).
- Llistes de valors obertes: a status, channel, payment_method, currency i original_currency poden aparèixer valors nous; tractar un valor desconegut sense trencar (p. ex. com a «altre»).
- Només un canvi de versió MAJOR (ph.order/2.0) requeriria adaptació, i s'avisaria amb antelació; les versions menors no exigeixen cap canvi per part del consumidor, llevat de l'excepció de 1.1 indicada més amunt.
Per validar amb un JSON Schema, se'n facilita un de lax per a ph.order/1.x que ja contempla tot això (accepta camps nous i qualsevol versió menor). Per coordinar el canvi o sol·licitar l'esquema i payloads de prova, contactar amb el responsable a Portal Hero.