---
title: Webhooks
description: Webhooks de Coinetic: configuración, verificación de la firma HMAC, deduplicación, reintentos, orden de entrega, tipos de eventos y rotación del secreto.
url: https://coinetic.money/es/docs/webhooks/
lang: es
---

# Webhooks

Coinetic notifica a su servidor los cambios de una factura mediante una solicitud POST. Un webhook es una señal de «consulte la factura», no una prueba de pago.

## Configuración

- Panel → «Claves y webhooks» → «Añadir». La URL debe ser `https://`, con dirección pública y puerto 443 (en el sandbox, también `http://localhost`).
- El secreto del endpoint se muestra una sola vez. Puede tener hasta 5 endpoints activos; cada evento se envía a todos.

## Solicitud

```http
POST /webhooks/coinetic HTTP/1.1
Content-Type: application/json
User-Agent: cryptopay-webhooks/1
X-Webhook-Id: evt_3f9c…
X-Webhook-Timestamp: 1760000000
X-Webhook-Signature: v1=5d1e…

{"id":"evt_3f9c…","type":"invoice.paid","created_at":"2026-10-12T15:04:05Z","livemode":true,"data":{"invoice_id":"inv_x7k2…","order_id":"ORDER-1001","status":"paid","paid_amount":"49990000"}}
```

`X-Webhook-Id` se mantiene en los reintentos. Durante una rotación del secreto, `X-Webhook-Signature` contiene dos firmas separadas por una coma. Los nombres técnicos (`cryptopay-webhooks/1`) son históricos; no necesita cambiarlos en su código.

## Verificación de la firma

```
expected = "v1=" + hex(HMAC-SHA256(webhook_secret, X-Webhook-Timestamp + "." + raw_body))
```

- Tome el **cuerpo sin procesar**: los bytes antes de interpretar el JSON.
- Compruebe que `X-Webhook-Timestamp` no difiere de la hora actual en más de 5 minutos.
- Divida `X-Webhook-Signature` por la coma. La firma es válida si **cualquiera** de las partes coincide con la esperada (comparación en tiempo constante).
- Si no coincide, responda `401` y no haga nada más.

Referencia: secreto `whsec-0123456789abcdef0123456789abcdef`, timestamp `1760000000`, cuerpo `{"id":"evt_1","type":"invoice.paid"}` → `v1=aceeb56215ba09e7a2923d48f89afb8331f422f2d0a8cf60f76fef69fe06a6a4`.

## Procesamiento

```
verificar la firma → deduplicar por X-Webhook-Id → GET /v1/invoices/{invoice_id}
→ actualizar el pedido según el estado de la API (entrega una sola vez) → responder 2xx
```

- **Deduplicación.** Un mismo evento puede llegar varias veces. Guarde los `X-Webhook-Id` procesados y marque el pedido como «entregado» en la misma transacción que la entrega.
- **Responda rápido**: en menos de 10 segundos. Envíe el trabajo largo a una cola.
- **Códigos de respuesta:** `2xx`, aceptado; `410 Gone`, no reintentar esta entrega; cualquier otro código (incluido `3xx`: las redirecciones no se siguen) o un tiempo de espera agotado provocan un reintento.
- Ignore los campos y tipos de eventos que no conozca: la lista irá creciendo.

Encontrará gestores listos para usar en cuatro lenguajes en el [inicio rápido](https://coinetic.money/es/docs/quickstart/#webhook).

## Reintentos

10 s → 30 s → 2 min → 10 min → 30 min → 1 h → 3 h ×7 → 1 h, con una pequeña variación aleatoria. El último intento se hace aproximadamente un día después. Una entrega fallida puede enviarse de nuevo: panel → «Webhooks» → «Reenviar».

## Orden

Los eventos de **una misma factura** se entregan al endpoint en orden: el siguiente no sale mientras la entrega anterior siga pendiente de reintento. Cuando esta termina, con éxito o sin él, se envían los siguientes. Por eso, básese en el estado de `GET /v1/invoices/{id}` y no en la secuencia de eventos. Los eventos de facturas distintas son independientes.

## Tipos de eventos

| Evento | Cuándo |
| --- | --- |
| `invoice.detected` | El pago es visible en la red |
| `invoice.confirming` | El pago está en un bloque y se acumulan confirmaciones |
| `invoice.paid` | Pagada y confirmada: puede entregar (tras volver a consultar). `data.late: true` indica que una stablecoin llegó fuera de plazo y se acreditó automáticamente |
| `invoice.overpaid` | Pagada con excedente |
| `invoice.underpaid` | Confirmado menos de lo necesario |
| `invoice.awaiting_payment` | La factura vuelve a esperar el pago (por ejemplo, tras la reorganización de su único pago) |
| `invoice.expired` | Venció el plazo sin pago |
| `invoice.late_payment` | Pago con un activo volátil fuera de plazo |
| `invoice.manual_review` | Pago en verificación AML |
| `invoice.payment_held` | Pago retenido por AML (cuarentena) |
| `invoice.reorged` | El bloque con el pago se revirtió y el estado se recalculó (por ejemplo, `paid` → `confirming`) |
| `invoice.payment_after_close` | Llegó un pago a una factura ya cerrada: no paga el pedido y queda disponible para reembolso |
| `invoice.cancelled` | Factura cerrada sin pago al ejecutarse un reembolso |
| `refund.sent` | Reembolso ejecutado; `data.refund` incluye el importe, la dirección y el `tx_hash` |

Los eventos de facturación (`billing.*`) se refieren a las facturas de comisión de la plataforma: emitida, pagada, vencida, suspensión y levantamiento de la suspensión.

> **Productos digitales e `invoice.reorged`.** Una reorganización después de `paid` es poco frecuente, pero ocurre. Si entrega el producto al instante, suscríbase a este evento y derive esos casos al equipo de soporte.

## Rotación del secreto

Panel → «Cambiar secreto»: Coinetic empieza a firmar con **ambos** secretos.

- Añada el secreto nuevo a su servidor (acepte ambos).
- Pulse «Finalizar rotación»: el antiguo se eliminará.
- Retire el secreto antiguo de su servidor.
