Recursos · API y pedidos

Pedidos en JSON: esquema ph.order/1.2

Payload versionado de pedidos ph.order/1.2: esquema JSON publicado, reglas de compatibilidad y ejemplos de entrega.

Cuando se confirma una venta, el pedido se entrega en la integración (webhook, SFTP o correo) con este JSON canónico y versionado. Esta página es la especificación exacta del formato ph.order/1.2.

Reglas de formato

  • Todas las claves están siempre presentes; las claves nunca se omiten.
  • null significa «dato desconocido»; no debe interpretarse como 0 (algunos canales no desglosan impuestos por línea).
  • Los importes son números con hasta 2 decimales.
  • tax_rate es un decimal: 0.21 equivale al 21 %.
  • channel es el código interno del canal (p. ej. ebay, wllp) y channel_name su nombre visible (p. ej. Ebay, Wallapop).
  • total_gross es el precio de venta para el vendedor, con la comisión del vendedor incluida: channel_fees_gross (lo que el canal le retiene de ese importe) y buyer_fees_gross (lo que el comprador paga al canal además del precio, nunca dentro de total_gross) son informativos; shipping_gross (transporte) también lo es, y puede estar incluido o no en total_gross según el canal (las lines dan el desglose de la mercancía).

Ejemplo 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
}

Campos

CampoTipoDescripción
schemastringIdentificador del esquema y su versión, «ph.order/MAYOR.MENOR» (hoy ph.order/1.2). Fijarse solo en el mayor.
order_idstringIdentificador único del pedido.
channelstringCódigo interno del canal de venta (p. ej. ebay, wllp).
channel_namestringNombre visible del canal de venta (p. ej. Ebay, Wallapop).
created_atstring | nullFecha y hora de creación del pedido, en formato ISO 8601.
statusstringEstado del pedido (p. ej. accepted). Lista de valores abierta.
currencystring | nullMoneda de los importes del pedido en formato ISO 4217 (p. ej. EUR).
original_currencystring | nullMoneda en la que pagó el comprador, en formato ISO 4217. Si es otra, el pedido se convirtió y sus importes están en currency.
exchange_ratenumber | nullUnidades de original_currency que valía una unidad de currency al convertir el pedido (p. ej. 0.8346 libras por euro); 1 si no se convirtió.
customerobjectDatos del comprador (objeto; ver campos más abajo).
linesarrayLíneas del pedido, una por artículo (lista de objetos; ver campos más abajo).
shipping_grossnumber | nullImporte del envío con impuestos incluidos.
channel_fees_grossnumber | nullComisión que el canal retiene al vendedor por el pedido (informativo; incluida en total_gross, el canal la descuenta del cobro).
buyer_fees_grossnumber | nullCargos que el comprador paga al canal además del precio, p. ej. la protección de compra (informativo; no forma parte de total_gross).
total_netnumber | nullBase imponible total del pedido (sin impuestos).
total_taxnumber | nullImporte total de impuestos del pedido.
total_grossnumber | nullPrecio de venta para el vendedor, impuestos y comisión del vendedor incluidos (el envío puede estar incluido o no según el canal).
carrierstring | nullTransportista del envío.
tracking_codestring | nullCódigo de seguimiento del envío.
tracking_urlstring | nullURL de seguimiento del envío.
payment_methodstring | nullMétodo de pago (p. ej. card). Lista de valores abierta.
source_accountstring | nullCuenta de origen en el canal de venta, si aplica.
customer.foreign_idstring | nullIdentificador del comprador en el canal de origen.
customer.first_namestring | nullNombre del comprador.
customer.last_namestring | nullApellidos del comprador.
customer.company_namestring | nullRazón social del comprador, si es una empresa.
customer.emailstring | nullCorreo electrónico del comprador.
customer.tax_numberstring | nullIdentificación fiscal del comprador (NIF/CIF/VAT).
customer.phonestring | nullTeléfono del comprador.
customer.addressobjectDirección de envío del comprador (objeto; ver campos más abajo).
customer.address.streetstring | nullCalle y número de la dirección de envío.
customer.address.citystring | nullPoblación de la dirección de envío.
customer.address.provincestring | nullProvincia o región de la dirección de envío.
customer.address.postal_codestring | nullCódigo postal de la dirección de envío.
customer.address.countrystring | nullPaís de la dirección de envío, en formato ISO 3166-1 alpha-2 (p. ej. ES).
lines[].external_idstring | nullIdentificador del artículo en el catálogo (SKU o referencia).
lines[].titlestring | nullTítulo o descripción del artículo.
lines[].quantityinteger | nullUnidades del artículo en esta línea.
lines[].line_netnumber | nullBase imponible de la línea (sin impuestos).
lines[].line_taxnumber | nullImporte de impuestos de la línea.
lines[].line_grossnumber | nullImporte de la línea con impuestos incluidos.
lines[].tax_ratenumber | nullTipo impositivo de la línea en decimal (0.21 = 21 %).

Compatibilidad y versiones

Para no tener que volver a tocar la integración en futuras versiones, conviene construir el lector siguiendo estas reglas:

  • Versionado: el campo schema es ph.order/MAYOR.MENOR (hoy ph.order/1.2). Fijarse solo en el MAYOR (el 1) y aceptar cualquier versión menor.
  • Versiones publicadas: 1.0, el esquema inicial. 1.1 añade buyer_fees_gross y deja channel_fees_gross como la comisión que el canal cobra al vendedor en todos los canales; en Wallapop contenía la protección de compra del comprador, que pasa a buyer_fees_gross. 1.2 añade original_currency y exchange_rate: un pedido pagado en otra moneda llega con los importes en euros, y estos campos dicen en qué moneda pagó el comprador y a qué cambio.
  • Solo se añade, nunca se quita: dentro de la versión mayor 1 los cambios son aditivos. Se podrán añadir campos nuevos (siempre presentes, con null cuando no apliquen), pero nunca se eliminará, renombrará ni se cambiará el tipo o el significado de un campo existente. Única excepción: la de 1.1 indicada en las versiones publicadas.
  • Ignorar los campos no reconocidos: el lector debe descartarlos sin fallar (no validar con additionalProperties: false).
  • Listas de valores abiertas: en status, channel, payment_method, currency y original_currency pueden aparecer valores nuevos; tratar un valor desconocido sin romper (p. ej. como «otro»).
  • Solo un cambio de versión MAYOR (ph.order/2.0) requeriría adaptación, y se avisaría con antelación; las versiones menores no exigen ningún cambio por parte del consumidor, salvo la excepción de 1.1 indicada arriba.

Para validar con un JSON Schema, se facilita uno laxo para ph.order/1.x que ya contempla todo esto (acepta campos nuevos y cualquier versión menor). Para coordinar el cambio o solicitar el esquema y payloads de prueba, contactar con el responsable en Portal Hero.