Transfers & Payments API
APIs for the three-step transfer workflow: prepare, execute, and monitor transfers.
Base URL: https://sandbox.finhub.cloud/api/v2.1/fintrans
For complete details on authentication and headers, refer to the Standard HTTP Headers reference documentation.
Transfer Prerequisites Checklist
Before executing transfers:
Complete Transfer Flow
3-Step Process
Step 1: Prepare Transfer Order
Validates transfer details and beneficiary
Calculates fees and total debit amount
Reserves funds in the source account
Returns preparedOrderId with validUntil timestamp
Critical: Order expires after 15 minutes and must be executed before validUntil
Step 2: Execute Transfer Order
Confirms payment consent (if required)
Processes multi-level approvals (for high-value transactions)
Attaches supporting documents (for transactions above threshold)
Executes the actual payment
Returns executionId and transaction reference
Step 3: Monitor Status
Track execution progress (PENDING → PROCESSING → COMPLETED)
View state transition history
Check settlement status
Download transaction receipt
Two-Phase Pattern Explained
15-Minute Expiration : Prepared orders are only valid for 15 minutes from creation. You must execute the order before the validUntil timestamp or the order will expire and need to be prepared again.
Why Two Phases?
The prepare/execute pattern provides several benefits:
Pre-Validation - Catch errors before committing funds
Fee Transparency - Show exact fees before execution
Balance Reservation - Prevent overdrafts during execution
Compliance Window - Allow time for high-value transaction document upload
User Confirmation - Give users time to review and confirm
Idempotency - Prevent duplicate transfers
Timing Example
// Prepare at 10:00:00
const prepared = await prepareTransfer ( accountId , {
amount: { value: '10000' , scale: 2 , currency: 'EUR' },
target: { beneficiaryRef: 'ben_123' }
});
console . log ( 'Prepared Order ID:' , prepared . preparedOrderId );
console . log ( 'Valid Until:' , prepared . validUntil ); // 2026-01-13T10:15:00Z
// You have until 10:15:00 to execute (15 minutes)
// After 10:15:00, the order expires and returns error:
// "Prepared order expired or not found"
// Execute before expiration
if ( Date . now () < new Date ( prepared . validUntil ). getTime ()) {
const result = await executeTransfer ( accountId , prepared . preparedOrderId );
console . log ( 'Executed!' , result . executionId );
} else {
console . error ( 'Order expired - prepare again' );
}
High-Value Transaction Flow
For transactions above the threshold (typically €10,000), additional documents are required:
// 1. Prepare high-value transfer
const prepared = await prepareTransfer ( accountId , {
amount: { value: '1500000' , scale: 2 , currency: 'EUR' } // €15,000
});
// 2. Upload supporting documents (BEFORE execute)
const documents = [
{ type: 'PROOF_OF_FUNDS' , content: proofOfFundsBase64 },
{ type: 'INVOICE' , content: invoiceBase64 },
{ type: 'CONTRACT' , content: contractBase64 }
];
for ( const doc of documents ) {
await uploadPaymentDocument ( walletId , prepared . preparedOrderId , doc );
}
// 3. Execute with consent confirmation
await executeTransfer ( accountId , prepared . preparedOrderId , {
consentConfirmation: {
consentId: 'consent_abc123' ,
confirmed: true ,
timestamp: new Date (). toISOString (),
channel: 'WEB' ,
signature: 'user_digital_signature'
},
authenticationCode: '123456' , // 2FA code
supportingDocuments: documents . map ( d => d . documentId )
});
Get Allowed Operations
Returns available transfer types, saved beneficiaries, current limits, and applicable fees.
Request
Source account ID for the transfer
Bearer token for authentication
Active session ID (optional)
Code Examples
curl -X GET "https://sandbox.finhub.cloud/api/v2.1/transfers/acc_12345/allowed-ops" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID"
Response
List of available transfer types (INTERNAL, SEPA, SEPA_INSTANT, SWIFT)
Saved beneficiaries for quick transfers
Current transaction limits and usage
Fee structure per transfer type
{
"success" : true ,
"data" : {
"allowedOperations" : [ "INTERNAL" , "SEPA" , "SEPA_INSTANT" , "SWIFT" ],
"beneficiaries" : [
{
"beneficiaryId" : "ben_12345" ,
"name" : "John Doe" ,
"iban" : "DE89370400440532013000" ,
"type" : "SEPA"
}
],
"limits" : {
"daily" : {
"value" : 50000.00 ,
"currency" : "EUR" ,
"used" : 1000.00 ,
"remaining" : 49000.00
},
"perTransaction" : {
"value" : 10000.00 ,
"currency" : "EUR"
}
},
"fees" : {
"INTERNAL" : { "value" : 0 , "currency" : "EUR" },
"SEPA" : { "value" : 1.50 , "currency" : "EUR" },
"SEPA_INSTANT" : { "value" : 2.50 , "currency" : "EUR" },
"SWIFT" : { "value" : 25.00 , "currency" : "EUR" }
}
}
}
Prepare Transfer
Validates transfer details and stages the order for execution. Returns fees and estimated arrival.
Request
Source account ID for the transfer
Bearer token for authentication
Type of transfer: INTERNAL, SEPA, SEPA_INSTANT, or SWIFT
Transfer amount details Three-letter currency code (e.g., EUR, USD)
ID of the beneficiary to receive the transfer
Payment reference (max 140 characters)
Internal description for the transfer
Code Examples
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/transfers/acc_12345/prepare" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "X-Session-Id: YOUR_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{
"transferType": "SEPA",
"amount": {
"value": 500.00,
"currency": "EUR"
},
"beneficiaryId": "ben_12345",
"reference": "Invoice Payment",
"description": "Payment for services"
}'
Response
Unique identifier for the prepared order
Applicable fees for this transfer
Total amount to be debited (amount + fees)
Order expiration timestamp (must execute before this time)
200 - Success
400 - Validation Error
403 - Insufficient Funds
{
"success" : true ,
"data" : {
"orderId" : "ord_12345" ,
"status" : "PREPARED" ,
"amount" : {
"value" : 500.00 ,
"currency" : "EUR"
},
"fees" : {
"value" : 1.50 ,
"currency" : "EUR"
},
"totalDebit" : {
"value" : 501.50 ,
"currency" : "EUR"
},
"estimatedArrival" : "2024-01-17" ,
"expiresAt" : "2024-01-15T11:00:00Z"
}
}
Execute Transfer
Executes a prepared transfer order. The order must be executed before it expires.
Request
Bearer token for authentication
Order ID from the prepare step
Code Examples
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/transfers/acc_12345/execute" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "X-Session-Id: YOUR_SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"orderId": "ord_12345"}'
Response
Unique transaction identifier for tracking
Transaction status (PROCESSING, COMPLETED, FAILED)
ISO 8601 timestamp of execution
Estimated completion timestamp
200 - Success
400 - Order Expired
404 - Order Not Found
{
"success" : true ,
"data" : {
"transactionId" : "txn_67890" ,
"orderId" : "ord_12345" ,
"status" : "PROCESSING" ,
"executedAt" : "2024-01-15T10:35:00Z" ,
"estimatedCompletion" : "2024-01-17T12:00:00Z"
}
}
Transfer Types
INTERNAL Speed: Instant
Fee: Free
Between FinHub accounts
SEPA Speed: 1-2 business days
Fee: €1.50
Eurozone bank transfers
SEPA_INSTANT Speed: Under 10 seconds
Fee: €2.50
Real-time Eurozone transfers
SWIFT Speed: 2-5 business days
Fee: €25.00
International wire transfers
Direct Transfer Operations
These endpoints create transfers directly without the prepare/execute workflow.
Create Top-up Transfer
POST /api/v2.1/fintrans/{accountId}/transfers/types.topup
Adds funds to an account (deposit).
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/fintrans/acc_12345/transfers/types.topup" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"amount": {"value": 1000.00, "currency": "EUR"},
"reference": "Deposit",
"sourceDetails": {"method": "BANK_TRANSFER"}
}'
{
"success" : true ,
"data" : {
"transactionId" : "txn_topup_12345" ,
"type" : "TOPUP" ,
"amount" : { "value" : 1000.00 , "currency" : "EUR" },
"status" : "COMPLETED" ,
"createdAt" : "2024-01-15T10:30:00Z"
}
}
Create Withdrawal Transfer
POST /api/v2.1/fintrans/{accountId}/transfers/types.withdraw
Withdraws funds from an account.
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/fintrans/acc_12345/transfers/types.withdraw" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"amount": {"value": 500.00, "currency": "EUR"},
"destinationIban": "DE89370400440532013000",
"reference": "Withdrawal"
}'
{
"success" : true ,
"data" : {
"transactionId" : "txn_withdraw_12345" ,
"type" : "WITHDRAW" ,
"amount" : { "value" : 500.00 , "currency" : "EUR" },
"fees" : { "value" : 1.50 , "currency" : "EUR" },
"status" : "PROCESSING" ,
"estimatedCompletion" : "2024-01-17T12:00:00Z"
}
}
Create Standard Transfer
POST /api/v2.1/fintrans/{accountId}/transfers/types.transfer
Creates a direct account-to-account transfer.
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/fintrans/acc_12345/transfers/types.transfer" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"amount": {"value": 250.00, "currency": "EUR"},
"destinationAccountId": "acc_67890",
"reference": "Payment for services"
}'
{
"success" : true ,
"data" : {
"transactionId" : "txn_transfer_12345" ,
"type" : "TRANSFER" ,
"amount" : { "value" : 250.00 , "currency" : "EUR" },
"status" : "COMPLETED" ,
"createdAt" : "2024-01-15T10:30:00Z"
}
}
Create Purchase Transfer
POST /api/v2.1/fintrans/{accountId}/transfers/types.purchase
Creates a purchase transaction (e.g., card payment, merchant payment).
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/fintrans/acc_12345/transfers/types.purchase" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"amount": {"value": 99.99, "currency": "EUR"},
"merchantId": "merchant_12345",
"merchantName": "Online Store",
"reference": "Order #12345"
}'
{
"success" : true ,
"data" : {
"transactionId" : "txn_purchase_12345" ,
"type" : "PURCHASE" ,
"amount" : { "value" : 99.99 , "currency" : "EUR" },
"merchantName" : "Online Store" ,
"status" : "COMPLETED" ,
"createdAt" : "2024-01-15T10:30:00Z"
}
}
Create Sale Transfer
POST /api/v2.1/fintrans/{accountId}/transfers/types.sale
Creates a sale transaction (receiving payment as a merchant).
curl -X POST "https://sandbox.finhub.cloud/api/v2.1/fintrans/acc_12345/transfers/types.sale" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-Tenant-ID: YOUR_TENANT_ID" \
-H "Content-Type: application/json" \
-d '{
"amount": {"value": 150.00, "currency": "EUR"},
"customerReference": "CUST-001",
"description": "Product sale"
}'
{
"success" : true ,
"data" : {
"transactionId" : "txn_sale_12345" ,
"type" : "SALE" ,
"amount" : { "value" : 150.00 , "currency" : "EUR" },
"status" : "COMPLETED" ,
"createdAt" : "2024-01-15T10:30:00Z"
}
}
Operation Types Summary
Type Description Use Case topupAdd funds Deposits, incoming transfers withdrawRemove funds Bank withdrawals transferMove between accounts P2P, internal transfers purchaseDebit for purchase Card payments, merchant payments saleCredit from sale Merchant receiving payments
Transfer Status Flow
Status Description Next Step PREPARED Order validated, funds reserved Execute within 15 min EXECUTING Payment being processed Wait for completion COMPLETED Transfer successful None FAILED Transfer failed Review error, retry CANCELLED Manually cancelled Create new order
Idempotency (Prevent Duplicates)
Use X-Idempotency-Key header to prevent duplicate transfers:
const idempotencyKey = `transfer- ${ Date . now () } - ${ Math . random () } ` ;
await fetch ( url , {
method: 'POST' ,
headers: {
'X-Idempotency-Key' : idempotencyKey ,
... otherHeaders
},
body: JSON . stringify ( transferData )
});
Important: Same key within 24 hours = same response (no duplicate charge)
Response Codes
Code Description 200Transfer status retrieved successfully 201Transfer prepared/executed successfully 400Invalid request data or prepared order expired (>15 min) 403Insufficient funds or limits exceeded 404Account, order, or beneficiary not found 409Duplicate idempotency key 422Missing consent or approval required 500Internal server error
API Schema Reference
For the complete OpenAPI schema specification, see the API Schema Mapping document:
Changelog
Version Date Changes v1.0 2026-01-13 Comprehensive transfer operations documentation