POST
/
api
/
v2.1
/
fintrans
/
{accountId}
/
types
/
{operationType}
/
prepare
{
  "data": {
    "preparedOrderId": "<string>",
    "validUntil": "<string>",
    "totalAmount": "<string>",
    "fees": {
      "processingFee": "<string>",
      "networkFee": "<string>",
      "totalFee": "<string>"
    },
    "consentValidation": {
      "required": true,
      "valid": true,
      "beneficiaryAllowed": true
    }
  }
}

Overview

The Prepare Order endpoint is the second step in the three-step transfer flow. It:
  • Validates operation parameters
  • Calculates applicable fees
  • Checks consent requirements
  • Reserves funds (if configured)
  • Returns a prepared order ID for execution

Path Parameters

accountId
string
required
The wallet/account ID
operationType
string
required
Type of operation: transfer, withdraw, or topup

Headers

Authorization
string
required
Bearer token for authentication
X-Tenant-ID
string
required
Tenant identifier for multi-tenant operations
X-Session-Id
string
required
Session ID for transaction tracking
Content-Type
string
required
Must be application/json

Request Body

sourceAccount
object
required
Source account details
amount
object
required
Transaction amount using precise decimal representation
currency
string
required
Top-level currency field (must match amount.currency)
type
string
required
Transaction type: EXTERNAL or INTERNAL
description
string
required
Transaction description
target
object
Required for transfer operations
reference
string
Payment reference
Payment consent reference
supportingDocuments
array
Array of document IDs for high-value transactions

Response

data
object
Prepared order details

Example Request - Transfer

curl --request POST \
  --url https://api.finhub.cloud/api/v2.1/fintrans/wal_abc123def456/types/transfer/prepare \
  --header 'Authorization: Bearer YOUR_TOKEN' \
  --header 'X-Tenant-ID: fh_api_finsei_ltd_7f957f77' \
  --header 'X-Session-Id: sess_xyz789' \
  --header 'Content-Type: application/json' \
  --data '{
    "sourceAccount": {
      "walletId": "wal_abc123def456"
    },
    "amount": {
      "value": "10000",
      "scale": 2,
      "currency": "EUR"
    },
    "currency": "EUR",
    "type": "EXTERNAL",
    "description": "Transfer to John Doe",
    "target": {
      "iban": "FR1420041010050500013M02606",
      "name": "John Doe"
    },
    "reference": "INV-2025-001",
    "consent": {
      "consentReference": "consent-payment-abc123"
    }
  }'
```text`n## Example Response

```json
{
  "data": {
    "preparedOrderId": "prep_order_xyz123abc456",
    "validUntil": "2025-01-23T13:30:00.000Z",
    "totalAmount": "101.50",
    "fees": {
      "processingFee": "1.00",
      "networkFee": "0.50",
      "totalFee": "1.50"
    },
    "consentValidation": {
      "required": true,
      "valid": true,
      "beneficiaryAllowed": true
    }
  }
}
```text`n## Amount Representation

All monetary values use string representation to avoid floating-point precision issues:

```javascript
// Correct amount representation
{
  "amount": {
    "value": "10000",    // €100.00 in cents
    "scale": 2,          // 2 decimal places
    "currency": "EUR"
  }
}

// Converting from decimal
const euros = 100.00;
const cents = Math.round(euros * 100);
const amountValue = cents.toString();
```text`n## Consent Validation

If a payment consent exists for the operation type:

1. **Beneficiary Validation**: Target IBAN must be in allowed list
2. **Amount Validation**: Must be within consent limits
3. **Validity Check**: Consent must not be expired

### Invalid Beneficiary Example

```json
// This will fail if IBAN is not in consent's allowed list
{
  "target": {
    "iban": "INVALID99999999999",  // Not in allowed list!
    "name": "Unauthorized Recipient"
  },
  "consent": {
    "consentReference": "consent-payment-abc123"
  }
}
```text`n## Operation-Specific Parameters

### Transfer
```json
{
  "target": {
    "iban": "FR1420041010050500013M02606",
    "name": "Beneficiary Name"
  },
  "reference": "Payment reference"
}
```text`n### Withdraw
```json
{
  "withdrawalMethod": "BANK_TRANSFER",
  "destinationAccount": "Personal Account",
  "reference": "Withdrawal reference"
}
```text`n### Topup
```json
{
  "source": "BANK_TRANSFER",
  "reference": "Topup reference"
}
```text`n## High-Value Transactions

For amounts above €10,000:

```json
{
  "amount": {
    "value": "1500000",  // €15,000.00
    "scale": 2,
    "currency": "EUR"
  },
  "supportingDocuments": [
    "doc_proof_of_funds_123",
    "doc_bank_statement_456",
    "doc_income_verification_789"
  ]
}
```text`n## Error Handling

| Error Code | Description | Resolution |
|------------|-------------|------------|
| 400 | Invalid parameters | Check request format |
| 403 | Beneficiary not allowed | Use allowed beneficiary |
| 409 | Insufficient balance | Check available balance |
| 422 | Consent validation failed | Create valid consent |

## Prepared Order Expiration

Prepared orders expire after a configured time (typically 30 minutes). After expiration:
- The order cannot be executed
- Any reserved funds are released
- A new preparation is required

## PowerShell Script Example

```powershell
# Prepare transfer order
$orders = @(
    @{
        amount = @{
            value = "10050"    # €100.50 in cents
            scale = 2
            currency = "EUR"
        }
        operationType = "TRANSFER"
        target = @{
            iban = "FR1420041010050500013M02606"
            name = "John Doe"
        }
        reference = "Payment for invoice #12345"
        consent = @{
            consentReference = $paymentConsentId  # From previous consent creation
        }
    },
    @{
        amount = @{
            value = "500000"   # €5,000.00 in cents
            scale = 2
            currency = "EUR"
        }
        operationType = "TRANSFER"
        target = @{
            iban = "DE89370400440532013000"
            name = "Acme Corporation"
        }
        reference = "Monthly payment"
        consent = @{
            consentReference = $paymentConsentId
        }
    }
)

