Payment provider integration
Different providers. One shared contract.
The Rail Adapter Contract connects payment providers to the Flominzo financial core. Adapters translate provider formats into canonical types, so the core stays independent of each partner.
Last updated:
Discuss a provider integrationKeep provider details at the boundary
Provider status codes, file layouts, field mappings, and authentication belong inside the adapter and its Rail Profile. The payment core consumes canonical results and events.
Capability declarations describe what an adapter supports. A statement-only bank adapter does not need to pretend it can execute a payout.
The common interface
interface RailAdapter {
ProviderId provider();
CapabilityDeclaration getCapabilities();
Health healthCheck();
AdapterResult<Balance> getBalance(String selector);
WebhookVerification verifyWebhook(RawWebhookRequest request);
AdapterResult<List<ProviderEvent>> parseWebhook(RawWebhookRequest request);
AdapterResult<RawFileReference> fetchStatement(StatementPeriod period);
AdapterResult<ParsedStatement> parseStatement(
RawFileReference file, StatementFormat format);
}Interface excerpt. Imports and implementation details are omitted. Payout and collection capabilities extend this boundary separately.
Capability contracts
Providers overlap in what they can do, so capabilities are composed rather than inherited. A mobile-money operator may collect and pay out; a bank may pay out and deliver statements; a PSP may collect and refund.
| Capability | Operations |
|---|---|
| Payout | validateBeneficiary, getQuote, createPayout, getPayoutStatus, cancelPayout |
| Collection | initiateCollection, getCollectionStatus, refundCollection |
| Common (every provider) | getCapabilities, healthCheck, getBalance, verifyWebhook, parseWebhook, fetchStatement, parseStatement |
Every result has a class
Each adapter result is classified, so the core never guesses what a provider meant.
- SUCCESS
- The provider completed the request.
- RETRYABLE
- Safe to retry with the same idempotency key.
- NON_RETRYABLE
- The provider rejected the instruction. Do not send it again.
- UNKNOWN_OUTCOME
- The request may have been processed. Resolve it by lookup, never by sending it again.
What a provider declares
- The capabilities it implements, and the countries, corridors, currencies, and methods it serves.
- Its limits and features, such as name lookup, quotes, cancellation, refunds, webhooks, and idempotency support.
- Its settlement model: prefunded or postpaid, frequency, cutoffs, currency, and accounts.
- Its evidence sources: which APIs, webhooks, files, and statements it delivers, and when they are expected.
Preserve the original evidence
- Capture raw requests, responses, callbacks, and files before interpreting them.
- Verify callback signatures, source, and freshness before parsing.
- Link normalised records back to the original file, row, or message.
- Report unknown statuses and invalid formats explicitly; never invent a successful outcome.
- Treat health-check metrics separately from financial evidence.
Files and bank statements
The integration modules include parsers for ISO 20022 camt.053 and camt.052, SWIFT MT940, and configured CSV layouts. Format support still requires the correct profile and validation against the actual files produced by your provider.
Validate before activation
Test callbacks, invalid signatures, stale messages, duplicate deliveries, malformed rows, and equivalent bank statement representations. Agree expected behaviours for timeouts, late settlement records, and unknown outcomes.
Activation follows the integration plan and acceptance criteria, with partner-specific credentials and configuration kept outside the common contract.
See the integration pathLet’s make it specific to you.
Bring your systems, payment flows, and questions. We’ll help define the next step.
Talk to the team