Recepción de pagos

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

TipoEndpointIdentificadorCuándo usarlo
Pago a créditoPOST /credit-paymentpaymentIdEl cliente paga un crédito. Recomendado si tu sistema trabaja por crédito.
Pago globalPOST /register-paymentglobalPaymentIdUn 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 curp puede devolver varios clientes: muestra userName al 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: storeId debe 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

TipoEndpoint
Pago a créditoGET /api/v4/integration/cash-in/credit-payment/{paymentId}
Pago globalGET /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

EstadoDescripción
successEl pago se aplicó al crédito
pending_conciliationPago registrado, pendiente de aplicarse
cancelledPago cancelado y revertido del crédito

Códigos de error


400 - Datos incorrectos

CausaMensaje / Detalle
userId faltante o inválidodetails: "userId es requerido"
payments faltante o vacíodetails: "Debe incluir al menos un pago"
Monto o creditId inválidodetails: "payments[].amount debe ser un monto mayor a cero"
Sucursal no autorizadamessage: "La sucursal X no está autorizada o no existe."
Monto mayor al permitidomessage: "El monto a pagar no puede ser mayor al monto a liquidar"
Usuario sin créditos activosmessage: "No se encontraron créditos activos para este usuario"
Créditos no pertenecen al usuariomessage: "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"