Appearance
Descarga de Recibos — Vista del Cliente
Módulo: Portal de Clientes Tipo: View Estado: Implementado Fecha: 2026-05-14
Descripción
Los clientes del portal pueden descargar el recibo digital de sus pagos aprobados directamente desde el portal, sin intervención de un operador. El recibo se genera en PDF y se abre en una nueva pestaña del navegador.
La funcionalidad aparece en dos lugares: en la vista de resultado de pago (PagoResultado) y en el historial de pagos (/historial).
Vista: Resultado de Pago (PagoResultado)
Ruta: /resultado (post-pago, con payment_id en query params o estado) Componente: PagoResultado.tsx
Comportamiento según estado del pago
El recibo solo aplica a pagos con status === 'approved'. Para otros estados (pending, rejected, cancelled, refunded) no se muestra ningún elemento relacionado al recibo.
Caso 1 — Pago aprobado con recibo disponible
Cuando status === 'approved' y recibo_id es un valor no nulo:
- Se muestra un botón "Descargar recibo"
- Al hacer click, el sistema llama al endpoint
GET /backend/portal/pagos/{id}/recibo - El PDF se abre en una nueva pestaña del navegador (
window.open) - Mientras la descarga está en curso, el botón muestra un indicador de carga (loading state)
- Si el servidor responde con
409 RECIBO_PENDIENTE, el botón desaparece y se muestra el mensaje de "en proceso" (ver Caso 2)
Caso 2 — Pago aprobado con recibo en proceso
Cuando status === 'approved' y recibo_id es null (reconciliación TX2 aún no completó):
- Se muestra el mensaje: "Recibo en proceso, intentá nuevamente en unos minutos"
- No se muestra ningún botón de descarga
Caso 3 — Pago no aprobado
Cuando status !== 'approved' (pending, rejected, cancelled, refunded):
- No se muestra ningún elemento relacionado al recibo
Vista: Historial de Pagos (/historial)
Ruta: /historial Componente: HistorialView.tsx → HistorialList.tsx → HistorialRow.tsx
Tabla de pagos
El historial muestra una tabla con todos los pagos del cliente, con las siguientes columnas:
| Columna | Descripción |
|---|---|
| Fecha | Fecha del pago, formato dd/MM/yyyy |
| Monto | Monto en formato peso argentino ($N.NNN,NN) |
| Estado | Badge de estado del pago (approved, pending, rejected, etc.) |
| Gateway | Nombre del gateway de pago utilizado (ej: paypertic, mercadopago) |
| Acción | Botón de descarga o texto informativo según el estado del recibo |
Estados de la columna Acción
La columna Acción varía según la combinación de status y recibo_id de cada fila:
| Condición | Acción mostrada |
|---|---|
status === 'approved' y recibo_id no nulo | Botón "Descargar recibo" |
status === 'approved' y recibo_id nulo | Texto: "Recibo en proceso..." |
| Cualquier otro estado | Badge de estado solamente (sin botón ni texto adicional) |
Descarga desde el historial
Al hacer click en "Descargar recibo":
- El sistema llama a
GET /backend/portal/pagos/{id}/recibo - El PDF se abre en una nueva pestaña del navegador
- El botón de esa fila muestra estado de carga mientras se procesa
- Otras filas no son afectadas (el estado de carga es por fila)
Respuesta 409 — Recibo en proceso
Si el servidor responde con 409 RECIBO_PENDIENTE al intentar descargar:
- Se muestra un mensaje inline en la fila: "Recibo en proceso, intentá nuevamente en unos minutos"
- El mensaje reemplaza el botón en esa fila
- No se muestra ningún toast ni notificación global de error
Estados de la vista
Cargando
Mientras se obtiene el historial del servidor, se muestran 3 filas de skeleton (marcadores de posición animados). No se muestra la tabla ni el mensaje de vacío durante la carga.
Sin pagos
Cuando el historial está vacío:
"No tenés pagos registrados"
Error de carga
Cuando el historial no pudo obtenerse:
"No se pudieron cargar tus pagos."
Con pagos
Se muestra la tabla con todas las filas y controles de paginación (botones Anterior / Siguiente).
Paginación
El historial usa paginación por offset clásica:
- Tamaño de página: 20 registros por defecto
- Controles: botones "Anterior" y "Siguiente"
- El total de registros se usa para determinar si hay más páginas
Comportamiento de Errores
| Error | Presentación |
|---|---|
409 RECIBO_PENDIENTE | Mensaje inline en la fila/botón, sin toast |
502 INFORMES_ERROR | Mensaje de error genérico (el servicio no está disponible) |
404 PAYMENT_NOT_FOUND | Error genérico — no debería ocurrir desde el historial propio |
422 RECIBO_NO_DISPONIBLE | No aplica en el historial (solo pagos approved tienen el botón) |
Permisos
Solo usuarios autenticados en el portal pueden acceder a estas vistas. La autenticación se valida mediante JWT en el header Authorization: Bearer. Sin JWT válido, la ruta /historial redirige al login.
Dependencias
- Proceso de descarga de recibo — flujo técnico end-to-end
- Auto-Reconciliación — Proceso — cómo se genera el
recibo_id - Endpoints API — contrato del endpoint
GET /backend/portal/pagos/{id}/recibo