The Generic Connector for Formance Connectivity provides a way to connect your Formance Stack with Financial Service Providers that are not natively supported by Formance.
Formance Connectivity interacts with the remote Financial Service Provider through the Generic Connector in two directions:
The Generic Connector handles two directions of communication with the Financial Service Provider:
- Data polling (read): Periodically fetches accounts, balances, transactions, and beneficiaries from the PSP
- Payment initiation (write): Sends payout and transfer requests to the PSP on behalf of Formance
Integration with the Financial Service Provider
The Generic Connector interacts with the Financial Service Provider by sending requests formatted according to the Generic Connector API specifications and expecting responses formatted according to the same specifications. The full machine-readable spec is available as an OpenAPI definition.
As a consequence, it is necessary to create a service on your side that will interact with the Financial Service Provider and expose the data with the expected format.
The typical deployment of the Generic Connector is as follows:
Polling mechanism
The Generic Connector uses a state-based approach for polling payment data efficiently.
How it works
- The connector stores the timestamp of the last successful data retrieval
- In subsequent polls, it uses this timestamp to fetch only new or updated data
- The
UpdatedAtFrom query parameter is passed in API calls to your service
- This parameter indicates that only transactions from that specific point in time should be returned
Data storage and updates
The system doesn’t fetch all data fresh every time it polls. Instead:
- Each batch of data received is stored
- The internal state is updated with the latest timestamp of the data received
- In the next polling cycle, the updated timestamp is used to fetch only new or changed data
Benefits
This polling method offers several advantages:
- Reduced data transfer: Only fetches new or updated information
- Minimized load: Reduces strain on both Formance and your API
- No duplicates: Ensures the database stays up-to-date without duplicating existing data
When setting up the Generic Connector, ensure that your API can handle and respond correctly to the UpdatedAtFrom query parameter. This allows the system to efficiently retrieve only the necessary data during each polling cycle.
Authentication
When instantiating the Generic Connector, you will need to pass an API key that will be used to authenticate the requests to your service. The Generic Connector will send requests with the API key in the Authorization header so that your service can authenticate the requests.
Example:
Authorization: Bearer <API_KEY>
Polling endpoints
Your integration service must expose the following GET endpoints for the Generic Connector to poll data from the PSP.
| Operation | Method | Path | Description |
|---|
| List accounts | GET | /accounts | Fetch internal accounts |
| Get account balances | GET | /accounts/{accountId}/balances | Fetch balances for a specific account |
| List beneficiaries | GET | /beneficiaries | Fetch external accounts (payout destinations) |
| List transactions | GET | /transactions | Fetch payment transactions |
All list endpoints support the following query parameters:
| Parameter | Type | Default | Description |
|---|
pageSize | integer | 100 | Number of items per page (minimum 1). |
page | integer | 1 | Page number (minimum 1). |
sort | string | — | Sort order (e.g., createdAt:asc). |
createdAtFrom | date-time | — | Return items created after this timestamp. Used by /accounts and /beneficiaries. |
updatedAtFrom | date-time | — | Return items updated after this timestamp. Used by /transactions. |
Account response
{
"id": "acc_123",
"accountName": "Main Operating Account",
"createdAt": "2025-01-10T08:00:00Z",
"metadata": {
"region": "eu-west"
}
}
| Field | Type | Required | Description |
|---|
id | string | Yes | Unique account identifier on the PSP. Becomes the account reference in Formance. |
accountName | string | Yes | Human-readable name for the account. |
createdAt | string | Yes | RFC 3339 timestamp. |
metadata | object | No | Arbitrary key-value pairs. |
Balance response
Returned by GET /accounts/{accountId}/balances:
{
"id": "bal_001",
"accountID": "acc_123",
"at": "2025-03-15T10:30:00Z",
"balances": [
{
"amount": "150000",
"currency": "USD/2"
},
{
"amount": "500000000",
"currency": "BTC/8"
}
]
}
| Field | Type | Required | Description |
|---|
id | string | Yes | Unique balance snapshot identifier. |
accountID | string | Yes | The account this balance belongs to. Must match a known account id. |
at | string | Yes | RFC 3339 timestamp of when the balance was captured. |
balances | array | Yes | List of balances, one per currency. |
Each item in the balances array has the following fields:
| Field | Type | Required | Description |
|---|
amount | string | Yes | Amount in minor units as an integer string (e.g., "150000" for $1,500.00 with precision 2). |
currency | string | Yes | Asset in UMN format (e.g., "USD/2", "BTC/8"). |
Beneficiary response
{
"id": "ben_456",
"createdAt": "2025-02-20T14:00:00Z",
"ownerName": "Acme Supplier Inc.",
"metadata": {
"bankCountry": "FR"
}
}
| Field | Type | Required | Description |
|---|
id | string | Yes | Unique beneficiary identifier on the PSP. Becomes an external account reference in Formance. |
createdAt | string | Yes | RFC 3339 timestamp. |
ownerName | string | Yes | Name of the beneficiary. |
metadata | object | No | Arbitrary key-value pairs. |
Transaction response
{
"id": "txn_789",
"relatedTransactionID": "txn_100",
"createdAt": "2025-03-15T10:30:00Z",
"updatedAt": "2025-03-15T10:35:00Z",
"currency": "USD/2",
"scheme": "visa",
"type": "PAYIN",
"status": "SUCCEEDED",
"amount": "50000",
"sourceAccountID": "acc_123",
"destinationAccountID": "acc_456",
"metadata": {
"orderId": "order_42"
}
}
Unique transaction identifier on the PSP. Becomes the payment reference in Formance.
Identifier of a related transaction (e.g., the original transaction for a refund). Mapped as the parent reference in Formance.
RFC 3339 timestamp of creation.
RFC 3339 timestamp of last update. Used by the connector for incremental polling.
Asset in UMN format (e.g., "USD/2").
Payment scheme (e.g., visa, mastercard, sepa).
Amount in minor units as an integer string.
Source account identifier.
Destination account identifier.
Arbitrary key-value pairs.
Transaction types
The type field is mapped to Formance payment types:
| PSP Type | Formance Type | Description |
|---|
PAYIN | Pay-in | Incoming payment (e.g., customer payment) |
PAYOUT | Payout | Outgoing payment to an external account |
TRANSFER | Transfer | Internal transfer between accounts |
OTHER | Other | Any other transaction type |
Transaction statuses
The status field is mapped to Formance payment statuses. This is the full lifecycle status set that captures transactions in any state during polling:
| PSP Status | Formance Status | Description |
|---|
PENDING | Pending | Awaiting processing |
SUCCEEDED | Succeeded | Completed successfully |
FAILED | Failed | Failed |
CANCELLED | Cancelled | Cancelled |
EXPIRED | Expired | Expired |
REFUNDED | Refunded | Refunded |
REFUNDED_FAILURE | Refund failed | Refund attempt failed |
REFUND_REVERSED | Refund reversed | Refund was reversed |
DISPUTE | Dispute | Under dispute |
DISPUTE_WON | Dispute won | Dispute resolved in merchant’s favor |
DISPUTE_LOST | Dispute lost | Dispute resolved against merchant |
AUTHORISATION | Authorisation | Authorized but not yet captured |
CAPTURE | Capture | Captured |
CAPTURE_FAILED | Capture failed | Capture attempt failed |
OTHER | Other | Any other status |
Any unrecognized status value is also mapped to OTHER.
Identifier mapping
Understanding how identifiers flow between your PSP, the Generic Connector, and Formance is critical for reconciliation and payment initiation.
When the Generic Connector polls data from your integration service, identifiers are mapped as follows:
| PSP field | Formance field | Description |
|---|
Account.id | Account reference | The PSP account ID becomes the Formance internal account reference. |
Account.accountName | Account name | Displayed in Formance as the account name. |
Beneficiary.id | External account reference | The PSP beneficiary ID becomes the Formance external account reference. |
Beneficiary.ownerName | External account name | Displayed in Formance as the external account name. |
Transaction.id | Payment reference | The PSP transaction ID becomes the Formance payment reference. |
Transaction.relatedTransactionID | Payment parent reference | Links related transactions (e.g., a refund to its original payment). |
Transaction.sourceAccountID | Payment source account | Must match a previously polled account or beneficiary id. |
Transaction.destinationAccountID | Payment destination account | Must match a previously polled account or beneficiary id. |
When Formance initiates a payout or transfer, the identifier flow reverses. The Generic Connector sends the original PSP identifiers back to your service:
| Formance field | PSP request field | Description |
|---|
| Transfer initiation reference | idempotencyKey | Formance’s unique reference for this initiation. Your service must use this for idempotency. |
| Source account reference | sourceAccountId | The PSP account id that was originally polled from your service. |
| Destination account reference | destinationAccountId | The PSP account or beneficiary id that was originally polled from your service. |
The response then establishes the link back:
| PSP response field | Formance field | Description |
|---|
id | Payment reference | The PSP-generated payment ID, used to track this payment in Formance. |
idempotencyKey | Payment parent reference | Links the resulting payment back to the Formance transfer initiation. |
The account identifiers used in payment initiation requests are the same id values your service returned during polling. Ensure your integration service can accept these IDs in payout and transfer requests to route payments correctly on the PSP.
Payment initiation
Payment initiation support for the Generic Connector is available as of Payments v3.2.
In addition to polling data, the Generic Connector can initiate outbound payments through your integration service. This enables two types of payment initiation:
- Payout: Transfer funds from an internal account to an external account (e.g., paying out to a vendor’s bank account)
- Transfer: Move funds between two internal accounts (e.g., moving funds between wallets)
When a payout or transfer is initiated through Formance, the Generic Connector sends a POST request to your integration service, which then executes the payment on the Financial Service Provider.
Endpoints your service must implement
Your integration service needs to expose two additional endpoints to support payment initiation:
| Operation | Method | Path | Description |
|---|
| Create payout | POST | /payouts | Initiate a payout to an external account |
| Create transfer | POST | /transfers | Initiate an internal transfer between accounts |
Both endpoints receive a JSON request body and must return a JSON response with the created payment details.
The request body for both POST /payouts and POST /transfers shares the same structure:
{
"idempotencyKey": "unique-request-id",
"amount": "10000",
"currency": "USD/2",
"sourceAccountId": "acc_123",
"destinationAccountId": "ben_456",
"description": "Payment description",
"metadata": {
"key": "value"
}
}
| Field | Type | Required | Description |
|---|
idempotencyKey | string | Yes | Unique identifier for the request. Retries with the same key must return the existing payment instead of creating a duplicate. |
amount | string | Yes | Amount in minor units as an integer string (e.g., "10000" for $100.00 with precision 2). |
currency | string | Yes | Asset in UMN format (e.g., "USD/2", "BTC/8"). |
sourceAccountId | string | Yes | PSP account id of the source account (originally polled via GET /accounts). |
destinationAccountId | string | Yes | PSP account or beneficiary id of the destination. For payouts, this is typically a beneficiary id (polled via GET /beneficiaries). For transfers, this is an account id. |
description | string | No | Human-readable description of the payment. |
metadata | object | No | Arbitrary key-value pairs attached to the payment. |
Your service must return an HTTP 201 response with the created payment details:
{
"id": "psp_payout_789",
"idempotencyKey": "unique-request-id",
"amount": "10000",
"currency": "USD/2",
"sourceAccountId": "acc_123",
"destinationAccountId": "ben_456",
"description": "Payment description",
"status": "PENDING",
"createdAt": "2025-03-15T10:30:00Z",
"metadata": {
"key": "value"
}
}
| Field | Type | Required | Description |
|---|
id | string | Yes | PSP-generated unique identifier for the payment. Becomes the payment reference in Formance. |
idempotencyKey | string | Yes | The idempotency key from the request. Used to link this payment back to the Formance transfer initiation. |
amount | string | Yes | Amount in minor units (integer string). |
currency | string | Yes | Asset in UMN format. |
sourceAccountId | string | Yes | Source account identifier. |
destinationAccountId | string | Yes | Destination account identifier. |
description | string | No | Payment description. |
status | string | Yes | Initial status of the payment (see below). |
createdAt | string | Yes | RFC 3339 timestamp of when the payment was created. |
updatedAt | string | No | RFC 3339 timestamp of the last status update. |
metadata | object | No | Key-value pairs attached to the payment. |
Initial status
For the creation response, the typical statuses are:
| Status | Description |
|---|
PENDING | The PSP accepted the request and the payment is being processed. |
SUCCEEDED | The payment completed immediately (synchronous processing). |
FAILED | The payment was rejected by the PSP. |
The full set of transaction statuses (e.g., CANCELLED, EXPIRED, REFUNDED) is supported and will be mapped correctly, but these lifecycle statuses are typically observed later through polling via GET /transactions rather than in the initial creation response.
Idempotency
Your integration service must implement idempotency on the idempotencyKey field. If a request arrives with an idempotencyKey that has already been processed, your service should return the existing payment rather than creating a duplicate. This is critical because Formance may retry failed requests.
Failing to implement idempotency correctly can result in duplicate payments being created on the PSP.
Error handling
If your service encounters an error, return an appropriate HTTP error status code with a JSON body:
{
"Title": "Payment failed",
"Detail": "Insufficient funds in source account"
}
The Generic Connector will propagate the error back to Formance, and the transfer initiation will be marked as FAILED. You can then retry the initiation through the Formance API.