# Notificaciones

Las notificaciones son enviadas cada vez que:

- se realiza un cambio de estado de una Transacción, Suscripción o Autorización
- se produce un error al intentar confirmar una Transacción, Suscripción o Autorización
- se genera o no un nuevo pago después de un charge a una Autorización
- se genera o no un nuevo pago debido a una Suscripción
- se realizan acciones sobre un Pago


Se envía una notificación `POST` a la url definida en el campo `notify_url` que se envió en el momento de la creación del objeto.

> Gracias a que la url de notificación se define al crear el objeto, en el campo `notify_url`, la url puede ser dinámica pudiendo ser diferente para cada objeto creado.


## Lógica recomendada

La forma más sencilla de implementar la lógica de notificaciones es:

1. Usar el campo `notification_type` para identificar qué evento ha ocurrido.
2. Revisar el campo `fail`: si contiene un código de error, la notificación corresponde a un evento fallido; si es `null`, el evento fue exitoso.


## Valores de notification_type

El campo `notification_type` está siempre presente en todas las notificaciones.

### Transacción

| Valor | Descripción |
|  --- | --- |
| `transaction_confirmation_error` | El cliente intentó pagar y falló |
| `transaction_expired` | Transacción expirada |
| `transaction_cancelled` | Transacción cancelada |
| `transaction_rejected_by_rules` | Transacción rechazada por reglas de fraude |


### Suscripción

| Valor | Descripción |
|  --- | --- |
| `subscription_confirmation_error` | El cliente intentó confirmar la suscripción y falló |
| `subscription_done` | Suscripción confirmada |
| `subscription_expired` | Suscripción expirada |
| `subscription_cancelled` | Suscripción cancelada |
| `subscription_rejected_by_rules` | Cobro rechazado por reglas de fraude |
| `subscription_paused` | Suscripción pausada |
| `subscription_stopped` | Suscripción parada |
| `subscription_started` | Suscripción iniciada |
| `subscription_actived` | Suscripción activada |
| `subscription_charge_error` | Error al intentar cobrar una suscripción activa |


### Autorización

| Valor | Descripción |
|  --- | --- |
| `authorization_confirmation_error` | El cliente intentó confirmar la autorización y falló |
| `authorization_done` | Autorización confirmada |
| `authorization_expired` | Autorización expirada |
| `authorization_cancelled` | Autorización cancelada |
| `authorization_rejected_by_rules` | Autorización rechazada por reglas de fraude |
| `authorization_removed` | Autorización eliminada |
| `authorization_charge_error` | Error al intentar realizar un cobro sobre la autorización |


### Sale (Pago)

| Valor | Descripción |
|  --- | --- |
| `sale_created` | Pago completado. Puede corresponder a una transacción confirmada, un cobro a una suscripción o un cobro a una autorización. Usa el campo `type` para distinguirlos: `P` = Transacción, `S` = Suscripción, `A` = Autorización |
| `sale_refund` | Devolución realizada |
| `sale_refund_in_process` | Devolución en proceso |
| `sale_capture` | Captura de un pago que estaba en hold |
| `sale_void` | Liberación de un pago |
| `sale_settled` | Pago liquidado |


### Transferencia

| Valor | Descripción |
|  --- | --- |
| `transfer_completed` | Transferencia completada |
| `transfer_failed` | Transferencia fallida |


### Marketplace

| Valor | Descripción |
|  --- | --- |
| `client_compliance` | Verificación de compliance de cliente |
| `wallet_compliance` | Verificación de compliance de wallet |
| `iban_compliance` | Verificación de compliance de IBAN |


## Contenido de la notificación

La notificación consiste en un POST que envía un JSON con los siguientes campos:

- `notification_type`: Tipo de notificación. Ver tabla de valores más arriba.
- `fail`: En el caso de que este campo incluya contenido nos referimos a una notificación de error. El contenido sería un código de error, los cuales podemos ver [aquí](/tools/errors).
- `signature`: Firma de la notificación, para validar que la notificación es enviada por Zru. Ver más adelante como calcular la firma.
- `id`: ID de la Transacción, Suscripción o Autorización relacionada con la notificación.
- `type`: Tipo de objeto relacionado con la notificación (P - Transacción, S - Suscripción, A - Autorización).
- `order_id`: Incluye el contenido enviado en el campo `order_id` al crear el objeto.
- `status`: Estado de la transacción (N - Pendiente, D - Completado, C - Cancelado, E - Expirado).


