_Docs/
Get StartedModulesPlatformDeployCookbookChangelogReference
_Stack
_Modules
  • Ledger
  • Numscript
  • Connectivity
    • Capabilities
    • Operations
    • Accounts
    • Payments
    • Orders
    • Conversions
    • Payment Initiation
    • Account Pools
    • Payment Service Users
    • Connectors
      • Generic Connector
        • Getting Started
        • How it Works
      • PSP Connectors
        • Adyen
        • Atlar
        • Banking Circle
        • Column
        • Currencycloud
        • Increase
        • Mangopay
        • Modulr
        • Moneycorp
        • Qonto
        • Stripe
        • Wise
        • Banking BridgeEE
        • RoutableEE
      • Exchange Connectors
        • Coinbase PrimeEE
        • FireblocksEE
        • BitstampEE
      • Open Banking
        • Getting Started with Open Banking
        • Plaid
        • Tink
        • Powens
      • Build a connector
  • WalletsEE
  • FlowsEE
  • ReconciliationEE
  1. Modules
  2. Connectivity
  3. Payment Initiation
Connectivity

Payment Initiation

A payment initiation is your stack's instruction to a connector to move funds — either between two internal accounts at the provider (TRANSFER) or out to an external account such as a bank account (PAYOUT). The initiation is a Connectivity-side record with its own lifecycle that the platform resolves against the connector's CreateTransfer / CreatePayout workflow, then against the provider's asynchronous status updates, until it links to a settled Payment.

This page documents the v3 surface (/api/payments/v3/payment-initiations). The legacy v2 transfer-initiation endpoints are still served for backward compatibility on stacks that pin Payments < 3.0 — they use the same state machine and a near-identical shape.

Lifecycle#

A payment initiation moves through six states:

WAITING_FOR_VALIDATION ─── approve ──▶ PROCESSING ──▶ PROCESSED
        │                                  │
        │                                  ├── failure ──▶ FAILED ──▶ retry ──▶ PROCESSING
        │                                  │
        └── reject ──▶ REJECTED            └── reverse ──▶ REVERSE_PROCESSING ──▶ REVERSED
  • WAITING_FOR_VALIDATION — initial state when the create request passes validated: false. The platform parks the initiation; nothing is sent to the connector yet.
  • PROCESSING — either the platform sent the create request straight through (validated: true on create, or approve on a parked one), or it's retrying a previously failed one. The connector's CreateTransfer / CreatePayout workflow is in flight.
  • PROCESSED — the connector returned a settled payment. The initiation is linked to a Payment via v3ListPaymentInitiationRelatedPayments.
  • FAILED — the connector returned a terminal error. The full error body is on the latest adjustment. Retryable per §Retrying.
  • REJECTED — the initiation was rejected from WAITING_FOR_VALIDATION. Terminal.
  • REVERSE_PROCESSING / REVERSED — a v3ReversePaymentInitiation call is in flight or has been confirmed by the connector.

Listing initiations carries the current status; the full transition log is on v3ListPaymentInitiationAdjustments.

Listing payment initiations#

curl -X GET $FORMANCE_API_URL/api/payments/v3/payment-initiations
GET/api/payments/v3/payment-initiations

Reading a single initiation#

curl -X GET $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>
GET/api/payments/v3/payment-initiations/<PI_ID>

The id is the platform-assigned UUID returned by v3InitiatePayment. The reference is the caller-supplied idempotency key — typically echoed downstream on the resulting Payment so you can resolve one from the other (see Correlation).

Creating a payment initiation#

curl -X POST $FORMANCE_API_URL/api/payments/v3/payment-initiations \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "payout-acmecorp-20260506-172725",
    "connectorID": "<CONNECTOR_ID>",
    "type": "PAYOUT",
    "amount": 50000,
    "asset": "USD/2",
    "sourceAccountID": "<INTERNAL_ACCOUNT_ID>",
    "destinationAccountID": "<EXTERNAL_ACCOUNT_ID>",
    "description": "Vendor payment",
    "metadata": {
      "invoice_id": "inv_123"
    },
    "validated": true
  }'
POST/api/payments/v3/payment-initiations

Required fields:

