Documentación Shipping
Tarifas, creación y gestión de envíos: endpoints, parámetros y ejemplos listos para usar.
Partner Developer Program Integración E-commerce (módulos / conectores)
Guía rápida para desarrollar tu propio módulo/conector y conectar tu e-commerce con Shipping Z-Bombilla: registrar tienda, abrir la pasarela de envío y recibir el tracking por callback.
Flujo recomendado
Se obtiene desde
shipping.z-bombilla.com/ecommerces y se pega en el módulo del e-commerce.
Ese mismo token se usa para autenticar el callback de tracking.
platform debe ser un identificador en minúsculas (ej: prestashop, woocommerce o uno propio).instanceId debe ser estable por tienda (ej: dominio + id shop). Si cambias el instanceId, será “otra tienda”.
Paso a paso
-
Solicitar AccessToken al usuario (desde
/ecommerces) y guardarlo en la configuración del módulo. -
Registrar tienda (conexión) usando el endpoint de conexión:
ver “Registrar tienda”.
Aquí se guarda:
platform,siteUrl,apiBase,instanceIdy, muy importante,trackingCallbackUrl(URL pública del e-commerce que recibirá el tracking). -
En el panel de pedidos (admin), añade un botón “Enviar a Shipping” que abra una pestaña nueva y haga:
POST /nuevoEnvio con
envioJson(Base64 JSON) y opcionales comoitemsJsonyalertasMarketplace. - Shipping devuelve el tracking por callback a tu módulo (e-commerce) vía: Callback tracking (webhook).
-
Mostrar tracking en:
- panel admin (listado de pedidos + ficha del pedido)
- cuenta cliente / detalle del pedido
- email (si el e-commerce lo soporta)
UI recomendada en el módulo
Backoffice (panel de pedidos)
-
Botón “Enviar a Shipping” en la ficha del pedido (abre pestaña nueva).
El botón hace un
POSThacia/nuevoEnvio(autopost). - Columna en el listado (opcional): icono camión + tracking (si existe). Si hay tracking, al hacer clic muestra un modal de seguimiento (ver más abajo).
-
Alertas del pedido: si bloqueas o adviertes, pasa mensajes en
alertasMarketplacepara que Shipping las pinte en pantalla (ej: “ya enviado”, “estado no permitido”, etc.).
envioJson + extras, renderiza un HTML con un <form>
y hace autosubmit a Shipping.
Frontoffice (cuenta cliente)
- Tarjeta “Seguimiento del envío” con tracking + transportista.
- Botón “Ver seguimiento” que abre un modal con el seguimiento embebido (iframe) o una pestaña nueva.
Modal de seguimiento (admin + cliente)
Implementación recomendada hoy: embebe la URL web de seguimiento de Shipping:
https://shipping.z-bombilla.com/envio/seguimiento?numSeguimiento=TRACKING.
Estados en JSON: si tu plataforma ya tiene un endpoint propio de estados, puedes llamarlo desde el modal. Si no, usa el iframe. (Más adelante podrás sustituir el iframe por un
fetch a un endpoint de estados cuando se publique).
Snippet (HTML + JS vanilla, sin dependencias)
<!-- Botón / link (admin o cliente) -->
<a href="#" class="zb-open-tracking" data-trk="PQ29BT071019809B">
Ver seguimiento
</a>
<!-- Modal simple -->
<div id="zbTrackModal" style="display:none; position:fixed; inset:0; z-index:99999;">
<div id="zbTrackBackdrop" style="position:absolute; inset:0; background:rgba(0,0,0,.55);"></div>
<div style="position:relative; max-width:980px; margin:5vh auto; background:#fff; border-radius:10px; padding:12px; box-shadow:0 10px 35px rgba(0,0,0,.35);">
<button type="button" id="zbTrackClose"
style="position:absolute; top:8px; right:10px; background:transparent; border:0; font-size:28px; line-height:28px; cursor:pointer;">
×
</button>
<div style="padding:6px 6px 10px 6px; border-bottom:1px solid #eee;">
<strong>Seguimiento del envío</strong>
<a id="zbTrackOpenNew" href="#" target="_blank" rel="noopener" style="float:right; font-size:13px;">Abrir en pestaña nueva</a>
</div>
<div style="padding:10px 6px 0 6px;">
<iframe id="zbTrackFrame" src="about:blank" style="width:100%; height:70vh; border:0;" loading="lazy"></iframe>
<div style="margin-top:10px;">
<div style="padding:10px; border:1px solid #ffeeba; background:#fff3cd; border-radius:6px; font-size:13px;">
Si no se muestra el contenido, usa “Abrir en pestaña nueva”.
</div>
</div>
</div>
</div>
</div>
<script>
(function(){
function q(sel, root){ return (root||document).querySelector(sel); }
function qa(sel, root){ return Array.prototype.slice.call((root||document).querySelectorAll(sel)); }
var modal = q('#zbTrackModal');
var frame = q('#zbTrackFrame');
var openNew = q('#zbTrackOpenNew');
var closeBtn = q('#zbTrackClose');
var backdrop = q('#zbTrackBackdrop');
function buildUrl(trk){
trk = (trk||'').trim();
return trk ? ('https://shipping.z-bombilla.com/envio/seguimiento?numSeguimiento=' + encodeURIComponent(trk)) : '';
}
function openModal(trk){
var url = buildUrl(trk);
if(!url) return;
frame.src = url;
openNew.href = url;
modal.style.display = 'block';
}
function closeModal(){
modal.style.display = 'none';
frame.src = 'about:blank';
}
qa('.zb-open-tracking').forEach(function(a){
a.addEventListener('click', function(ev){
ev.preventDefault();
openModal(a.getAttribute('data-trk') || '');
});
});
closeBtn.addEventListener('click', closeModal);
backdrop.addEventListener('click', closeModal);
document.addEventListener('keydown', function(e){
if(e && e.keyCode === 27 && modal.style.display === 'block') closeModal();
});
})();
</script>
Callback de tracking (resumen técnico)
| Elemento | Detalle |
|---|---|
| Método | POST JSON |
| Auth | Authorization: Bearer <accessToken> (comparación constante) |
| Body |
{ order_id, tracking, carrier, shipped_at }
|
| Respuesta | 200 con { "ok": true } |
Implementaciones avanzadas (masivo / empresas)
1) Cotizar + generar etiqueta (calcular-envio ➜ do-envio)
- Llamas a calcular-envio para obtener precio/servicio de todas las agencias disponibles según bultos y destino.
- El usuario (o tu lógica) elige una agencia/servicio.
- Llamas a do-envio indicando la agencia elegida y recibes etiqueta + tracking.
- Si la tienda está conectada, Shipping notificará el tracking al e-commerce por callback (si está configurado).
2) Generación automática (do-envio con reglas ya configuradas)
Para operativas avanzadas, puedes preconfigurar reglas en Shipping (preferencias por calidad/precio/rapidez, horarios, recogidas, etc.) y lanzar do-envio para que Shipping elija el mejor servicio automáticamente.
Este flujo reduce lógica en el e-commerce y centraliza decisiones en Shipping.
/nuevoEnvio Pasarela de creación de envío
Abre Shipping con datos precargados (envío + destinatario + bultos) y, opcionalmente, productos y alertas del pedido.
Resumen
envioJson y muestra el formulario con los datos precargados.
Autenticación
accessToken para auto-login/autorización (según tu flujo).
Parámetros
| Nombre | Tipo | Oblig. | Descripción |
|---|---|---|---|
envioJson |
string (Base64 JSON) | Sí | Base64 del JSON de EnvioV3DTO (UTF-8). Es el payload principal. |
idExpedicion |
number | No | Si se envía, Shipping carga una expedición existente y precarga el formulario (editar/duplicar). |
marketplaceName |
string | No | Nombre del marketplace para rotular el bloque de productos (ej. WooCommerce, PrestaShop). |
itemsJson |
string (Base64 JSON) | No | Lista de productos/líneas del pedido. Ver detalle |
alertasMarketplace |
string (JSON/Base64) | No | Lista de alertas del pedido. Ver detalle |
order_id |
string/number | No | ID de pedido del marketplace (para asociar tracking u operaciones posteriores). |
combined |
0/1 | No | Si 1, Shipping pinta productos por pedido (modo combinado). |
accessToken |
string | No | Token para auto-login/autorización (si tu integración lo soporta). |
salesChannelUrl |
string (URL) | No | Enlace directo al pedido en el marketplace/panel (por ejemplo, la edición del pedido en el backoffice). Shipping puede mostrarlo como acceso rápido tipo “Ver pedido”. Compatibilidad: también se acepta dentro de 'envioJson'. |
envioJson. Si envías idExpedicion, puede no ser necesario envioJson (dependiendo del flujo).
Cómo construir envioJson
JSON de EnvioV3DTO codificado en Base64 (UTF-8).
const codificado = btoa(unescape(encodeURIComponent(JSON.stringify(envio))));
Ejemplo de JSON (antes de Base64)
{
"refEnvio":"WC-12345",
"tipoPortes":"Pagados",
"valorTotal":59.90,
"destinatario":{
"nombre":"Cliente SL",
"direccion":"Calle Falsa 123, 1",
"codigoPostal":"28001",
"poblacion":"Madrid",
"provincia":"Madrid",
"pais":{"isoCode":"ES"},
"telefono":"600000000",
"email":"cliente@email.com",
"observaciones":""
},
"olBultos":[{"largo":30,"ancho":20,"alto":10,"peso":1.2}],
"salesChannelUrl":"https://tu-tienda.com/panel/index.php?controller=AdminOrders&id_order=12345&vieworder"
}
itemsJson · productos del pedido
Si envías itemsJson, Shipping podrá pintar el bloque Productos Marketplace (tabla).
El frontend es flexible: usa name/title, image/img, sku/sellerSKU,
qty/quantity y price/itemPriceAmount.
form-urlencoded.
Campos detectados por el frontend
| Uso | Campos aceptados |
|---|---|
| Título | name o title |
| Imagen | image o img |
| SKU | sku / sku_id / sellerSKU |
| Cantidad | qty / quantity / quantityOrdered |
| Precio | price o itemPriceAmount |
| Link producto | idProduct + linkProduct (si existen) |
| Fila gastos envío | isShippingFee = true + name + price |
Ejemplo JSON (antes de Base64)
[
{"name":"Producto 1","sku":"REF1","qty":2,"price":8.264,"image":"https://tuweb/img1.jpg"},
{"isShippingFee":true,"name":"Gastos de envío","price":4.95}
]
alertasMarketplace · alertas del pedido
Si envías alertasMarketplace, Shipping lo convierte a List<String> y lo pinta como lista en “Alertas del pedido”.
Ejemplo JSON (antes de Base64)
[
"Este pedido ya consta como ENVIADO (TRK: 1234567890).",
"El pedido no está listo porque su estado actual es En espera.",
"Pedido marcado como urgente"
]
/oauth/ecommerce/callback Registrar tienda / conectar marketplace
Registra (o actualiza) una tienda/instancia de marketplace en Shipping para poder: recibir callbacks de tracking y asociar pedidos/seguimientos a esa instancia. Normalmente se abre desde el BackOffice del marketplace (botón “Conectar”).
Resumen
token es un secreto (shared secret).
En callbacks, el marketplace debe validar Authorization: Bearer <token>.
Usa siempre HTTPS y evita registrar el token en logs.
Autenticación
token (AccessToken).
Shipping lo almacena asociado a la instancia para autenticar callbacks posteriores.
Parámetros (QueryString)
| Nombre | Tipo | Oblig. | Descripción |
|---|---|---|---|
platform |
string | Sí | Plataforma / conector. Ej: prestashop, woocommerce. |
siteUrl |
string (URL) | Sí | URL base de la tienda. Ej: https://www.tienda.com (con o sin idioma). |
apiBase |
string (URL) | No | Base para llamadas API del marketplace (si aplica). Normalmente igual que siteUrl. |
shopId |
string/number | No | ID de tienda (útil en multishop). Ej: 1. |
psVersion |
string | No | Versión de PrestaShop (si aplica). Ej: 1.6.0.8. |
moduleVersion |
string | No | Versión del módulo/conector. Ej: 0.2.0. |
trackingCallbackUrl |
string (URL) | Sí |
URL del marketplace a la que Shipping enviará el tracking vía POST JSON. Ej (PrestaShop): https://www.tienda.com/module/shippingzb/trackingupdate
|
token |
string | Sí |
Secreto compartido (AccessToken). Se usará como Bearer en callbacks:Authorization: Bearer <token>
|
trackingCallbackUrl debe aceptar:
- Método: POST
- Headers:
Authorization: Bearer <token>,Content-Type: application/json - Body:
{"order_id":..., "tracking":"...", "carrier":"...", "shipped_at":"..."}
Ver contrato del webhook:
Callback de tracking (POST JSON)
/envio/calcularEnvio Tarificación
Calcula las tarifas disponibles para un envío y devuelve la lista de agencias ordenada según las reglas configuradas en tu cuenta. La primera agencia válida siempre es la recomendada.
¿Qué hace este endpoint?
- Calcula las tarifas de todas las agencias configuradas en tu cuenta.
- Aplica las reglas de agencia que hayas definido (exclusiones, preferencias, safety nets…).
- Devuelve la lista ordenada: la primera agencia con
isGood: truees siempre la recomendada. - Indica si la auto-selección está permitida o si el usuario debe elegir manualmente.
Autenticación
Incluye el token en cabecera:
Authorization: Bearer {accessToken}
Cabeceras
| Cabecera | Valor | Obligatorio |
|---|---|---|
Authorization |
Bearer {accessToken} |
Sí |
Content-Type |
application/x-www-form-urlencoded |
Sí |
Parámetros del body
| Parámetro | Tipo | Oblig. | Descripción |
|---|---|---|---|
codigoPostal |
string | Sí | Código postal de destino. En España se usa para resolver provincia automáticamente. |
paisCliente |
string | No | Código ISO del país destino (ej. ES, PT, FR) o ID numérico interno. Por defecto: ES. |
tipoPortes |
string | No | Pagados (por defecto) o Contrareembolso. |
valorMercancia |
decimal | Condicional |
Valor declarado de la mercancía en euros. Opcional si el destino es España. Obligatorio y > 0 para envíos internacionales. También obligatorio si tipoPortes=Contrareembolso.
|
marketplaceName |
string | No |
Nombre del marketplace origen del pedido (ej. Amazon, Temu).
Se usa para aplicar reglas de exclusión por marketplace.
|
fechaLimiteEntrega |
string | No |
Fecha límite de entrega en formato YYYY-MM-DD (ej. 2025-12-31).Se usa para aplicar reglas de exclusión por plazo de entrega cuando no tienes configurado un número fijo de días en la regla. Si la agencia no puede entregar antes de esta fecha, queda excluida automáticamente. |
largo[], ancho[], alto[], peso[] |
array repetible | Sí |
Dimensiones de cada bulto en centímetros y kilogramos.
Repite el grupo de cuatro parámetros una vez por bulto. 1 bulto: largo[]=20&ancho[]=30&alto[]=40&peso[]=52 bultos: largo[]=20&ancho[]=30&alto[]=40&peso[]=5&largo[]=10&ancho[]=10&alto[]=10&peso[]=2Si tu cliente escapa los corchetes: largo%5B%5D.
|
Respuesta (HTTP 200)
Devuelve un objeto con la lista de agencias y metadatos del motor de reglas:
{
"agencias": [
{
"nombreAgenciaCalculada": "Correos Paq. Estándar (48-72h) (Zona 2)",
"precioPorte": 4.52,
"precioSeguro": 100.00,
"precioReembolso": 0.00,
"precioTotal": 4.52,
"isGood": true,
"errors": []
},
{
"nombreAgenciaCalculada": "Envialia (Peninsular)",
"precioPorte": 5.63,
"precioSeguro": 69.93,
"precioReembolso": 0.00,
"precioTotal": 5.63,
"isGood": true,
"errors": []
},
{
"nombreAgenciaCalculada": "Correos (Paq Standard Internacional)",
"precioPorte": 0,
"precioSeguro": 0,
"precioReembolso": 0,
"precioTotal": 0,
"isGood": false,
"errors": ["No existe ningún baremo con la provincia o el País en su configuración."]
}
],
"autoSeleccionPermitida": true,
"motivoNoAutoSeleccion": "",
"usuarioValidado": true
}
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
agencias |
array |
Lista de agencias calculadas, ya ordenada según las reglas de tu cuenta.
La primera agencia con isGood: true es siempre la recomendada.
Las agencias con isGood: false aparecen al final con el motivo en errors.
|
agencias[].nombreAgenciaCalculada |
string | Nombre del servicio de la agencia, incluyendo zona o tarifa aplicada. |
agencias[].precioPorte |
decimal | Coste neto del porte. |
agencias[].precioSeguro |
decimal | Importe máximo cubierto en caso de incidencia. No es un coste adicional, es la cobertura incluida. |
agencias[].precioReembolso |
decimal | Gastos de reembolso. Solo aplica cuando tipoPortes=Contrareembolso. |
agencias[].precioTotal |
decimal | Precio total = precioPorte + precioReembolso. |
agencias[].isGood |
boolean |
true si la agencia puede gestionar este envío con esta tarifa.
false si hay algún problema (peso, medidas, zona no cubierta, excluida por regla…).
|
agencias[].errors |
array string | Motivos por los que isGood es false. Vacío si todo es correcto. |
autoSeleccionPermitida |
boolean |
true: puedes seleccionar automáticamente la primera agencia recomendada.false: el precio supera el umbral configurado en tus reglas y se recomienda
que el usuario elija manualmente. Consulta motivoNoAutoSeleccion para mostrar el aviso.
|
motivoNoAutoSeleccion |
string | Explicación legible de por qué la auto-selección está deshabilitada. Vacío si autoSeleccionPermitida=true. |
usuarioValidado |
boolean | Indica si la cuenta está activa y configurada. Si es false, las agencias pueden estar vacías. |
Orden de la lista y agencia recomendada
La lista devuelta no está ordenada por precio. Está ordenada según las reglas de agencia configuradas en tu cuenta (exclusiones, preferencias, tolerancias de precio…).
- La primera entrada con
isGood: truees siempre la agencia recomendada. - Puede que no sea la más barata: las reglas pueden promover una agencia más cara si la diferencia está dentro del margen configurado.
- Si no tienes reglas configuradas, la lista se ordena por
precioTotalascendente.
Errores
| HTTP | Causa | Respuesta |
|---|---|---|
| 400 | Parámetros incorrectos o faltantes | {"errores": ["codigoPostal es obligatorio", ...]} |
| 401 | Token inválido o ausente | {"errores": "Usuario no autenticado"} |
| 500 | Error interno | {"error": "Error interno: ..."} |
// HTTP 400 — ejemplo de errores de validación
{
"errores": [
"codigoPostal es obligatorio",
"valorMercancia debe ser mayor que 0 para envíos fuera de España",
"Debe especificar al menos un bulto (largo, ancho, alto, peso)"
]
}
Notas importantes
- Este endpoint solo calcula tarifas. No registra ningún envío.
- Filtra siempre por
isGood: trueantes de mostrar o seleccionar una agencia. - Si
autoSeleccionPermitidaesfalse, muestramotivoNoAutoSeleccional usuario antes de confirmar. - El campo
precioSeguroes la cobertura incluida, no un coste extra. - Pasa
marketplaceNamesi el pedido viene de un marketplace para que se apliquen correctamente las reglas de exclusión por marketplace.
/codigoPostalLookup Lookup CP
Obtiene población y provincia a partir de un código postal.
Resumen
[]).
Autenticación
Parámetros (query)
| Parámetro | Tipo | Oblig. | Descripción |
|---|---|---|---|
codigoPostal |
string | Sí | Código postal del que obtener población y provincia. |
Ejemplo
GET https://shipping.z-bombilla.com/codigoPostalLookup?codigoPostal=03500
Respuesta (HTTP 200)
[
{
"poblacion": "Benidorm",
"codigoPostal": "03501",
"provincia": "Alicante"
}
]
Notas
- Devuelve siempre un array JSON.
- Si no hay coincidencias:
[].
/envio/doEnvioApi Confirmar envío (API)
Genera el envío definitivo, crea el tracking y devuelve las etiquetas en Base64.
Resumen
/envio/doEnvioApi.El endpoint
/envio/doEnvio existe para uso web interno (sesión/JSESSIONID) y no sirve para integraciones por token.
Autenticación
Incluye el token en cabecera:
Authorization: Bearer {accessToken}
Cabeceras
| Cabecera | Valor | Obligatorio |
|---|---|---|
Authorization |
Bearer {accessToken} |
Sí |
Content-Type |
application/json |
Sí |
Parámetros del body (JSON)
| Campo | Tipo | Oblig. | Descripción |
|---|---|---|---|
agencia.nombreAgenciaCalculada |
string | Sí | Nombre de la agencia (obtenido desde Calcular Envío). Debe coincidir exactamente. |
agencia.precioPorte |
decimal | No |
Opcional (informativo). El sistema recalcula internamente y selecciona por nombreAgenciaCalculada.
|
envio.tipoPortes |
string | No (recomendado) | Pagados o Contrareembolso. Recomendado enviarlo siempre. |
envio.refEnvio |
string | No | Referencia interna (por ejemplo nº de pedido). |
envio.descripcionEnvio |
string | No |
Descripción del contenido. Recomendado para envíos internacionales / ciertas agencias.
Ej: "Papel Secamanos".
|
envio.destinatario.nombre |
string | Sí | Nombre del destinatario (máx. 120). |
envio.destinatario.direccion |
string | Sí | Dirección del destinatario (máx. 300). |
envio.destinatario.numero |
string | No | Número de dirección (máx. 45). |
envio.destinatario.paisISO |
string | No | ISO país. Por defecto ES. |
envio.destinatario.provincia |
string | No | Para España puede recalcularse desde el CP (máx. 45). |
envio.destinatario.poblacion |
string | No | Población del destinatario (máx. 45). |
envio.destinatario.codigoPostal |
string | Sí | Código postal (máx. 10). |
envio.destinatario.telefono |
string | No | Teléfono de contacto (máx. 20). |
envio.destinatario.email |
string | No | Email de contacto (máx. 120). |
envio.destinatario.observaciones |
string | No | Observaciones (máx. 300). |
envio.bultos |
array | Sí | Listado de bultos (mínimo 1, máximo 100). |
envio.bultos[].largo |
decimal | Sí | Largo (cm). |
envio.bultos[].ancho |
decimal | Sí | Ancho (cm). |
envio.bultos[].alto |
decimal | Sí | Alto (cm). |
envio.bultos[].peso |
decimal | Sí | Peso (kg). |
envio.valorMercancia |
decimal | Cond. |
Obligatorio y > 0 si paisISO != ES o si tipoPortes = Contrareembolso.
|
envio.envioConRetorno |
boolean | No | Indica retorno (solo algunas agencias). |
Respuesta (HTTP 200)
{
"numSeguimiento": "1234567890",
"olEtiquetas": [
"Base64Etiqueta1",
"Base64Etiqueta2"
]
}
- olEtiquetas: puede ser Base64 de PDF o imagen según agencia.
- numSeguimiento: tracking asignado al envío.
Errores
- 400 Bad Request: validación / faltan campos / agencia no disponible.
- 401 Unauthorized: token no enviado o inválido.
- 404 Not Found: URL incorrecta (por ejemplo usar
/api/...
{
"error": "Falta campo obligatorio: envio.destinatario.nombre"
}
Notas
- Se recomienda usar una agencia con
isGood = truedesde Calcular Envío. agencia.nombreAgenciaCalculadadebe coincidir exactamente con el valor devuelto en tarificación.- Para
Contrareembolso,valorMercanciadebe ser > 0.
/envio/seguimiento Seguimiento unificado
Endpoint de seguimiento: recibe un numSeguimiento, localiza la expedición y
muestra el estado según la agencia (Correos, MRW, UPS, etc.).
Ideal para abrir en modal/iframe en panel admin y para mostrar seguimiento en front.
Resumen
numSeguimiento (también soporta tracking de bulto).
Seguridad
datos=view está pensado como enlace público (para mostrar seguimiento).
Algunas acciones especiales como datos=pod pueden requerir sesión iniciada,
dependiendo de la agencia.
Parámetros
| Nombre | Tipo | Oblig. | Descripción |
|---|---|---|---|
numSeguimiento |
string | Sí | Número de seguimiento. Si corresponde a un bulto, el sistema intenta resolver la expedición igualmente. |
datos |
string | No |
Modo de salida. Por defecto: view.
|
Uso recomendado en Admin/Front (modal / iframe)
Para una integración rápida, abre el enlace en pestaña nueva. Para una UX pro, abre un modal con un <iframe>
apuntando a datos=view y añade fallback “Abrir en pestaña nueva”.
// URL (para modal, admin o front)
const trackingUrl =
"https://shipping.z-bombilla.com/envio/seguimiento?numSeguimiento=" +
encodeURIComponent(trackingNumber);
// Último estado (JSON compacto)
const lastStatusUrl =
"https://shipping.z-bombilla.com/envio/seguimiento?datos=ultimoestado&numSeguimiento=" +
encodeURIComponent(trackingNumber);
Códigos de respuesta
| HTTP | Cuándo ocurre |
|---|---|
400 |
Falta numSeguimiento o el formato no es válido para localizar expedición. |
404 |
No se localiza ninguna expedición/bulto con ese número de seguimiento. |
501 |
Agencia sin soporte de seguimiento (aún). |
401/403 |
Acceso denegado (p.ej. datos=pod sin sesión o sin permisos). |
500 |
Error interno de seguimiento. |
{trackingCallbackUrl} Callback de tracking (webhook)
Shipping llama al endpoint que registraste como trackingCallbackUrl para enviar el tracking al marketplace.
En PrestaShop sería el controller del módulo (ej: /module/shippingzb/trackingupdate).
Resumen
order_id del marketplace.
Autenticación
Authorization: Bearer <token>Ese
token es el que se registró al conectar la tienda (token en el endpoint de conexión).
accessToken dentro del JSON (solo si tu integración lo permite).
Headers
Content-Type: application/json; charset=UTF-8
Authorization: Bearer {token}
Body (JSON)
| Campo | Tipo | Oblig. | Descripción |
|---|---|---|---|
order_id |
number/string | Sí | ID del pedido en el marketplace (el que enviaste en /nuevoEnvio). |
tracking |
string | Sí | Número de seguimiento. |
carrier |
string | No | Nombre del transportista (texto). Ej: “Correos Paq. Estándar…”. |
shipped_at |
string (ISO-8601) | No | Fecha/hora del envío. Ej: 2026-02-21T22:10:00Z. |
accessToken |
string | No | Fallback opcional si no llega Authorization. Normalmente no es necesario. |
Ejemplo request
{
"order_id": 127308,
"tracking": "PQ29BT071019809B",
"carrier": "Correos Paq. Estándar (48-72h) (Zona 1)",
"shipped_at": "2026-02-21T22:10:00Z"
}
Respuesta
{"ok":true}
Errores típicos
| HTTP | Motivo |
|---|---|
405 | Método no permitido (solo POST). |
401 | Token inválido o ausente. |
400 | Body vacío o JSON inválido. |
422 | Falta order_id o tracking. |
404 | Pedido no encontrado en el marketplace. |
500 | Error interno guardando tracking/cambiando estado/enviando email. |
200 igualmente.