Acreditación de gift cards sobre una tarjeta equivocada — POS 72

Grupo Dinosaurio, Suc. 13 · Reclamo recibido 14/09/2026 · Documento elaborado 15/09/2026
Fix aplicado en pos_devi.cpp Compila limpio (POS_MAIN.MAP verificado) Pendiente prueba en vivo con lector real Regularización manual de saldo pendiente

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.

Casos reportados por el cliente
FechaDescripción del clienteConfirmado 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

ANTES del fix — camino REBUILDT2 pisa el PAN, camino normal no Lectura OK tecla '?' EV_BAND pos_devi.cpp:1439 poscard.buffer = BuffBanda pos_devi.cpp:1440 (se actualiza) PAN correcto GetDataCard lee el PAN nuevo Camino REBUILDT2 Error Track2 carácter 'E' Reconstruye sttracks.cTrack2 (1505) EV_BAND pos_devi.cpp:1512 (antes) poscard.buffer NO se toca PAN VIEJO GetDataCard relee el buffer anterior ns2:venta con PAN ajeno acredita sobre la tarjeta anterior DESPUÉS del fix — el camino REBUILDT2 refresca poscard.buffer igual que el camino normal Error Track2 carácter 'E' Reconstruye sttracks.cTrack2 (1505) poscard.buffer = BuffBanda pos_devi.cpp:1510-1511 (nuevo) EV_BAND pos_devi.cpp:1512 PAN correcto GetDataCard lee el PAN nuevo ns2:venta OK acredita la tarjeta propia Refuerzo fail-closed Comienza lectura ('%') pos_devi.cpp:1383 poscard.buffer = 0 pos_devi.cpp:1390 (nuevo) Una lectura abortada o incompleta ya no puede servir el PAN de la tarjeta anterior.

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.

Origen de los datos por día. 04/09: 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

Ventas de gift card, POS 72, 04/09/2026 — recalculado desde el log completo
TicketHora ventaREBUILDT2PAN (últimos 4) ImporteSaldo respuesta¿Repite PAN anterior?
43340614:39:55Sí (14:39:11)...7190 40.000,0040.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.
43340714:40:46No...7208 40.000,0040.000,00No
43340814:41:27Sí (14:40:50)...7208 40.000,0080.000,00 — repite el PAN de 433407
43340914:42:22No...7224 40.000,0040.000,00No
43341014:43:15Sí (14:42:28)...7224 40.000,0080.000,00 — repite el PAN de 433409
43341114:44:08Sí (14:43:21)...7224 40.000,00120.000,00 — repite el PAN de 433410
43342015:06:36Sí (15:05:22)...7257 100.000,00100.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

Ventas de gift card, POS 72, 05/09/2026 — log completo
TicketHora ventaREBUILDT2PAN (últimos 4) ImporteSaldo respuesta¿Repite PAN anterior?
43354710:15:34No...1531 150.000,00150.000,00No
43354810:16:48Sí (10:15:57)...1531 150.000,00300.000,00
43354910:17:43Sí (10:16:57)...1531 50.000,00350.000,00
43355010:18:41Sí (10:17:55)...1531 50.000,00400.000,00
43355110:19:38Sí (10:18:50)...1531 50.000,00450.000,00
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

Ventas de gift card, POS 72, 06/09/2026 — log completo
TicketHora ventaREBUILDT2PAN (últimos 4) ImporteSaldo respuesta¿Repite PAN anterior?
43377716:23:29No...1663 70.000,0070.000,00No
43377816:24:39Sí (16:23:40)...1663 70.000,00140.000,00
43377916:25:30Sí (16:24:45)...1671 70.000,0070.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.
43378016:26:28No...1697 70.000,0070.000,00No
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

Ventas de gift card, POS 72, 14/09/2026 — log completo
TicketHoraREBUILDT2PAN (últimos 4) ImporteSaldo respuestaObservación
43456613:52:56No...5671 100.000,00100.000,00Venta normal.
43456713:53:09...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.
43456813:53:45 → venta 13:54:46Sí (13:53:50)...5531 (nuevo) 100.000,00100.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.
43456913:54:49Sí (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).
43457013:56:18No...5549 175.000,00175.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
El 14/09 tiene la mayor tasa de fallas de lectura de la muestra (3 de 9, 33%) pero, por una combinación de anulación de cajero y lecturas sueltas casualmente favorables, no se tradujo en un saldo mal acreditado dentro de esta ventana de log. Esto no es una señal de que el defecto sea menos grave ese día: es evidencia de que el resultado (tarjeta correcta o incorrecta) depende del azar de qué quedó en poscard.buffer en cada momento, exactamente el comportamiento indeterminado que describe la causa raíz.

4.5 Totales consolidados (4 días)

MétricaValor
Lecturas de banda ("Leyendo banda...")34
Eventos REBUILDT214
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).

Lecturas de banda vs. REBUILDT2 por día — recalculado de los logs completos
DíaLeyendo bandaREBUILDT2% de fallas de Track 2
04/0916531,3%
05/095480,0%
06/094250,0%
14/099333,3%
Total341441,2%
Un lector sano en este tipo de equipo falla Track 2 en torno al 1% de las pasadas. El POS 72 está en 41% en la ventana analizada — un lector degradado de forma severa, no una anomalía puntual.

Recomendación

  1. Limpiar el cabezal lector del POS 72 con tarjeta de limpieza húmeda y volver a medir la tasa de REBUILDT2 durante una jornada.
  2. Si la tasa no baja a un dígito bajo, reemplazar el lector del POS 72.
  3. 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.
  4. Para priorizar qué otros POS revisar, correr grep REBUILDT2 sobre D:\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 de REBUILDT2 en 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(&gtime,&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)

SegmentoTamaño usadoLibre de 64 KBNota
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.cpp
  • C:\tmp\20260914\pos\real\pos_devi.cpp (copia idéntica, byte a byte)

Resultado de build

Compila limpioPOS_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.

  1. 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.
  2. Vender la gift card de la tarjeta A, cerrar y cobrar el ticket con normalidad.
  3. 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.LOG que aparece la línea REBUILDT2 <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.
  4. Consultar el saldo de ambas tarjetas en el portal de TiPrepaga: cada una debe tener únicamente su propio importe, sin acumulación cruzada.
  5. 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 nroTarjeta heredado 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.

Cargas a regularizar con TiPrepaga
FechaTicketPAN que recibió el crédito (mal)Importe a mover
04/09433408...7208$40.000,00
04/09433410...7224$40.000,00
04/09433411...7224$40.000,00
05/09433548...1531$150.000,00
05/09433549...1531$50.000,00
05/09433550...1531$50.000,00
05/09433551...1531$50.000,00
06/09433778...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

  1. Limpieza inmediata del cabezal lector.
  2. Si la tasa de REBUILDT2 no vuelve a un dígito bajo tras la limpieza, reemplazo del lector.
  3. 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

  1. Ejecutar el plan de prueba con lector real de la sección 7 antes de liberar a producción.
  2. 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.
  3. Monitorear LOG_CARD_TRACKS la primera semana post-despliegue para confirmar que ningún REBUILDT2 vuelva a coincidir con un PAN repetido en ns2:venta.
  4. 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.