MVP API (v0.1) — The payments surface covers core payment creation, lifecycle tracking,
and cross-currency delivery. Additional capabilities (staged intents, compliance gates, refunds,
batches) will be added in future releases.
Why payments matter
Payments unlock the majority of OpenFX’s revenue potential. FX-only captures a fraction of transaction economics — customers who hold balances, receive inbound payments, and originate outbound payments generate 3-5x the revenue per customer through account fees, payment fees, and FX on a larger transaction base. The payments layer also enables the local rail advantage: instead of routing a cross-border payment via SWIFT ($25-45, 2-5 business days), OpenFX can convert currencies via the FX Engine and deliver via local rails. For example, convert USD to GBP and deliver via UK Faster Payments — instant delivery, under 1 GBP in fees. This is only possible because OpenFX combines FX conversion and multi-rail payment origination in a single platform.What Are Payments?
Payments are Layer 3 of the OpenFX platform — the top of the stack. A payment moves money from an OpenFX account to an external counterparty via a specific payment rail. Every payment touches the layers below it:- Layer 0 (Identity): The customer who owns the source account must be onboarded and KYB-approved.
- Layer 1 (FX Engine): If the payment involves a currency conversion, the FX engine provides the quote and executes the conversion.
- Layer 2 (Banking): The source account holds the funds that are debited to fund the payment.
- Layer 3 (Payments): The payment is originated on the chosen rail and delivered to the counterparty.
Two Approaches to Creating Payments
OpenFX provides two ways to create a payment. Both produce the samePayment resource with the same lifecycle.
Unified endpoint
POST /payments accepts any rail. You specify the rail field in the request body, and the
API routes to the appropriate backend. This is the canonical entrypoint for cross-rail payment
creation.
Rail-specific endpoints
POST /payments/{rail} (e.g., POST /payments/ach, POST /payments/swift) provides direct
access to a specific rail with rail-native request and response schemas. The request body
omits the rail field since it is implicit in the URL.
Supported Payment Rails
| Rail | Endpoint Suffix | Currencies | Typical Settlement | Use Case |
|---|---|---|---|---|
ach | /payments/ach | USD | 1-2 business days | US domestic payments |
fedwire | /payments/fedwire | USD | Same day | US domestic high-value |
swift | /payments/swift | Multi-currency | 1-5 business days | International cross-border |
crypto | /payments/crypto | Stablecoins | Minutes | On-chain stablecoin delivery |
open | /payments/open | Any supported | Instant | Fee-free internal platform payments |
Payment Lifecycle at a Glance
Every payment progresses through a defined set of statuses. Most payments follow the happy path:created -> processing -> completed.
See Payment Lifecycle for detailed status definitions and
webhook events for each transition.
Key Payment Fields
| Field | Type | Description |
|---|---|---|
id | string | Payment ID with pmt_ prefix (e.g., pmt_01953e1a5f4b7005) |
sourceAccountId | string | The account debited to fund the payment |
counterpartyId | string | The recipient of the payment |
paymentMethodId | string | The counterparty’s delivery method (rail-specific details) |
rail | enum | One of: ach, fedwire, swift, crypto, open |
status | enum | Current lifecycle status |
sendAmount | Money | Amount sent from source ({ "currency": "USD", "value": "150000" }) |
receiveAmount | Money | Amount received by counterparty (may differ if cross-currency) |
amountInputSide | enum | Whether you specified send or receive amount |
fees | FeeBreakdown | Fee details including feeAmount, feeCurrency, and feeComponents |
totalDebitAmount | Money | Total debited from source account (send amount + fees) |
exchangeRate | ExchangeRateDetail | FX rate details if cross-currency |
executionPreference | enum | use_quote (locked rate) or at_market (spot rate) |
senderReference | string | Your reference for the payment (visible to counterparty on some rails) |
purpose | enum | Payment purpose code (required for SWIFT) |
createdAt | datetime | ISO 8601 timestamp |
Guides in This Section
Creating Payments
Step-by-step payment creation with code examples for unified and rail-specific endpoints.
Payment Lifecycle
Full state machine, status definitions, webhook events, and terminal states.
Cross-Currency Payments
Sending in one currency and delivering in another with FX integration.
Payment Returns
Handling returns from receiving institutions.
API Reference
- POST /payments — Create payment (unified)
- GET /payments — List payments
- GET /payments/ — Get payment