> ## Documentation Index
> Fetch the complete documentation index at: https://developers.confiopagos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integración de Webhooks para Notificaciones en Tiempo Real

> Aprende a configurar y manejar webhooks para recibir notificaciones de eventos importantes de Confío en tiempo real.

Esta guía explica cómo puedes usar webhooks para recibir notificaciones automáticas de Confío cada vez que ocurran eventos importantes, como un cambio en el estado de un pago. Implementar webhooks es fundamental para mantener tu plataforma sincronizada y automatizar tus flujos de trabajo.

## Descripción General del Proceso

Cuando ocurre un evento en tu cuenta de Confío, como la actualización del estado de un pago, Confío envía una solicitud `POST` a un endpoint que tú configuras. Esta solicitud contiene toda la información relevante sobre el evento.

Tu plataforma debe:

1. **Recibir** la notificación del webhook en un endpoint público.
2. **Verificar** que la solicitud proviene de Confío (usando el token de autorización).
3. **Procesar** la información del evento y actualizar el estado correspondiente en tu sistema.
4. **Responder** con un código de estado `200 OK` para confirmar la recepción.

```mermaid theme={null}
sequenceDiagram
    participant Confio
    participant TuPlataforma as "Tu Plataforma"

    Note over Confio, TuPlataforma: Ocurre un evento en Confío (ej. cambio de estado de pago)
    Confio->>TuPlataforma: POST /tu-endpoint-de-webhooks
    Note right of Confio: Payload con datos del evento<br>Headers: Authorization, X-Confio-Event
    TuPlataforma-->>Confio: HTTP 200 OK
```

## Requisitos Previos

Para manejar webhooks de Confío, necesitarás:

1. Un **endpoint HTTPS** en tu servidor que sea accesible públicamente.
2. Haber contactado a tu **gerente de cuenta de Confío** para:
   * Registrar la URL de tu endpoint de webhooks
   * Obtener o definir la `WEBHOOK_KEY` que Confío usará para autenticarse en tus webhooks
   * Configurar los eventos que deseas recibir
3. Lógica en tu backend para verificar y procesar las solicitudes entrantes.

## Seguridad de los Webhooks

Para asegurar que las notificaciones son genuinas y provienen de Confío, debes verificar el encabezado `Authorization` en cada solicitud entrante.

* **Authorization**: `Bearer <WEBHOOK_KEY>`

Este es el token acordado o registrado para autenticar a Confío contra tu endpoint. Cualquier solicitud que no contenga este encabezado o cuyo token no sea válido debe ser rechazada.

Además, Confío incluye un checksum en el header `X-Confio-Checksum` y en `signature.checksum`.

### Firma/checksum

El checksum se calcula así:

```text theme={null}
SHA256(data[property1] + data[property2] + ... + timestamp + signature_key)
```

Detalles:

* Usa las propiedades en el orden exacto de `signature.properties`.
* Concatena los valores como strings, sin separadores.
* Concatena `timestamp` después de las propiedades.
* Concatena la clave de firma al final.
* Es SHA-256 simple, no HMAC.
* El resultado es hexadecimal en mayúscula, sin prefijos como `sha256=`.

Clave de firma:

* Usa la `WEBHOOK_KEY` configurada para el webhook.

## Eventos de Webhook

Confío envía diferentes tipos de eventos, cada uno identificado por el encabezado `X-Confio-Event` y el campo `event` en el payload.

### Cambio de Estado del Pago

* **Event**: `payment.statusChanged`
* **Cuándo se envía**: Cuando el estado de un pago es actualizado.
* **Payload**: Ejemplo real

```json theme={null}
{
  "event": "payment.statusChanged",
  "data": {
    "name": "stores/01JXJVXE6R10GB6MX6SSPW40AM/payments/01K4V4HTSRQA4N7R6VQQSQXY7W",
    "url": "https://checkout.confiopagos.com/p/01K4V4HTSRQA4N7R6VQQSQXY7W",
    "amountCents": 8000000,
    "currencyCode": "COP",
    "title": "Dos Memorias Ram",
    "description": "Dual channel de memoria ram de 16gb cada una gamer RGB a 4600mhz marca viper DDr4",
    "buyer": {
      "firstName": "Juan",
      "phoneNumber": "+573053568988",
      "email": "juan@example.com"
    },
    "status": "UNDER_REVIEW",
    "organization": "organizations/01JXJVXE5240N8BZVPMWF91576",
    "redirectUri": "https://tu-tienda.com/ordenes/123",
    "disableBuyerNotification": false,
    "paymentType": "PRODUCT",
    "enabledPaymentMethods": ["CARD", "PSE"],
    "correlationId": "ord_12345"
  },
  "timestamp": 1757553509,
  "signature": {
    "properties": [
      "name",
      "correlationId",
      "amountCents",
      "currencyCode",
      "status"
    ],
    "checksum": "4F6A..."
  }
}
```

### Cambio de Estado del Intento de Pago

* **Event**: `paymentAttempt.statusChanged`
* **Cuándo se envía**: Cuando el estado de un intento de pago es actualizado.
* **Payload**: Ejemplo real

