Guía de integración: Recepción de pagos en tienda (Cash-In)
Esta guía está dirigida a comercios que desean integrar el registro de pagos en tienda física con la API de Atrato.
Requisitos previos
- Cuenta de partner en Atrato con acceso al dashboard
- Funcionalidad Recepción de pagos en sucursal habilitada para tu comercio
- Tipo de cuenta: Administrador, Gerente o Desarrollador
Dos formas de registrar un pago
| Tipo | Endpoint | Identificador | Cuándo usarlo |
|---|---|---|---|
| Pago a crédito | POST /credit-payment | paymentId | El cliente paga un crédito. Recomendado si tu sistema trabaja por crédito. |
| Pago global | POST /register-payment | globalPaymentId | Un mismo pago del cliente se reparte entre uno o varios de sus créditos. |
Los dos ids vienen de secuencias distintas y pueden repetirse entre sí: guarda siempre el tipo junto con el id.
Requisitos previos
- Cuenta de partner en Atrato con acceso al dashboard
- Funcionalidad Recepción de pagos en sucursal habilitada para tu comercio
- Tipo de cuenta: Administrador, Gerente o Desarrollador
Flujo de integración
sequenceDiagram
participant Comercio
participant API
Comercio->>API: POST /login (username, password)
API-->>Comercio: token
Comercio->>API: GET /credits?applicationId=XXX (x-auth-token)
API-->>Comercio: créditos abiertos [creditId, settleAmount, ...]
Comercio->>API: GET /available-stores (x-auth-token)
API-->>Comercio: stores[]
Comercio->>API: POST /credit-payment (creditId, amount, storeId)
API-->>Comercio: paymentId, status
Paso 1: Autenticación
Obtén un token con tus credenciales del dashboard partner:
POST /api/v4/integration/login
Content-Type: application/json
{
"username": "tu_usuario",
"password": "tu_contraseña"
}
Respuesta: { "token": "..." }
Envía el token en el header x-auth-token en todas las peticiones siguientes. El token expira en 5 minutos: renuévalo antes de que venza, o reintenta una vez con un token nuevo cuando recibas un 401.
Paso 2: Buscar al cliente
Por crédito (recomendado)
Busca con exactamente uno de: applicationId, los primeros 10 caracteres de la curp o userId.
GET /api/v4/integration/cash-in/credits?applicationId=12345
GET /api/v4/integration/cash-in/credits?curp=LORM870826
GET /api/v4/integration/cash-in/credits?userId=366
x-auth-token: <tu_token>
Respuesta: un renglón por crédito abierto, con userId, userName, userCURP (enmascarada), applicationId, creditId, merchantName, debtToDate, settleAmount e installmentAmount.
- Un cliente aparece solo si tiene o tuvo un crédito con tu comercio. Si cumple, se devuelven todos sus créditos abiertos, de cualquier comercio.
- La búsqueda por
curppuede devolver varios clientes: muestrauserNameal cajero para elegir.
Por usuario
Antes de registrar un pago, identifica al cliente por su referencia CIE (inicia con la letra U) o por el ID de solicitud (applicationId). Se requiere al menos uno de los dos parámetros.
GET /api/v4/integration/cash-in/search?reference=U123456789
GET /api/v4/integration/cash-in/search?applicationId=12345
x-auth-token: <tu_token>
Respuesta: userName, userId y lista de credits con: creditId, debtToDate, settleAmount, merchantName, installmentAmount.
Paso 3: Obtener sucursales
Obtén las sucursales autorizadas para tu cuenta. Necesitarás el storeId para registrar el pago.
GET /api/v4/integration/cash-in/available-stores
x-auth-token: <tu_token>
Respuesta: stores: [{ storeId, name }]. Usa el storeId de la sucursal donde se recibe el pago.
Paso 4: Registrar el pago
Pago a crédito
POST /api/v4/integration/cash-in/credit-payment
x-auth-token: <tu_token>
Content-Type: application/json
{ "creditId": 479, "amount": 1500.50, "storeId": 382 }
Respuesta 201: paymentId, creditId, status, amount, message.
Reintentos seguros: si recibes un timeout, reintenta con el mismo body. Si en las últimas 24 horas ya existe un pago no cancelado al mismo crédito por el mismo monto, la API no crea otro y devuelve el paymentId del primero.
Pago global
POST /api/v4/integration/cash-in/register-payment
x-auth-token: <tu_token>
Content-Type: application/json
{
"userId": 12345,
"storeId": 1,
"payments": [
{ "creditId": 100, "amount": 500.00 },
{ "creditId": 101, "amount": 300.00 }
]
}
Respuesta 201: globalPaymentId, status, totalAmount, appliedPayments, message.
Validaciones al registrar
- Monto máximo: el monto de cada crédito no puede ser mayor a su
settleAmount. Si excede: "El monto a pagar no puede ser mayor al monto a liquidar". - Decimales: máximo 2 decimales en el pago a crédito.
- Créditos válidos: el crédito debe estar abierto y su cliente debe cumplir la regla de acceso.
- Sucursal:
storeIddebe ser una de tus sucursales autorizadas. Si no lo envías, se usa la primera sucursal autorizada. - Horario: algunas sucursales tienen horario de registro; fuera de él la API responde 405 y no registra el pago.
Consultar pagos
Listar pagos con filtros
| Tipo | Endpoint |
|---|---|
| Pago a crédito | GET /api/v4/integration/cash-in/credit-payment/{paymentId} |
| Pago global | GET /api/v4/integration/cash-in/payment-details/{globalPaymentId} |
Los dos devuelven status (incluye cancelled), paymentDate en hora de México y receiptUrl (link firmado que dura 1 hora, si el comprobante existe).
Para listar pagos globales con filtros usa GET /api/v4/integration/cash-in/payments. Esta lista todavía no incluye pagos a crédito ni refleja cancelaciones.
Cancelar un pago
POST /api/v4/integration/cash-in/cancel-payment
x-auth-token: <tu_token>
Content-Type: application/json
{ "paymentId": 615, "reason": "El cajero capturó un monto equivocado" }
Envía exactamente uno de paymentId (pago a crédito) o globalPaymentId (pago global). Se puede cancelar dentro de los 3 días naturales posteriores al registro (en hora de México), y el pago se revierte del crédito.
Estados del pago
| Estado | Descripción |
|---|---|
success | El pago se aplicó al crédito |
pending_conciliation | Pago registrado, pendiente de aplicarse |
cancelled | Pago cancelado y revertido del crédito |
Códigos de error
400 - Datos incorrectos
| Causa | Mensaje / Detalle |
|---|---|
| userId faltante o inválido | details: "userId es requerido" |
| payments faltante o vacío | details: "Debe incluir al menos un pago" |
| Monto o creditId inválido | details: "payments[].amount debe ser un monto mayor a cero" |
| Sucursal no autorizada | message: "La sucursal X no está autorizada o no existe." |
| Monto mayor al permitido | message: "El monto a pagar no puede ser mayor al monto a liquidar" |
| Usuario sin créditos activos | message: "No se encontraron créditos activos para este usuario" |
| Créditos no pertenecen al usuario | message: "No puede pagar créditos que no correspondan al usuario" |
401 - No autorizado
Credenciales inválidas, token expirado o sin permiso para usar la integración.
404 - No encontrado
- Usuario sin créditos: "No se encontraron créditos activos para este usuario"
- Resumen de créditos: "No se encontró el resumen de los créditos para este usuario"
500 - Error de servidor
- Error general: "Error al registrar el pago."
- Fuera de horario: "El horario de registro de pagos de la sucursal es de 09:00 a 18:00 Hora de México"
