Card charges use PowerTranz SPI with server-finalized 3-D Secure (strict Y+CAVV)
Context
Card payments run on PowerTranz, the gateway for FAC (First Atlantic Commerce) — the only card processor wired in either the live adapter service or the new control plane. PowerTranz offers two integration styles: FPI, a multi-step merchant-driven flow, and SPI ("Simplified Payment Interface"), a single call in which the gateway orchestrates the whole transaction. It also lets the integrator ask for 3-D Secure at different strengths via a ChallengeIndicator.
Two forces shaped the choice. First, an earlier FPI-based attempt broke on the cards that most need 3DS: FPI returns a "fingerprint device" step with the challenge data nested under risk management, which the single-call code could not continue. Second, the product wanted a visible step-up on every card, matching the old FAC hosted page — but that goal later collided with a gateway constraint (below).
Decision
Charge cards through PowerTranz SPI (not FPI), let the gateway run the whole 3-D Secure dance, and finalize the money server-side only on a genuine authentication.
- SPI single-call sale. The sale is placed via SPI; PowerTranz returns a single top-level
RedirectDataiframe and orchestrates frictionless + challenge itself, and SPI holds no authorization or funds until the completion call. - The server finalizes, fail-closed on Y+CAVV. After the ACS, PowerTranz redirects the browser to a server
MerchantResponseUrl; the authoritative 3DS result is read from that server-captured callback, never a browser-relayed value, and the charge is completed with the single-use SpiToken. The strength gate is stricter than the gateway's payable set: only a statusYwith a CAVV proceeds; A/U/N/R are refused. The strict gate is applied identically at the edge and in the control plane. - The amount is not the browser's to choose. The amount and currency come from a commerce-api-signed checkout intent the charging component verifies (ADR 0012); the card component never supplies the amount.
- Challenge strength differs by flow and is gateway-constrained. The intent was to mandate the challenge on every card (
ChallengeIndicator "04"), and the edge/CDE flow still sets"04". But the committed production flow (commerce-adapters) uses"01"/"02"(issuer-decides / no forced challenge), because forcing the challenge broke tokenization: the prod PowerTranz profile withholds thePanTokenon a challenge, so a mandated"04"sale vaulted zero cards (the same constraint that forces the subscription no-3DS stopgap, ADR 0025). So on the deployed default, 3DS is requested but the step-up is issuer-decided, not mandated.
Consequences
- Positive: letting the gateway own the 3DS orchestration (SPI) removes the multi-step client-driven state that broke fingerprint/challenge cards under FPI; and the liability shift is only claimed when it is genuine (Y+CAVV) — weaker "attempted"/"unable" outcomes never silently pass as authenticated.
- Current state / to revisit: a consistent forced step-up on every card is not the deployed reality. The committed flow requests issuer-decided 3DS (
"01"/"02"); the"04"mandate remains in the edge flow but shares the same vaulting failure (ADR 0025). Restoring a mandated challenge that also vaults depends on the PowerTranz profile returning the token through the challenge flow. - Neutral / to revisit: the flow is specific to PowerTranz/FAC SPI semantics; a second card processor would need its own 3DS orchestration mapped to the same server-finalized, Y+CAVV model.
Alternatives considered
- PowerTranz FPI (multi-step, merchant-driven): rejected — its fingerprint/challenge step could not be continued by the single-call flow; SPI hands the whole dance to the gateway.
- Mandating the challenge on every card (
ChallengeIndicator "04"): the intended design and still set in the edge flow, but not what the committed production flow runs — it broke card tokenization (gateway withholds the token on a challenge), so the committed flow fell back to issuer-decided"01"/"02". This is a gateway-forced compromise, not a free choice. - Trusting the browser-relayed 3DS result to speed completion: rejected — the outcome is money-authoritative and must be read from the server-captured callback, not a value the browser could alter.