Designing a Dual-Payment Gateway
The core challenge was integrating two payment providers — Peach Payments and iPay — without coupling business logic to either vendor's API contract. I modelled the domain around a PaymentPort interface, keeping the application layer fully ignorant of which adapter was in use at runtime.
Each provider was encapsulated in its own adapter class — PeachAdapter and iPayAdapter — both implementing the same PaymentPort. The domain layer emitted PaymentInitiated and PaymentSettled events regardless of provider, enabling clean audit trails and idempotent retry logic at the infrastructure boundary.
This boundary isolation meant swapping or extending providers required zero changes to business rules, reducing provider-switch risk from a multi-week re-architecture to a single adapter implementation with a passing test suite.