How to Add a New PSP
Step-by-step checklist for integrating any new payment provider
Overview
Maps your unified request to PSP-specific API call. Returns unified response regardless of PSP format.
Same pattern as deposit.
Polling fallback. Maps PSP-specific status string to UnifiedStatus enum.
Validates signature, parses payload, emits a unified event for the State Machine.
Returns methods this PSP supports for the given geo+currency. Used by Orchestrator to filter candidates.
Integration Checklist
Step 1 -- Research & Decision
PM- Obtain PSP API documentation (sandbox + production)
- Identify supported payment methods, countries, and currencies
- Clarify integration type for each method: H2H (direct API) or Invoice Link (redirect)
- Confirm webhook delivery: what events are sent, payload format, signing algorithm
- Clarify settlement currency and payout schedule
- Confirm sandbox credentials are available for development
- Map PSP-specific transaction statuses to UnifiedStatus enum (see State Machine spec)
The status mapping must be complete and agreed before any code is written. Gaps here cause reconciliation bugs later.
Step 2 -- Admin Panel Configuration
PM- Create a new PSP record in Admin Panel: name, slug, base URL, timeout, retry policy
- Enter API credentials (key/secret) -- stored encrypted, never visible after save
- Enter webhook signing secret
- Register each supported payment method under this PSP with correct integration type (H2H / Invoice Link)
- Set PSP status to MAINTENANCE -- it will be excluded from routing until explicitly activated
- Add routing rules for the new PSP (brand + country + method combinations)
Step 3 -- Adapter Implementation
BE- Create a new class implementing IPaymentProvider interface -- do not modify the interface itself
- Implement initiateDeposit() -- maps UnifiedDepositRequest → PSP-specific request, returns UnifiedResponse
- Implement initiateWithdrawal() -- same pattern
- Implement getTransactionStatus() -- maps PSP status response → UnifiedStatus
- Implement handleWebhook() -- validate signature, parse payload, emit UnifiedEvent
- Implement getSupportedMethods() -- returns Method[] filtered by geo + currency
- Register the new adapter in the adapter factory/registry (the only place that knows concrete PSP classes)
Zero changes to Orchestrator, Cascade Manager, or any other service. If you need to change something outside the adapter + registry, the interface contract is likely broken -- revisit before proceeding.
Step 4 -- Data & Configuration
BE- Add a migration that inserts the new PSP into psp_configs (if seeded from code, not Admin Panel)
- Add new PSP-specific status codes to the status_mapping table (psp_slug + raw_status → UnifiedStatus)
- Ensure reconciliation job handles this PSP's transaction format (date format, amount unit, currency field name)
- Add PSP to the health-check scheduler configuration
Step 5 -- Testing (Sandbox)
BE- Unit tests for status mapping: every PSP status code maps to a UnifiedStatus without gaps
- Unit tests for webhook signature validation: valid signature passes, tampered payload fails
- Integration test: deposit flow end-to-end against PSP sandbox
- Integration test: withdrawal flow end-to-end against PSP sandbox
- Test cascade fallback: PSP #1 fails, traffic routes to new PSP successfully
- Test MAINTENANCE mode: new PSP in MAINTENANCE is never selected by Orchestrator
- Test reconciliation: a sample PSP settlement file is parsed correctly and matched to transactions
Step 6 -- Frontend (if new methods added)
FE- Add method icon/logo asset to the checkout UI asset registry
- If integration type is Invoice Link: ensure redirect + return URL flow is handled (the checkout already supports this generically)
- If integration type is H2H with a custom form (e.g. crypto address input): add the method-specific input component
- No changes to checkout routing, state machine, or method list ordering logic -- these are driven by backend response
In most cases (card PSPs, standard redirects) zero frontend changes are needed. The checkout UI is data-driven from the backend method list.
Step 7 -- Production Launch
Both- Enter production API credentials in Admin Panel (sandbox credentials must not reach production)
- Set routing rules to send a small % of traffic (1-5%) to the new PSP -- A/B split in Admin Panel
- Monitor success rate and error rate for the new PSP in real time for 30 minutes
- If success rate is comparable to existing PSPs -- increase traffic split gradually
- If success rate drops below threshold -- switch PSP back to MAINTENANCE in Admin Panel (no code deploy needed)
- Update the routing rules to full traffic once stability is confirmed over 24h
Never go straight to 100% traffic for a new PSP. The A/B split + MAINTENANCE toggle combination means rollback takes seconds, not a deploy.