Summary
PR #248 review identified that OffRampActivityImpl uses hardcoded bank routing that ignores actual recipient data. Three related issues need a comprehensive fix.
Issues to Fix
Major — Hardcoded Bank Routing
resolveBankAccount / resolveBankCode ignore recipientId (OffRampActivityImpl.java:84-90)
- All GBP payouts route to hardcoded
"12345678" / "040004" regardless of recipient
- All non-GBP currencies fall back to hardcoded DE IBAN
"DE89370400440532013000"
- Action: Extend
OffRampRequest with recipient banking details (account, sort code/IBAN) or inject a RecipientRepository to look up banking details by recipientId
Major — Silent Currency Fallback
- Unsupported currencies silently fall back to SEPA/DE (
OffRampActivityImpl.java:80-98)
resolvePaymentRail, resolveBankAccount, resolveBankCode, resolveAccountType, resolveCountry all default to SEPA/DE for any currency that isn't "GBP"
- USD, CHF, JPY etc. would silently route to a German IBAN
- Action: Use exhaustive
switch expressions with explicit currency matching. Throw IllegalArgumentException for unsupported currencies
Minor — Fake Hash
recipientAccountHash is not actually hashed (OffRampActivityImpl.java:47)
"sha256:" + request.recipientId() is string concatenation, not a cryptographic hash
- If used for compliance/audit, this is misleading
- Action: Compute actual SHA-256 digest using
MessageDigest, encode as hex, prefix with "sha256:"
Acceptance Criteria
References
Summary
PR #248 review identified that
OffRampActivityImpluses hardcoded bank routing that ignores actual recipient data. Three related issues need a comprehensive fix.Issues to Fix
Major — Hardcoded Bank Routing
resolveBankAccount/resolveBankCodeignorerecipientId(OffRampActivityImpl.java:84-90)"12345678"/"040004"regardless of recipient"DE89370400440532013000"OffRampRequestwith recipient banking details (account, sort code/IBAN) or inject aRecipientRepositoryto look up banking details byrecipientIdMajor — Silent Currency Fallback
OffRampActivityImpl.java:80-98)resolvePaymentRail,resolveBankAccount,resolveBankCode,resolveAccountType,resolveCountryall default to SEPA/DE for any currency that isn't"GBP"switchexpressions with explicit currency matching. ThrowIllegalArgumentExceptionfor unsupported currenciesMinor — Fake Hash
recipientAccountHashis not actually hashed (OffRampActivityImpl.java:47)"sha256:" + request.recipientId()is string concatenation, not a cryptographic hashMessageDigest, encode as hex, prefix with"sha256:"Acceptance Criteria
OffRampRequestcarries or resolves real recipient banking detailsrecipientAccountHashuses real SHA-256 digestReferences
OffRampRequestrecord:payment-orchestrator/.../domain/workflow/activity/OffRampRequest.javaOffRampActivityImpl:payment-orchestrator/.../infrastructure/activity/OffRampActivityImpl.java