> Los estados Completado, Cancelado y Expirado son estados finales.


- `subscription_status`: Estado de la Suscripción, solo se envía si la notificación es relacionada con una suscripción (W - En Espera, A - Activa, P - Pausada, S - Parada).


> El estado Parada es un estado final.


- `authorization_status`: Estado de la Autorización, solo se envía si la notificación es relacionada con una autorización (A - Activa, R - Eliminada).


> El estado Eliminada es un estado final.


- `amount`: Cantidad cobrada al cliente.
- `sale_id`: En el caso de que se haya cobrado al cliente incluirá el ID del Sale relacionado con el pago.
- `action`: Última acción del objeto.
- `sale_action`: Última acción del Sale.
- `_extra`: Incluye el contenido enviado en el campo `extra` al crear el objeto o al realizar un charge. No se envía en el caso de que no se haya enviado.
- `_charge_id`: Incluye el contenido enviado en el campo `charge_id` al realizar un charge.
- `_method`: En el caso de pagos con tarjeta incluye la información de la tarjeta utilizada.


> Es importante tener en cuenta al realizar la implementación que en cualquier momento puede añadirse un nuevo campo al JSON recibido.


### Posibles valores del campo `action`

- I: Error
- D: Completado
- E: Expirado
- C: Cancelado
- A: Suscripción Activa (solo en el caso de suscripción)
- T: Suscripción Iniciada (solo en el caso de suscripción)
- P: Suscripción Pausada (solo en el caso de suscripción)
- S: Suscripción Parada (solo en el caso de suscripción)
- R: Autorización Eliminada (solo en el caso de autorización)
- Y: Pago recibido (solo en el caso de suscripción o autorización)


### Posibles valores del campo `sale_action`

- I: Error
- G: Cantidad cobrada
- H: Cantidad en hold
- V: Cantidad liberada
- C: Cantidad capturada
- R: Cantidad devuelta
- S: Cantidad liquidada
- E: Cantidad en escrow rechazada


### Valores del campo `_method`

- `name`: Nombre de la tarjeta
- `masked`: Número de tarjeta enmascarada
- `unique_hash`: Hash que representa a la tarjeta de manera única. Siempre que un cliente utilice el mismo número de tarjeta y la misma fecha de expiración recibirán el mismo hash.
- `brand`: Marca de la tarjeta
- `expiration_month`: Mes de expiración de la tarjeta
- `expiration_year`: Año de expiración de la tarjeta


## Ejemplos

### Pago completado (sale_created)


```json
{
  "id": "a1b2c3d4-0000-0000-0000-000000000001",
  "fail": null,
  "type": "P",
  "notification_type": "sale_created",
  "status": "D",
  "action": "D",
  "amount": 157.5,
  "sale_id": "b2c3d4e5-0000-0000-0000-000000000001",
  "sale_action": "G",
  "order_id": "order_example_001",
  "signature": "c1eed82e684cccf2507535f137085d9aafa818114009d9c7f6b2a9edad013014"
}
```

### Intento de pago fallido (transaction_confirmation_error)


```json
{
  "id": "a1b2c3d4-0000-0000-0000-000000000002",
  "fail": "MC2P-07001",
  "type": "P",
  "notification_type": "transaction_confirmation_error",
  "status": "N",
  "action": "I",
  "amount": 13.2,
  "sale_id": "",
  "sale_action": "",
  "order_id": "order_example_002",
  "signature": "859e878993ccd736aec1c089f7dd5b73469d47b9213e88659e0ef22cc36f91d4"
}
```

## Calcular la firma

Los pasos para calcular la firma y verificar que es correcta son los siguientes:

1. Partimos del diccionario JSON recibido e ignoramos los keys:
  - `fail`
  - `signature`
  - cualquier otro que empiece por `_`
2. El resto de keys del JSON los ordenamos por orden alfabético, por ejemplo:
  - `['action', 'amount', 'authorization_status', 'id', 'order_id', 'sale_action', 'sale_id', 'status', 'subscription_status', 'type']`
3. Por ese orden ponemos los valores uno detrás de otro en una variable ignorando los que sean null, reemplazando en los valores los símbolos <, >, ", ', (, ), \ por espacio y quitando los espacios del inicio y del final de cada valor, por ejemplo:
  - `D5.0d825c974-7288-4ddf-ae8b-21635c44eac3323232G545b8519-3e3c-4ee7-adef-9da7eefe5283DP`
