Cada evento. Cada payload. Firmado.
Fabrixa envía eventos de pedidos a su endpoint en tiempo real. Su servidor expone un endpoint POST público; nosotros enviamos el cuerpo completo del pedido con una firma HMAC-SHA256 y el topic del evento en los encabezados. Verifique la firma, devuelva un código de estado 200 rápidamente y procese el pedido de forma asíncrona.
Hay tres encabezados que identifican y verifican la solicitud.
Cada solicitud POST de webhook incluye los mismos tres encabezados. Utilice x-webhook-topic para redirigir el evento y x-webhook-signature para comprobarlo antes de confiar en el cuerpo del mensaje.
content-type es siempre application/json. x-webhook-signature es el HMAC-SHA256 codificado en base64 del cuerpo sin procesar. x-webhook-topic es el nombre del evento.
{
"content-type": "application/json",
"x-webhook-topic": "order.updated",
"x-webhook-signature": "YmEwNjBhMGMy...MAxMw=="
}
Dos topics por ahora.
Cada webhook se activa mediante un valor concreto de x-webhook-topic en cuestión. Ambos contienen el objeto de pedido completo, por lo que un único handler puede bifurcar según el topic.
Se ha realizado un nuevo pedido.
Se activa cuando se crea un pedido en Fabrixa, ya sea a través de una solicitud de API o directamente en la plataforma.
Se produce un cambio en un pedido ya existente.
Se activa cuando cambian los detalles del pedido; por ejemplo, cuando cambia el estado del pedido o el estado de fulfilment.
Qué pueden indicar los campos de estado.
Lel payload transporta tanto un pedido status y un fulfillment_status. Bifurque según estos valores para gestionar el estado de su propio pedido.
- Completed — enviado o recogido y con el recibo confirmado.
- Canceled — El pago se ha cancelado; la transacción no se ha completado.
- On hold — El pedido está bloqueado temporalmente.
- Imported — El pedido se ha importado a la plataforma.
- Unfulfilled — aún no está preparado ni enviado.
- Partially fulfilled — algunos artículos ya se han tramitado o enviado, otros están pendientes.
- Scheduled — planificados y programados para su procesamiento.
- Rejected — La solicitud de tramitación ha sido denegada.
- Fulfilled — totalmente procesados y entregados o puestos a disposición.
Cómo es el cuerpo.
El payload completo de order.updated tal y como se documenta en la referencia de la API: el pedido, sus estados y las filas con los detalles de variante, producto y source.
{
"id": 23069,
"number": "1250211835",
"comments": null,
"is_archived": false,
"status": "imported",
"fulfillment_status": "unfulfilled",
"purchased_at": "2025-04-17T16:17:21.000000Z",
"created_at": "2025-04-17T16:17:23.000000Z",
"updated_at": "2025-04-18T07:43:52.000000Z",
"rows": [
{
"id": 27954,
"quantity": 1,
"client_barcode": "1250211835",
"fulfillment_status": "unfulfilled",
"variant": {
"id": 293457,
"name": "Sherpa fleece deken",
"subtitle": "100x150",
"SKU": "SFD787231",
"product": {
"id": 5319, "name": "Sherpa fleece deken", "subtitle": "Sherpa fleece deken"
}
},
"sources": [
{
"type": "print",
"url": "https://storage.googleapis.com/fabrixa-api/…/120002795400.pdf",
"properties": { "fill_style": "contain" }
}
]
}
]
}
Vuelva a calcular el HMAC, compárelo y, a continuación, considera fiable el cuerpo del mensaje.
Vuelve a calcular el HMAC-SHA256 de lel payload sin procesar de la solicitud con su clave secreta, codifíquela en base64 y compárela con x-webhook-signature. Utilice siempre una comparación de tiempo constante (hash_equals) para evitar ataques de temporización.
$payload = file_get_contents('php://input'); $secret = 'your-secret-key'; $expected = base64_encode( hash_hmac('sha256', $payload, $secret, true) ); $received = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''; // constant-time compare if (!hash_equals($expected, $received)) { http_response_code(403); exit('Invalid signature'); }
public function handle(Request $request)
{
$secret = 'your-secret-key';
$payload = $request->getContent();
$expected = base64_encode(
hash_hmac('sha256', $payload, $secret, true)
);
$received = $request->header('x-webhook-signature');
if (!hash_equals($expected, $received)) {
abort(403, 'Invalid signature');
}
// Continue processing…
}
Los reintentos y la respuesta que esperamos.
Hasta 10 intentos; después, se desactiva
A 2xx (p. ej., 200) o un 301 / 302 se considera un éxito. Cualquier 4xx, 5xx o si se agota el tiempo de espera, se inicia un nuevo intento —hasta un máximo de 10 en total—. Tras el décimo fallo, el webhook se desactiva.
Devuelva 200 rápido y procese de forma asíncrona
Confirmar con 200 OK lo antes posible y, a continuación, gestionar lel payload de forma asíncrona mediante una tarea en segundo plano o una cola. Un endpoint lento puede considerarse un error, aunque finalmente se complete con éxito.
Configure su endpoint de webhook.
La guía de integración explica paso a paso cómo registrar su endpoint y gestionar el ciclo de vida del pedido de principio a fin. La referencia completa de API incluye el esquema completo de lel payload.


