WebHooks
Es un mecanismo que permite que un sistema le avise automáticamente a otro cuando ocurre un evento, sin necesidad de que el segundo esté consultando todo el tiempo.
En vez de que tu aplicación consulte la API cada intervalo, el sistema origen envía una notificación a la URL que vos definiste. Esa notificación llega como una solicitud
HTTP POST con un cuerpo en formato JSON.
Eventos disponibles
| Categoría | Eventos |
|---|---|
| Pedidos | Completo (pedido_completo) |
Más eventos se pueden agregar en el futuro manteniendo el mismo formato.
Registro de Webhook
Para registrarse en el evento de completado de pedido, por ejemplo, debe enviar pedido_completo el campo de evento. Básicamente, realiza una solicitud POST en el punto final de Webhooks proporcionando un cuerpo con el tipo de webhook que desea crear, así como la URL donde se le notificará.
POST https://api.v2.digipwms.com/api/v2/WebHooks
{
"eventType": "Pedido_Completo",
"url": "https://myapp.com/pedidocompleto",
"secretKey": "string"
}
- eventType: evento al que se suscribe (ej:
pedido_completooPedido_Completo). - url: endpoint que recibirá los eventos.
- secretKey: clave secreta para validar la firma.
puede utilizar RequestCatcher . PostCatcher es una aplicación web que genera una URL única que puede utilizar como punto final de un webhook y muestra cualquier solicitud POST que se le envíe para que la examine.
Sobre el ordenamiento
Los mensajes de webhook se administran a través de un sistema distribuido, por lo que son manejados por varios servidores independientes que trabajan en paralelo para garantizar un procesamiento rápido, confiable y eficiente de los miles de mensajes que enviamos por minuto. Debido a la naturaleza del sistema distribuido, no podemos garantizar que el orden en que se colocan en cola para su procesamiento sea el mismo que el orden en que se procesan.
Además, algunos mensajes pueden enviarse varias veces con el mismo contenido. Esos mensajes deben tratarse como únicos. Es responsabilidad del desarrollador integrar su servicio con nuestro webhook para garantizar la idempotencia.
Verificación de un Webhook
Cada solicitud de Webhook incluye un X-Signature encabezado que se genera utilizando el secreto de la aplicación, junto con los datos enviados en la solicitud.
Descripción general del proceso:
Lee el contenido del mensaje desde el cuerpo de la solicitud HTTP.
Obtiene la firma enviada en el encabezado del webhook (X-Signature).
Genera una firma localmente usando la misma secretkey y el contenido del mensaje recibido.
Compara la firma generada con la firma recibida:
- Si coinciden, el webhook es válido y se procesa.
- Si no coinciden, se rechaza con una respuesta
Unauthorized.
@using Microsoft.AspNetCore.Mvc;
@using System.IO;
@using System.Linq;
@using System.Security.Cryptography;
@using System.Text;
@using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
public class WebhookController : ControllerBase
{
private const string SecretKey = "your_secret_key"; // Reemplazar
[HttpPost]
public async Task<IActionResult> ReceiveWebhook()
{
using var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var receivedSignature = Request.Headers["X-Signature"].FirstOrDefault();
var generatedSignature = GenerateSignature(SecretKey, body);
if (receivedSignature == generatedSignature)
{
var webhookEvent = System.Text.Json.JsonSerializer
.Deserialize<WebhookEvent>(body);
// Procesar webhook...
return Ok();
}
else
{
return Unauthorized();
}
}
private static string GenerateSignature(string secretKey, string payload)
{
var keyBytes = Encoding.UTF8.GetBytes(secretKey);
var bodyBytes = Encoding.UTF8.GetBytes(payload);
using var hmac = new HMACSHA256(keyBytes);
var hash = hmac.ComputeHash(bodyBytes);
return Convert.ToBase64String(hash);
}
}
Politicas de Reintento
Una notificación de Webhook espera un código de estado 2XX como respuesta
(para garantizar que la aplicación haya recibido la notificación) y tiene un tiempo de espera de 30 segundos.
Cuando no se puede entregar una notificación de webhook debido a un problema (por ejemplo, cuando la aplicación no funciona), la política de reintento se activa.
Se producirán 5 reintentos:
- El primero al minuto del intento original.
- Luego aproximadamente a los 2 minutos.
- Después a los 4 minutos.
- Más tarde a los 8 minutos.
- Y finalmente a los 30 minutos.
- Se envía el webhook.
- Espera 30 segundos la confirmación de respuesta por parte de la App.
- Si no recibimos ninguna respuesta, se activa la política de reintento.
Un código de respuesta de éxito detendrá las próximas notificaciones. Pero, si eso no sucede, las notificaciones se enviarán 5 veces.
Ejemplo de evento: pedido_completo
Headers:
Headers:
X-EVENT-TYPE: pedido_completo
X-SIGNATURE: 2iCYbCLjEKwsCJtNd42RufFFGu4fVIgOq+C77Ut7URM=
Body:
{
"eventId": 24,
"event": "Pedido_Completo",
"eventAt": "2024-07-26T19:50:09.538083",
"data": {
"Codigo": "CONSOLIDADO",
"Fecha": "2024-06-25T15:53:26.658816",
"FechaEstimadaEntrega": "2024-06-25T00:00:00",
"Estado": "Completo",
"FechaHoraEstado": "2024-06-25T17:05:18.6726419",
"Observacion": null,
"Importe": null,
"CodigoDespacho": null,
"CodigoDeEnvio": null,
"ServicioDeEnvioTipo": null,
"OrdenPreparacion": null,
"Items": [
{
"Linea": null,
"Unidades": 1,
"MinimoDiasVencimiento": 1,
"UnidadesSatisfecha": 1,
"PesoDeclarado": null,
"Lote": null,
"FechaVencimiento": null,
"Articulo": {
"Codigo": "132011",
"Descripcion": "Alcohol en Aerosol Rexona Boca Juniors",
"EsVirtual": false
}
}
],
"Tags": [],
"ClienteUbicacion": {
"Descripcion": "DIGITAL EXPRESS S.R.L.",
"Direccion": "Delgado 1550, C1426BDY CABA, Argentina",
"Provincia": "Buenos Aires",
"Localidad": "Delgado 1550, C1426BDY CABA, Argentina",
"Cliente": {
"Codigo": "CL-000329",
"Descripcion": "DIGITAL EXPRESS S.R.L."
}
}
}
}