Outbound Payments

Outbound payments let an organisation pay its suppliers directly from its own bank account. Felloh never holds the funds: payments are queued, batched into a payment run, submitted to our payment partner (Crezco) and then authorised by the organisation at its bank in a hosted flow. Statuses are read back from the provider as the money moves.

All endpoints live on the bank service (/bank/...), take the organisation in the body, and require the suppliers:manage role unless stated otherwise. Amounts are integers in minor units.


Setting up

Before an organisation can create payment runs it needs an account with the provider:

  1. PUT /bank/outbound-payments/account creates the provider organisation, registering the calling user as its administrator (organisation:integrations role).
  2. POST /bank/outbound-payments/account/verify with return_url returns a hosted verification (KYB) url, or { url: null, verified: true } when nothing more is needed.
  3. POST /bank/outbound-payments/account/connect with return_url returns a hosted url to connect the bank account pay runs are funded from.
  4. POST /bank/outbound-payments/account returns the account; send sync: true to refresh verification and connected bank accounts (payment_sources) from the provider first. POST .../account/default-source with payment_source_id picks the default funding account.

The account status is NOT_SETUP, PENDING_VERIFICATION, ACTIVE or FAILED. Runs can only be created while it is ACTIVE.


Payment Model

Properties

  • Name
    id
    Type
    string
    Description

    Unique identifier of the payment.

  • Name
    status
    Type
    string
    Description

    QUEUED, PENDING_AUTHORISATION, PROCESSING, PROCESSED, CANCELLED, REVERSED or FAILED.

  • Name
    amount
    Type
    integer
    Description

    Amount to the supplier in minor units of currency.

  • Name
    currency
    Type
    string
    Description

    ISO 4217 code, GBP by default.

  • Name
    reference
    Type
    string
    Description

    Reference the supplier sees on their statement (letters, digits, space, dot, hyphen; 18 characters).

  • Name
    supplier
    Type
    object
    Description

    { id, name } of the supplier being paid.

  • Name
    supplier_bank_account
    Type
    object
    Description

    The supplier bank account it pays into, once resolved (the supplier's default when none was chosen).

  • Name
    booking
    Type
    object
    Description

    { id, booking_reference, customer_name, departure_date } when the payment relates to a booking.

  • Name
    due_line
    Type
    object
    Description

    The supplier payment reported due by the booking system that this settles: { id, payment_type, due_date, product }. Only one live payment can exist per due line.

  • Name
    payment_run
    Type
    object
    Description

    { id, reference, status, provider_reference } once the payment is in a run.

  • Name
    provider_reference
    Type
    string
    Description

    The provider's id for the payment.

  • Name
    fee_amount
    Type
    integer
    Description

    Provider fee attributed to the payment, once known.

  • Name
    failure_reason
    Type
    string
    Description

    Why the provider could not pay it, when it failed.

  • Name
    processed_at
    Type
    timestamp
    Description

    When the supplier was paid.

Payment

{
  "id": "0b5c7d2e-9c6f-4f4e-9a11-5a2c0f2f1d10",
  "status": "PROCESSED",
  "amount": 32280,
  "currency": "GBP",
  "reference": "9364 BALANCE",
  "description": "Hotel Riga · Hotel · A Traveller",
  "supplier": { "id": "54969d6f-2695-4314-97a1-63e5696b4807", "name": "Hotel Riga" },
  "supplier_bank_account": {
    "id": "acct-1", "account_holder_name": "Hotel Riga Ltd", "currency": "GBP", "country": "GB",
    "sort_code": "123456", "account_number": "12345678", "iban": null
  },
  "booking": { "id": "1e2a0c8e-4d5e-4d1f-9b7a-2f1f7c1d1a11", "booking_reference": "9364", "customer_name": "Lead Passenger", "departure_date": "2026-11-01" },
  "due_line": { "id": "0d92104e-fb69-45da-9347-17271e73655e", "payment_type": "Balance", "due_date": "2026-10-05", "product": "Hotel" },
  "payment_run": { "id": "run-1", "reference": "Supplier run 30 Sep 2026 #1", "status": "PROCESSED", "provider_reference": "4ca10291-a1aa-4b69-b68e-25ab2fe3a22d" },
  "provider_reference": "9787f4ef-a5ac-472c-a39d-53a3314a4386",
  "fee_amount": 30,
  "funding_amount": 32280,
  "failure_reason": null,
  "processed_at": "2026-10-01T09:12:00.000Z",
  "created_at": "2026-09-30T15:02:11.000Z"
}

PUT/bank/outbound-payments

Queue Payments

Queue one or more payments to suppliers. Nothing is paid until the payments are placed in a run and the run is authorised.

Parameters

  • Name
    organisationrequired
    Type
    string
    Description

    The organisation ID.

  • Name
    paymentsrequired
    Type
    array
    Description

    Up to 200 items, each with supplier_id and amount (minor units) and optionally currency (default GBP), reference, description, booking_id, booking_component_id, booking_component_payment_id (the due line being settled) and supplier_bank_account_id (else the supplier's default account at run time).

Returns

The queued payments (compact form). 409 when a due line already has a payment that is queued, in progress or paid.

Request

PUT
/bank/outbound-payments
import axios from 'axios';

const response = await axios.put(
  'https://api.felloh.com/bank/outbound-payments',
  {
    organisation: 'X9876',
    payments: [
      {
        supplier_id: '54969d6f-2695-4314-97a1-63e5696b4807',
        amount: 32280,
        currency: 'GBP',
        reference: '9364 BALANCE',
        booking_id: '1e2a0c8e-4d5e-4d1f-9b7a-2f1f7c1d1a11',
        booking_component_payment_id: '0d92104e-fb69-45da-9347-17271e73655e'
      }
    ]
  },
  { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer <YOUR TOKEN HERE>` } }
);

POST/bank/outbound-payments

List Payments

Payments newest first, with status totals in meta.summary (queued, pending_authorisation, processing, paid_30_days, failed, each { count, amount }).

Parameters

  • Name
    organisationrequired
    Type
    string
    Description

    The organisation ID.

  • Name
    status
    Type
    string | array
    Description

    One or more statuses to include.

  • Name
    run_id
    Type
    string
    Description

    Payments in one run.

  • Name
    supplier_id
    Type
    string
    Description

    Payments to one supplier.

  • Name
    booking_id
    Type
    string
    Description

    Payments against one booking.

  • Name
    booking_component_payment_ids
    Type
    array
    Description

    Payments settling these due lines.

  • Name
    keyword
    Type
    string
    Description

    Matches supplier, booking reference, customer, payment reference or run name.

  • Name
    skip
    Type
    integer
    Description

    See the pagination section for details.

  • Name
    take
    Type
    integer
    Description

    Defaults to 50, maximum 200.

Related: POST /bank/outbound-payments/{id} returns one payment; POST /bank/outbound-payments/{id}/cancel removes a QUEUED payment from the queue (payments in a run are cancelled with the run).

Response

{
  "data": [ { "...": "Payment" } ],
  "errors": [],
  "meta": {
    "code": 200,
    "reason": "OK",
    "message": "The request was successful",
    "count": 12,
    "summary": {
      "queued": { "count": 5, "amount": 98700 },
      "pending_authorisation": { "count": 3, "amount": 41000 },
      "processing": { "count": 0, "amount": 0 },
      "paid_30_days": { "count": 4, "amount": 152300 },
      "failed": { "count": 0, "amount": 0 }
    }
  }
}

Payment Run Model

  • Name
    id
    Type
    string
    Description

    Unique identifier of the run.

  • Name
    reference
    Type
    string
    Description

    Human name, e.g. Supplier run 30 Sep 2026 #1.

  • Name
    status
    Type
    string
    Description

    PENDING_AUTHORISATION (created, waiting for the bank), PROCESSING (authorised, money moving), PROCESSED (all paid), CONCLUDED (finished, not all paid), CANCELLED or FAILED (rejected on submission).

  • Name
    provider_reference
    Type
    string
    Description

    The provider's pay run id.

  • Name
    payment_source_id
    Type
    string
    Description

    The connected bank account the run is funded from, with a readable payment_source_label.

  • Name
    scheduled_execution_date
    Type
    date
    Description

    When set, the provider pays on this date rather than immediately after authorisation.

  • Name
    total_amount
    Type
    integer
    Description

    Sum of the payments' amounts in currency.

  • Name
    fees_amount
    Type
    integer
    Description

    Provider fees charged to the organisation, once known.

  • Name
    payments_count
    Type
    integer
    Description

    Number of payments in the run.

  • Name
    payments
    Type
    array
    Description

    The run's payments (on single-run responses).

  • Name
    submitted_at / authorised_at / completed_at / cancelled_at
    Type
    timestamp
    Description

    Lifecycle timestamps; authorised_by is the Felloh user who took the run to the bank.

Payment Run

{
  "id": "run-1",
  "reference": "Supplier run 30 Sep 2026 #1",
  "status": "PENDING_AUTHORISATION",
  "provider": "CREZCO",
  "provider_reference": "4ca10291-a1aa-4b69-b68e-25ab2fe3a22d",
  "provider_status": "Open",
  "payment_source_id": "63F49021-A5FA-4A29-A3CB-2BECC11E721C",
  "payment_source_label": "Barclays · Baltic Travel · 20-00-00 · 12345678",
  "scheduled_execution_date": null,
  "currency": "GBP",
  "total_amount": 73280,
  "fees_amount": 60,
  "payments_count": 2,
  "failure_reason": null,
  "created_by": "user-1",
  "authorised_by": null,
  "submitted_at": "2026-09-30T15:05:00.000Z",
  "authorised_at": null,
  "completed_at": null,
  "cancelled_at": null,
  "last_synced_at": "2026-09-30T15:05:01.000Z",
  "created_at": "2026-09-30T15:05:00.000Z",
  "payments": [ { "...": "Payment" } ]
}

PUT/bank/outbound-payments/runs

Create Payment Run

Batch queued payments into a run and submit it to the provider. Every payment must be QUEUED, in the same currency, and its supplier must have a bank account on file (the chosen one, else the default). The run then needs authorising.

Parameters

  • Name
    organisationrequired
    Type
    string
    Description

    The organisation ID.

  • Name
    payment_idsrequired
    Type
    array
    Description

    Queued payment ids.

  • Name
    payment_source_id
    Type
    string
    Description

    Connected bank account to pay from; defaults to the account's default source.

  • Name
    scheduled_execution_date
    Type
    date
    Description

    YYYY-MM-DD; omit to pay as soon as it is authorised.

  • Name
    reference
    Type
    string
    Description

    A name for the run (100 characters).

Returns

The run with its payments. If the provider rejects the run it is recorded as FAILED with the reason, the payments return to QUEUED, and a 400 is returned.

Related

  • POST /bank/outbound-payments/runs/estimate with payment_ids returns the provider's fee and timing estimate before creating a run.
  • POST /bank/outbound-payments/runs lists runs (status filter, skip/take).
  • POST /bank/outbound-payments/runs/{id} returns a run with its payments; send sync: true to refresh from the provider first.
  • POST /bank/outbound-payments/runs/{id}/checkout with complete_url and incomplete_url returns the hosted url where the organisation authorises the run at its bank; it is redirected to one of the two urls afterwards.
  • POST /bank/outbound-payments/runs/{id}/cancel cancels a run that has not been authorised.
  • POST /bank/outbound-payments/runs/{id}/sync re-reads the run from the provider and applies its statuses.

Request

PUT
/bank/outbound-payments/runs
import axios from 'axios';

const run = await axios.put(
  'https://api.felloh.com/bank/outbound-payments/runs',
  {
    organisation: 'X9876',
    payment_ids: ['0b5c7d2e-9c6f-4f4e-9a11-5a2c0f2f1d10', '7a1d0c3b-2e4f-4b6a-8c9d-0e1f2a3b4c5d'],
    reference: 'October balances'
  },
  { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer <YOUR TOKEN HERE>` } }
);

const checkout = await axios.post(
  `https://api.felloh.com/bank/outbound-payments/runs/${run.data.data.id}/checkout`,
  {
    organisation: 'X9876',
    complete_url: 'https://dashboard.example.com/runs/done',
    incomplete_url: 'https://dashboard.example.com/runs/incomplete'
  },
  { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer <YOUR TOKEN HERE>` } }
);
// send the user to checkout.data.data.url

Webhooks

The provider notifies Felloh as pay runs and payments change (POST /bank/webhooks/crezco, signature-verified). Each event is recorded once and the affected run is re-read from the provider, so run and payment statuses in this API update without polling. Reading a run with sync: true gives the very latest state on demand.