# TCN payments integration plan ## Decision - Treat the current `/admin/payments` QR generator as an operator test harness, not the final production payment UX for vending machines. - Production vending flow should integrate with the TCN machine protocol and let the machine render the buyer-facing QR on its own screen. ## Why - TCN protocol `2.5V` states: `to scan QR codes additional hardware devices are necessary.` - That wording applies to **machine-side QR scanning**, not to the machine displaying a QR on its screen for the buyer to scan with a phone. - The payment section (`2.1.5 Integral exchange`, `FunCode=8000`) already defines a dynamic payment flow: - machine sends `MachineID`, `TradeNo`, `SlotNo`, `Price`, `NotityUrl` - server returns `CodeUrl`, `TradeNo` - `CodeUrl` is described as the returned value used to generate the QR code. - That is enough to proceed with integration planning without assuming extra scanner hardware. ## Intended production flow 1. Buyer selects product on TCN machine. 2. TCN machine requests Ballbox payment session using the TCN payment contract. 3. Ballbox creates a Mercado Pago QR order. 4. Ballbox maps the Mercado Pago output into the TCN response shape and returns `CodeUrl`. 5. TCN machine renders the QR on its screen. 6. Buyer scans with Mercado Pago app on phone. 7. Payment provider notifies Ballbox webhook. 8. Ballbox validates/persists approved payment. 9. TCN machine receives the success signal through the TCN-side notify/result path and dispenses product. ## Ballbox work now ### 1. Lock the machine-facing contract - Define a Ballbox route for TCN `8000` payment-init requests. - Define exact request/response mapping for: - `MachineID` -> Ballbox `vendingMachineId` or external machine identifier - `TradeNo` -> machine transaction id / canonical `externalReference` - `SlotNo` - `Price` - `NotityUrl` - response `CodeUrl` - Confirm whether TCN expects raw payment URL, QR payload string, or a specific provider deep link in `CodeUrl`. ### 2. Define result/dispense handshake - Map how Ballbox should signal payment success back into the TCN flow. - Verify whether Ballbox must call `NotityUrl`, expose a callback endpoint, or rely on a polling/result interface in the broader TCN protocol set. - Confirm how TCN links approved payment to dispense using `TradeNo` and/or `SlotNo`. ### 3. Normalize machine identity - Decide the canonical mapping between TCN `MachineID` and Ballbox `VendingMachine`. - Add any missing external-id field only if needed for clean lookup. ### 4. Keep admin QR page as a test tool - `/admin/payments` remains useful for: - Mercado Pago config checks - live QR creation smoke tests - webhook validation - manual provider debugging - Do not frame it as the final vending-machine payment UX. ## Unknowns still to close - Exact payload expected inside TCN `CodeUrl`. - Exact success callback / notify shape between Ballbox and TCN after payment approval. - Whether machine-side polling (`4000`) participates in payment completion or only app-driven vend/load flows. - Whether TCN needs additional payment-status endpoints beyond `8000` for a full dispense flow. ## Recommendation - Next implementation slice should be a TCN adapter spec + stub endpoints, not more work on the standalone admin QR page. - Keep Mercado Pago-native Ballbox routes as the provider layer underneath that adapter. ## Evidence - `test-results/tcn-payment-protocol/Protocol 2.5V English version.pdf` - `test-results/tcn-payment-protocol/findings-2026-04-23.md`