Skip to content

La papeleta

Análisis Funcional: Pago con documentos — parte 4 de 5. ← Datos y documentos · Índice · Siguiente: Preguntas Abiertas →

La papeleta es el comprobante que se imprime al pagar, firman el cliente y el operador, y vuelve escaneada como uno de los cuatro soportes obligatorios. Es el único artefacto del módulo que sale del sistema hacia el papel y regresa.

El cliente lo pidió así, en dos filas del material:

"Se genera la papeleta, la firma y la hace firmar al cliente" — hoja Módulo caja, fila 13. "Generar el pdf desde el módulo de cajero el momento en el que se paga la tx" — requerimiento #4.

Y adjuntó el modelo en Word, con un ejemplo real completo. Eso convierte a la papeleta en el único documento de todo el proyecto donde no hubo nada que diseñar: había que replicarlo.

3.1 Qué replica del modelo del cliente

Se respetan el orden, los rótulos y el texto legal exactos. No es una pantalla que se pueda reinterpretar: es un documento que una persona firma.

La declaración del cliente se transcribió literal del modelo, con sus cuatro incisos: haber leído y aceptado los términos y condiciones, que la información declarada es fiel reflejo de su situación, que los fondos provienen de actividades lícitas, y haber aceptado el tratamiento de sus datos personales. Está en backend/resources/views/pdf/papeleta.blade.php:75-82.

De dónde sale cada dato (backend/app/Services/PapeletaService.php:52-79):

CampoOrigen
AGENCIAEl nombre del PDV que resolvió la transacción
OPERADOREl mail del usuario que la pagó
FECHA/HORALa fecha del pago, no la de impresión — ver §3.4
MTCNEl MTCN de la transacción
REMITENTE / PAÍS DE ORIGENConstantes: SOTEREX y ESTADOS UNIDOS
BENEFICIARIONombre y apellido, en mayúsculas
TIPO y NRO DE IDENTIFICACIÓNLos que cargó el operador en el formulario de datos (§2.1)
TELÉFONOEl que mandó Soterex
MONTO ENVIADO / RECIBIDO / TOTALLos tres son el mismo valor: el principal
MONEDA A PAGARLa moneda de pago del país
TASA CAMBIO1.00000000

Los tres montos son iguales y la tasa es 1 por dos razones distintas que conviene no confundir: la tasa es 1 porque el cambio de moneda se difirió a MVP2 (confirmado por el cliente en este mismo material), y los montos son iguales porque la comisión no se le cobra al beneficiario — la paga Soterex, y nunca aparece en un documento que ve el cliente.

Cuando MVP2 habilite la conversión, hay que tomar el tipo de cambio congelado en el movimiento de caja, no el vigente al momento de imprimir. Está anotado en el propio servicio (PapeletaService.php:17-23), y es la clase de detalle que se pierde si no queda escrito.

3.2 Por qué 58 mm

El modelo Word está maquetado sobre una hoja A4, pero dibuja sus separadores a unos 66 mm: es la maqueta de un ticket, no de una carta. La impresora del mostrador es térmica.

Se eligió 58 mm de ancho, que es el rollo estándar de mostrador, con el alto resuelto por el contenido (PapeletaService.php:26-30). El cuerpo va en 6,5 pt y el texto legal en 5,5 pt, que es lo que entra sin que la declaración ocupe media tira.

El espacio de firma es deliberadamente generoso —7 mm entre bloques, con línea real (papeleta.blade.php:37-39)—: sin lugar para firmar, la papeleta no cumple su función, y ese es todo su motivo de existir.

3.3 Es reimprimible

El botón dice "Imprimir papeleta" y está siempre disponible sobre una transacción pagada (frontend/src/components/DocumentacionPago.vue:143-149). No hay límite de reimpresiones.

Es una necesidad real: el cliente pierde el papel, la impresora se traba, el supervisor necesita una copia. Que la papeleta sea reimprimible convierte todos esos casos en un click.

Lo que lo hace posible es que todo lo que la papeleta muestra sale de la transacción ya persistida, no de la configuración de hoy. Reimprimirla el mes que viene tiene que dar exactamente el mismo papel.

3.4 La fecha es la del pago, no la de impresión

Es el corolario de §3.3 y merece renglón propio porque es fácil equivocarse.