4. A eso le agregamos al final la Clave Secreta de vuestro entorno, por ejemplo:
  - `D5.0d825c974-7288-4ddf-ae8b-21635c44eac3323232G545b8519-3e3c-4ee7-adef-9da7eefe5283DP18754581c5434008b9262dd5a6938ed3`
5. Finalmente le hacemos sha256 a esa variable y obtendríamos el signature para comprobarlo con el recibido en el JSON, por ejemplo:
  - `783600a129c93cad54f561bca60e60c9b8dc328209841751a600a5e1c941ccee`


## Flujos más importantes

### Transacción

| Evento | `notification_type` | Notas |
|  --- | --- | --- |
| Error al intentar confirmar | `transaction_confirmation_error` | Verificar código de error en `fail` |
| Cancelación | `transaction_cancelled` | `status=C` |
| Expiración | `transaction_expired` | `status=E` |
| Transacción completada | `sale_created` | `status=D`, `type=P`, incluye `sale_id` |


El resto de notificaciones posibles siempre serán relacionadas con el pago.

### Suscripción

| Evento | `notification_type` | Notas |
|  --- | --- | --- |
| Error al intentar confirmar | `subscription_confirmation_error` | Verificar código de error en `fail` |
| Error al cobrar suscripción activa | `subscription_charge_error` | `status=D`, verificar código de error en `fail` |
| Cancelación | `subscription_cancelled` | `status=C` |
| Expiración | `subscription_expired` | `status=E` |
| Suscripción confirmada | `subscription_done` | `status=D`, sin `sale_id` |
| Pago recibido | `sale_created` | `type=S`, incluye `sale_id`. Se lanza la primera vez si la confirmación incluye cobro y en cada cobro posterior. |


El resto de notificaciones posibles siempre serán relacionadas con los pagos de la suscripción.

### Autorización

| Evento | `notification_type` | Notas |
|  --- | --- | --- |
| Error al intentar confirmar | `authorization_confirmation_error` | Verificar código de error en `fail` |
| Error al cobrar autorización activa | `authorization_charge_error` | `status=D`, verificar código de error en `fail` |
| Cancelación | `authorization_cancelled` | `status=C` |
| Expiración | `authorization_expired` | `status=E` |
| Autorización confirmada | `authorization_done` | `status=D`, sin `sale_id` |
| Pago recibido | `sale_created` | `type=A`, incluye `sale_id`. Se lanza si la confirmación incluye cobro y en cada cobro realizado con el endpoint `charge`. |


El resto de notificaciones posibles siempre serán relacionadas con los pagos de la autorización.

### Pago

> Estas notificaciones siempre incluyen en el campo `id` el objeto relacionado con el pago y el `status=D`.


| Evento | `notification_type` | Notas |
|  --- | --- | --- |
| Error en una acción sobre el pago | (varía) | Como devolución, liberación, etc. Verificar código de error en `fail`. |
| Captura (puede ser parcial) | `sale_capture` | Verificar campo `amount` |
| Liberación (puede ser parcial) | `sale_void` | Verificar campo `amount` |
| Devolución (puede ser parcial) | `sale_refund` | Verificar campo `amount` |
| Liquidación | `sale_settled` | - |


## Panel

Desde la sección **Desarrolladores** del panel tienes acceso a herramientas pensadas para facilitar las tareas de integración. Ve al menú lateral y selecciona **Desarrolladores** para acceder a las pestañas **Notificaciones** y **Webhooks**.

### Notificaciones

Muestra todas las notificaciones enviadas a tu servidor, la respuesta que devolvió y permite reenviarlas si es necesario.

Al desplegar una notificación verás:

- **Información**: ID de notificación, URL de notificación, fecha y hora.
- **Solicitud**: JSON completo enviado por Zru a tu servidor.
- **Respuesta**: respuesta devuelta por tu servidor.


Puedes filtrar por ID, ID externo, URL de notificación, fecha y código de respuesta. También puedes exportar el listado en CSV.

Para reenviar una notificación: despliega el detalle y haz clic en **Volver a enviar**.

### Webhooks

Los Webhooks permiten configurar los endpoints a los que Zru enviará notificaciones de forma global para todo el entorno, como alternativa a definir la `notify_url` en cada objeto.

> La diferencia entre Webhooks y Notificaciones: los **Webhooks** son la configuración del endpoint (a qué URL enviar). Las **Notificaciones** son los eventos concretos enviados a esos endpoints, con su solicitud y respuesta.