FieldTypePurpose
referencestringCaller-supplied unique key. Sent to the connector as the upstream Idempotency-Key when the connector supports one; retries with the same reference return the original initiation.
connectorIDstringThe connector instance to route through. Find it in the response of v3ListConnectors or in the Console under Connectors.
typeenumTRANSFER (internal → internal) or PAYOUT (internal → external).
amountintegerMinor units at the asset's precision. 100 of USD/2 = $1.00.
assetstringAsset code with precision suffix (USD/2, EUR/2, BTC/8). Must match the source account's currency.
sourceAccountIDstringInternal account ID at the connector.
destinationAccountIDstringInternal account for TRANSFER, external for PAYOUT.

Optional:

  • description — propagated to the upstream payment when the connector supports a memo / description field.
  • metadata — opaque map. Connectors that accept upstream metadata forward it where they can; otherwise it stays Connectivity-side only.
  • validated — when true, skip the WAITING_FOR_VALIDATION step and go straight to PROCESSING. Default false.
  • scheduledAt — RFC3339 timestamp. Defers the connector call until that wall-clock time (used for cut-off-aware ACH or wire submission windows).

Connector-specific metadata#

Some connectors accept extra metadata keys to control rail selection, delivery method, or operator context. These live under com.<provider>.spec/<key> and are documented on the per-connector reference pages. Routable, for example, uses:

Metadata keyPurpose
com.routable.spec/typeRoutable payable rail (ach, wire, check, …).
com.routable.spec/delivery_methodSpecific delivery option compatible with type.
com.routable.spec/acting_team_memberRoutable team member initiating the payable (required by Routable's API).

See the Routable reference for the full list.

Approving or rejecting#

When the initiation is created with validated: false, the platform parks it in WAITING_FOR_VALIDATION until your reviewer decides:

curl -X POST $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>/approve
POST/api/payments/v3/payment-initiations/<PI_ID>/approve
curl -X POST $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>/reject
POST/api/payments/v3/payment-initiations/<PI_ID>/reject

Approve transitions the initiation to PROCESSING and dispatches it to the connector. Reject moves it to REJECTED terminally — the connector is never called.

The approval step is the platform's hook for a four-eyes / RBAC gate. Approval API access can be restricted independently of creation access via RBAC.

Retrying a failed initiation#

curl -X POST $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>/retry
POST/api/payments/v3/payment-initiations/<PI_ID>/retry

v3RetryPaymentInitiation is valid only when the initiation is in FAILED. It re-dispatches to the connector with the same reference, which means a connector that uses the reference as an upstream idempotency key will either return the failed payment as-is (no retry actually attempted) or accept a fresh attempt — connector-dependent. See each connector's reference page for the per-provider retry semantics.

Reversing a settled initiation#

curl -X POST $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>/reverse \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "rev-<PI_ID>-001",
    "description": "Reverse mistaken payout",
    "metadata": {}
  }'
POST/api/payments/v3/payment-initiations/<PI_ID>/reverse

Available on connectors that declare ReverseTransfer / ReversePayout. The reversal carries its own reference and goes through REVERSE_PROCESSING → REVERSED (or FAILED). The list of reversal attempts is accessible via the same adjustment endpoint.

Adjustments#

Every state transition lands on the initiation's adjustment list:

curl -X GET $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>/adjustments
GET/api/payments/v3/payment-initiations/<PI_ID>/adjustments

Adjustments carry the timestamp, the new status, and the connector's raw response when relevant — including the upstream error body on failed transitions. This is the audit trail you'd surface in a back-office UI.

Correlation#

Once the connector returns a settled payment, the initiation links to it in two directions:

Deleting#

curl -X DELETE $FORMANCE_API_URL/api/payments/v3/payment-initiations/<PI_ID>
DELETE/api/payments/v3/payment-initiations/<PI_ID>

Only valid in WAITING_FOR_VALIDATION. Once an initiation has been dispatched to the connector, it stays in the platform indefinitely so the linked payment(s) and adjustment log remain queryable.

Connector support matrix#

Initiation requires CAPABILITY_CREATE_TRANSFER or CAPABILITY_CREATE_PAYOUT on the target connector. See Capabilities for the live matrix — the columns light up per connector and per Payments version. Reversal is available on connectors that additionally implement ReverseTransfer or ReversePayout; that subset is smaller.

ConversionsAccount Pools
On This Page
  • Lifecycle
  • Listing payment initiations
  • Reading a single initiation
  • Creating a payment initiation
  • Connector-specific metadata
  • Approving or rejecting
  • Retrying a failed initiation
  • Reversing a settled initiation
  • Adjustments
  • Correlation
  • Deleting
  • Connector support matrix