# Webhooks API # Tutorial Con el sistema de **webhooks**, puedes suscribirte a los eventos que se producen sobre la mayoría de recursos del sistema, de forma que puedes recibir notificaciones para que tu sistema reaccione como corresponda. La mayoría de recursos permiten suscribirse a los eventos de: - `created` - `updated` - `deleted` ## Recursos con soporte de Webhooks | Dominio | Recurso | Descripción | |-------------|------------------------|------------------------------------| | Contact | Customer | Clientes | | Contact | Supplier | Proveedores | | Warehouse | Article | Artículos | | Warehouse | Warehouse | Almacenes | | Purchase | Order | Pedidos de proveedor | | Purchase | Delivery-note | Albaranes de proveedor | | Purchase | Invoice | Facturas de proveedor | | Sale | Quote | Presupuesto de cliente | | Sale | Order | Pedido de cliente | | Sale | Delivery-note | Albarán de cliente | | Sale | Invoice | Factura de cliente | | Sale | Template-sale-invoice | Plantilla de facturación periódica | | Accounting | Account | Cuentas contables | | Accounting | Entry | Asientos contables | --- ## Obtención del Api Key Para utilizar el sistema de webhooks, es necesario disponer de un Api Key desde el área del desarrollador. Los pasos para obtenerlo son los siguientes: 1. Accede a tu cuenta de PRANA. 2. Dirígete al área de "Configuración". 3. Selecciona la opción "Desarrolladores". 4. Haz clic en "Añadir API Key". 5. Dale un nombre descriptivo a tu API Key y guarda los cambios. 6. Copia el valor del API Key generado y guárdalo en un lugar seguro. Este valor tendrás que pasarlo como cabecera, en todas las peticiones que hagas contra el sistema. ![Añadir ApiKey](api-key.png) --- ## Recursos y eventos a los que puedes suscribirte Puedes obtener la lista completa de recursos y eventos a los que es posible suscribirse, de esta forma. **Request** ```http GET /event-type Content-Type: application/json x-api-key: ``` **Responses** **200 OK** Lista de tipos de evento disponibles en el sistema. ```json [ { "appName": "PRANA", "eventDomain": "ACCOUNTING", "resource": "ACCOUNT", "eventName": "CREATED", "semanticName": "PRANA.ACCOUNTING.ACCOUNT.CREATED", "id": "c6e050ee-b2a8-4df9-bf80-7655be7afbdf", "active": true }, { "appName": "PRANA", "eventDomain": "ACCOUNTING", "resource": "ACCOUNT", "eventName": "DELETED", "semanticName": "PRANA.ACCOUNTING.ACCOUNT.DELETED", "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "active": true } ] ``` ## Subscribirse a eventos Para crear una nueva subscripción, debes hacer una petición POST indicando: * `callbackUrl`: URL de tu sistema donde deseas recibir las notificaciones * `secret`: Palabra clave que usaremos para firmar cada mensaje * `events`: Lista de cadenas con los nombres semánticos de los eventos a los que deseas suscribirte ```http POST /subscription Content-Type: application/json x-api-key: { "callbackUrl": "https://url-de-tu-sistema.com/webhook", "secret": "", "events": [ "PRANA.CONTACT.CUSTOMER.CREATED", "PRANA.CONTACT.CUSTOMER.UPDATED", "PRANA.CONTACT.CUSTOMER.DELETED" ] } ``` **200 OK** Obtendrás una respuesta con los datos de la suscripción creada. ```json { "subscriptionId": "f575bd47-826b-4ff8-9934-60656ee7d89f", "responseState": "SUCCESS", "errors": null } ``` **handshake** Al crear una nueva suscripción, el sistema realizará una petición `POST` a la URL indicada en `callbackUrl`, para verificar que tu sistema está preparado para recibir las notificaciones. El sistema esperará una respuesta con código `200 OK` y cuerpo vacío, para considerar que la verificación ha sido correcta. El mensaje de esta petición, contendrá la siguiente información. ```json { "subscriptionId": "f575bd47-826b-4ff8-9934-60656ee7d89f", "tenantInformation": { "tenantId": "999999", "userId": "aaaaaa999999" }, "eventType": { "appName": "webhook", "eventDomain": "", "resource": "", "eventName": "handshake", "semanticName": "webhook...handshake", "id": "e53ae4e1-d970-43de-8bf5-f7be2954e46d", "active": true }, "payload": "{\"Type\":\"Acknowledge\"}" } ``` * `subscriptionId`: Identificador de la suscripción que acabas de crear. * `tenantInformation`: Información del inquilino y usuario asociado a la suscripción. * `eventType`: Tipo de evento, en este caso `handshake`. * `payload`: Contenido del mensaje, en este caso un JSON con el campo `Type` con valor `Acknowledge`. A partir de este momento, tu sistema estará preparado para recibir las notificaciones de los eventos a los que te has suscrito. ### Notificaciones de eventos Cada vez que se produzca un evento al que te has suscrito, el sistema realizará una petición `POST` a la URL indicada en `callbackUrl`. Esta petición incluirá una cabecera `x-signature`, que contendrá una firma HMAC-SHA256 del cuerpo del mensaje, utilizando la `secret` que proporcionaste al crear la suscripción. Esto te permitirá verificar la autenticidad del mensaje recibido. El cuerpo del mensaje tendrá la siguiente estructura: ```json { "subscriptionId": "f575bd47-826b-4ff8-9934-60656ee7d89f", "tenantInformation": { "tenantId": "999999", "userId": "aaaaaa999999" }, "eventType": { "appName": "PRANA", "eventDomain": "CONTACT", "resource": "CUSTOMER", "eventName": "UPDATED", "semanticName": "PRANA.CONTACT.CUSTOMER.UPDATED" }, "payload": "{\"EntityId\":\"369986\"}" } ``` En el elemento `payload`, encontrarás la información específica del evento. En este caso, el campo `EntityId` indica el identificador del cliente que ha sido actualizado. Con esta información, podrás enviar una petición a la API para obtener los detalles del cliente actualizado. ## Consulta tus suscripciones En cualquier momento, puedes consultar las suscripciones que has creado realizando una petición `GET` a la siguiente URL: ```http GET /subscription Content-Type: application/json x-api-key: ``` ```json [ { "id": "f575bd47-826b-4ff8-9934-60656ee7d89f", "secret": "", "callbackUrl": "https://url-de-tu-sistema.com/webhook", "status": "ACTIVE", "statusMessage": "", "webhooks": [ { "id": "2a87d134-6458-4379-af71-1cdab4f77d01", "eventType": { "appName": "PRANA", "eventDomain": "CONTACT", "resource": "CUSTOMER", "eventName": "CREATED", "semanticName": "PRANA.CUSTOMER.CUSTOMER.CREATED" } }, { "id": "9562db1d-b3a5-43f3-b0d7-daebed0b7c06", "eventType": { "appName": "PRANA", "eventDomain": "CONTACT", "resource": "CUSTOMER", "eventName": "UPDATED", "semanticName": "PRANA.CUSTOMER.CUSTOMER.UPDATED" } }, { "id": "55f62ac0-07e3-4d87-bf4f-5ecc55b47f89", "eventType": { "appName": "PRANA", "eventDomain": "CONTACT", "resource": "CUSTOMER", "eventName": "DELETED", "semanticName": "PRANA.CUSTOMER.CUSTOMER.DELETED" } } ] } ] ``` ## Elimina una suscripción Si deseas eliminar una suscripción, puedes hacerlo realizando una petición `DELETE` de la siguiente forma: ```http DELETE /subscription/{subscriptionId} Content-Type: application/json x-api-key: ``` Donde `subscriptionId` es el identificador de la suscripción que deseas eliminar. En este caso, la respuesta del sistema será un código 200 OK, indicando que la suscripción ha sido eliminada correctamente. ## Actualiza una suscripción Si necesitas actualizar una suscripción existente, puedes hacerlo mediante una petición `PUT`. La estructura de la petición es similar a la de creación, pero debes incluir el `subscriptionId` de la suscripción que deseas actualizar. Los valores que puedes actualizar son: * `callbackUrl`: URL de tu sistema donde deseas recibir las notificaciones * `secret`: Palabra clave que usaremos para firmar cada mensaje * `status`: Estado de la suscripción. Puede ser `ACTIVE` o `INACTIVE` ```http PUT /subscription/{subscriptionId} Content-Type: application/json x-api-key: { "callbackUrl": "https://url-de-tu-sistema.com/webhook", "secret": "", "status": "ACTIVE" } ``` ## Firma y verificación de mensajes Cada notificación enviada a tu sistema incluirá una cabecera `x-signature`, que contiene una firma HMAC-SHA256 del cuerpo del mensaje. Esta firma se genera utilizando la `secret` que proporcionaste al crear la suscripción. ```java import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; public final class SignatureUtils { private static final String ALGORITHM = "HmacSHA256"; private SignatureUtils() { throw new IllegalStateException("Utility class"); } public static String generateSignature(String secret, String payload) { try { SecretKey secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), ALGORITHM); Mac mac = Mac.getInstance(ALGORITHM); mac.init(secretKey); return Base64.getEncoder().encodeToString( mac.doFinal(payload.getBytes(StandardCharsets.UTF_8)) ); } catch (NoSuchAlgorithmException ex) { throw new IllegalStateException("Algorithm " + ALGORITHM + " not available", ex); } catch (InvalidKeyException ex) { throw new IllegalStateException("Invalid secret key for signature generation", ex); } } } ``` Version: 1.0.0 ## Servers Generated server url ``` https://ca-prana-prod-weu-webhooks.whitesky-98ecba0e.westeurope.azurecontainerapps.io ``` ## Security ### ApiKeyAuth Type: apiKey In: header Name: X-API-KEY ## Download OpenAPI description [Webhooks API](https://developers.prana.software/_bundle/Webhooks/openwebhooks.yaml) ## Subscriptions Endpoints for subscription management ### Update a subscription - [PUT /subscription/{id}](https://developers.prana.software/webhooks/openwebhooks/subscriptions/updatewebhook.md): Updates the data of an existing subscription ### Delete a subscription - [DELETE /subscription/{id}](https://developers.prana.software/webhooks/openwebhooks/subscriptions/deletewebhook.md): Deletes an existing subscription by its ID ### Get all subscriptions - [GET /subscription](https://developers.prana.software/webhooks/openwebhooks/subscriptions/getbyapikey.md): Retrieves the list of subscriptions associated with the authenticated API Key ### Create a new subscription - [POST /subscription](https://developers.prana.software/webhooks/openwebhooks/subscriptions/subscribe.md): Creates a new subscription to webhook events