Skip to content

Aceptación de Oferta

La aceptación de una oferta tiene dos caras que conviene no confundir:

  • Endpoint entrante PUT /api/v3/aceptacion: lo invoca el proveedor/central (o su integración) para aceptar una oferta que TSALVA le distribuyó. Está protegido por API key (x-apikey).
  • Notificación saliente de aceptación: cuando TSALVA determina el mejor ofertamiento, envía un webhook PUT hacia la URL configurada del cliente generador de la oferta para informarle qué central y técnico la tomaron.

Fuente

Documentado contra el código real: src/v3/routes/offers.routes.js, src/v3/middlewares/apikey.validator.js, src/v3/controller/gestion.controller.js (acceptOffer) y src/v3/utils/helpers.js (processAcceptedOffer).


1. Endpoint entrante: aceptar una oferta

Petición

PUT [URL_API]/api/v3/aceptacion

Autenticación

Este endpoint no usa Basic Auth. Usa API key por header:

x-apikey: <tu_api_key>
Content-Type: application/json

La clave se valida contra la tabla api_users. El middleware (apiKeyValidator) rechaza la petición si:

SituaciónHTTPmsg
No se envía el header x-apikey401No se ha brindado la clave de acceso.
La clave no existe o hay más de una coincidencia401La clave de acceso no es correcta.
El usuario de API está inactivo (access_status != 1)401La solicitud no puede ser completada, debido a que el estado del usuario de API es 'INACTIVO', comuniquese con el administrador del API.
El endpoint no está en los permitidos del usuario403La solicitud no puede ser completada, debido a que no tiene permiso de acceso a este endpoint, comuniquese con el administrador del API.
Error interno al validar500Error interno en la validación de la clave de acceso.

Todas las respuestas de error del validador incluyen status: false y un campo timestamp (ISO 8601). La respuesta 403 además incluye allowedEndpoints y requestedEndpoint.

Cuerpo (body) esperado

json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "dniPrestador": "900123456",
  "dniTecnico": "12345678",
  "tiempoLlegadaSitio": 25,
  "latitudTecnico": "6.2400",
  "longitudTecnico": "-75.5800"
}
CampoTipoRequeridoDescripción
idstring (UUID)UUID de la oferta que se acepta
dniPrestadorstringNIT de la central/prestador que acepta
dniTecnicostringDocumento del técnico que tomará el servicio
tiempoLlegadaSitionumberNoMinutos estimados de llegada al sitio
latitudTecnicostringNoLatitud actual del técnico (se registra en la auditoría)
longitudTecnicostringNoLongitud actual del técnico

WARNING

Si dniPrestador coincide con el NIT del generador de la oferta, TSALVA asigna directamente al técnico propio de la central. En caso contrario, TSALVA reenvía internamente la aceptación al endpoint POST /api/v3/asignacion del generador.

Respuestas

Los mensajes van en el campo data (copiados textualmente del código):

EscenarioHTTPCuerpo
Oferta aceptada (asignación confirmada)200{ "status": true, "data": "Oferta aceptada" }
Aceptada, pendiente confirmación de pago del cliente200{ "status": true, "data": "Se ha aceptado la oferta, cliente no ha confirmado el metodo de pago" }
Recurso propio: respuesta aceptada, espera confirmación200{ "status": true, "data": "RESPUESTA ACEPTADA, ESPERA POR FAVOR A QUE SE CONFIRME LA ASIGNACIÓN DEL SERVICIO" }
La oferta ya había sido aceptada400{ "status": false, "data": "Oferta ya aceptada" }
Técnico no encontrado404{ "status": false, "data": "NO SE ENCONTRÓ EL TÉCNICO" }
No se encontró la API del generador404{ "status": false, "data": "API GENERADOR NO ENCONTRADO" }
Oferta no encontrada (respaldo en BD)404{ "status": false, "data": "Oferta no encontrada" }
Error al aceptar la oferta500{ "status": false, "data": "Error al aceptar la oferta" }

INFO

Cuando el reenvío interno a /api/v3/asignacion es rechazado, TSALVA responde 400 devolviendo el cuerpo tal cual lo entregó ese endpoint.

Ejemplo (cURL)

bash
curl -X PUT "[URL_API]/api/v3/aceptacion" \
  -H "x-apikey: tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "dniPrestador": "900123456",
    "dniTecnico": "12345678",
    "tiempoLlegadaSitio": 25,
    "latitudTecnico": "6.2400",
    "longitudTecnico": "-75.5800"
  }'