$preparedOrders = @()

foreach ($order in $orders) {
    try {
        # Use fintrans API endpoint
        $prepareUrl = "$baseUrl/api/v2.1/fintrans/$walletId/order/prepare"
        $orderBody = $order | ConvertTo-Json -Depth 3
        
        # Create headers with authentication
        $headers = @{
            "Authorization" = "Bearer $token"
            "Content-Type"  = "application/json"
            "Accept"        = "application/json"
            "X-Tenant-Id"   = $xTenantId
            "X-Session-Id"  = $sessionId
        }
        
        # Convert cents to euros for display
        $amountInEuros = [decimal]$order.amount.value / [Math]::Pow(10, $order.amount.scale)
        
        Write-Host "`nPreparing order: $($order.reference)" -ForegroundColor Cyan
        Write-Host "  Amount: €$($amountInEuros.ToString('N2'))" -ForegroundColor White
        Write-Host "  Target: $($order.target.name) - $($order.target.iban)" -ForegroundColor White
        
        $prepareResponse = Invoke-RestMethod -Uri $prepareUrl -Method Post -Headers $headers -Body $orderBody
        
        if ($prepareResponse.data) {
            $orderData = $prepareResponse.data
            Write-Host "Order prepared successfully!" -ForegroundColor Green
            Write-Host "  Order ID: $($orderData.orderId)" -ForegroundColor White
            Write-Host "  Status: $($orderData.status)" -ForegroundColor White
            
            # Display fees
            if ($orderData.fees) {
                $totalFeesInEuros = [decimal]$orderData.fees.totalAmount / [Math]::Pow(10, 2)
                Write-Host "  Total fees: €$($totalFeesInEuros.ToString('N2'))" -ForegroundColor Yellow
            }
            
            # Display total amount (including fees)
            if ($orderData.totalAmount) {
                $totalInEuros = [decimal]$orderData.totalAmount.value / [Math]::Pow(10, $orderData.totalAmount.scale)
                Write-Host "  Total amount: €$($totalInEuros.ToString('N2'))" -ForegroundColor Magenta
            }
            
            # Check if approval required
            if ($orderData.metadata -and $orderData.metadata.requiresApproval) {
                Write-Host "  APPROVAL REQUIRED for this order!" -ForegroundColor Red
            }
            
            # Add to prepared orders
            $preparedOrders += @{
                orderId         = $orderData.orderId
                amount          = $amountInEuros
                target          = $order.target.name
                reference       = $order.reference
                status          = $orderData.status
                expiresAt       = $orderData.expiresAt
            }
            
            # Save order details
            $orderFile = "./prepared_order_$($orderData.orderId).json"
            $prepareResponse | ConvertTo-Json -Depth 5 | Set-Content -Path $orderFile
        }
    }
    catch {
        Write-Host "Failed to prepare order: $($_.Exception.Message)" -ForegroundColor Red
        
        # Handle specific errors  
        $errorBody = $_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue
        if ($errorBody) {
            switch ($errorBody.code) {
                "INSUFFICIENT_BALANCE" {
                    Write-Host "  Insufficient balance for transfer" -ForegroundColor Yellow
                }
                "LIMIT_EXCEEDED" {
                    Write-Host "  Transfer limit exceeded" -ForegroundColor Yellow
                }
                "INVALID_BENEFICIARY" {
                    Write-Host "  Beneficiary not allowed in consent" -ForegroundColor Yellow
                }
                "CONSENT_EXPIRED" {
                    Write-Host "  Payment consent has expired" -ForegroundColor Yellow
                }
                default {
                    Write-Host "  Error: $($errorBody.message)" -ForegroundColor Yellow
                }
            }
        }
    }
}

Write-Host "`nTotal orders prepared: $($preparedOrders.Count)" -ForegroundColor Cyan

# Display summary
if ($preparedOrders.Count -gt 0) {
    Write-Host "`nOrder Summary:" -ForegroundColor Green
    foreach ($po in $preparedOrders) {
        Write-Host "  Order $($po.orderId):" -ForegroundColor White
        Write-Host "    Amount: €$($po.amount.ToString('N2')) to $($po.target)" -ForegroundColor White
        Write-Host "    Status: $($po.status)" -ForegroundColor White
        if ($po.expiresAt) {
            Write-Host "    Expires: $($po.expiresAt)" -ForegroundColor Yellow
        }
    }
    
    # Save prepared orders summary
    $summaryFile = "./prepared_orders_summary_$(Get-Date -Format 'yyyyMMddHHmmss').json"
    $preparedOrders | ConvertTo-Json -Depth 3 | Set-Content -Path $summaryFile
}
```text`n## Next Steps

After successful preparation:

1. [Execute Order](/latest/api-reference/v2.1/fintrans/execute-order) - Complete the transaction
2. [Check Order Status](/latest/api-reference/v2.1/fintrans/order-status) - Monitor execution

## Related Endpoints

- [Get Allowed Operations](/latest/api-reference/v2.1/fintrans/allowed-operations) - Check available operations
- [Calculate Fees](/latest/api-reference/v2.1/fintrans/calculate-fees) - Preview fees only
- [Create Payment Consent](/latest/api-reference/v2.1/fintrans/create-payment-consent) - Set restrictions