JetbrainsAlina DolgikhExplainer
KotlinConf Recap: Lessons from Verifone’s Architect on Kotlin in Mission-Critical Payments
Summary
Verifone architect Yuri Geronimus presented at KotlinConf 2026 on using Kotlin’s type system to enforce payment specifications at compile time. He described six incident patterns where a single misused word caused outages, compliance failures, or financial loss, including a terminal fleet outage from a nullable mandatory field. His method uses value classes for spec nouns, validate factories at boundaries, non-null types, masked sensitive data by default, and state-specific classes to make illegal states unrepresentable. Geronimus advocates incremental migration from legacy Java and C++ systems using four parallel tracks rather than a rewrite, noting that payment terminals must operate offline for up to 40 days by regulation. The approach shifts reliability from developer discipline to compiler enforcement, enabling engineers to speak the business language and propose regulatory changes.
Context
Verifone operates payment terminals, gateways, and systems connecting to banks and regulators across EMEA. Each country has thousands of pages of specifications and roughly 1,000 scenarios that must pass before production. Terminals must work offline for up to 40 days by regulation, and contradictory rules from different countries must coexist in the same codebase. Twenty teams worldwide maintain the system, which includes 25-year-old Java and C++ code processing live transactions with no acceptable downtime.
Approach / What changed
Yuri Geronimus presents ten patterns using Kotlin’s type system to enforce payment specifications at compile time. Key patterns: value classes for spec nouns to prevent argument swapping; validate factories parsing external fields into sealed results at the boundary; non-null types with requireNotNull to fail loudly on missing mandatory fields; masked sensitive data by default via private constructors and overridden toString(); and state-specific data classes to make illegal state transitions unrepresentable. For migration, he advocates four parallel tracks: optimize existing codebase, shift to acceptance-test-driven development, build fitness functions, and migrate incrementally starting with adapters and domain models, leveraging Kotlin’s Java interop.
Takeaways
Kotlin’s inline value classes prevent argument swapping at compile time by wrapping spec nouns like Stan, TerminalId, and AmountMinor in distinct types, turning a runtime bug into a build error.
Validate factories parse external fields into sealed results at the boundary, ensuring exhaustive handling without exceptions or silent fallbacks, and structured rejection instead of try/catch.
Incremental migration using four parallel tracks—optimize existing code, acceptance tests, fitness functions, and incremental migration—avoids the risks of a rewrite in live payment systems with no acceptable downtime.
FAQ
How does Kotlin prevent argument swapping in payment code?
By wrapping each spec noun (e.g., Stan, TerminalId, AmountMinor) in an inline value class, the compiler treats them as distinct types. Swapping arguments in a function call like AuthRequest(terminalId, stan, amount) becomes a compile error instead of a runtime bug.
Why avoid nullable fields for mandatory payment data?
Nullable fields lead to silent fallbacks that hide bugs, causing outages like a terminal fleet failure. Using requireNotNull at the boundary fails loudly in one monitored place, ensuring the missing field is caught immediately rather than causing silent downstream failures.
Can these patterns be applied without rewriting legacy Java systems?
Yes. Kotlin's Java interop allows incremental migration starting with new adapters and domain models alongside unmodified Java code. Geronimus advocates four parallel tracks—optimize existing code, acceptance tests, fitness functions, and incremental migration—rather than a rewrite.
Source and freshness
- Source
- blog.jetbrains.com
- Published
- Added to Yomu
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.