Skip to content

Webhook de Aceptación de Oferta

Descripción

Este webhook se dispara automáticamente cuando una central acepta una oferta de servicio creada previamente. TSALVA enviará una notificación a tu servidor con los detalles de la central que aceptó el servicio y del técnico asignado.

Configuración

URL del Webhook

  • La URL debe ser configurada durante el proceso de integración
  • Debe ser accesible públicamente (HTTPS recomendado)
  • Timeout: 30 segundos
  • TSALVA reintentará hasta 3 veces si no hay respuesta

Método HTTP

PUT {tu_webhook_url}

Headers

Content-Type: application/json
User-Agent: TSALVA-Webhook/1.0

Payload

Estructura del Request

json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "dniGestor": "98765432",
  "dniPrestador": "900123456",
  "nombrePrestador": "Central Norte SAS",
  "telefonoCentral": "+57 4 123-4567",
  "latitudTecnico": "6.2400",
  "longitudTecnico": "-75.5800",
  "identificadorTecnico": "TEC001",
  "dniTecnico": "12345678",
  "telefonoTecnico": "+57 300-123-4567",
  "tarifaEstimadaServicio": "85000",
  "tiempoLlegadaSitio": "25"
}

Descripción de Campos

CampoTipoDescripción
idstring (UUID)UUID de la oferta original
dniGestorstringDocumento del gestor que aceptó
dniPrestadorstringNIT/documento de la central
nombrePrestadorstringNombre comercial de la central
telefonoCentralstringTeléfono de contacto de la central
latitudTecnicostringUbicación actual del técnico (latitud)
longitudTecnicostringUbicación actual del técnico (longitud)
identificadorTecnicostringCódigo interno del técnico
dniTecnicostringDocumento del técnico asignado
telefonoTecnicostringTeléfono del técnico
tarifaEstimadaServiciostringTarifa estimada en pesos colombianos
tiempoLlegadaSitiostringTiempo estimado de llegada en minutos

Respuesta Esperada

Tu servidor debe responder con:

✅ Éxito (200 OK)

json
{
  "received": true
}

❌ Error (cualquier código 4xx o 5xx)

Si no respondes correctamente, TSALVA reintentará el webhook.

Ejemplos de Implementación

Node.js (Express)

javascript
const express = require('express');
const app = express();

app.use(express.json());

app.put('/webhook/aceptacion-oferta', (req, res) => {
  const {
    id,
    dniGestor,
    nombrePrestador,
    telefonoCentral,
    latitudTecnico,
    longitudTecnico,
    identificadorTecnico,
    dniTecnico,
    telefonoTecnico,
    tarifaEstimadaServicio,
    tiempoLlegadaSitio
  } = req.body;

  console.log(`Oferta ${id} aceptada por ${nombrePrestador}`);
  console.log(`Técnico: ${identificadorTecnico} - ETA: ${tiempoLlegadaSitio} min`);
  
  // Aquí procesas la aceptación
  // - Notificar al usuario
  // - Actualizar base de datos
  // - Enviar confirmación
  
  res.status(200).json({ received: true });
});

app.listen(3000, () => {
  console.log('Webhook servidor corriendo en puerto 3000');
});

Python (Flask)

python
from flask import Flask, request, jsonify
import logging

app = Flask(__name__)

@app.route('/webhook/aceptacion-oferta', methods=['PUT'])
def aceptacion_oferta():
    data = request.get_json()
    
    oferta_id = data.get('id')
    nombre_prestador = data.get('nombrePrestador')
    tecnico_id = data.get('identificadorTecnico')
    tiempo_llegada = data.get('tiempoLlegadaSitio')
    tarifa = data.get('tarifaEstimadaServicio')
    
    print(f"Oferta {oferta_id} aceptada por {nombre_prestador}")
    print(f"Técnico: {tecnico_id} - ETA: {tiempo_llegada} min - Tarifa: ${tarifa}")
    
    # Procesar la aceptación
    # - Notificar al usuario
    # - Actualizar estado en BD
    # - Enviar confirmación
    
    return jsonify({"received": True}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

PHP

php
<?php
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] !== 'PUT') {
    http_response_code(405);
    echo json_encode(['error' => 'Method not allowed']);
    exit;
}

$input = json_decode(file_get_contents('php://input'), true);

