Formatos y Configuración de WebHooks



Sintaxis de Templating Dinámico

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]

1. Comandos Soportados (<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).
    • Ejemplo: "NombrePagador": "v:client.name"
    • Ejemplo con valor por defecto: "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.
    • Ejemplo: "Monto": "e2:total_e2"
    • Ejemplo con valor por defecto: "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.
    • Ejemplo: "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'.
    • Ejemplo: "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').
    • Ejemplo: "FechaISO": "datef3:created_at"
  • c:<literal>: Devuelve directamente un valor de tipo constante/literal en lugar de evaluarlo en el modelo.
    • Ejemplo: "Canal": "c:api"
  • if:<ruta>: Comando condicional para incluir o excluir de forma dinámica partes del JSON de salida.
    • Si la propiedad en <ruta> evalúa a verdadero (truthy), devuelve un array vacío [].
    • Si es falsa (falsy), devuelve "__skip__".
    • Comportamiento especial: Al evaluar una clave y recibir "__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).

2. Casteo de Tipos (::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).

Ejemplos de uso combinado:

  • "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)

Campos del JSON de Configuración (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.

Configuración de Condiciones (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"
        }
    ]
}

Especificación por Tipo de WebHook (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:

1. WebHooks con Cuerpo Personalizado por Código (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

  • Modelo de origen ($related): Order
  • Procesador de salida: OutboundOrderCreate
  • Estructura del JSON por Defecto: Genera un JSON con el detalle de la orden de compra, montos desglosados, datos de la sucursal de origen (shop) 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

  • Modelo de origen ($related): Order
  • Procesador de salida: OutboundShipmentCreate
  • Estructura del JSON por Defecto: Envía la información de la orden, datos de contacto del destinatario final (client), 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

  • Modelo de origen ($related): Company
  • Procesador de salida: OutboundProviderSync
  • Estructura del JSON por Defecto: Sincroniza un listado de los proveedores/repartidores asignados que están activos y pendientes de registrarse o integrarse en el aliado:
    {
        "providers": [
            {
                "provider_common_id": "proveedor@email.com",
                "provider_api_partner_id": "15"
            }
        ]
    }

wallet_sync_partner

  • Modelo de origen ($related): Company
  • Procesador de salida: OutboundWalletSync
  • Estructura del JSON por Defecto: Sincroniza saldos y movimientos de billetera entre la compañía y el aliado. Retorna un formato similar al sincronizador de proveedores con el desglose de cuentas vinculadas.

2. WebHooks Basados Completamente en Templating Dinámico

Estos WebHooks requieren obligatoriamente definir su campo body en base de datos. Se evalúan utilizando el modelo de origen indicado.

goods_import

  • Modelo de origen ($related): BranchGroup
  • Procesador de salida: OutboundGoodImport
  • Descripción: Realiza peticiones para descargar el inventario de bienes/productos de un grupo de sucursales aliadas.
  • Ejemplo de Body en Base de Datos:
    {
        "branch_group_id": "v:id",
        "company_id": "v:company_id",
        "sync_time": "datef3:updated_at"
    }

Configuración Avanzada de 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.

Estructura Completa de 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"
    }
}
1. Atributos Raíz de GoodImportOptions
  • auto_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.
2. Reglas del Motor de Importación (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.
3. Analizador de Archivos CSV (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).
4. Paginación de Consulta (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.
5. Mapeo Avanzado de Columnas (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).
    • Ejemplo: "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.
    • Ejemplo: "description": "pluck;es:descripcion_multidioma"
  • from_html: Limpia cualquier etiqueta HTML del texto externo, convirtiéndolo a texto plano.

order_status_report

  • Modelo de origen ($related): Order
  • Procesador de salida: OutboundOrderStatusReport
  • Descripción: Envía notificaciones a endpoints externos sobre actualizaciones en el estado de una orden de compra.
  • Ejemplo de Body en Base de Datos:
    {
        "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

  • Modelo de origen ($related): Payment
  • Procesador de salida: OutboundPaymentReport
  • Descripción: Reporta o valida pagos entrantes de Zelle o de Stripe contra pasarelas bancarias aliadas.
  • Ejemplo de Body en Base de Datos:
    {
        "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

  • Modelo de origen ($related): CartObject
  • Procesador de salida: OutboundFleetPricesFetch
  • Descripción: Consulta en tiempo real tarifas e itinerarios de transporte para cotizar los envíos en el carrito de compras.
  • Ejemplo de Body en Base de Datos:
    {
        "origen_lat": "v:branch.latitude",
        "origen_lng": "v:branch.longitude",
        "destino_lat": "v:delivery.latitude",
        "destino_lng": "v:delivery.longitude"
    }

promos_sync / discounts_refresh

  • Modelo de origen ($related): BranchGroup
  • Procesador de salida: OutboundForumPromo
  • Descripción: Sincroniza las promociones vigentes y actualiza los descuentos para un grupo específico de sucursales.
  • Ejemplo de Body en Base de Datos:
    {
        "grupo_sucursales": "v:id",
        "nombre_grupo": "v:name",
        "compania_id": "v:company_id"
    }