Servicio de Notificaciones de Cambios de Estado - Webhook
Nuestra API cuenta con un servicio de notificaciones de cambio de estados de un viaje/envío creado, el cual notifica al usuario del cambio de estado de un viaje en curso vía Webhook.
Creación del Webhook
Para crear un webhook, primero es necesario definir una URL de destino. Esta URL es el punto de conexión al cual el servidor enviará los datos mediante una solicitud HTTP POST cada vez que ocurra el evento que el webhook está monitoreando. En este caso, cambios de estado de un viaje.
La configuración del webhook la realiza el equipo de Ridery. Una vez que tengas lista la URL del endpoint que recibirá las notificaciones, compártela con el equipo de Ridery durante el onboarding de tu integración para que la registre. Este paso no se autogestiona desde el panel web.
Ejemplo de Datos Recibidos
Una vez que el webhook esté configurado y el evento monitoreado ocurra, recibirás los datos en el cuerpo (body) de la solicitud POST. Estos datos estarán en formato JSON y contienen información detallada sobre el estado de un viaje en particular.
Ejemplo:
{
"_id": "64729e1f8c9b652308de2347",
"unique_id": 123456,
"order_id": "64729e1f8c9b652308de2350",
"content": "_ID: 64729e1f8c9b652308de2347; TRIP ID: 123456; TRIP_STATUS: DRIVER_ARRIVED",
"trip_status": "DRIVER_ARRIVED",
"total": 5.5,
"created_at": "2024-10-09T12:34:56Z",
"provider": {
"_id": "507f1f77bcf86cd799439011",
"unique_id": 78910,
"first_name": "John",
"last_name": "Snow",
"phone": "4241112233",
"country_phone_code": "+58",
"email": "[email protected]",
"picture": "https://riderys3bucket.s3-sa-east-1.amazonaws.com/provider_profile/6686b082934378a5910dbf04D3bM.jpg",
"vehicle_detail": {
"type": "Sedan",
"brand": "Toyota",
"model": "Camry",
"color": "White",
"passing_year": 2020,
"plate_no": "ABC1234"
},
"provider_previous_location": [40.712776, -74.005974],
"provider_location": [40.712776, -74.005974]
}
}Ejemplo de cancelación:
Los campos cancel_reason_partner y will_be_recreated solo aparecen en eventos de cancelación. No forman parte del payload de estados como DRIVER_ARRIVED.
{
"_id": "64729e1f8c9b652308de2347",
"unique_id": 123456,
"order_id": "64729e1f8c9b652308de2350",
"content": "_ID: 64729e1f8c9b652308de2347; TRIP ID: 123456; TRIP_STATUS: ADMIN_CANCELLED_TRIP",
"trip_status": "ADMIN_CANCELLED_TRIP",
"total": 5.5,
"created_at": "2024-10-09T12:34:56Z",
"cancel_reason_partner": {
"code": "DRIVER_CANNOT_COMPLETE",
"label": "El conductor no puede completar el viaje"
},
"will_be_recreated": true,
"provider": {
"_id": "507f1f77bcf86cd799439011",
"unique_id": 78910,
"first_name": "John",
"last_name": "Snow",
"phone": "4241112233",
"country_phone_code": "+58",
"email": "[email protected]",
"picture": "https://riderys3bucket.s3-sa-east-1.amazonaws.com/provider_profile/6686b082934378a5910dbf04D3bM.jpg",
"vehicle_detail": {
"type": "Sedan",
"brand": "Toyota",
"model": "Camry",
"color": "White",
"passing_year": 2020,
"plate_no": "ABC1234"
},
"provider_previous_location": [40.712776, -74.005974],
"provider_location": [40.712776, -74.005974]
}
}Importante
El bloque provider de este ejemplo es ilustrativo y puede no venir. Solo se incluye cuando ya hay un conductor asignado al envío.
| Campo | Tipo de Dato | Descripción | Ejemplo |
|---|---|---|---|
_id | string | ID único del viaje. | "64729e1f8c9b652308de2347" |
unique_id | number | Identificador único del viaje. | 123456 |
order_id | string | ID del envío asociado. Opcional, puede venir undefined si el viaje no tiene un corporate_api_partner_shipment_details_id asociado. | "64729e1f8c9b652308de2350" |
content | string | Descripción del viaje con ID y estado del viaje. | "TRIP ID: TRIP123456; TRIP_STATUS: completed" |
trip_status | string | Estado actual del viaje (e.g., pending, completed). | "completed" |
total | number | Total del costo del viaje. | 150.75 |
created_at | string (ISO) | Fecha y hora de creación del viaje en formato ISO8601 UTC 0. | "2024-10-09T12:34:56Z" |
provider | object (opcional) | Conductor asignado al envío. Solo se incluye cuando ya hay un conductor asignado; por lo tanto no aparece en envíos cancelados antes de que un conductor aceptara. | { "_id": "507f1f77bcf86cd799439011", "first_name": "John" } |
provider._id | string | ID único del proveedor (conductor). | "507f1f77bcf86cd799439011" |
provider.unique_id | number | Identificador único del proveedor. | 78910 |
provider.first_name | string | Nombre del proveedor. | "John" |
provider.last_name | string | Apellido del proveedor. | "Doe" |
provider.phone | string | Número de teléfono del proveedor. | "+1234567890" |
provider.country_phone_code | string | Código telefonico del pais del proveedor. | "+58" |
provider.email | string | Correo electrónico del proveedor. | "[email protected]" |
provider.picture | string | Imagen del proveedor. | "https://riderys3bucket.s3-sa-east-1.amazonaws.com/provider_profile/6686b082934378a5910dbf04D3bM.jpg" |
provider.vehicle_detail.type | string | Tipo de vehículo del proveedor. | "Sedan" |
provider.vehicle_detail.brand | string | Marca del vehículo. | "Toyota" |
provider.vehicle_detail.model | string | Modelo del vehículo. | "Camry" |
provider.vehicle_detail.color | string | Color del vehículo. | "White" |
provider.vehicle_detail.passing_year | number | Año de registro del vehículo. | 2020 |
provider.vehicle_detail.plate_no | string | Número de placa del vehículo. | "ABC1234" |
provider.provider_previous_location | array[number, number] | Ubicación previa del proveedor, como [lat, lng]. | [40.712776, -74.005974] |
provider.provider_location | array[number, number] | Ubicación actual del proveedor, como [lat, lng]. | [40.712776, -74.005974] |
cancel_reason_partner | object | null | Motivo estandarizado de la cancelación comunicado al partner. Solo presente en eventos de cancelación. Es null cuando la cancelación no fue hecha por un operador de Ridery desde el panel interno; por ejemplo cancelación del usuario, del conductor, por timeout sin conductor, o hecha por el propio partner vía API (CORPORATE_CANCELLED_TRIP). | { "code": "DRIVER_CANNOT_COMPLETE", "label": "El conductor no puede completar el viaje" } |
cancel_reason_partner.code | string | Código estable del motivo. Valores posibles: DRIVER_CANNOT_COMPLETE, CUSTOMER_NO_ANSWER, MERCHANT_NO_ANSWER, ADDRESS_ERROR. | "DRIVER_CANNOT_COMPLETE" |
cancel_reason_partner.label | string | Texto legible del motivo, en español. Es informativo y puede cambiar; la integración debe basarse siempre en code. | "El conductor no puede completar el viaje" |
will_be_recreated | boolean | Indica si Ridery va a recrear automáticamente el envío. Solo presente en eventos de cancelación. Siempre viene presente en esos eventos, nunca null. Si es true, el partner no debe crear un envío nuevo: recibirá a continuación un evento RECREATED_TRIP con el son_trip_id del envío nuevo y luego los cambios de estado de ese envío. Si es false, el envío queda cancelado definitivamente y el partner decide si crea uno nuevo. | true |
Motivos de cancelación (cancel_reason_partner)
Cuando un operador de Ridery cancela el envío desde el panel interno, cancel_reason_partner llega como objeto con un código estable y un texto legible.
| Código | Descripción |
|---|---|
DRIVER_CANNOT_COMPLETE | El conductor no puede completar el viaje |
CUSTOMER_NO_ANSWER | El cliente no contesta (entregar) |
MERCHANT_NO_ANSWER | El comercio no contesta (retirar) |
ADDRESS_ERROR | Error en direcciones |
Importante
La lista de códigos puede crecer. El consumidor debe tolerar códigos desconocidos sin romper: usa code cuando lo reconozcas y, si no, haz fallback a label para mostrarlo o registrarlo.
Tip
label es informativo y puede cambiar. La integración debe basarse siempre en code.
¿Debo crear el envío de nuevo? (will_be_recreated)
will_be_recreated es la única señal que hay que mirar para decidir si el partner debe crear un envío nuevo. No infieras esa decisión a partir de trip_status ni de cancel_reason_partner.
- Si
will_be_recreatedestrue: no crees un envío nuevo. Ridery va a recrearlo. Espera el eventoRECREATED_TRIP, que trae elson_trip_iddel envío nuevo; a partir de ahí recibirás los cambios de estado de ese envío. Si la recreación no se completa, llegarás a recibirRECREATE_FAILEDy en ese caso sí puedes crear uno nuevo. - Si
will_be_recreatedesfalse: el envío quedó cancelado definitivamente. El partner decide si crea uno nuevo.
Un CORPORATE_CANCELLED_TRIP (cancelación hecha por el propio partner vía API) siempre llega con will_be_recreated: false.
// Endpoint receptor del webhook
if (esCancelacion(payload.trip_status)) {
if (payload.will_be_recreated === true) {
// No crear un envío nuevo. Esperar RECREATED_TRIP (son_trip_id)
// o, si la recreación falla, RECREATE_FAILED.
return
}
// will_be_recreated === false: el envío está cerrado.
// El partner decide si crea uno nuevo.
}
if (payload.trip_status === "RECREATE_FAILED") {
// La recreación automática falló. El partner crea el envío si lo necesita.
}Estados Disponibles
| Estado | Descripción |
|---|---|
| DRIVER_ACCEPTED_TRIP | El conductor ha aceptado el envío/viaje. |
| DRIVER_IN_ROUTE | El conductor está en ruta hacia la ubicación de recogida. |
| DRIVER_ARRIVED | El conductor ha llegado a la ubicación de recogida. |
| DRIVER_STARTED_TRIP | El envío/viaje ha comenzado. |
| DRIVER_COMPLETED_TRIP | El envío/viaje se ha completado exitosamente. |
| USER_CANCELLED_TRIP | El envío/viaje fue cancelado por el usuario. |
| DRIVER_CANCELLED_TRIP | El envío/viaje fue cancelado por el conductor. |
| ADMIN_CANCELLED_TRIP | El envío/viaje fue cancelado por un administrador. |
| DISPATCHER_CANCELLED_TRIP | El envío/viaje fue cancelado por un despachador de Ridery. |
| CORPORATE_CANCELLED_TRIP | El envío/viaje fue cancelado por un corporate. |
| DRIVER_NOT_FOUND_CANCELLED_TRIP | No se encontró conductor, el envío/viaje ha sido cancelado. |
| CANCELLED_TRIP | El envío/viaje fue cancelado sin un origen específico identificado. Es un estado de respaldo; si lo recibes, trátalo como una cancelación normal. |
| RECREATED_TRIP | El envío/viaje fue recreado por un admin . |
| RECREATE_FAILED | Ridery intentó recrear el envío tras cancelarlo pero la recreación falló; el envío no será recreado y el partner debe crearlo si lo necesita. |
Importante
El consumidor debe tolerar valores de trip_status que no reconozca sin romper. La lista de estados puede crecer a futuro; ante un valor no listado, no debe asumirse que se trata de un error ni de una cancelación.
RECREATED_TRIP
Un viaje recreado pudiere ocurrir en Ridery cuando un viaje original ha sido cancelado debido a razones operacionales. Ejemplos de estas situaciones no comunes incluyen:
- Los conductores no aceptan el viaje, lo que lleva a su cancelación.
- No hay conductores disponibles en el área en ese momento.
- Surge una eventualidad durante el traslado que interrumpe el viaje.
En estos casos, un administrador de Ridery tiene la capacidad de recrear el viaje, generando uno nuevo a partir del original, con el fin de asegurar que el servicio se complete exitosamente.
Tip
En este estado tenemos un payload de body diferente
{
"content": "RECREATED_TRIP: father_trip_id: ${fatherTripId}; son_trip_id: ${sonTripId};",
"trip_status": "RECREATED_TRIP",
"father_trip_id": "64729e1f8c9b652308de2348",
"son_trip_id": "64729c1f8c9b652308de2348"
}| Campo | Tipo de Dato | Descripción | Ejemplo |
|---|---|---|---|
content | string | Descripción de la recreación del viaje, incluyendo los IDs del padre e hijo. | "RECREATED_TRIP: father_trip_id: 64729e1f8c9b652308de2348; son_trip_id: 64729c1f8c9b652308de2348;" |
trip_status | string | Estado del viaje recreado. | "RECREATED_TRIP" |
father_trip_id | string | ID único del viaje original (viaje padre). | "64729e1f8c9b652308de2348" |
son_trip_id | string | ID único del nuevo viaje recreado (viaje hijo). | "64729c1f8c9b652308de2348" |
Importante
Es muy aconsejable que tu servidor pueda manejar esta eventualidad
Tip
A partir de un viaje recreado recibirás notificaciones por webhook de cambios de estatus del mismo
Tip
Cuando la cancelación del viaje original llegó con will_be_recreated: true, este es el evento que trae el ID del envío nuevo (son_trip_id).
RECREATE_FAILED
Este estado llega cuando Ridery intentó recrear el envío tras cancelarlo y la recreación falló. El envío original no será recreado: el partner debe crear uno nuevo si lo necesita.
Tip
En este estado tenemos un payload de body diferente
{
"content": "RECREATE_FAILED: father_trip_id: ${fatherTripId};",
"trip_status": "RECREATE_FAILED",
"father_trip_id": "64729e1f8c9b652308de2348",
"will_be_recreated": false
}| Campo | Tipo de Dato | Descripción | Ejemplo |
|---|---|---|---|
content | string | Descripción del fallo de recreación, incluyendo el ID del viaje padre. | "RECREATE_FAILED: father_trip_id: 64729e1f8c9b652308de2348;" |
trip_status | string | Estado que indica que la recreación falló. | "RECREATE_FAILED" |
father_trip_id | string | ID único del viaje original (viaje padre) que se intentó recrear. | "64729e1f8c9b652308de2348" |
will_be_recreated | boolean | En este evento siempre es false: el envío no será recreado. | false |
Importante
Si habías recibido una cancelación con will_be_recreated: true y después llega RECREATE_FAILED, el envío no se recreó. El partner debe crearlo si lo necesita.
Respuesta Esperada
Desde el lado de Ridery se espera una respuesta de tipo 200 hacia donde envíe el Webhook.
Importante
No hay reintento de Webhook si no se obtiene un 200 de parte de tu servidor.
Desactivación del Webhook
De ser necesario, el webhook configurado se puede desactivar, o su URL se puede actualizar. Solicítalo al equipo de Ridery y ellos aplicarán el cambio.
Credenciales
Se puede configurar el envío de un token de autenticación por cabecera de parte de Ridery de ser necesario.
Compatibilidad
Los campos cancel_reason_partner y will_be_recreated son aditivos. Los integradores existentes no necesitan cambios para seguir recibiendo los webhooks. Se recomienda ignorar cualquier campo desconocido en el payload.