Skip to main content
Pay a euro bank account over SEPA, or over SWIFT where SEPA can’t reach it. This guide covers only what’s specific to EUR. For the general flow, see Payouts. The bank account decides the rail, not you:
  • SEPA: an IBAN in a country the SEPA scheme covers.
  • SWIFT: anything else, such as an IBAN outside SEPA or an account with no IBAN.
If an address supports both, the payout goes over SEPA. A failed SEPA payout never falls back to SWIFT.

Set up the account and payout address

Before you can pay, three things must be ACTIVE: the account you’re paying, its EUR-receiving capability, and the payout address for their bank account. Account model explains each status. You do this once. If the account and address already exist, skip to pricing the payout.
1

Create the organization account

Create the account you’re paying, with the EUR-receiving capability, and keep the returned acc_ id. Capabilities lists the capability id and the identity it needs. The capability starts PENDING and usually activates within a minute; wait for common.account.capability_activated. You don’t need to wait to create the payout address, so do both at the same time.
cURL
2

Create the payout address

Create a BANK_ACCOUNT payout address for that acc_, with routingFamily set to SEPA or SWIFT. Send accountHolderName only if the bank account is in a different name from the account’s.
Send the IBAN as accountNumber. A bic is optional; adding one makes the account payable over SWIFT too, and supportedRails shows it.The IBAN is checked during the call: its country must be in SEPA, and the account must be reachable over SEPA. If either check fails, or the value isn’t an IBAN, the request fails and details.issues[] says why. Register those accounts with SWIFT instead.A name match (Verification of Payee) also runs, but finishes after the call, so the address may come back PENDING. Wait for payments.payout_address.activated or payments.payout_address.rejected, and continue only once the address is ACTIVE.
cURL

Price and create the payout

1

(Optional) List the financial accounts that can fund a EUR payout

Skip this if you already know the finacc_ id. List financial accounts returns every balance that can fund the payout: a EUR balance pays without conversion, and a USD balance is converted.
cURL
2

Quote the payout

Get a price before you create the payout. A quote moves no money. It returns a pytqte_ id and a rate locked until fxRates.expiresAt.The quote shows the rail, which sets the fees. Every payout pays a NETWORK_FEE, and a SWIFT payout adds a flat SWIFT_FEE, both in your send currency. They add up to fees.totalAmount.
cURL
3

Create the payout from the quote

Create the payout with type: "FROM_QUOTE" and the pytqte_ id. The payout keeps the quote’s rate and rail.
cURL
Besides the QUOTE entry, what confirmations[] contains depends on the rail.SEPA: regulation requires a new Verification of Payee on every payout. The payout includes an AccountHolderNameConfirmation comparing the accountHolderName you registered with the name the receiving bank holds. Confirming accepts the name as it is, even NO_MATCH. Cancel to decline it.SWIFT: the payout includes a ReceiveAmountDeductionsConfirmation. Banks along the way may take their own charges from the payment, so the account can receive less than receiveAmount. Those charges aren’t known when the payout is priced and aren’t part of fees. OpenFX adds this entry, so you can’t accept it in advance.
4

Confirm the payout

Confirm the payout to accept everything in confirmations[] and move it to ACCEPTED. Payouts covers confirming and cancelling in more detail.
cURL

Track settlement

After ACCEPTED, the payout settles in the background. See Payouts for each status and webhook. settlementTraceId gives you the payment’s reference: the end-to-end identifier on SEPA, or the UETR on SWIFT, which follows the payment through every bank. It doesn’t track Payout.status, so the create response never has it, and it can still read PENDING after the payout reaches PROCESSED. Use it once it reads AVAILABLE.

Common mistakes

  • Registering a non-SEPA account as SEPA. SEPA needs an IBAN in a SEPA country. Register anything else as SWIFT, with its bic and accountHolderAddress.
  • Expecting a name check on a SWIFT address. SWIFT has none, so verifications[] stays empty. Check the address status instead.
  • Skipping the SEPA name check on the payout. It runs again on every SEPA payout. Read it in confirmations[]; don’t rely on the address’s status.
  • Confirming without reading confirmations[]. NO_MATCH doesn’t block confirmation. The decision is yours.

What’s next

Payouts

The general payout flow.

INR payout integration guide

Paying Indian bank accounts, including NRE accounts.

Capabilities

What the EUR-receiving capability requires.

Payment Webhooks

Every payout and address event.