Resumen

En Autoservicio, el precio final de una compra con tarjeta lo fija el plan de cuotas que el cliente elige en el PINPAD. TsTicket registra la diferencia contra el total del ticket como un descuento o recargo global, asignado a cada ítem del ledger, y el ticket cierra exactamente por lo cobrado.

Reglas de diseño
  1. El monto se define antes de autorizar. Después de autorizar no se recalculan promociones.
  2. Total del ticket = importe autorizado por APICARD = suma de los movimientos PAGO.
  3. El ajuste es una línea normal del ledger, por ítem y con su propio tipo. No es una "compensación de diferencias".
  4. Hay dos formas de calcular el ajuste: con el UltraHost (camino A) o con TsPromos (camino B). B es el destino; A, el mínimo viable.

Alcance: consumidor final (Factura B), sin percepciones, un único pago con tarjeta por ticket, sin cashback.

Cómo es hoy el pago con tarjeta en el kiosco

Según el documento de referencia previo (changeset del 29/10, "compensación pospago"), el pago con tarjeta sigue estos pasos:

  1. El PINPAD lee la tarjeta.
  2. El BIN va al UltraHost, que devuelve el emisor y sus planes de cuotas, cada uno con su recargo o descuento.
  3. El cliente elige un plan. Ese es el monto real que va a pagar.
  4. Se autoriza ese monto con APICARD, vía TsTicket y TsPagos.
  5. Ya aprobado el cobro, TsTicket recalcula las promociones con TsPromos. Si el total cambia, absorbe la diferencia con una promoción compensatoria "pospago", imputa el PAGO y cierra el ticket.

Ese enfoque trata el ajuste como una contingencia y confunde dos cosas:

  • El ajuste por plan no es una anomalía: ocurre en casi todo pago con cuotas o con promo bancaria.
  • "Pospago" en el POS nombra otro concepto (el beneficio de billetera QR que se conoce después de cobrar). Acá el monto se conoce antes de autorizar.

Este documento plantea dos opciones en su lugar, y en ambas el ajuste se trata como ajuste por plan de tarjeta:

  • Camino A: el UltraHost define el ajuste y TsTicket lo reparte por ítem.
  • Camino B: TsPromos cotiza cada plan antes de autorizar y TsTicket aplica esa cotización.

Concepto: el ajuste vive en el ledger, por ítem

El ajuste por plan es una promoción más del ticket, de alcance global, repartida entre los ítems elegibles. Cada ítem termina con su parte, igual que con cualquier otra promo asociada.

Por qué repartirlo por ítem y no dejarlo como una línea suelta:

  • IVA: cada parte toma la alícuota de su ítem, así que neto e IVA contenido cierran sin cálculos por diferencia. En el POS, el recargo de tarjeta clásico quedaba fuera de las alícuotas y terminaba informado a ARCA como impuestos internos.
  • Devoluciones: devolver un ítem devuelve su parte, sin recalcular nada.
  • Reportes: la línea queda identificada por tipo, emisor y plan.

Qué lleva cada línea de ajuste:

AtributoContenido
TipoPLAN_TARJETA (camino A) o PROMO_MEDIO_PAGO (camino B)
OrigenUltraHost o TsPromos
Emisor, plan, cuotasLo que eligió el cliente
ImporteCon signo: negativo = descuento, positivo = recargo
ReferenciaAutorización de APICARD y, en B, la cotización aplicada

Reglas del reparto global (las aplica TsTicket en el camino A; en B el reparto ya viene de TsPromos):

  • Base: sólo ítems elegibles. Los rubros que no admiten planes ni promos bancarias quedan afuera (lista a definir).
  • Proporción: según el importe final de cada ítem, después de sus promos propias.
  • Redondeo: a 2 decimales; el centavo sobrante va al ítem de mayor importe.
  • Cierre: la suma de las partes es exactamente el ajuste.

Camino A: el UltraHost define el ajuste

El ajuste sale del plan del emisor que devuelve el UltraHost. Después de aprobar, TsTicket lo reparte en forma proporcional entre los ítems.

