Referencia API MSV Service

Bienvenido a la referencia técnica de MSV Service. Nuestra API está construida bajo principios RESTful, utiliza JSON para el intercambio de datos y códigos de respuesta HTTP estándar.


¿Qué es MSV Service?

MSV Service (Multi Step Validator) es un servicio que envía mensajes a un usuario final por WhatsApp, SMS o correo electrónico, en dos modalidades:

  • Notificación: entrega un mensaje informativo. Termina ahí: no genera token, no se puede consultar y no notifica nada de vuelta.
  • Validación: entrega un mensaje con un enlace para que el usuario apruebe o rechace. El servicio te avisa la respuesta por webhook y puedes consultarla cuando quieras.

Entornos y base URL

Todas las solicitudes deben enviarse a las siguientes URL base, dependiendo del entorno en el que te encuentres:

Entorno
Base URL
Producción
https://msv-service.placetopay.com/
UAT
https://msv-service-uat.placetopay.net
Develop
https://msv-service-dev.placetopay.ws

Ciclo de vida de una validación

  1. Creas la solicitud con POST /api/validations. El servicio envía el mensaje por los canales que indicaste. Si al menos un canal lo entrega, responde 201 con un token y la validación queda en PENDING. Si ningún canal lo entrega, responde 400 y la validación queda en FAILED.
  2. El mensaje lleva al usuario a una página de confirmación alojada por msv-service, donde aprueba o rechaza. En SMS y correo el enlace se agrega automáticamente; en WhatsApp solo aparece si incluyes [URL_VALIDATION] entre los parámetros de la plantilla.
  3. En cuanto responde, la solicitud pasa a APPROVED o REJECTED y se envía el webhook.
  4. Si no responde dentro de minutes_by_expire (30 minutos por defecto, máximo 60), la solicitud pasa a PARTIAL_EXPIRED y también se envía el webhook.
Estado
Significado
PENDING
Creada, a la espera de que el usuario responda.
APPROVED
El usuario aprobó.
REJECTED
El usuario rechazó.
PARTIAL_EXPIRED
Venció el plazo sin respuesta.
FAILED
Ningún canal confirmó la entrega del mensaje. No se envía webhook.

Flujo visual

Puedes consultar el estado en cualquier momento con Consulta validación.

Resultado por canal

Las respuestas de POST /api/validations y POST /api/notifications incluyen un arreglo channels con el resultado de cada canal, en el mismo orden en que los indicaste. Un canal puede fallar aunque otro haya entregado el mensaje; en ese caso la respuesta sigue siendo exitosa.

Campo
Tipo
Descripción
channel
string
Canal: sms, whatsapp o email.
delivered
boolean
true si el proveedor aceptó el mensaje.
reason
string
Motivo de la falla. Solo aparece si delivered es false.
message
string
Descripción del motivo en el idioma de la solicitud. Solo aparece si delivered es false.

Si el locale que envías no es soportado, se usa el idioma por defecto del servicio (en).

Motivos de falla

reason
Significado
invalid_destination
El número o correo de destino no es válido o no puede recibir mensajes.
template_rejected
WhatsApp rechazó la plantilla del mensaje.
provider_unavailable
El servicio de mensajería no está disponible en este momento.
rate_limited
Se superó el límite de envíos del proveedor. Intenta más tarde.
authentication_error
Error de autenticación con el proveedor de mensajería. No depende de los datos que enviaste.
delivery_unconfirmed
El proveedor no respondió a tiempo. El mensaje pudo haber llegado o no.
unknown
Error inesperado al enviar por el canal.

Webhook

Cuando el usuario responde la validación o cuando la validación expira sin respuesta, msv-service envía de forma asíncrona un POST a la url que configuraste en el campo webhook_url. Este payload NO es la respuesta síncrona del endpoint /api/validations. Llega despues, y es una notificación que tu servidor debe recibir y procesar.

Estructura del payload

  • Name
    status
    Type
    object
    is optional
    Description

    Objeto que contiene el estado de la validación.

    • Name
      status
      Type
      string
      is optional
      Description

      Estado actual: PENDING, APPROVED, REJECTED o PARTIAL_EXPIRED.

    • Name
      reason
      Type
      string | null
      is optional
      Description

      Código de razón adicional (puede ser nulo).

    • Name
      message
      Type
      string
      is optional
      Description

      Descripción del cambio de estado (ej: "El usuario ha respondido").

    • Name
      date
      Type
      date (ISO 8601)
      is optional
      Description

      Fecha y hora del cambio. Formato: YYYY-MM-DDTHH:MM:SS+00:00.

  • Name
    token
    Type
    string
    is optional
    Description

    Identificador único de la solicitud (8 caracteres hexadecimales). Generado al crear la validación.

  • Name
    reference
    Type
    string
    is optional
    Description

    Referencia del ítem validado (el reference que enviaste en la solicitud original).

  • Name
    kind
    Type
    string
    is optional
    Description

    Clasificación de la solicitud (el kind que enviaste originalmente).

  • Name
    signature
    Type
    string
    is optional
    Description

    Firma SHA-256 para autenticar el mensaje. Calculada como: hash('sha256', token + status.status + status.date + secret_token). Debes validarla siempre.

Ejemplos de payload

{
  "status": {
    "status": "APPROVED",
    "reason": null,
    "message": "El usuario ha respondido",
    "date": "2022-08-08T17:23:49+00:00"
  },
  "token": "d5d67dcb",
  "reference": "0122333444455555",
  "kind": "horus",
  "signature": "c1c0a085837b4042ab6cce604d5a51e665aa038c2eab58a6212037b459612ca1"
}

Validación de la firma

Antes de procesar el webhook, recalcula el hash SHA-256 y compáralo con el valor recibido en el campo signature. Si la firma calculada coincide con la firma proporcionada, se valida la autenticidad de la respuesta y se procede a persistir el registro en la base de datos:

$calculated = hash('sha256', $token . $status . $date . $secret_token);
// Ejemplo: hash('sha256', 'd5d67dcbAPPROVED2022-08-08T17:23:49+00:00ABCD1234')

if (!hash_equals($calculated, $signature)) {
    // Rechazar — no auténtico
    http_response_code(400);
    exit;
}

// Procesar el webhook
http_response_code(200);

Códigos de respuesta

Código
Cuándo ocurre
200 / 201
La solicitud se procesó y al menos un canal entregó el mensaje.
400
Ningún canal logró entregar el mensaje. El detalle por canal viene en channels.
401
Falta el token, es inválido o expiró.
404
El token consultado no existe (solo en consulta de validación).
422
Los datos no superaron la validación; el detalle viene en errors.
429
Superaste el límite de 60 peticiones por minuto.

Servicios disponibles

Explora los endpoints disponibles:

  • Login: Permite obtener un token para realizar peticiones a la API.
  • Validación: Crea una solicitud de validación (respuesta síncrona: HTTP 201 o 400).
  • Consulta validación: Consulta el estado actual de una validación previamente creada.
  • Notificación: Crea una solicitud de notificación.