Cuando un WebHook se configura para enviar un cuerpo personalizado (body), se puede usar un sistema de plantillas dinámicas que evalúa las propiedades del modelo de origen (el modelo relacionado o $related). Las expresiones se evalúan usando la siguiente estructura básica:
<comando>:<ruta_de_propiedad>[;valor_por_defecto][::tipo_de_casteo]
<comando>:)v:<ruta>: Obtiene un valor del modelo utilizando la función data_get($related, ruta). Soporta notación de puntos para acceder a relaciones u objetos anidados (por ejemplo, client.name).
"NombrePagador": "v:client.name""Email": "v:client.email;no-reply@example.com"e2:<ruta>: Recupera un valor entero que representa un monto en céntimos y lo divide por 100.0 para convertirlo a decimal.
"Monto": "e2:total_e2""Monto": "e2:total_e2;0"e6:<ruta>: Recupera un valor y lo divide por 1000000.0. Útil para conversiones de alta precisión de enteros grandes.
"MontoDecimal": "e6:total_e6"datef2:<ruta>: Formatea una propiedad de fecha (instancia de Carbon/DateTime) al formato estándar 'd-m-Y H:i:s'.
"Fecha": "datef2:updated_at"datef3:<ruta>: Formatea una propiedad de fecha al formato ISO 8601 con milisegundos ('Y-m-d\TH:i:s.v000\Z').
"FechaISO": "datef3:created_at"c:<literal>: Devuelve directamente un valor de tipo constante/literal en lugar de evaluarlo en el modelo.
"Canal": "c:api"if:<ruta>: Comando condicional para incluir o excluir de forma dinámica partes del JSON de salida.
<ruta> evalúa a verdadero (truthy), devuelve un array vacío []."__skip__"."__skip__", el procesador de payloads omitirá esa clave y removerá de manera recursiva todas las claves hijas que compartan el mismo prefijo plano (por ejemplo, si detalles evalúa como "__skip__", cualquier clave que comience con detalles. será eliminada del cuerpo final).::tipo_de_casteo)Para forzar un tipo de dato específico en la salida del JSON, se puede sufijar la expresión usando un doble dospuntos (::):
s o string: Fuerza el valor a una cadena de texto (string).i o integer: Fuerza el valor a un entero (int).f o float: Fuerza el valor a un decimal de punto flotante (float).d o double: Fuerza el valor a un decimal de doble precisión (double)."MontoTexto": "e2:total_e2::string" (divide por 100 y devuelve el resultado como "15.50")"Activo": "v:is_active;0::integer" (obtiene is_active, si no existe usa 0, y lo castea a entero 0 o 1)config)La base de datos del WebHook almacena opciones operativas adicionales bajo la columna JSON config. Estos campos se mapean directamente en los modelos:
| Atributo (en Base de Datos) | Clave en JSON de config |
Tipo | Descripción |
|---|---|---|---|
config_use_body |
use_body |
bool |
Si es true, fuerza el uso de la plantilla dinámica body incluso si el WebHook cuenta con un formateador personalizado (CustomBodyParsing) predefinido en código. |
config_order_status_mask |
order_status_mask |
int |
Máscara de bits utilizada para filtrar qué cambios de estado de una orden disparan el WebHook order_status_report. |
config_check_in_service |
check_in_service |
bool |
Si es true, antes de disparar el webhook de importación (goods_import), se comprueba que al menos una sucursal del grupo esté activa/en servicio. |
config_conditions |
conditions |
array |
Reglas de condiciones para que el WebHook decida si debe o no ejecutarse para el modelo asociado. |
config_response_processor_handler |
response_processor.handler |
string |
Nombre del manejador del procesador de respuestas (ej. payco, stripe, deliverect). |
config_response_processor_hook |
response_processor.hook_name |
string |
Nombre del hook específico del procesador de respuestas (ej. zelle-validate). |
config_auto_sync |
auto_sync |
bool |
Activa la sincronización automática de importaciones periódicas. |
config_auto_sync_delay |
auto_sync_delay |
int |
Retraso en minutos para la sincronización automática. |
config_auto_sync_offset |
auto_sync_offset |
int |
Margen de minutos para la sincronización periódica. |
config_tries |
tries |
int |
Número máximo de intentos permitidos para enviar el webhook. |
config_ttl |
ttl |
int |
Tiempo de vida del webhook en segundos antes de expirar. |
config_backoff |
backoff |
array |
Configuración de reintentos exponenciales. |
config.conditions)El array de conditions permite filtrar la ejecución de un webhook basándose en el estado de las propiedades del modelo $related. Cada objeto de condición soporta:
key: Nombre de la propiedad a evaluar en el modelo.op: Operador de comparación (por defecto =).value: Valor contra el cual comparar.fn: Tipo de filtrado. Valores permitidos:
where (por defecto): Realiza una comparación de valor típica con el operador op.null: Valida que la propiedad sea nula.notNull: Valida que la propiedad no sea nula.in: Valida que la propiedad exista dentro de la lista de valores provista.notIn: Valida que la propiedad NO exista dentro de la lista de valores provista.Ejemplo de condiciones en config:
{
"conditions": [
{
"key": "status",
"op": "=",
"value": "completed",
"fn": "where"
},
{
"key": "subtotal_e2",
"op": ">=",
"value": 1000,
"fn": "where"
}
]
}
name)El comportamiento de compilación de datos, respuestas y el modelo de origen ($related) enviado varía estrictamente según el name del WebHook:
CustomBodyParsing)Estos webhooks ignoran por defecto la plantilla JSON guardada en body y devuelven una estructura rígida óptima definida por la plataforma, a menos que se establezca config.use_body = true.
order_creation_partner / order_creation_ridery$related): OrderOutboundOrderCreateshop) y un array de los productos ordenados (product_array):
{
"order_id": "123456",
"internal_ridery_user_id": 98765,
"internal_api_partner_user_id": "789",
"shipment_details": {
"type": "Envío de Nombre Compañía",
"payment_type": "prepaid",
"weight": 1.5,
"weight_unit": "kg",
"cost": 15.00,
"currency": "USD",
"fare_id": 2,
"city_type_id": 1
},
"order_details": {
"payment_option": "Zelle",
"creation_channel": "app",
"amount": {
"shop_cost": 10.00,
"shipment_cost": 5.00,
"shopper_fee": 0.00,
"service_fee": 0.00,
"total": 15.00
}
},
"shop": {
"id": "12",
"name": "Sucursal Centro",
"phone_mobile": "04141234567",
"url_shop_avatar": "https://..."
},
"product_array": [
{
"product_id": "101",
"image_url": "https://...",
"name": "Hamburguesa Clásica",
"quantity": 2,
"price": 5.00,
"currency": "USD"
}
]
}shipment_creation_partner / shipment_creation_ridery$related): OrderOutboundShipmentCreateclient), coordenadas e instrucciones de despacho y los datos del transportista (picker) asignado:
{
"city_type_id": 1,
"responsible_phone": "04121111111",
"source_instructions": "Dirección Sucursal",
"package_description": "Caja de alimentos",
"destination_instructions": "Entregar en conserjería",
"responsible_last_name": "Pérez",
"responsible_first_name": "Juan",
"fare_id": 2,
"api_partner_shipment_details": {
"order_id": "123456",
"pod_pin": "1234",
"shop": {
"id": "12",
"name": "Sucursal Centro",
"phone_mobile": "04141234567",
"url_shop_avatar": "https://..."
},
"client": {
"username": "juanperez",
"full_name": "Juan Pérez",
"email": "juan@example.com",
"phone_mobile": "04121111111",
"avatar_url": "https://..."
},
"shipment_details": {
"type": "Zupper Envío",
"payment_type": "Zelle",
"payment_type_enum": 2,
"weight": 1.5,
"weight_unit": "kg",
"cost": 15.00,
"rif": "J-12345678-9",
"currency": "USD"
},
"product_array": [
{
"product_id": "101",
"image_url": "https://...",
"name": "Hamburguesa Clásica",
"quantity": 2,
"price": 5.00,
"currency": "USD"
}
],
"picker": {
"username": "chofer_juan",
"full_name": "Juan Chofer",
"email": "chofer@example.com",
"phone_mobile": "04147777777",
"avatar_url": "https://..."
}
}
}providers_sync_partner$related): CompanyOutboundProviderSync{
"providers": [
{
"provider_common_id": "proveedor@email.com",
"provider_api_partner_id": "15"
}
]
}wallet_sync_partner$related): CompanyOutboundWalletSyncEstos WebHooks requieren obligatoriamente definir su campo body en base de datos. Se evalúan utilizando el modelo de origen indicado.
goods_import$related): BranchGroupOutboundGoodImport{
"branch_group_id": "v:id",
"company_id": "v:company_id",
"sync_time": "datef3:updated_at"
}goods_import (GoodImportOptions)Cuando el WebHook es de tipo "goods_import", el campo config del WebHook almacena la estructura de GoodImportOptions para controlar las sincronizaciones periódicas, el mapeo de columnas y las reglas de inventario.
config para goods_import:{
"auto_sync": false,
"auto_sync_delay": 0,
"auto_sync_offset": 0,
"check_in_service": false,
"ext": "json",
"category_ignored_words": [],
"category_mapping": {},
"category_blacklist": [],
"currency_mapping": {},
"currency_var": "currency",
"host_image_var": "image_name",
"host_vertical_image_var": "vertical_image_name",
"host_image_url": "https://...",
"host_vertical_image_url": "https://...",
"appends": {},
"weight_config": {},
"config": {
"data_accessor": null,
"refresh_data": true,
"clear_missing": false,
"refresh_category": false,
"allow_null_stock": null,
"tax_included": false,
"tax_round_mode": null,
"tax_multiplier": null,
"quantity_threshold": 0,
"quantity_reservation": 0,
"starting_cell": "A1",
"separated_sku": false,
"currency": null,
"debug": false
},
"csv_settings": {
"delimiter": ",",
"enclosure": "\"",
"line_ending": "\n",
"use_bom": false,
"include_separator_line": false,
"excel_compatibility": false,
"escape_character": "\",
"contiguous": false,
"input_encoding": "UTF-8",
"output_encoding": "UTF-8"
},
"pagination": {
"page_parameter": null,
"limit_parameter": null,
"items_per_page_accessor": null,
"pages_count_accessor": null
},
"mapping": {
"sku": "sku_proveedor",
"name": "ucwords:titulo",
"price": "to_e2:precio_venta",
"stock": "decimal:inventario_disponible",
"description": "from_html:detalles_html"
}
}
GoodImportOptionsauto_sync (bool): Habilita o deshabilita la sincronización automática programada.auto_sync_delay (int): Retraso en minutos para ejecuciones automáticas de sincronización.auto_sync_offset (int): Desfase en minutos aplicable a la planificación automática.check_in_service (bool): Si es true, el webhook de importación se detendrá si ninguna sucursal del grupo está activa (en servicio).ext (string): Formato del archivo a importar. Valores permitidos: json, csv, xlsx, xls. Por defecto es json.currency_var (string): Clave o campo del elemento externo que define su moneda. Por defecto "currency".currency_mapping (array): Diccionario para traducir códigos de moneda del proveedor a los del sistema (ej: {"USD": "USD", "BS": "VES"}).category_ignored_words (array): Lista de palabras a excluir de los nombres de categorías generados.category_mapping (array): Diccionario de mapeo de homologación de categorías externas a internas.category_blacklist (array): Lista de nombres de categorías que se excluirán de la importación (cualquier producto en ellas será descartado).host_image_var (string): Clave del campo de la imagen principal. Por defecto "image_name".host_vertical_image_var (string): Clave del campo de la imagen vertical. Por defecto "vertical_image_name".host_image_url (string\|null): URL base que se antepondrá al nombre de la imagen principal para construir una ruta absoluta.host_vertical_image_url (string\|null): URL base para imágenes verticales.appends (array): Atributos estáticos agregados por defecto a todos los productos (por ejemplo, "branch_id").weight_config (array): Ajustes de procesamiento de peso físico de los productos.config / GoodImportConfig)data_accessor (string\|null): Ruta o selector JSON (en notación de puntos) para acceder a la lista de productos dentro del JSON de respuesta (útil si la lista no viene en la raíz).refresh_data (bool): Si es true, se reescriben todos los atributos del producto (nombre, descripción, etc.). Si es false, solo se actualizan precios y stock. Por defecto true.clear_missing (bool): Si es true, marca como "no disponible" o inactiva cualquier producto local que no aparezca en el payload de la importación actual. Por defecto false.refresh_category (bool): Si es true, actualiza o reasigna las categorías del producto en cada ciclo. Por defecto false.allow_null_stock (bool\|null): Permite establecer stock nulo.tax_included (bool): Determina si los precios de costo/venta externos ya tienen el impuesto incluido. Por defecto false.tax_round_mode (string\|null): Modo de redondeo decimal de impuestos (up, down, half).tax_multiplier (float\|null): Factor de ajuste de impuestos aplicable a los productos.quantity_threshold (int): Stock mínimo requerido para marcar un producto importado como disponible para la venta. Por defecto 0.quantity_reservation (int): Cantidad "virtual" sustraída del stock real importado a modo de reserva de seguridad. Por defecto 0.starting_cell (string): Celda inicial de lectura si el formato de archivo es de hoja de cálculo (ej. Excel). Por defecto "A1".separated_sku (bool): Indica si los SKUs son gestionados de forma individual e independiente en la sucursal. Por defecto false.currency (string\|null): Moneda por defecto utilizada si el ítem externo carece de este valor.debug (bool): Habilita trazas adicionales del proceso en los logs de depuración del backend.csv_settings / CsvSettings)Utilizado exclusivamente si el campo ext es "csv".
delimiter (string): Carácter delimitador de columnas (ej. ,, ;, \t).enclosure (string): Carácter delimitador de cadenas de texto (ej. ").line_ending (string): Carácter de salto de línea (ej. \n, \r\n).use_bom (bool): Ignora u omite la firma UTF-8 BOM en la cabecera.include_separator_line (bool): Indica si el archivo contiene una cabecera de definición de separador (sep=...).excel_compatibility (bool): Activa el comportamiento compatible con exportaciones directas de Excel.escape_character (string): Carácter de escape (ej. \).contiguous (bool): Fuerza el procesamiento contiguo de bloques de datos en memoria.input_encoding / output_encoding (string): Codificaciones de origen y destino del archivo (ej. UTF-8).pagination / GoodImportPagination)page_parameter (string\|null): Parámetro GET de número de página. Su definición habilita el modo de paginación automática del motor de importaciones.limit_parameter (string\|null): Parámetro GET para definir el tamaño de la página.items_per_page_accessor (string\|null): Selector JSON para leer la cantidad de ítems por página de la respuesta.pages_count_accessor (string\|null): Selector JSON para leer la cantidad total de páginas de la respuesta.mapping / FieldConfig)El objeto mapping traduce claves externas del proveedor a campos de base de datos de productos locales. Soporta transformaciones directas o encadenadas bajo la sintaxis:
"<funcion>;[arg1];[arg2]:<columna_externa>"
to_e2: Multiplica el decimal recibido por 100.0 y lo redondea a entero (convierte montos a céntimos en base de datos).
"price": "to_e2:precio"to_e6: Multiplica el valor por 1000000.0 para alta precisión de decimales.to_prc: Divide el valor por 100.0 para normalizar tasas o porcentajes.ucwords: Formatea el texto a mayúsculas iniciales por cada palabra (Title Case).decimal: Remueve comas de cadenas numéricas.decimal_alt: Formatea numéricos de estilo europeo/latinoamericano, reemplazando comas por puntos y eliminando puntos de miles.pluck;<clave>: Extrae un campo específico dentro de un objeto o diccionario anidado.
"description": "pluck;es:descripcion_multidioma"from_html: Limpia cualquier etiqueta HTML del texto externo, convirtiéndolo a texto plano.order_status_report$related): OrderOutboundOrderStatusReport{
"id_orden": "v:uid::string",
"nuevo_estado": "v:status::integer",
"sucursal_id": "v:branch_id",
"fecha_actualizacion": "datef2:updated_at"
}payments_validation_zelle / payments_report_stripe$related): PaymentOutboundPaymentReport{
"Monto": "e2:total_e2",
"CodigoAutorizacion": "v:metadata.payload.identifier",
"Email": "v:metadata.payload.email",
"NombrePagador": "v:client.name",
"Fecha": "datef2:updated_at"
}fleet_prices_partner / fleet_prices_ridery$related): CartObjectOutboundFleetPricesFetch{
"origen_lat": "v:branch.latitude",
"origen_lng": "v:branch.longitude",
"destino_lat": "v:delivery.latitude",
"destino_lng": "v:delivery.longitude"
}promos_sync / discounts_refresh$related): BranchGroupOutboundForumPromo{
"grupo_sucursales": "v:id",
"nombre_grupo": "v:name",
"compania_id": "v:company_id"
}