Camino A: el UltraHost fija el monto y TsTicket reparte el ajuste Camino A: el UltraHost fija el monto y TsTicket reparte el ajuste Kiosco PINPAD UltraHost TsTicket APICARD BIN Emisor y planes Planes con recargo Elige plan Autorizar plan Autorizar Aprobado Ajuste = autorizado − total PLAN_TARJETA repartida por ítem PAGO y cierre del ticket
Camino A · secuencia de punta a punta.
  1. El UltraHost devuelve los planes, cada uno con su recargo o descuento.
  2. El cliente elige un plan y el PINPAD autoriza ese monto.
  3. TsTicket calcula ajuste = importe autorizado − total del ticket, crea la línea PLAN_TARJETA y la reparte con las reglas de la sección anterior.
  4. TsTicket imputa el PAGO y cierra el ticket.

A favor: no cambia el apidriver ni TsPromos, no agrega latencia en el kiosco y el pago no depende de que TsPromos responda.

En contra:

  • El UltraHost no conoce ítems, tipo de cliente ni vigencias: un plan aplica igual a todo el ticket.
  • El reparto proporcional es una aproximación. Sólo puede excluir ítems con una lista fija en TsTicket.
  • Si TsPromos también aplica promos por banco, hay doble descuento. En este camino, TsPromos no debe aplicar promos por medio de pago.

Camino B: TsPromos cotiza por medio de pago

Antes de mostrar los planes, el apidriver pide al backend una cotización por plan. TsPromos calcula el descuento o recargo con toda su selectividad, y TsTicket aplica esa cotización tal cual después de aprobar.

Camino B: TsPromos cotiza cada plan y TsTicket aplica la cotización Camino B: TsPromos cotiza cada plan y TsTicket aplica la cotización Kiosco PINPAD UltraHost TsTicket TsPromos APICARD BIN Emisor y planes Cotizar planes Promos por plan Monto por ítem Cotización N Montos por plan Elige plan Autorizar N Autorizar Aprobado Aplica la cotización N tal cual Sin volver a llamar a TsPromos PAGO y cierre del ticket
Camino B · secuencia de punta a punta.
  1. El UltraHost devuelve emisor y planes.
  2. El apidriver pide a TsTicket "cotizar medio de pago", con el ticket, el emisor y los planes.
  3. TsPromos calcula cada plan con las promos vigentes por ítem, rubro, tipo de cliente y topes. Devuelve el total y la asignación por ítem.
  4. TsTicket guarda la cotización con un identificador y un vencimiento, y la devuelve.
  5. El kiosco muestra cada plan con su monto real y el cliente elige.
  6. El PINPAD autoriza el monto cotizado para ese plan.
  7. TsTicket aplica la cotización sin volver a llamar a TsPromos, imputa el PAGO y cierra.

Condiciones del diseño:

  • Cotización congelada: lo que se muestra es lo que se aplica. Si cambia el ticket (se agrega o quita un ítem), la cotización se invalida.
  • Vencimiento: si vence antes de autorizar, se recotiza. Todavía no se cobró nada.
  • Coherencia: si el importe autorizado no coincide con la cotización, es un error explícito, no una compensación.
  • TsPromos sin respuesta: falla antes de cobrar. Se reintenta o se ofrecen los planes sin promo (decisión pendiente).

A favor: selectividad completa, asignación exacta por ítem, y los fallos de promos ocurren antes de cobrar. Desaparece el recálculo después de aprobar.

En contra: cambia el apidriver, TsTicket (cotización y su guardado) y TsPromos (cálculo por plan). Suma una llamada antes de mostrar los planes, y las promos bancarias dependen de que TsPromos esté disponible.

Comparación y recomendación

Recomendación: empezar por A si hace falta salir rápido, y apuntar a B como diseño final.

