Acreditación de gift cards sobre una tarjeta equivocada — POS 72
1. Resumen ejecutivo
Qué vio el cliente
Al vender gift cards en el POS 72 (Sucursal 13), el sistema acreditó el importe de la segunda tarjeta
(y a veces de una tercera y una cuarta) sobre el número de la tarjeta anterior. El ticket impreso
mostraba el mismo TARJ: repetido y el saldo consultado en el autorizador (TiPrepaga)
aparecía acumulado (por ejemplo $40.000 + $40.000 = $80.000 en una sola tarjeta), mientras que la
tarjeta física entregada al cliente quedaba en $0. El cliente reportó el mismo patrón el 04/09, el
05/09, el 06/09 y nuevamente el 14/09, y pidió frenar la venta de gift cards.
Causa raíz en 3 líneas
Cuando la lectura de Track 2 de la banda falla y el POS reconstruye el Track 2 a partir del Track 1
(camino interno REBUILDT2, pos_devi.cpp:1484-1519), el evento
EV_BAND se publica sin refrescar poscard.buffer. Ese búfer es el único que
lee GetCardPan/CARD_READER::GetDataCard
(pos_misc.cpp:3833, pos_card.cpp:2015), y como nunca se limpia entre
lecturas, conserva el PAN de la última tarjeta leída con éxito. El sistema identifica y factura sobre
esa tarjeta vieja, no sobre la que el cajero acaba de pasar.
Fix en 2 líneas
El camino REBUILDT2 ahora copia BuffBanda a poscard.buffer antes
de publicar EV_BAND, igual que hace el camino normal (pos_devi.cpp ~línea
1510-1511). Como refuerzo fail-closed, una lectura de banda que arranca (carácter %)
limpia poscard.buffer para que una lectura abortada no herede nunca el PAN anterior
(pos_devi.cpp:1390).
Estado
El fix está aplicado sobre pos_devi.cpp (marcador //20260915++) y el build de
producción compila limpio: POS_MAIN.MAP quedó actualizado 7 minutos después de la última
modificación del fuente, con POS_DEVI_TEXT en 0x3A2F (14.895 bytes, 50.641
libres de 64 KB). Falta la prueba en vivo con un lector físico forzando un error
real de Track 2 (sección 7) antes de dar el fix por cerrado en producción.
Qué NO resuelve este fix
- No revierte los saldos ya mal acreditados: eso requiere una regularización manual con TiPrepaga (sección 8).
- No corrige la causa física de por qué el Track 2 falla tan seguido en el lector del POS 72 (sección 5): el fix hace que el sistema reaccione bien ante el error, pero la tasa de error de lectura sigue siendo anormalmente alta.
- No agrega un control adicional de "PAN repetido dos veces seguidas" en
pos_vnta.cpp: se evaluó y se descartó porque, con el Hunk 1 aplicado, el invariante queda garantizado por construcción, y esa variable adicional hubiera consumido presupuesto ya escaso de DGROUP.
2. Reclamo
El reclamo llegó por correo de Franco Vega (Operador Mesa de Ayuda, Grupo Dinosaurio) el 14/09/2026, encadenando un reporte previo del 05/09 y agregando un caso nuevo del mismo 14/09.
| Fecha | Descripción del cliente | Confirmado en el log |
|---|---|---|
| 04/09 | Compra de gift cards por $40.000 para dos tarjetas distintas; se terminó acreditando $80.000
a una sola tarjeta (...7208). |
Sí — tickets 433407/433408, saldo final 80.000,00 |
| 05/09 | Se vende y cobra una gift card; al instante siguiente se venden 4 gift más distintas y quedan todas asociadas a la primera tarjeta, acumulando importes. | Sí — tickets 433548 a 433551 encadenados sobre ...1531 |
| 06/09 | "El mismo problema ocurrió el día 06/09"; se adjuntan tickets donde se repite el número de tarjeta. | Sí — ticket 433778 encadenado sobre ...1663 |
| 14/09 | "Hoy volvió a suceder lo mismo con 2 tarjetas." | Parcial — se registran 3 eventos REBUILDT2, pero en esta ventana ninguna venta
quedó doble-acreditada (ver sección 4): un ticket fue anulado por el cajero antes de facturar y
otro recuperó un PAN limpio por una lectura suelta previa. No se descarta que "2 tarjetas" se
refiera a un ticket fuera de la ventana capturada en el log entregado. |
3. Causa raíz técnica
3.1 Camino normal de lectura (correcto)
Con una banda sana, el fin de lectura llega con el carácter ?. El POS publica
EV_BAND y copia el búfer crudo a poscard.buffer:
pos_devi.cpp:1439 PutEvent(event, EV_BAND);
pos_devi.cpp:1440 strncpy(poscard.buffer, BuffBanda, sizeof(poscard.buffer)-1);
pos_devi.cpp:1449 strncpy(sttracks.cTrack2, &BuffBanda[iLenT1], uLen2Copy);
3.2 Camino REBUILDT2 (defectuoso antes del fix)
Cuando el lector IBM marca error de Track 2 con el carácter E
(iCheckIfNextCharIsErrorIBM, seteado en pos_devi.cpp:1479), el POS reconstruye
el Track 2 a partir del Track 1 y publicaba EV_BAND sin tocar
poscard.buffer:
pos_devi.cpp:1505 sprintf(sttracks.cTrack2, "%.20s=%.8s000000000000", ct2pan, ct2vto);
pos_devi.cpp:1512 PutEvent(event, EV_BAND); <-- antes del fix: poscard.buffer no se tocaba
pos_devi.cpp:1516 Log(LOGERROR, LOG_CARD_TRACKS, GCmos.NroZ, "REBUILDT2 %.5s(%d)", ...);
BuffBanda (pos_devi.cpp:1243) sí contiene en ese momento el Track 1 de la
tarjeta actual: la reconstrucción del PAN es correcta, sólo que antes del fix quedaba confinada a
sttracks. El (37) del log confirma una reconstrucción exitosa: 20 (PAN) + 1
(=) + 8 (vencimiento) + 12 ceros = 37 caracteres, con un PAN de 16 dígitos.
3.3 El consumidor lee poscard.buffer, no sttracks
pos_vnta.cpp:857 if(GetCardPan( poscard.buffer, tick->_msgbuff)) return;
pos_misc.cpp:3833-3848 GetCardPan(...) -> CARD_READER::GetDataCard(poscard.buffer)
pos_card.cpp:2016-2057 GetDataCard: parsea `buff` (= poscard.buffer) y llena track.pan desde el Track 1
pos_card.cpp:2076-2088 sólo respalda con sttracks.cTrack2 si track.pan sigue vacío <-- nunca se alcanza
Como poscard.buffer conserva la banda completa y válida de la tarjeta anterior,
track.pan se llena con el PAN viejo y el respaldo sobre sttracks nunca se
ejecuta. poscard.buffer (char buffer[200] según la documentación de
cabeceras citada en el diagnóstico; instancia en pcpos.h) tampoco se limpiaba al iniciar
un ticket ni al iniciar una nueva lectura de banda — de ahí que el PAN persista entre tickets.
3.4 Propagación hasta el autorizador
El PAN leído (correcto o residual) se guarda por ítem del ticket y viaja así hasta la llamada SOAP:
pos_vnta.cpp:628 strncpy(cNroTarjetaRegalo, tick->_msgbuff, sizeof(cNroTarjetaRegalo)-1);
pos_vnta.cpp:690 GiftCard_ConsultaEstadoTarjeta(...) -> <ns2:identificarTarjeta>
pos_tick.cpp:2069-78 persiste el PAN por ítem en dB_TDeta (iPeriodo/iNroUser, iModo=9999)
pos_lnov.cpp:772-800 stRegaloArray::AddTrx() relee dB_TDeta y arma la lista a enviar
pos_lnov.cpp:1585 GiftCard_EnviarAlAutorizador(...)
pos_lnov.cpp:1606 Transmitir_Trx(...) -> <ns2:venta> con <nroTarjeta>, <importe>, <ticketPOS>
El dato ya entra equivocado desde la lectura de banda; no hay un segundo búfer global a nivel de venta que se pueda corregir más abajo en la cadena.
3.5 Diagrama: antes y después del fix
4. Evidencia en los logs
Las tablas de esta sección se recalcularon con un script propio (Python) sobre el texto completo de
cada log, buscando Inicia TickPOS, REBUILDT2, los pedidos
<ns2:venta> (PAN, importe, ticket) y las respuestas <ns2:ventaResponse>
(saldo, código). No se tomó ningún número del diagnóstico previo sin recalcularlo desde el log fuente.
Log pos 72 04-09 completo.txt
(38.654 líneas, log completo, recalculado directamente). 05/09, 06/09 y 14/09: el drive de red
(G:) donde estaban los logs originales se desconectó durante la sesión de trabajo; el
coordinador entregó primero un extracto manual tomado antes de la desconexión
(C:\Work\TI\20260914\GIIFT\newlogs\EXTRACTO_05_06_14.txt) y luego copió los tres logs
completos a C:\Work\TI\20260914\GIIFT\newlogs\ (1.895 / 1.571 / 1.424 líneas
respectivamente). Las tablas de 05/09, 06/09 y 14/09 de abajo están recalculadas desde esos tres logs
completos, no desde el extracto. Resultado del cruce: cero discrepancias entre el
extracto manual y el recálculo desde el log completo, en tickets, PAN, importes y saldos.
4.1 Día 04/09/2026
| Ticket | Hora venta | REBUILDT2 | PAN (últimos 4) | Importe | Saldo respuesta | ¿Repite PAN anterior? |
|---|---|---|---|---|---|---|
| 433406 | 14:39:55 | Sí (14:39:11) | ...7190 | 40.000,00 | 40.000,00 | No — primera gift del día; el REBUILDT2 recuperó el PAN de una lectura previa del propio ticket 433402 (pasado a espera), no de una tarjeta ya vendida. |
| 433407 | 14:40:46 | No | ...7208 | 40.000,00 | 40.000,00 | No |
| 433408 | 14:41:27 | Sí (14:40:50) | ...7208 | 40.000,00 | 80.000,00 | Sí — repite el PAN de 433407 |
| 433409 | 14:42:22 | No | ...7224 | 40.000,00 | 40.000,00 | No |
| 433410 | 14:43:15 | Sí (14:42:28) | ...7224 | 40.000,00 | 80.000,00 | Sí — repite el PAN de 433409 |
| 433411 | 14:44:08 | Sí (14:43:21) | ...7224 | 40.000,00 | 120.000,00 | Sí — repite el PAN de 433410 |
| 433420 | 15:06:36 | Sí (15:05:22) | ...7257 | 100.000,00 | 100.000,00 | No — el primer REBUILDT2 quedó anulado por una relectura limpia a las 15:05:29 antes de la venta; el PAN que finalmente viajó fue el correcto. |
| Totales del día | 5 REBUILDT2 / 16 lecturas | 3 cargas mal acreditadas | Excedente a redistribuir: $120.000,00 | |||
Ticket adicional 433457 (17:06, lectura limpia, PAN ...7133, $60.000) es una venta de gift
card posterior del mismo día, sin relación con la ventana del reclamo; se incluye en el log pero no en
la lista de cargas a corregir.
Verificación cruzada por numeración de serie (04/09)
Los PAN vendidos ese día son correlativos: ...7190, ...7208,
...7224, ...7257. Faltan exactamente tres números intermedios, en la misma
cantidad y posición que los tres tickets afectados por REBUILDT2 con carga repetida
(433408, 433410, 433411). Esas tres tarjetas físicas fueron entregadas al cliente sin saldo — coincide
exactamente con el excedente de $120.000 calculado arriba (3 × $40.000).
4.2 Día 05/09/2026
| Ticket | Hora venta | REBUILDT2 | PAN (últimos 4) | Importe | Saldo respuesta | ¿Repite PAN anterior? |
|---|---|---|---|---|---|---|
| 433547 | 10:15:34 | No | ...1531 | 150.000,00 | 150.000,00 | No |
| 433548 | 10:16:48 | Sí (10:15:57) | ...1531 | 150.000,00 | 300.000,00 | Sí |
| 433549 | 10:17:43 | Sí (10:16:57) | ...1531 | 50.000,00 | 350.000,00 | Sí |
| 433550 | 10:18:41 | Sí (10:17:55) | ...1531 | 50.000,00 | 400.000,00 | Sí |
| 433551 | 10:19:38 | Sí (10:18:50) | ...1531 | 50.000,00 | 450.000,00 | Sí |
| Totales del día | 4 REBUILDT2 / 5 lecturas | 4 cargas mal acreditadas | Excedente a redistribuir: $300.000,00 | |||
Este es el caso más severo de la muestra: cuatro tickets consecutivos, cada uno con un lector que falló en Track 2, quedaron todos encadenados sobre la primera tarjeta del bloque. Coincide con el relato del cliente ("se vende gift card... al instante siguiente se venden 4 gift más distintas y quedan asociadas a la primera").
4.3 Día 06/09/2026
| Ticket | Hora venta | REBUILDT2 | PAN (últimos 4) | Importe | Saldo respuesta | ¿Repite PAN anterior? |
|---|---|---|---|---|---|---|
| 433777 | 16:23:29 | No | ...1663 | 70.000,00 | 70.000,00 | No |
| 433778 | 16:24:39 | Sí (16:23:40) | ...1663 | 70.000,00 | 140.000,00 | Sí |
| 433779 | 16:25:30 | Sí (16:24:45) | ...1671 | 70.000,00 | 70.000,00 | No — excepción: hubo REBUILDT2 pero el PAN que llegó a ns2:venta
fue nuevo (...1671), no el de 433778. El log no registra una segunda pasada de
banda ni uso de scanner entre medio; no se pudo determinar la causa exacta de por qué este
REBUILDT2 en particular sí devolvió un PAN limpio. |
| 433780 | 16:26:28 | No | ...1697 | 70.000,00 | 70.000,00 | No |
| Totales del día | 2 REBUILDT2 / 4 lecturas | 1 carga mal acreditada | Excedente a redistribuir: $70.000,00 | |||
4.4 Día 14/09/2026
| Ticket | Hora | REBUILDT2 | PAN (últimos 4) | Importe | Saldo respuesta | Observación |
|---|---|---|---|---|---|---|
| 434566 | 13:52:56 | No | ...5671 | 100.000,00 | 100.000,00 | Venta normal. |
| 434567 | 13:53:09 | Sí | ...5671 (heredado) | — | — | Sin venta: el ticket fue anulado por el cajero (Anula TicPOS:434567
Causa:1) antes de llegar a facturar la gift card. Habría repetido el PAN de 434566 de
haberse completado. |
| 434568 | 13:53:45 → venta 13:54:46 | Sí (13:53:50) | ...5531 (nuevo) | 100.000,00 | 100.000,00 | No repite PAN: entre la anulación de 434567 y el REBUILDT2 de este ticket hubo una pasada de banda suelta a las 13:53:44 (sin ticket asociado en ese instante, registrada igual en el log). Esa lectura limpia "regaló" un PAN nuevo que quedó vigente cuando se disparó el REBUILDT2 de 434568, evitando la duplicación. |
| 434569 | 13:54:49 | Sí (13:55:04) | ...5549 (heredado) | — | — | No se registra <ns2:venta> para este ticket en la ventana del log — la
operación de gift card no llegó a completarse (tres pasadas de banda seguidas antes del
REBUILDT2 sugieren un lector luchando por leer la tarjeta). |
| 434570 | 13:56:18 | No | ...5549 | 175.000,00 | 175.000,00 | Venta normal; hereda de manera inofensiva el PAN de la lectura suelta de 13:55:15 porque es su propia tarjeta, leída limpiamente. |
| Totales del día | 3 REBUILDT2 / 9 lecturas | 0 cargas mal acreditadas confirmadas | Excedente a redistribuir: $0,00 | |||
poscard.buffer en cada momento, exactamente el comportamiento indeterminado
que describe la causa raíz.
4.5 Totales consolidados (4 días)
| Métrica | Valor |
|---|---|
| Lecturas de banda ("Leyendo banda...") | 34 |
| Eventos REBUILDT2 | 14 |
| Cargas mal acreditadas (PAN repetido con venta efectiva) | 8 |
| Excedente total a redistribuir | $490.000,00 |
5. Estado del lector del POS 72
REBUILDT2 es la señal de que el lector no pudo leer el Track 2 y el software tuvo que
reconstruirlo. Es un indicador directo del estado físico del cabezal lector, independiente del bug de
software: incluso con el fix aplicado, cada REBUILDT2 sigue siendo una lectura degradada
(aunque ahora ya no se traduzca en un PAN equivocado).
| Día | Leyendo banda | REBUILDT2 | % de fallas de Track 2 |
|---|---|---|---|
| 04/09 | 16 | 5 | 31,3% |
| 05/09 | 5 | 4 | 80,0% |
| 06/09 | 4 | 2 | 50,0% |
| 14/09 | 9 | 3 | 33,3% |
| Total | 34 | 14 | 41,2% |
Recomendación
- Limpiar el cabezal lector del POS 72 con tarjeta de limpieza húmeda y volver a medir la tasa de
REBUILDT2durante una jornada. - Si la tasa no baja a un dígito bajo, reemplazar el lector del POS 72.
- Probar el mismo lote de gift cards en otro POS de la sucursal para descartar que el problema esté en la calidad de la banda magnética del lote de tarjetas, no en el lector.
- Para priorizar qué otros POS revisar, correr
grep REBUILDT2sobreD:\POS\SERVDINO\ZLOG\POSnnnn\por cada POS y ordenar por cantidad de ocurrencias. Hasta que el fix esté desplegado en todos los puestos, cada ocurrencia deREBUILDT2en cualquier POS es una carga potencialmente mal acreditada.
6. El fix
Cambio mínimo y quirúrgico, en el estilo del código existente, aplicado únicamente sobre
pos_devi.cpp. Ambos hunks están presentes en el archivo con el marcador
//20260915++.
Hunk 1 — obligatorio (pos_devi.cpp, ~línea 1503-1519)
@@ pos_devi.cpp: rama REBUILDT2 (error Track2, carácter 'E') @@ if(strlen(cpan)){ strncpy( ct2vto, cpan, 8); sprintf(sttracks.cTrack2, "%.20s=%.8s000000000000", ct2pan, ct2vto); + //20260915++ Este camino publicaba EV_BAND sin refrescar poscard.buffer, + //el unico buffer que lee GetCardPan/CARD_READER::GetDataCard: quedaba + //el PAN de la lectura anterior (gift cards acreditadas a la tarjeta + //previa, reclamo Dinosaurio POS72 04/09). Mismo copy que el camino '?'. + memset(poscard.buffer,0,sizeof(poscard.buffer)); + strncpy(poscard.buffer, BuffBanda, sizeof(poscard.buffer)-1); PutEvent(event, EV_BAND); lastComienzoLecturaBanda=0L; BandaReadStatus=0;
Por qué: es el fix real. BuffBanda contiene en ese punto el Track 1 de la
tarjeta actual, sin el % inicial — exactamente la misma forma que el camino normal deja
en poscard.buffer en pos_devi.cpp:1440. GetDataCard detecta
TRACK1 por los caracteres ^ y extrae el PAN correcto. Con este cambio, el
camino REBUILDT2 deja de ser distinto del camino normal desde el punto de vista de quién consume
EV_BAND.
Hunk 2 — recomendado, fail-closed (pos_devi.cpp, ~línea 1383-1396)
@@ pos_devi.cpp: caso '%' (comienza Track1) @@ case '%': //comienza Track1 iCheckIfNextCharIsErrorIBM=0; lastComienzoLecturaBanda=ToJul(>ime,&gdate); sttracks.Clear(); iLenT1=0; Error("Leyendo banda..."); memset(BuffBanda,0,sizeof(BuffBanda)); + memset(poscard.buffer,0,sizeof(poscard.buffer)); //20260915++ una lectura abortada no hereda el PAN anterior BandaReadStatus=1; BandaCounter=0; LastKeyBanda=1; EsActualTrack1=1; PutEvent(event, evNothing); return;
Por qué: refuerzo defensivo. Evita que una lectura abortada o incompleta —cualquiera
que sea el motivo, no solo REBUILDT2— quede servida con el PAN de la tarjeta anterior.
Se aplica junto con el Hunk 1, no en su reemplazo: por sí solo convertiría el defecto silencioso en un
error visible de lectura, lo cual es preferible al estado original pero no resuelve la venta.
Impacto de segmento / DGROUP (verificado)
| Segmento | Tamaño usado | Libre de 64 KB | Nota |
|---|---|---|---|
POS_DEVI_TEXT |
0x3A2F (14.895 bytes) |
50.641 bytes | Verificado en POS_MAIN.MAP tras compilar con el fix aplicado. Amplio margen. |
POS_MPPO_TEXT |
0xFF9F (65.439 bytes) |
97 bytes | No tocado por este fix — prácticamente lleno, sin margen para cambios futuros ahí. |
| DGROUP | sin cambios | — | No se agregaron variables globales ni estáticas. |
Archivos a integrar
Un único archivo, presente idéntico en dos copias (verificado con diff):
C:\Work\AI\DINO_20260902\pos_devi.cppC:\tmp\20260914\pos\real\pos_devi.cpp(copia idéntica, byte a byte)
Resultado de build
Compila limpio — POS_MAIN.MAP quedó modificado 7 minutos
después que pos_devi.cpp (15:42 → 15:49 del 15/09/2026), consistente con una recompilación
exitosa posterior al parche. No se verificó todavía el comportamiento con hardware lector real (sección 7).
7. Plan de prueba con lector real
Objetivo: confirmar en banco de pruebas, con el POS ya compilado con el fix, que un error real de Track 2 nunca vuelve a acreditar sobre la tarjeta anterior.
- Preparar dos tarjetas. Tarjeta A: banda limpia y en buen estado. Tarjeta B: banda deteriorada a propósito (cinta adhesiva sobre la pista 2, o pasada muy rápida/inclinada) de forma que el lector marque error de Track 2 mientras el Track 1 siga siendo legible.
- Vender la gift card de la tarjeta A, cerrar y cobrar el ticket con normalidad.
-
Inmediatamente después, vender la gift card de la tarjeta B forzando el error de Track 2.
- Resultado esperado: la carga debe ir a la tarjeta B, o la operación debe rechazarse — nunca debe acreditarse sobre la tarjeta A.
- Confirmar en el log
LG26mmdd.LOGque aparece la líneaREBUILDT2 <5 caracteres>(37)seguida de un<ns2:identificarTarjeta>con el PAN de B, no el de A. - Verificar que el ticket impreso muestre
TARJ:con el número de la tarjeta B.
- Consultar el saldo de ambas tarjetas en el portal de TiPrepaga: cada una debe tener únicamente su propio importe, sin acumulación cruzada.
-
Caso adicional — swipe abortado + PLU manual. Iniciar una lectura de banda y
abortarla a mitad de camino (o cancelar el ticket antes de terminar de leer), y a continuación
cargar una gift card por PLU manual (sin banda). Verificar que esa venta por PLU no lleve ningún
nroTarjetaheredado de la lectura abortada — debe pedir el número por teclado o rechazar la operación, nunca reusar un PAN fantasma.
Regresión mínima a cubrir
- Venta de gift card con lectura de banda limpia (camino
?): sin cambios de comportamiento. - Consulta de saldo de cuenta corriente y fidelización por banda.
- Ingreso de gift card por PinPad y por teclado (sin banda).
- Tickets en espera (StandBy) con tarjeta leída previamente — el escenario del ticket 433402/433406 del 04/09.
- Medios de pago con banda en cobros.
8. Acciones para el cliente
8.1 Crédito manual de las tarjetas afectadas
Estas son las cargas que quedaron mal direccionadas y que requieren transferir saldo desde la tarjeta que las recibió por error hacia la tarjeta física que el cliente realmente tiene en la mano. Los importes surgen directamente de las tablas de la sección 4.
| Fecha | Ticket | PAN que recibió el crédito (mal) | Importe a mover |
|---|---|---|---|
| 04/09 | 433408 | ...7208 | $40.000,00 |
| 04/09 | 433410 | ...7224 | $40.000,00 |
| 04/09 | 433411 | ...7224 | $40.000,00 |
| 05/09 | 433548 | ...1531 | $150.000,00 |
| 05/09 | 433549 | ...1531 | $50.000,00 |
| 05/09 | 433550 | ...1531 | $50.000,00 |
| 05/09 | 433551 | ...1531 | $50.000,00 |
| 06/09 | 433778 | ...1663 | $70.000,00 |
| Total a regularizar | $490.000,00 | ||
Para el 04/09, las tres tarjetas físicas destino corresponden a los tres seriales faltantes en la numeración correlativa vendida ese día (ver sección 4.1). Para 05/09 y 06/09 se recomienda que Grupo Dinosaurio identifique, con el ticket impreso o el registro de caja, cuál fue la tarjeta física entregada al cliente en cada uno de esos tickets, ya que el log no imprime el número de serie físico cuando la venta fue por gift card sin scanner. El 14/09 no requiere regularización según los logs analizados (sección 4.4), salvo que el cliente confirme un ticket adicional fuera de esta ventana.
8.2 Mantenimiento del lector — POS 72
- Limpieza inmediata del cabezal lector.
- Si la tasa de
REBUILDT2no vuelve a un dígito bajo tras la limpieza, reemplazo del lector. - Prueba cruzada del lote de gift cards en otro POS para descartar defecto de fábrica en la banda magnética de las tarjetas.
8.3 Despliegue del fix
- Ejecutar el plan de prueba con lector real de la sección 7 antes de liberar a producción.
- Desplegar
pos_devi.cpp(único archivo) al POS 72 y, preventivamente, a los demás POS de la sucursal 13 y de cualquier otra sucursal con el mismo modelo de lector. - Monitorear
LOG_CARD_TRACKSla primera semana post-despliegue para confirmar que ningúnREBUILDT2vuelva a coincidir con un PAN repetido enns2:venta. - Instrucción operativa mientras tanto: si al vender una gift card la pantalla muestra error de lectura o el ticket repite el número de una tarjeta anterior, cancelar y releer la banda — el ticket 433420 del 04/09 demuestra que una segunda lectura limpia corrige el PAN incluso sin el fix.