```json theme={null}
{
  "event": "paymentAttempt.statusChanged",
  "data": {
    "name": "stores/01JXJVXE6R10GB6MX6SSPW40AM/payments/01K4V4HTSRQA4N7R6VQQSQXY7W/attempts/01K4V4KT2T2HFBP9WJECW5373X",
    "createTime": "2025-09-11T01:00:37.337Z",
    "method": "PSE",
    "payer": {
      "name": "users/01JXJVXE3SNHKVCEY2E8SR89D0",
      "firstName": "Juan",
      "lastName": "Perez",
      "document": "132656565",
      "documentType": "CC",
      "phoneNumber": "+57305595686",
      "email": "juan@gmail.com",
      "ip": "0.0.0.0"
    },
    "status": "SUCCEEDED",
    "correlationId": "ord_12345",
    "errorMessage": ""
  },
  "timestamp": 1757552495,
  "signature": {
    "properties": ["name", "correlationId", "method", "status"],
    "checksum": "4F6A..."
  }
}
```

### Estado de Cobro de Suscripción

* **Event**: `subscription.billingStatusChanged`
* **Cuándo se envía**: Cuando se procesa un cobro de suscripción, exitoso o fallido.
* **Payload**: Ejemplo de cobro exitoso

```json theme={null}
{
  "event": "subscription.billingStatusChanged",
  "data": {
    "name": "stores/01JXJVXE6R10GB6MX6SSPW40AM/subscription-plans/01K4V7HTSRQA4N7R6VQQSQXY0Z/subscriptions/01K4V5HTSRQA4N7R6VQQSQXY8X",
    "payment": "organizations/01JXJVXE5240N8BZVPMWF91576/stores/01JXJVXE6R10GB6MX6SSPW40AM/payments/01K4V6HTSRQA4N7R6VQQSQXY9Y",
    "cycleNumber": 3,
    "amountCents": 5000000,
    "currencyCode": "COP",
    "status": "SUCCEEDED",
    "createTime": "2026-01-14T10:00:00Z"
  },
  "timestamp": 1768384800,
  "signature": {
    "properties": [
      "name",
      "cycleNumber",
      "amountCents",
      "currencyCode",
      "status",
      "payment"
    ],
    "checksum": "4F6A..."
  }
}
```

**Payload**: Ejemplo de cobro fallido

```json theme={null}
{
  "event": "subscription.billingStatusChanged",
  "data": {
    "name": "stores/01JXJVXE6R10GB6MX6SSPW40AM/subscription-plans/01K4V7HTSRQA4N7R6VQQSQXY0Z/subscriptions/01K4V5HTSRQA4N7R6VQQSQXY8X",
    "cycleNumber": 3,
    "amountCents": 5000000,
    "currencyCode": "COP",
    "status": "FAILED",
    "failedCount": 1,
    "reason": "Fondos insuficientes",
    "createTime": "2026-01-14T10:00:00Z"
  },
  "timestamp": 1768384800,
  "signature": {
    "properties": [
      "name",
      "cycleNumber",
      "amountCents",
      "currencyCode",
      "status",
      "failedCount",
      "reason"
    ],
    "checksum": "4F6A..."
  }
}
```

### Cambio de Estado de Suscripción

* **Event**: `subscription.subscriptionStatusChanged`
* **Cuándo se envía**: Cuando cambia el estado de una suscripción, por ejemplo al crearse, aceptarse, entrar en mora, suspenderse o cancelarse.
* **Payload**: Ejemplo de suscripción creada

```json theme={null}
{
  "event": "subscription.subscriptionStatusChanged",
  "data": {
    "name": "stores/01JXJVXE6R10GB6MX6SSPW40AM/subscription-plans/01K4V7HTSRQA4N7R6VQQSQXY0Z/subscriptions/01K4V5HTSRQA4N7R6VQQSQXY8X",
    "status": "PENDING_ACCEPTANCE",
    "createTime": "2026-01-14T10:00:00Z",
    "buyer": {
      "email": "cliente@example.com",
      "phoneNumber": "+573001234567",
      "firstName": "María",
      "lastName": "González"
    }
  },
  "timestamp": 1768384800,
  "signature": {
    "properties": ["name", "status", "buyer"],
    "checksum": "4F6A..."
  }
}
```

**Payload**: Ejemplo de suscripción cancelada

```json theme={null}
{
  "event": "subscription.subscriptionStatusChanged",
  "data": {
    "name": "stores/01JXJVXE6R10GB6MX6SSPW40AM/subscription-plans/01K4V7HTSRQA4N7R6VQQSQXY0Z/subscriptions/01K4V5HTSRQA4N7R6VQQSQXY8X",
    "status": "CANCELED",
    "createTime": "2026-01-14T10:00:00Z",
    "reason": "Solicitado por el cliente",
    "buyer": {
      "email": "cliente@example.com",
      "phoneNumber": "+573001234567",
      "firstName": "María",
      "lastName": "González"
    }
  },
  "timestamp": 1768384800,
  "signature": {
    "properties": ["name", "status", "buyer", "reason"],
    "checksum": "4F6A..."
  }
}
```

## Mejores Prácticas

1. **Responde Rápidamente**: Tu endpoint debe responder con un código `200` lo más rápido posible. Para operaciones que toman tiempo, procésalas de forma asíncrona en segundo plano para evitar timeouts.

2. **Manejo de Reintentos**: Confío reintentará enviar un webhook si no recibe una respuesta exitosa (`2xx`). Tu sistema debe ser idempotente para manejar notificaciones duplicadas sin causar problemas.

3. **Registra las Notificaciones**: Mantén un registro de los webhooks recibidos. Esto es invaluable para depurar problemas y tener una auditoría de los eventos.

## Recursos Adicionales

* [Guía de Eventos Logísticos](/cookbooks/logistics)
* [Referencia de la API](/api-reference)