if (!$input || !isset($input['id'])) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid payload']);
    exit;
}

$ofertaId = $input['id'];
$nombrePrestador = $input['nombrePrestador'];
$tecnicoId = $input['identificadorTecnico'];
$tiempoLlegada = $input['tiempoLlegadaSitio'];
$tarifa = $input['tarifaEstimadaServicio'];

error_log("Oferta {$ofertaId} aceptada por {$nombrePrestador}");
error_log("Técnico: {$tecnicoId} - ETA: {$tiempoLlegada} min - Tarifa: \${$tarifa}");

// Procesar la aceptación
// - Notificar al usuario
// - Actualizar base de datos
// - Enviar confirmación

http_response_code(200);
echo json_encode(['received' => true]);
?>

Flujo de Trabajo

1. Crear Oferta

bash
curl -X POST "[URL_API]/api/v2/oferta" \
  -H "Authorization: Basic $(echo -n 'usuario:password' | base64)" \
  -H "Content-Type: application/json" \
  -d '{
    "uuid": "123e4567-e89b-12d3-a456-426614174000",
    "ciudad": "Medellín",
    "departamento": "Antioquia",
    "latitudOrigen": 6.2442,
    "longitudOrigen": -75.5812,
    "direccionOrigen": "Calle 50 #45-20",
    "tipoServicio": "1",
    "descripcionServicio": "Grúa para vehículo averiado"
  }'

2. Recibir Webhook de Aceptación

json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "nombrePrestador": "Central Norte SAS",
  "identificadorTecnico": "TEC001",
  "tiempoLlegadaSitio": "25",
  "tarifaEstimadaServicio": "85000"
}

3. Procesar y Responder

json
{
  "received": true
}

4. Continuar con Asignación

Una vez recibida la aceptación, puedes proceder con la asignación de detalles.

Casos de Uso

Notificación al Usuario

javascript
app.put('/webhook/aceptacion-oferta', (req, res) => {
  const { id, nombrePrestador, tiempoLlegadaSitio, telefonoTecnico } = req.body;
  
  // Buscar usuario asociado a la oferta
  const usuario = findUserByOfertaId(id);
  
  // Enviar notificación
  sendNotification(usuario, {
    message: `¡Tu servicio fue aceptado por ${nombrePrestador}!`,
    eta: `Tiempo estimado: ${tiempoLlegadaSitio} minutos`,
    contact: `Teléfono técnico: ${telefonoTecnico}`
  });
  
  res.status(200).json({ received: true });
});

Actualización de Estado

javascript
app.put('/webhook/aceptacion-oferta', async (req, res) => {
  const { id, dniPrestador, identificadorTecnico, tarifaEstimadaServicio } = req.body;
  
  try {
    // Actualizar en base de datos
    await updateServiceStatus(id, {
      status: 'ACEPTADO',
      providerId: dniPrestador,
      technicianId: identificadorTecnico,
      estimatedCost: tarifaEstimadaServicio,
      acceptedAt: new Date()
    });
    
    res.status(200).json({ received: true });
  } catch (error) {
    console.error('Error updating service:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

Mejores Prácticas

🔐 Seguridad

  • Valida la IP de origen si es posible
  • Implementa autenticación adicional si es necesario
  • Registra todos los webhooks recibidos

⚡ Performance

  • Responde rápidamente (< 5 segundos)
  • Procesa en background si es necesario
  • Implementa retry logic para operaciones críticas

📊 Monitoreo

  • Registra métricas de webhooks recibidos
  • Alerta si no se reciben webhooks esperados
  • Monitorea errores y reintentos

Solución de Problemas

Webhook no recibido

  1. Verifica que tu URL sea accesible públicamente
  2. Confirma que respondes con código 200
  3. Revisa logs de tu servidor
  4. Contacta soporte técnico si persiste

Reintentos excesivos

  1. Asegúrate de responder con {"received": true}
  2. Verifica que no haya errores 5xx
  3. Optimiza el tiempo de respuesta

Próximo paso

Después de recibir la aceptación, puedes asignar detalles adicionales usando POST /api/v2/asignacion.

Importante

Este webhook es crítico para el flujo de trabajo. Asegúrate de que tu endpoint sea confiable y responda correctamente.

Tsalva API - Documentación desarrollada por RobPixels