Skip to main content

Transactions

The transaction service handles all money movement — internal transfers, interbank transfers via NIBSS NIP, cross-currency transfers, deposits, and withdrawals. Every transaction includes automatic fee calculation and limit enforcement.

Transaction Flow

Client                   API Gateway              Transaction Service
│ │ │
│ POST /transfers/* │ │
│─────────────────────────▶│─────────────────────────▶│
│ │ │── validate accounts
│ │ │── check limits
│ │ │── calculate fees
│ │ │── debit source
│ │ │── credit destination
│ │ │── create GL journal
│ { transaction_ref } │ │── emit event
│◀─────────────────────────│◀─────────────────────────│

Internal Transfers

Move funds between accounts on the same tenant. Settles instantly.

POST /api/v1/transfers/internal
curl -X POST https://api.korastratum.com/api/v1/cba/transfers/internal \
-H "Authorization: Bearer $TOKEN" \
-H "X-Tenant-ID: demo_bank" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: txn-$(uuidgen)" \
-d '{
"source_account_id": "acct-uuid-1",
"destination_account_id": "acct-uuid-2",
"destination_account_name": "John Doe",
"amount": 100000.00,
"currency": "NGN",
"channel": "API",
"narration": "Invoice #INV-001",
"initiated_by": "user-uuid"
}'

Response:

{
"id": "txn-uuid",
"transaction_ref": "TRN20260228001234",
"transaction_type": "TRANSFER",
"status": "COMPLETED",
"source_account_id": "acct-uuid-1",
"source_account_num": "1001234567",
"dest_account_id": "acct-uuid-2",
"dest_account_num": "1001234568",
"dest_account_name": "John Doe",
"amount": 100000.00,
"currency": "NGN",
"fee": 0.00,
"vat": 0.00,
"total_amount": 100000.00,
"transfer_type": "INTERNAL",
"channel": "API",
"narration": "Invoice #INV-001",
"initiated_by": "user-uuid",
"processed_at": "2026-02-28T10:00:00Z",
"completed_at": "2026-02-28T10:00:02Z"
}

Interbank Transfers (NIBSS NIP)

Send money to accounts at other Nigerian banks via the NIBSS Instant Payment system.

Step 1: Validate the Recipient

POST /api/v1/transfers/validate-account
{
"account_number": "0123456789",
"bank_code": "058"
}

Response:

{
"account_number": "0123456789",
"account_name": "JANE SMITH",
"bank_code": "058",
"bank_name": "Guaranty Trust Bank"
}

Step 2: Get Available Banks

GET /api/v1/transfers/banks

Returns a list of all banks with their CBN codes.

Step 3: Submit the Transfer

POST /api/v1/transfers/interbank
{
"source_account_id": "acct-uuid",
"destination_account_num": "0123456789",
"destination_bank_code": "058",
"destination_account_name": "JANE SMITH",
"amount": 50000.00,
"currency": "NGN",
"channel": "API",
"narration": "Payment",
"initiated_by": "user-uuid"
}

Interbank transfers may take a few seconds to settle. Poll for status:

GET /api/v1/transfers/status/:reference

Cross-Currency Transfers

Transfer between accounts in different currencies with automatic exchange rate conversion.

POST /api/v1/transfers/cross-currency
{
"source_account_id": "ngn-acct-uuid",
"dest_account_id": "usd-acct-uuid",
"send_amount": 1580500.00,
"send_currency": "NGN",
"receive_currency": "USD",
"corridor_id": "corridor-uuid",
"narration": "FX conversion",
"initiated_by": "user-uuid"
}

Response:

{
"transaction": {
"id": "txn-uuid",
"transaction_ref": "TRN20260228005678",
"status": "COMPLETED"
},
"exchange_rate": 1580.50,
"send_amount": 1580500.00,
"send_currency": "NGN",
"receive_amount": 1000.00,
"receive_currency": "USD",
"fee": 500.00,
"total_cost": 1581000.00
}

Deposits and Withdrawals

Deposit

POST /api/v1/deposits
{
"account_id": "acct-uuid",
"amount": 500000.00,
"channel": "BRANCH",
"narration": "Cash deposit",
"initiated_by": "teller-uuid"
}

Withdrawal

POST /api/v1/withdrawals
{
"account_id": "acct-uuid",
"amount": 100000.00,
"channel": "BRANCH",
"narration": "Cash withdrawal",
"initiated_by": "teller-uuid"
}

Fee Calculation

Fees are calculated automatically based on the transaction type, transfer type, and amount:

Fee TypeDescription
FLATFixed fee regardless of amount
PERCENTAGEFee as a percentage of the transfer amount

Fee configuration:

{
"transaction_type": "TRANSFER",
"transfer_type": "INTERBANK",
"min_amount": 0.00,
"max_amount": 999999999.00,
"fee_type": "FLAT",
"fee_value": 500.00,
"min_fee": 100.00,
"max_fee": 5000.00,
"vat_rate": 10.0
}

The fee is included in the total_amount field of the transaction response. VAT is calculated as fee * (vat_rate / 100).

Transaction Limits

Limits are enforced per account type and transaction type:

LimitDescription
single_limitMax amount for a single transaction
daily_limitMax total amount per day
weekly_limitMax total amount per week
monthly_limitMax total amount per month

Exceeding a limit returns 422 with code BUSINESS_RULE_ERROR.

Transaction History

GET /api/v1/transactions?limit=20

Supports cursor-based pagination and filtering by status, type, date range, and channel.

Reverse a Transaction

POST /api/v1/transactions/:id/reverse

Requires manager role. Creates a reversal transaction and corresponding GL journal.

Provider Failover

The transaction service uses a circuit breaker for interbank transfers:

  • Primary provider: Configurable (NIBSS or Interswitch)
  • Fallback provider: Automatic failover after consecutive failures
  • Admin endpoints:
    • GET /api/v1/admin/providers — Provider health status
    • GET /api/v1/admin/providers/circuit-breaker — Circuit breaker stats
    • POST /api/v1/admin/providers/:provider/reset — Reset a circuit breaker

Next Steps