Skip to content

Cancelar Servicio

Endpoint

POST /api/v3/cancelacion

Descripción

Permite cancelar una oferta/servicio que ya fue asignada a una central. La cancelación se registra en la oferta y, cuando es posible, se notifica y se cancela el servicio en la central asignada.

Casos de uso:

  • Cancelación por parte del cliente
  • Cancelación por circunstancias imprevistas
  • Cancelación por fuerza mayor

Autenticación

Este endpoint usa autenticación HTTP Basic (autValidator).

Authorization: Basic <credentials>

Parámetros de Entrada

Body (JSON)

CampoTipoRequeridoDescripción
idServiciostringSí*Identificador (UUID) del servicio/oferta a cancelar. Se aceptan también serviceId o uuid como alias.
serviceIdstringNoAlias de idServicio.
uuidstringNoAlias de idServicio.
motivoCancelacionstringNoMotivo de la cancelación. Tiene prioridad sobre reason. Si no se envía ninguno se registra NO SE PROPORCIONÓ MOTIVO DE CANCELACIÓN.
reasonstringNoMotivo alternativo de la cancelación (se usa si no viene motivoCancelacion).
codigoSolicitudstringNoCódigo de solicitud/movimiento asociado.
internalnumberNoBandera interna de la oferta. Por defecto 0.
globalnumberNoBandera de oferta global. Por defecto 0.

*Debe enviarse al menos uno de idServicio, serviceId o uuid. En el código se resuelve como idServicio || serviceId || uuid.

Nota sobre el motivo

El campo en el código es reason / motivoCancelacion (no razon). El texto efectivo del motivo es motivoCancelacion || reason.

Ejemplo de Request

json
{
  "idServicio": "123e4567-e89b-12d3-a456-426614174000",
  "motivoCancelacion": "El cliente solucionó el problema por cuenta propia",
  "codigoSolicitud": "MOV01"
}

Ejemplo básico

json
{
  "idServicio": "123e4567-e89b-12d3-a456-426614174000",
  "reason": "El cliente canceló el servicio"
}

Respuestas

Todas las respuestas de éxito devuelven status: true y msg. Cuando el usuario integrador corresponde a una configuración especial, la respuesta incluye además un objeto plano con campos adicionales del servicio (ver Respuesta extendida).

Éxito — cancelación efectiva (200)

json
{
  "status": true,
  "msg": "Se ha efectuado la cancelación del servicio en la central NOMBRE CENTRAL correctamente."
}

Éxito — sin poder notificar a la central (200)

Cuando no se puede relacionar la central para notificarla:

json
{
  "status": true,
  "msg": "Cancelación procesada correctamente, sin embargo no fue posible relacionar la central para notificarla."
}

Cuando no se encuentra el servicio en la central para notificarle:

json
{
  "status": true,
  "msg": "Se ha efectuado la cancelación del servicio, sin embargo no fue posible encontrar el servicio en la central NOMBRE CENTRAL para notificarle."
}

Éxito — no aplicable por gestión en curso (200)

Cuando al menos una tarea del servicio ya tiene gestión en curso (task_status > 2), la cancelación no se hace efectiva pero la petición responde status: true:

json
{
  "status": true,
  "msg": "La cancelación no se pudo efectuar porque al menos una tarea del servicio ya tiene gestión en curso."
}

Falta el identificador (404)

json
{
  "status": false,
  "msg": "El campo [idServicio] o [uuid] es obligatorio para procesar la cancelación del servicio."
}

Oferta no encontrada (404)

json
{
  "status": false,
  "msg": "Lo sentimos, no fue posible encontrar la oferta bajo el UUID [<uuid>] en nuestros registros, por favor verifica que el UUID sea correcto."
}

Oferta aún no asignada (403)

json
{
  "status": false,
  "msg": "La oferta que se intenta cancelar aún no ha sido asignada, por lo tanto no es posible procesar la cancelación del servicio."
}