Los dos caminos se separan en quién define el ajuste Los dos caminos se separan en quién define el ajuste Tarjeta leída en PINPADBIN al UltraHost: emisor y planes A · Planes del emisorRecargo o descuento por cuota Cliente elige planMonto = plan del Host Autorización APICARDPor ese monto TsTicket: ajuste globalReparto proporcional por ítem B · apidriver al backendCotizar medio de pago TsPromos por planÍtems, cliente, vigencias, topes Cliente elige planMonto ya cotizado Autorización APICARDPor la cotización N TsTicket aplica NCongelada, ya asignada por ítem Camino A · UltraHost Camino B · TsPromos
Los dos caminos · mismo inicio, distinto dueño del ajuste.
AspectoA · UltraHostB · TsPromos
SelectividadSólo emisor y plan de cuotasÍtems, rubros, tipo de cliente, vigencias, topes
Asignación en el ledgerReparto proporcional (aproximado)Por ítem, calculada por TsPromos
Cuándo se define el montoAl elegir el plan, en el HostAl cotizar, antes de mostrar los planes
Recálculo después de aprobarNoNo: se aplica la cotización congelada
Si TsPromos no respondeNo afectaFalla antes de cobrar
Latencia en el kioscoSin cambioUna llamada más
Componentes que cambianTsTicketApidriver, TsTicket y TsPromos
DevolucionesDevuelve la parte prorrateadaDevuelve la parte asignada al ítem

Cada concepto tiene un solo dueño. Si el plan del Host ya trae un descuento bancario, TsPromos no aplica otro por el mismo banco.

Mejora frente al changeset del 29/10

El Plan B mueve la llamada a TsPromos a antes del cobro. En el changeset actual, todo lo que puede fallar o cambiar el monto pasa después de que APICARD aprobó; en el Plan B pasa cuando todavía no se cobró nada.

El Plan B saca a TsPromos de después del cobro El Plan B saca a TsPromos de después del cobro Antes de cobrarDespués de cobrar APICARD aprueba Actual · changeset 29/10Plan B · cotización por plan Cotiza promosSin plan elegido Elige y autorizaMonto del Host Recalcula promosTimeout, 5xx, otro $ CompensaAjuste pospago Cotiza por planTsPromos, +1 viaje Elige y autorizaMonto cotizado Aplica tal cualCotización N Cierra ticketPAGO y CAE Riesgo con la plata ya cobrada Cambio del Plan B
Changeset 29/10 contra Plan B · dónde queda TsPromos respecto del cobro.
SituaciónActual (changeset 29/10)Plan B
TsPromos da timeoutSe conserva el ticket original y se compensa contra élSe reintenta o se ofrecen planes sin promo. No se cobró nada
TsPromos da HTTP 500Cobrado y sin cerrar: hay que recuperar la ordenError antes de mostrar los planes. No se cobró nada
El recálculo da otro montoSe absorbe con una promo compensatoriaNo pasa: lo cotizado es lo que se cobra
El cliente ve un monto y paga otroPosible: cotizado sin plan, cobrado con planNo: ve el monto del plan con sus promos
Promo bancaria selectiva por ítemNo se puede: el Host no conoce ítemsTsPromos la calcula por ítem
IVA del ajuste en el ledgerProrrateado, aproximadoAsignado por TsPromos a cada ítem
Complejidad después de cobrarCopia del ticket, clasificar errores, contingencia, compensaciónAplicar la cotización N

El costo del viaje extra es chico. La llamada a TsPromos ya existe en el flujo actual; el Plan B no la suma, la cambia de lugar. Lo que se agrega es una espera mientras el kiosco muestra los planes, en un momento en que el cliente igual está mirando la pantalla del PINPAD. A cambio desaparecen los casos de "cobrado y sin cerrar" por fallas de promos, que en un kiosco sin cajero son los más caros de resolver.

Lo que se mantiene del changeset: la recuperación de una orden aprobada (ajuste pendiente → aplicado). Sigue haciendo falta por si falla el cierre fiscal o la red después de aprobar.

Ciclo de vida del pago

Los dos caminos comparten los mismos estados; sólo cambia cómo se cotizan los planes y cómo se aplica el ajuste. Todo lo que puede cambiar el monto pasa antes de autorizar.

El monto se fija antes de autorizar; después sólo se aplica El monto se fija antes de autorizar; después sólo se aplica Denegado: elegir otro plan B: cotización vencida, recotizar Falla: reintentar sin volver a cobrar Tarjeta leídaBIN al UltraHost Planes cotizadosUltraHost o TsPromos Plan elegidoMonto final fijo AutorizandoAPICARD AprobadoOrden pagada Ajuste pendientePersistido Ajuste aplicadoReparto o cotización Ticket cerradoPAGO y CAE Difiere entre camino A y camino B · Punteado: transición de error
Estados del pago con tarjeta · 8 estados, 3 transiciones de error.