php
// backend/app/Services/PapeletaService.php:60-62
// La fecha del pago, no la de impresión: una reimpresión no puede
// cambiar cuándo se entregó la plata.
'fechaHora' => optional($transaction->last_updated_at)->format('d/m/Y H:i') ?? '—',

Si la papeleta imprimiera now(), una reimpresión pedida tres semanas después produciría un comprobante firmado que afirma que el dinero se entregó ese día. Sería un documento falso, con la firma del cliente al pie. La reimpresión tiene que ser una copia, no un documento nuevo.

3.5 No se guarda el PDF

Se genera al vuelo en cada pedido y se descarga; no queda nada en el disco (TransactionController::papeleta(), líneas 521-544).

La alternativa —guardar el PDF al pagar— obligaría a versionarlo cada vez que cambie el membrete o un rótulo, para un documento que es enteramente derivable de la transacción. Y no aporta nada como evidencia: el respaldo legal no es el PDF que generamos, es la papeleta firmada que el cliente escaneó y subió como soporte PAPELETA_FIRMADA.

O sea que sí hay un PDF guardado de cada papeleta — el escaneado, con las dos firmas. Guardar además el original en blanco sería guardar el molde.

3.6 Se emite solo si está pagada, y cada emisión queda auditada

Pedir la papeleta de una transacción ACCEPTED devuelve 422 TRANSACTION_NOT_PAID con el mensaje "La papeleta se emite recién cuando la transacción está pagada" (TransactionController.php:527-532). Una papeleta de un pago que no ocurrió es un comprobante de algo falso.

Cada emisión escribe PAPELETA_GENERATED en auditoría con el MTCN (TransactionController.php:534-541). Saber cuántas veces se reimprimió una papeleta importa: es el respaldo de que se entregó la plata, y un patrón de reimpresiones sobre la misma transacción es una señal que alguien va a querer mirar.

3.7 Lo que NO se replicó del modelo, y por qué

Dos cosas del Word quedaron afuera. Ninguna por descuido — ninguna se entiende.

TRANSACCIÓN FIJA: SI / NO. El modelo lo imprime al lado de la tasa de cambio, con las dos opciones visibles como si fuera para tildar a mano. No hay nada en el resto del material que explique qué significa, ni una columna equivalente en el reporte, ni un campo en el modelo de datos. Se omitió antes que imprimir un rótulo cuyo significado nadie puede explicarle al cliente que lo firma. Ver Preguntas Abiertas #1.

El teléfono de servicio al cliente. En el modelo figura literalmente como XXXXXXXXXXX — el cliente mandó la plantilla sin completarlo. La app lo toma de una variable de configuración (app.customer_service_phone) y, mientras esté vacía, imprime un guión. Ver Preguntas Abiertas #2.

3.8 El formulario de enrolamiento — 📋 sin implementar

El segundo modelo Word que mandó CIS-EC es el formulario de enrolamiento para giros no presenciales, que solo aplica a pagos por transferencia bancaria. Sus campos son: nombres y apellidos, tipo y número de identificación, dirección, ciudad, estado/provincia, teléfono, país de residencia, nacionalidad, correo, género, fecha de nacimiento, estado civil, y los datos de cuenta bancaria (banco, tipo de cuenta y número).

El cliente sugirió generarlo desde el sistema:

"Ver la posibilidad de emitirlo desde la misma API porque ya se cuenta con todos los datos el momento que se registra la tx" — hoja Módulo caja, fila 21.

No se generó. Hoy el tipo FORMULARIO_ENROLAMIENTO existe solo como casillero para subir el formulario escaneado, igual que los otros ocho.

La razón es concreta: de los campos que el formulario pide, género y estado civil no existen en el modelo de datos ni vienen en el reporte de Soterex. Generarlo hoy produciría un formulario con dos casilleros en blanco que igual habría que completar a mano — o sea, exactamente el mismo trabajo que imprimirlo aparte, más el costo de mantener la plantilla. Ver Preguntas Abiertas #6.


Análisis Funcional: Pago con documentos — parte 4 de 5. ← Datos y documentos · Índice · Siguiente: Preguntas Abiertas →

Documentación viva — se actualiza junto con el código, no es un anexo aparte.