Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usezentra.com/llms.txt

Use this file to discover all available pages before exploring further.

In a high-integrity financial operating system, money movement must never be represented by an implicit, black-box state change. The Zentra Control Plane models every transaction as an immutable, explicit state-machine execution. Whether initiating an outbound transfer, collecting a customer-present payment, or mapping a virtual account settlement, every balance-affecting operation moves through a predictable, inspectable path. This lifecycle ensures that engineering, risk, operations, and compliance teams can inspect the precise history, retry attempts, and raw evidence behind every ledger mutation.

The Operational State Path

The following diagram traces the state transitions of a balance-affecting transfer request as it is ingested, verified, dispatched to provider bank networks, and settled.

Lifecycle Stages

Every transaction progresses through the following deterministic states managed by GenStateMachine at the core BaaS layer:
1

ACCEPTED

The API Gateway ingests the HTTP request and registers the transaction identifier. At this stage, the payload is validated against JSON schema rules, tenant-scoped credentials are authenticated, and the transaction’s unique key is prepared for idempotency verification. No ledger mutations have occurred.
2

PROCESSING

The system attempts to acquire a distributed lock in Redis for the transaction’s idempotency key. Once locked, Zentra verifies tenant policy rules (checking daily transfer velocity limits, risk thresholds, and compliance clearance), computes standard fee models, and executes the initial journal entry to reserve funds on the core ledger.
3

AWAITING_PROVIDER

The transaction is handed off to the designated provider gateway or banking rail (e.g., Providus, GTBank, or virtual sandbox networks). Because bank settlements are highly asynchronous, the transfer enters a holding state while the core routing engine waits for a callback hook or polls the partner endpoint.
4

SUCCESSFUL or FAILED

A terminal execution state.
  • SUCCESSFUL: The partner rail confirms execution and Zentra marks the ledger entry as posted.
  • FAILED: The partner network rejects the transfer (e.g., due to insufficient counterparty funds, invalid account details, or routing timeouts), recording a precise error signature in the ledger log.
5

RECONCILED or REVERSED

Post-transaction cleanup states.
  • RECONCILED: End-of-day bank statement parsing matches the ledger entry exactly to settlement reports, verifying absolute matching evidence.
  • REVERSED: If a transaction halts after a partial debit, an automated ledger.reversal event is dispatched to credit the tenant’s ledger and restore the balance.

Strict Idempotency Guarantees

Fintech developers must design their applications to handle network timeouts, dropped packets, and temporary server failures. To prevent duplicate fund movement, Zentra enforces strict idempotency at the gateway layer for all mutating endpoints (POST, PUT, PATCH).

The Idempotency Workflow

  1. Submit Unique Keys: Attach a unique x-idempotency-key (typically a UUIDv4) as an HTTP header or payload parameter to every mutating API call.
  2. Lock Acquisition: Zentra checks Redis for a cached response using the format gateway:idempotency:<tenant_id>:<key>.
  3. Handle Concurrent Calls: If a second request arrives while the first is still processing, the gateway rejects the duplicate with an HTTP 409 Conflict.
  4. Cache & Replay: Once processing is complete, Zentra caches the payload and HTTP status code in Redis for 24 hours. Any subsequent calls with the exact same key immediately receive the identical cached response.
Node.js
import { Zentra } from "@zentra/sdk";

const zentra = new Zentra({
  apiKey: process.env.ZENTRA_SECRET_KEY,
  environment: "sandbox"
});

// Use a deterministic, business-event-based idempotency key
const idempotencyKey = "tx_transfer_payout_user_9921_iter1";

try {
  const transfer = await zentra.transfers.create({
    amountMinor: 250000, // 2,500.00 Kobo/cents
    destinationBankCode: "058",
    destinationAccountNumber: "0123456789",
    reference: idempotencyKey,
    narration: "Sandbox payroll transfer"
  }, {
    headers: {
      "X-Idempotency-Key": idempotencyKey
    }
  });

  console.log(`Transfer status: ${transfer.status}`);
} catch (error) {
  if (error.statusCode === 409) {
    console.error("Duplicate request detected. Operation already in progress.");
  } else {
    console.error("Operational failure:", error.message);
  }
}
By enforcing explicit transitions, transaction caching, and deterministic ledger writes, Zentra eliminates duplicate transfer risks and ensures every single unit of currency is accounted for across all operational steps.