Error Interno (500)

json
{
  "status": false,
  "msg": "OCURRIÓ UN ERROR AL PROCESAR LA CANCELACIÓN DEL SERVICIO"
}

Respuesta extendida

Para determinados integradores, la respuesta de éxito incluye además los siguientes campos junto a status y msg:

CampoDescripción
idServicioUUID del servicio cancelado
dniTecnicoDocumento del técnico asociado (o "0")
nombreTecnicoNombre del técnico
dniGestorDocumento del gestor
dniPrestadorNIT + dígito de verificación de la central prestadora
nombrePrestadorNombre de la central prestadora
distanciaRecorridaDistancia recorrida (solo si había gestión en curso)
fechaRecepcionFecha/hora de recepción de la cancelación (YYYY-MM-DD HH:mm:ss)
observacionObservación de la cancelación
codigoEstadoServicioCódigo de estado del servicio (7 = Cancelado)

Ejemplos de Código

cURL

bash
curl -X POST "[URL_API]/api/v3/cancelacion" \
  --user "tu_usuario:tu_password" \
  -H "Content-Type: application/json" \
  -d '{
    "idServicio": "123e4567-e89b-12d3-a456-426614174000",
    "motivoCancelacion": "El cliente canceló el servicio"
  }'

JavaScript

javascript
const cancelarServicio = async (idServicio, motivoCancelacion, codigoSolicitud = null) => {
  const body = { idServicio, motivoCancelacion };

  if (codigoSolicitud) {
    body.codigoSolicitud = codigoSolicitud;
  }

  const response = await fetch('[URL_API]/api/v3/cancelacion', {
    method: 'POST',
    headers: {
      'Authorization': `Basic ${btoa('usuario:password')}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  });

  const result = await response.json();

  if (!result.status) {
    throw new Error(result.msg);
  }

  return result;
};

// Ejemplo de uso
try {
  const resultado = await cancelarServicio(
    '123e4567-e89b-12d3-a456-426614174000',
    'El cliente solucionó el problema'
  );
  console.log(resultado.msg);
} catch (error) {
  console.error('Error al cancelar:', error.message);
}

Python

python
import requests
from requests.auth import HTTPBasicAuth

def cancelar_servicio(id_servicio, motivo_cancelacion, codigo_solicitud=None):
    url = '[URL_API]/api/v3/cancelacion'

    data = {
        'idServicio': id_servicio,
        'motivoCancelacion': motivo_cancelacion
    }

    if codigo_solicitud:
        data['codigoSolicitud'] = codigo_solicitud

    response = requests.post(
        url,
        auth=HTTPBasicAuth('usuario', 'password'),
        json=data
    )

    result = response.json()

    if not result['status']:
        raise Exception(result['msg'])

    return result

# Ejemplo de uso
try:
    resultado = cancelar_servicio(
        '123e4567-e89b-12d3-a456-426614174000',
        'El cliente canceló el servicio'
    )
    print(f"Éxito: {resultado['msg']}")
except Exception as error:
    print(f"Error: {error}")

Comportamiento de la Cancelación

  • La oferta se marca con estado de cancelación y se liberan los recursos bloqueados.
  • Si la central existe y el servicio se encuentra en ella, se cancela el servicio (estado 8) y se registran evento y notificaciones.
  • Si el técnico asociado tiene token, se le envía una notificación push de "SERVICIO CANCELADO".
  • Si al menos una tarea del servicio ya tiene gestión en curso, la cancelación no se hace efectiva.

Importante

Si offer_status es mayor a 2, la oferta se considera aún no asignada y no se procesa la cancelación.

Buena Práctica

Proporciona siempre un motivoCancelacion claro. Si no se envía, se registra automáticamente NO SE PROPORCIONÓ MOTIVO DE CANCELACIÓN.

Tsalva API - Documentación desarrollada por RobPixels