Webhooks are a way to receive real-time notifications from Retino about various events. Instead of periodically querying the API, you can create a webhook and Retino will automatically send you information about changes to the URL you specify.
Note: Webhooks are a premium feature included in the "API & Webhooks" extension. If you have this extension active, you can find webhook settings in Settings > API > Webhooks.
For information about the shipping.ordered
webhook, see the Shipping Order Webhook article.
Creating a Webhook
Prepare a URL endpoint on your server to receive webhooks (e.g.,
your-store.com/webhook-retino
)Go to Settings > API > Webhooks in Retino
Click "Create webhook"
Enter the URL of your endpoint
Select the events you want to subscribe to
Save the settings
Webhooks are configured at the account level and are not limited to individual users. After creating a webhook, you can send a test event from the webhook detail to verify the correct configuration.
Security
Each webhook includes an authentication token in the request header to verify that the request is actually from Retino:
X-Retino-Secret: <token>
You can find this token in the individual webhook settings. When receiving webhooks, you should always verify that the header contains the correct token matching your webhook.
Renewing the Secret Token
IMPORTANT! If you renew the webhook token, your server will not be able to receive webhooks until you implement the new token on your side.
HTTPS
We strongly recommend using the encrypted HTTPS protocol for communication. If your webhook uses the insecure HTTP protocol, Retino will notify you about this risk in the settings.
Event Types for Tickets
A webhook can be linked to several event types simultaneously. Each event sends information about the ticket, products, shipping, and the associated order.
Event | Description |
| Creation of a new ticket |
| Any modification of the ticket |
| Creation of a new product in the ticket |
| Updating a product in the ticket |
| Creation of new shipping in the ticket |
| Shipping modification or status update |
| Creation of a refund |
| Modification of a refund |
Sample Data for Events
ticket.created / ticket.updated
Sent when a ticket is created or modified.
{ "event_type": "ticket.created", "created_at": "2020-09-24T10:28:10.010Z", "ticket": { "id": "8fad1c8d-3740-4aab-a224-c0ef379ea216", "code": "20210001", "state": "4531636a-108f-4ae3-abff-367901418600", "tags": [ "3fa85f64-5717-4562-b3fc-2c963f66afa6" ], "type": "44c88eec-b995-4c84-b269-2ff06c8fe5d5", "owner": "e342f794-7b11-4acc-a46e-784a74a30af2", "bound_order": null, "customer": { "name": "Vladimír Remek", "email": "[email protected]", "phone": "987654321" }, "currency": "CZK", "language": "cs", "country": "CZ", "order_id": "234567", "order_date": "2020-09-09T00:00:00.000Z", "customer_rating": null, "customer_rating_comment": null, "custom_fields": { "resolve_by": "2020-10-08" }, "verification_state": "VERIFIED_AUTOMATICALLY", "is_unread": false, "created_at": "2020-09-24T11:30:53.210107+02:00", "updated_at": "2020-09-24T11:30:53.525472+02:00", "closed_at": null } }
ticket.product.created / ticket.product.updated
Sent when a product is added or updated in the ticket.
{ "event_type": "ticket.product.created", "created_at": "2020-09-24T10:28:10.010Z", "ticket_id": "8fad1c8d-3740-4aab-a224-c0ef379ea216", "product": { "id": "09c69980-299d-4d37-81d5-ed18c9565856", "bound_order_item": null, "price": { "with_vat": "990000000.0000", "without_vat": null, "vat": null }, "files": [], "name": "Apollo 11", "manufacturer": "NASA", "category": "Rakety", "product_id": "#1", "variant": "XL", "ean": "", "serial": null, "amount": "1.0000", "custom_fields": { "1b8508b0-ba85-427c-b23c-ae739453b0cd": "74ea523e-ea95-44d4-85ff-758c485ff77d" } } }
ticket.shipping.created / ticket.shipping.updated
Sent when shipping is created or updated.
{ "event_type": "ticket.shipping.created", "created_at": "2020-09-24T10:28:10.010Z", "ticket_id": "8fad1c8d-3740-4aab-a224-c0ef379ea216", "shipping": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "vendor_id": "PPL", "shipping_type": "Parcel", "state": "WAITING_FOR_PICKUP", "trace_url": "http://example.com/tracking/123", "sender": { "name": "Vladimír Remek", "email": "[email protected]", "phone": "987654321", "address": { "street": "Kosmonautů 10", "city": "Praha", "zip": "16000", "country": "CZ" } }, "recipient": { "name": "Your Store", "email": "[email protected]", "phone": "123456789", "address": { "street": "Hlavní 123", "city": "Praha", "zip": "11000", "country": "CZ" } }, "created_at": "2020-09-24T10:28:10.010Z", "updated_at": "2020-09-24T10:28:10.010Z" } }
ticket.refund.created / ticket.refund.updated
Sent when a refund is created or updated.
{ "event_type": "ticket.refund.created", "created_at": "2020-09-24T10:28:10.010Z", "ticket_id": "8fad1c8d-3740-4aab-a224-c0ef379ea216", "refund": { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "amount": "990000000.0000", "currency": "CZK", "state": "WAITING_FOR_APPROVAL", "type": "BANK_ACCOUNT", "bank_account": { "account_number": "123456789/1010", "iban": "CZ1234567890123456789012", "bic": "GIBACZPX" }, "created_at": "2020-09-24T10:28:10.010Z", "updated_at": "2020-09-24T10:28:10.010Z" } }
Implementing Webhook Reception
To receive webhooks, you need to implement an endpoint on your server that handles HTTP POST requests. Here's a simple example implementation in Node.js:
const express = require('express'); const bodyParser = require('body-parser'); const app = express();app.use(bodyParser.json());app.post('/webhook-retino', (req, res) => { // Check secret token const token = req.headers['x-retino-secret']; if (token !== 'your_secret_token') { return res.status(403).send('Invalid token'); } // Process event const event = req.body; console.log(`Received event: ${event.event_type}`); // Process data based on event type switch (event.event_type) { case 'ticket.created': // Process ticket creation console.log(`New ticket created: ${event.ticket.code}`); break; case 'ticket.product.created': // Process product addition console.log(`Product added to ticket: ${event.product.name}`); break; // other event types... } // Server response res.status(200).send('OK'); });app.listen(3000, () => { console.log('Webhook receiving server running on port 3000'); });
Best Practices
Token Verification - Always verify the token in the X-Retino-Secret header for security.
Fast Response - Respond to the webhook as quickly as possible (ideally within 5 seconds) and perform more complex processing asynchronously.
Error Handling - Implement robust error handling to make your endpoint resilient to invalid data.
Logging - Log received webhooks for later analysis and debugging.
Idempotence - Design webhook processing to be idempotent (repeated processing of the same event does not cause problems).
Testing Webhooks
For testing webhooks, you can use the following options:
Use a service like webhook.site or requestbin.com to capture and inspect webhook requests.
Use local tunneling tools like ngrok to test webhooks in your local development environment.
Send a test event directly from the webhook detail in the Retino administration.
For more information on other integration options with Retino, visit the Tickets API documentation.