> ## Documentation Index
> Fetch the complete documentation index at: https://public-openfx.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# EUR payout integration guide

> Pay a euro bank account over SEPA or SWIFT: set up the account and bank details, then price, create, and confirm the payout.

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](/v3/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 <span class="ofx-enum">ACTIVE</span>: the account you're paying, its EUR-receiving capability, and the payout address for their bank account. [Account model](/v3/account-model#the-shared-state-machine) explains each status. You do this once. If the account and address already exist, skip to [pricing the payout](#price-and-create-the-payout).

<Steps>
  <Step title="Create the organization account">
    Create the account you're paying, with the EUR-receiving capability, and keep the returned `acc_` id. [Capabilities](/v3/capabilities#the-capability-catalog) lists the capability id and the identity it needs. The capability starts <span class="ofx-enum">PENDING</span> and usually activates within a minute; wait for [`common.account.capability_activated`](/v3/webhooks/payments/accounts-webhooks/account-capability-activated). You don't need to wait to create the payout address, so do both at the same time.

    ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
    curl -X POST https://api.openfx.com/v3/common/accounts \
      -H "Authorization: Bearer $OPENFX_JWT" \
      -H "X-Request-Signature: $OPENFX_SIGNATURE" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{
        "capabilities": ["cap_Ji86R1HUP9uUTtp9kdkqBw"],
        "identity": {
          "identityType": "ORGANIZATION",
          "organization": {
            "legalName": "Novalia Handels GmbH",
            "registeredAddress": { "country": "DE" }
          }
        }
      }'
    ```
  </Step>

  <Step title="Create the payout address">
    Create a `BANK_ACCOUNT` payout address for that `acc_`, with `routingFamily` set to <span class="ofx-enum">SEPA</span> or <span class="ofx-enum">SWIFT</span>. Send `accountHolderName` only if the bank account is in a different name from the account's.

    <Tabs>
      <Tab title="SEPA">
        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 <span class="ofx-enum">SWIFT</span> instead.

        A name match (Verification of Payee) also runs, but finishes after the call, so the address may come back <span class="ofx-enum">PENDING</span>. Wait for [`payments.payout_address.activated`](/v3/webhooks/payments/addresses-webhooks/payout-address-activated) or [`payments.payout_address.rejected`](/v3/webhooks/payments/addresses-webhooks/payout-address-rejected), and continue only once the address is <span class="ofx-enum">ACTIVE</span>.

        ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
        curl -X POST https://api.openfx.com/v3/payments/payout-addresses \
          -H "Authorization: Bearer $OPENFX_JWT" \
          -H "X-Request-Signature: $OPENFX_SIGNATURE" \
          -H "Idempotency-Key: $(uuidgen)" \
          -H "Content-Type: application/json" \
          -d '{
            "payoutAddressType": "BANK_ACCOUNT",
            "accountId": "acc_BMY3UenpGBn8ZQ8hio4BgE",
            "bankAccount": { "routingFamily": "SEPA", "accountNumber": "DE89370400440532013000" }
          }'
        ```
      </Tab>

      <Tab title="SWIFT">
        Send the `accountNumber` (it doesn't have to be an IBAN), the bank's `bic`, and the holder's `accountHolderAddress`.

        `accountHolderAddress` is where the account holder lives, not where the bank is, and OpenFX doesn't compare the two. The city and country travel with the payment, so both are required. The BIC must be in a country OpenFX can pay over SWIFT; this is checked during the call.

        SWIFT has no name check, so `verifications[]` is empty. The address still starts <span class="ofx-enum">PENDING</span> while OpenFX finishes its own setup. Wait for the same two webhooks, and continue only once it's <span class="ofx-enum">ACTIVE</span>.

        ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
        curl -X POST https://api.openfx.com/v3/payments/payout-addresses \
          -H "Authorization: Bearer $OPENFX_JWT" \
          -H "X-Request-Signature: $OPENFX_SIGNATURE" \
          -H "Idempotency-Key: $(uuidgen)" \
          -H "Content-Type: application/json" \
          -d '{
            "payoutAddressType": "BANK_ACCOUNT",
            "accountId": "acc_BMY3UenpGBn8ZQ8hio4BgE",
            "bankAccount": {
              "routingFamily": "SWIFT",
              "accountNumber": "8801234567",
              "bic": "PAVEGE22XXX",
              "accountHolderAddress": {
                "country": "DE",
                "city": "Berlin",
                "line1": "Friedrichstrasse 100",
                "postalCode": "10117"
              }
            }
          }'
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Price and create the payout

<Steps>
  <Step title="(Optional) List the financial accounts that can fund a EUR payout">
    Skip this if you already know the `finacc_` id. [List financial accounts](/v3/api-reference/payments/accounts/list-financial-accounts) returns every balance that can fund the payout: a EUR balance pays without conversion, and a USD balance is converted.

    ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
    curl "https://api.openfx.com/v3/common/financial-accounts?receiveCurrency=EUR" \
      -H "Authorization: Bearer $OPENFX_JWT" \
      -H "X-Request-Signature: $OPENFX_SIGNATURE"
    ```
  </Step>

  <Step title="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 <span class="ofx-enum">NETWORK\_FEE</span>, and a SWIFT payout adds a flat <span class="ofx-enum">SWIFT\_FEE</span>, both in your send currency. They add up to `fees.totalAmount`.

    ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
    curl -X POST https://api.openfx.com/v3/payments/payout-quotes \
      -H "Authorization: Bearer $OPENFX_JWT" \
      -H "X-Request-Signature: $OPENFX_SIGNATURE" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{
        "financialAccountId": "finacc_AmKC5dMVXUbiAW8VzKBfqz",
        "receiver": { "payoutAddressId": "pytadd_PbDQ126YUAbkNrNX6XbGL" },
        "sendAmount": "1087.00",
        "receiveCurrency": "EUR"
      }'
    ```
  </Step>

  <Step title="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.

    ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
    curl -X POST https://api.openfx.com/v3/payments/payouts \
      -H "Authorization: Bearer $OPENFX_JWT" \
      -H "X-Request-Signature: $OPENFX_SIGNATURE" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{ "type": "FROM_QUOTE", "quoteId": "pytqte_5PKPvtstSbXf9BurnLJfLA" }'
    ```

    Besides the <span class="ofx-enum">QUOTE</span> 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 <span class="ofx-enum">NO\_MATCH</span>. 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.
  </Step>

  <Step title="Confirm the payout">
    [Confirm the payout](/v3/api-reference/payments/payouts/confirm-payout) to accept everything in `confirmations[]` and move it to <span class="ofx-enum">ACCEPTED</span>. [Payouts](/v3/payouts) covers confirming and cancelling in more detail.

    ```bash cURL theme={"theme":{"light":"poimandres","dark":"poimandres"}}
    curl -X POST https://api.openfx.com/v3/payments/payouts/pyt_9P3Gs3GSn4hMdHQ22Evi5f/confirm \
      -H "Authorization: Bearer $OPENFX_JWT" \
      -H "X-Request-Signature: $OPENFX_SIGNATURE" \
      -H "Idempotency-Key: $(uuidgen)"
    ```
  </Step>
</Steps>

## Track settlement

After <span class="ofx-enum">ACCEPTED</span>, the payout settles in the background. See [Payouts](/v3/payouts#send-the-payout) 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 <span class="ofx-enum">PENDING</span> after the payout reaches <span class="ofx-enum">PROCESSED</span>. Use it once it reads <span class="ofx-enum">AVAILABLE</span>.

## Common mistakes

* **Registering a non-SEPA account as <span class="ofx-enum">SEPA</span>.** <span class="ofx-enum">SEPA</span> needs an IBAN in a SEPA country. Register anything else as <span class="ofx-enum">SWIFT</span>, 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[]`.** <span class="ofx-enum">NO\_MATCH</span> doesn't block confirmation. The decision is yours.

## What's next

<CardGroup cols={2}>
  <Card title="Payouts" icon="https://public-assets.openfx.com/docs/icons/withdrawals.svg" href="/v3/payouts">
    The general payout flow.
  </Card>

  <Card title="INR payout integration guide" icon="https://public-assets.openfx.com/currencies/INR.svg" href="/v3/inr-payout-integration">
    Paying Indian bank accounts, including NRE accounts.
  </Card>

  <Card title="Capabilities" icon="https://public-assets.openfx.com/docs/icons/capabilities.svg" href="/v3/capabilities#be-paid-in-euro-over-sepa">
    What the EUR-receiving capability requires.
  </Card>

  <Card title="Payment Webhooks" icon="https://public-assets.openfx.com/docs/icons/webhooks-setup.svg" href="/v3/webhooks/payments/payouts-webhooks/payout-created">
    Every payout and address event.
  </Card>
</CardGroup>
