VerifikaDocs
Guías

Verifica desde tu propio bot

Cómo un bot de WhatsApp ajeno valida comprobantes con Verifika por dentro.

Si ya tienes un bot que recibe comprobantes, lo que te falta no es el bot: es saber si ese comprobante es real. Eso cabe en una llamada.

curl -X POST https://api.verifika.tech/v1/verifications \
  -H "Authorization: Bearer $VERIFIKA_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+573001112233",
    "amount": 45000,
    "reference": "M1A2B3C4",
    "occurredAt": "2026-09-04T15:04:05-05:00",
    "customerName": "Juan Pérez",
    "bankLabel": "Nequi",
    "imageUrl": "https://tu-cdn.com/comprobante.jpg"
  }'
Respuesta
{
  "outcome": "REGISTERED",
  "business": { "companyId": "cmt7…", "companyName": "Panadería Delipan" },
  "income": { "id": "cmtj…", "status": "PENDING", "amount": 45000, "reference": "M1A2B3C4" },
  "attachment": { "stored": true }
}

Qué manda cada campo

Solo dos son obligatorios

phone y amount. Todo lo demás mejora el resultado —sobre todo reference, que es lo único que permite detectar un comprobante repetido— pero no impide registrar el pago.

CampoTipo¿Obligatorio?Qué significa y para qué sirve
phonestring E.164Quién reporta el pago. Tiene que ser un teléfono del equipo del negocio (dueño, supervisor o cajero): es lo que ata el movimiento a una persona y a una sucursal. Se tolera con o sin + y con separadores — 573001112233 y +57 300 111 2233 resuelven al mismo número. Si no está en el equipo: 404 PHONE_NOT_REGISTERED.
amountintegerCuánto dice el comprobante, en pesos enteros y sin decimales: 45000 son $45.000. Es uno de los tres datos con los que se cruza contra el aviso del banco, así que un valor mal leído impide la verificación.
referencestringNo, pero mándaloLa referencia del comprobante bancario. Es la llave anti-duplicados. Con ella detectamos que el mismo comprobante se está usando dos veces; sin ella no podemos, porque dos ventas de $20.000 el mismo día son perfectamente legítimas. Si tu OCR la extrae, mándala siempre.
occurredAtstring ISO 8601NoCuándo dice el comprobante que se hizo el pago, con zona horaria (-05:00 para Colombia). Si falta, se usa el momento de la llamada — y el cruce con el aviso del banco pierde precisión, porque la ventana de tiempo deja de coincidir.
customerNamestringNoQuién pagó, según el comprobante. Solo para que el dueño lo reconozca en su libro; no se valida contra nada.
bankLabelstringNoDe dónde salió la plata: «Nequi», «Bancolombia», «Daviplata». Ayuda al cruce y sale en el reporte.
accountLabelstringNoA qué cuenta del negocio entró: «Nequi *4821». Alimenta el corte por cuenta de recaudo.
imageUrlstring URLNoURL pública de la foto del comprobante. La descargamos y la copiamos a nuestro almacenamiento, así que no dependemos de que tu enlace siga vivo. Si la descarga falla, el pago se registra igual y te lo decimos en attachment.stored.

Y una cabecera que no es opcional en la práctica:

Cabecera¿Obligatoria?Para qué
Idempotency-KeyNo, pero úsalaUna llave única por comprobante, no por intento HTTP. Si la red se corta después de que procesamos y tu bot reintenta, te devolvemos la respuesta original en vez de registrar la venta dos veces. Ver Idempotencia.

Qué ramificar

outcome es lo único que tu flujo necesita mirar:

outcomeEstado del ingresoQué decirle al cliente
REGISTEREDPENDING«Recibido, estamos confirmando con el banco»
REGISTEREDVERIFIEDEl banco ya había avisado: entrega el producto
DUPLICATE«Ese comprobante ya se usó»

Cuando el banco ya había reportado el pago, el cruce ocurre en esa misma llamada y el ingreso vuelve verificado. Cuando no, queda PENDING y se confirma en cuanto entre el aviso — para enterarte en ese momento, suscribe income.verified.

Lo que hay que saber antes de construirlo

Un pago registrado por API nace PENDING, nunca VERIFIED

Solo el cruce contra el aviso real del banco puede confirmarlo. Marcar como verificado algo que solo dijo un bot destruiría el único dato que hace útil a Verifika — y con él, la razón por la que tu cliente te está pagando a ti.

  • La referencia es la llave anti-duplicados. Sin reference no podemos saber que el mismo comprobante se está usando dos veces: dos ventas de $20.000 el mismo día son legítimas. Extráela siempre que puedas.
  • El teléfono tiene que ser del equipo. phone identifica a quien reporta y tiene que estar en el equipo del negocio (dueño, supervisor o cajero). Si no, 404 PHONE_NOT_REGISTERED.
  • El comprobante lo guardamos nosotros. Nos pasas una URL, la descargamos y la copiamos a nuestro almacenamiento. Si tu enlace caduca, la evidencia sigue existiendo.
  • Un duplicado no consume cupo. Solo se descuenta una verificación cuando de verdad se registra algo.
  • Usa Idempotency-Key. Tu bot va a reintentar cuando la red falle, y no quieres duplicarle una venta a nadie. Ver Idempotencia.

Antes de la primera llamada

El negocio tiene que haber conectado su banco en Verifika: sin eso no hay contra qué cruzar. Es un asistente guiado en el panel, no un trámite técnico. Puedes comprobarlo desde tu lado antes de prometer nada:

curl https://api.verifika.tech/v1/connections \
  -H "Authorization: Bearer vk_live_..."
{ "object": "connectionStatus", "healthy": true, "channels": [ /* … */ ] }

Si healthy es false, el negocio dejó de tener con qué verificar. Vale la pena revisarlo a diario: enterarte tú antes que tu cliente es media razón para integrar.

Si manejas muchos negocios

Una llave por negocio, hoy

Hoy cada negocio te da su propia llave, creada desde su panel. Si atiendes cuarenta negocios, guardas cuarenta llaves.

Estamos construyendo el modelo de partner: una sola credencial tuya que actúa sobre los negocios que te hayan dado permiso explícito, con una pantalla de aprobación que ellos firman. Si estás en ese caso, escríbenos — podemos habilitarlo antes de la apertura general.

La razón de que no exista todavía no es técnica: conocer el teléfono de un negocio no puede ser autorización para escribir en su libro. El consentimiento tiene que ser del dueño, explícito y revocable, y esa pantalla es lo que estamos terminando.

En esta página