2. Notificación saliente de aceptación

Cuando TSALVA evalúa las respuestas de las centrales y elige la mejor oferta, notifica al cliente generador enviando una petición a su endpoint configurado.

Petición

PUT {url_api}{api_endpoint.respuesta}

La URL de destino se compone de dos campos configurados en tu perfil de API: url_api (URL base) + la clave respuesta del JSON api_endpoint. Ver Configuración.

Headers

Content-Type: application/json
x-apikey: <tu_api_key>   # solo si tienes una apiKey configurada

INFO

El header x-apikey se envía únicamente si tu perfil de API tiene una apiKey registrada. Si no la tienes, la petición se envía sin ese header.

Cuerpo (payload) enviado

json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "idGestor": "TSALVA",
  "dniGestor": "901668869",
  "dniPrestador": "900123456",
  "nombrePrestador": "Central Norte SAS",
  "telefonoCentral": "+57 4 123-4567",
  "latitudTecnico": "6.2400",
  "longitudTecnico": "-75.5800",
  "identificadorTecnico": "12345678",
  "dniTecnico": "12345678",
  "telefonoTecnico": "+57 300-123-4567",
  "tarifaEstimadaServicio": "0",
  "tiempoLlegadaSitio": 25
}
CampoTipoDescripción
idstring (UUID)UUID de la oferta aceptada
idGestorstringIdentificador del gestor TSALVA (TSALVA)
dniGestorstringDocumento del gestor TSALVA (901668869)
dniPrestadorstringNIT de la central que aceptó
nombrePrestadorstringRazón social de la central
telefonoCentralstringTeléfono de la central
latitudTecnicostringLatitud del técnico asignado
longitudTecnicostringLongitud del técnico asignado
identificadorTecnicostringIdentificador del técnico
dniTecnicostringDocumento del técnico
telefonoTecnicostringTeléfono del técnico
tarifaEstimadaServiciostringTarifa estimada. Actualmente se envía "0"
tiempoLlegadaSitionumberMinutos estimados de llegada

Integraciones legacy

Para el NIT 890903279, algunos campos cambian de formato: idGestor es TSALV, dniGestor es A900445812, dniPrestador incluye el dígito de verificación, e identificadorTecnico/dniTecnico se prefijan con C.

Respuesta que TSALVA espera de tu endpoint

Importante — tu endpoint debe responder HTTP 200

Si tu endpoint responde con un código distinto de 200, TSALVA interpreta que rechazaste la asignación: libera los recursos, marca la oferta como inactiva y notifica a la central que el servicio no fue asignado. No hay reintentos automáticos: es un único intento.

El contenido del cuerpo de tu respuesta no se valida; solo importa el código HTTP 200.

Ejemplo de receptor (Node.js / Express)

javascript
const express = require('express');
const app = express();
app.use(express.json());

app.put('/webhook/aceptacion', (req, res) => {
  // Verificación opcional del header x-apikey (si lo configuraste)
  if (req.headers['x-apikey'] !== process.env.TSALVA_API_KEY) {
    return res.status(401).json({ error: 'API Key inválida' });
  }

  const { id, nombrePrestador, dniTecnico, tiempoLlegadaSitio } = req.body;
  console.log(`Oferta ${id} aceptada por ${nombrePrestador}, técnico ${dniTecnico}`);

  // Responder 200 para CONFIRMAR la asignación
  res.status(200).json({ received: true });
});

app.listen(3000);

Ejemplo de receptor (Python / Flask)

python
from flask import Flask, request, jsonify
import os

app = Flask(__name__)

@app.route('/webhook/aceptacion', methods=['PUT'])
def aceptacion():
    if request.headers.get('x-apikey') != os.environ.get('TSALVA_API_KEY'):
        return jsonify({'error': 'API Key inválida'}), 401

    data = request.get_json()
    print(f"Oferta {data['id']} aceptada por {data['nombrePrestador']}")

    # Responder 200 para CONFIRMAR la asignación
    return jsonify({'received': True}), 200

Siguiente paso

Después de la aceptación, recibirás notificaciones de Cambio de Estado a medida que avanza el servicio. Consulta también la Configuración de webhooks.

Tsalva API - Documentación desarrollada por RobPixels