Cómo se manejan los fallos:

  • Denegado: el cliente elige otro plan. No se registró nada en el ledger.
  • Cotización vencida o ticket modificado (B): se recotiza antes de autorizar.
  • TsPromos sin respuesta (B): pasa antes de cobrar, así que no hay plata en juego.
  • Falla después de aprobar (al aplicar el ajuste, imputar o pedir el CAE): la orden queda pagada y el ajuste pendiente queda persistido. Se recupera esa misma orden; nunca se inicia otro cobro. Este mecanismo se mantiene del diseño anterior.
  • En el kiosco no hay cajero: la pantalla confirma que el pago quedó registrado, y si la recuperación no termina se avisa al supervisor.

Ejemplo por ítem

Un mismo ticket de $10.000 con cuatro artículos, resuelto por cada camino. Montos ilustrativos.

Camino A. El cliente elige 3 cuotas con 6 % de recargo; el UltraHost cotiza $10.600. El ajuste de +$600 se reparte en proporción al importe de cada ítem, y cada parte toma la alícuota de su ítem.

ÍtemIVAImporte ($)Ajuste ($)Final ($)Neto ($)IVA contenido ($)
Artículo 121 %4.000,00+240,004.240,003.504,13735,87
Artículo 210,5 %3.000,00+180,003.180,002.877,83302,17
Artículo 321 %2.000,00+120,002.120,001.752,07367,93
Artículo 4Exento1.000,00+60,001.060,001.060,000,00
Total10.000,00+600,0010.600,009.194,031.405,97

Total del ticket = importe autorizado = $10.600; neto + IVA contenido = $10.600.

Camino B. El Banco X tiene 20 % de descuento en los rubros de los artículos 1 y 2, con tope de $1.000, en 3 cuotas sin interés. El artículo 4 no participa de promos bancarias. TsPromos calcula 20 % de $7.000 = $1.400, aplica el tope de $1.000 y lo asigna sólo a los ítems de la promo.

ÍtemImporte ($)Promo Banco X ($)Final ($)
Artículo 14.000,00−571,433.428,57
Artículo 23.000,00−428,572.571,43
Artículo 32.000,000,002.000,00
Artículo 41.000,000,001.000,00
Total10.000,00−1.000,009.000,00

El kiosco muestra "3 cuotas: $9.000" y el PINPAD autoriza $9.000. Con el camino A, ese mismo descuento de $1.000 se repartiría también sobre los artículos 3 y 4, que no participan de la promo, y el IVA de cada ítem quedaría mal asignado.

Reglas fiscales y de comprobante

Lo informado a ARCA y lo impreso tienen que coincidir con lo cobrado. Como el ajuste ya está asignado por ítem, eso sale sin cálculos por diferencia.

  • CAE: importe total = importe autorizado, y neto + IVA + tributos = importe total. Sin percepciones (consumidor final).
  • Transparencia fiscal: el IVA contenido y los impuestos internos se calculan por ítem, con su parte del ajuste incluida.
  • Redondeo: el residuo de centavos va al neto del ítem de mayor importe; nunca se descarta. En el POS, descartarlo dejaba el CAE desbalanceado en un centavo.
  • Recargo financiero: lo habitual es que siga el tratamiento de IVA de la operación principal. A confirmar con el contador, sobre todo para ítems con impuestos internos.
  • Comprobante impreso: una sola línea por ajuste, con leyenda clara ("Descuento Banco X 3 cuotas", "Recargo financiero 6 cuotas"). En el POS hubo un caso de línea duplicada que hacía que el ticket no sumara a la vista.
  • Devoluciones: se devuelve el importe final del ítem, con su parte del ajuste.

Decisiones pendientes

  • Camino a implementar: A o B, y en qué orden.
  • Dueño de cada concepto: quién define recargo financiero, descuento bancario y promos por ítem.
  • Rubros excluidos de planes y promos bancarias.
  • En B, qué se ofrece si TsPromos no responde: reintentar o planes sin promo.
  • En B, vencimiento de la cotización.
  • Tratamiento fiscal del recargo financiero, confirmado con el contador.
  • Leyendas del comprobante y si corresponde informar el costo financiero del plan.
  • Qué parte del diseño anterior (copia del ticket, contingencia por timeout) se mantiene.