Proxy-seller

Webhooks

Actualizado:

En lugar de realizar consultas periódicas, puedes recibir los eventos de un pedido en tu punto final HTTPS. Los webhooks transmiten los mismos eventos que Ordenar eventos. El registro de eventos sigue estando disponible tanto si hay webhooks como si no, por lo que siempre puedes recurrir al sondeo.

Configuración

  • Aceptado callback_url en Realizar un pedido, o configúralo más tarde con Orden de actualización.

  • La respuesta devuelve webhook_secret (whsec_…) una vez. Guárdalo: firma cada webhook.

  • Cambiar callback_url emite un nuevo secreto. El secreto anterior sigue firmando los webhooks durante 24 horas: durante este tiempo X-PS-Signature Lleva dos firmas.

Solicitud

Propiedad

Valor

Método

POST a callback_url

Encabezados

Content-Type: application/json; charset=utf-8, User-Agent: ProxySeller-Webhooks/1, X-PS-Timestamp, X-PS-Signature

Cuerpo

Un evento, como en Ordenar eventos; attempt es el número de intento de entrega (1, 2, …)

Éxito

Cualquier 2xx en un plazo de 5 segundos. No se siguen las redirecciones ni se lee el cuerpo de la respuesta

Entrega

Al menos una vez, sin orden concreto. Eliminar duplicados mediante event_id

POST /hooks/proxy HTTP/1.1
Host: agent.example.com
Content-Type: application/json; charset=utf-8
User-Agent: ProxySeller-Webhooks/1
X-PS-Timestamp: 1762077838
X-PS-Signature: v1=5f0c2a…9e

{"event_id":"evt_01JZ8QA2C4E6G8J0K2M4P6R8T0","type":"order.active","created_at":"2026-11-02T10:03:58Z","api_version":"v1","order_id":"ord_01JZ8Q7K5N2R4T6V8X0Z2B4D6F","wallet":"0x857b06519e91e3a54538791bdbb0e22373e36b66","attempt":1,"data":{"lines":[{"line_id":"1","status":"active","delivered":2,"qty":2}],"expires_at":"2026-12-02T23:59:59Z"}}

Verifica la firma

X-PS-Signature: v1=hex(HMAC-SHA256(key, timestamp + "." + raw_body))

  • key — los bytes (UTF-8) del conjunto webhook_secret cadena, incluyendo el whsec_ prefijo.

  • timestamp — el valor de X-PS-Timestamp, segundos Unix.

  • raw_body — el cuerpo tal y como se ha recibido, antes de cualquier análisis JSON.

  • Durante las 24 horas posteriores a un cambio secreto, el encabezado es v1=<current>,v1=<previous>: acepta la solicitud si alguna de ellas coincide.

  • Rechaza las solicitudes cuya marca de tiempo difiera de tu reloj en más de 300 segundos.

Python

import hashlib
import hmac
import time

def verify(secret: str, timestamp: str, signature_header: str, raw_body: bytes, tolerance: int = 300) -> bool:
    if abs(time.time() - int(timestamp)) > tolerance:
        return False
    expected = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
    candidates = [part.strip()[3:] for part in signature_header.split(",") if part.strip().startswith("v1=")]
    return any(hmac.compare_digest(expected, candidate) for candidate in candidates)

Node.js

import crypto from 'node:crypto';

function verify(secret, timestamp, signatureHeader, rawBody, toleranceSeconds = 300) {
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;
  const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.`).update(rawBody).digest('hex');
  return signatureHeader.split(',').map((s) => s.trim()).filter((s) => s.startsWith('v1='))
    .some((s) => s.length === expected.length + 3
      && crypto.timingSafeEqual(Buffer.from(s.slice(3)), Buffer.from(expected)));
}

Reintentos

Regla

Valor

Primer intento

No antes de 30 segundos tras el suceso

Reintentos

Después de 1 min, 5 min, 30 min, 2 h, 6 h, 12 h y 24 h: 8 intentos en unas 44,6 horas

Demasiado antiguo

Un evento que tenga más de unas 45,6 horas ya no se envía.

Disyuntor

Tras tres fallos consecutivos, el resto de eventos de la secuencia esperan al siguiente intento.

Desactivar

Si el último intento de un evento falla y la URL no ha aceptado ningún webhook desde que se creó dicho evento, se desactiva el envío a la URL. El pedido en sí no se ve afectado.

Para habilitar una URL desactivada, envíala de nuevo con Orden de actualización: la misma URL como máximo una vez por hora; una nueva URL en cualquier momento. Los eventos perdidos siempre se encuentran en Ordenar eventos.

Normas de callback_url

Se comprueba en el momento de emitir el presupuesto y en PATCH. Cualquier incumplimiento dará lugar a 400 invalid_request:

Regla

detalle

ASCII imprimible, hasta 2048 caracteres

/callback_url: must be a printable URL up to 2048 characters

https solo

/callback_url: only https is allowed

No incluyas nombre de usuario ni contraseña en la URL.

/callback_url: credentials in URL are not allowed

Sin fragmento

/callback_url: fragment is not allowed

Solo puerto 443

/callback_url: only port 443 is allowed

Un nombre DNS público, una dirección IPv4 canónica o una dirección IPv6 entre paréntesis

/callback_url: host must be a public DNS name, /callback_url: IPv4 address must be a canonical dotted quad

Todas las direcciones del servidor son públicas

/callback_url: host resolves to a private or reserved address, /callback_url: host does not resolve

No es un proveedor del servicio en sí mismo

/callback_url: host is not allowed

El DNS se comprueba de nuevo antes de cada envío; la solicitud se envía únicamente a las direcciones comprobadas.

On this page