Back to Case Studies
Illustration of multi-currency settlement flows between INR and USDT
Payments & Settlements Featured

Delivering Seamless Multi-Currency Settlements with INR and USDT Integration

Protize Engineering Team Updated
#Settlements #USDT #INR #FX #Reconciliation #Fintech

Delivering Seamless Multi-Currency Settlements with INR and USDT Integration

Merchants operating across regions often need fast settlement in multiple currencies. We built multi-currency settlements supporting INR and USDT while maintaining strict reconciliation, FX disclosure, and regulatory compliance. The result: predictable payouts, transparent fees, and simplified treasury operations for high-volume merchants.


1) Problem Statement


2) Objectives

  1. Unified ledger for INR and USDT with clear state transitions.
  2. Deterministic reconciliation independent of network confirmation timing.
  3. Transparent FX with locked quotes + slippage limits.
  4. Operational safety: retry-safe workflows and two-person approvals for risky actions.
  5. Merchant experience: one dashboard, predictable schedules, instant status.

3) System Architecture (High Level)


4) Double-Entry Ledger (Multi-Asset)

Each journal entry has {asset, amount, dr_account, cr_account, refId, refType}.
We enforce idempotency on (refType, refId) to prevent duplicate postings.

Example: INR → USDT FX + Settlement

  1. Merchant Balance (INR) → FX Reserve (INR)
  2. FX Reserve (INR) → FX Reserve (USDT) (at locked rate)
  3. FX Reserve (USDT) → Merchant Payout (USDT)

All three legs are posted atomically within a transaction; external transfers (chain) do not block the ledger posting but affect delivery status.

-- simplified posting sketch
BEGIN;
-- lock fx quote id=Q123 valid_until=...
INSERT INTO journal (...); -- INR -> FX_INR
INSERT INTO journal (...); -- FX_INR -> FX_USDT (using rate, fee)
INSERT INTO journal (...); -- FX_USDT -> MERCHANT_PAYOUT_USDT
COMMIT;

5) FX Handling

type Quote = {
  id: string;
  base: "INR";  // payin currency
  counter: "USDT";
  spot: number;
  spreadBps: number;
  fee: number;
  expiresAt: string;
};

6) USDT On/Off-Ramp & Wallet Safety


7) Limits, Risk, and Compliance


8) Reconciliation Model

We produce three layers of statements:

  1. Operational Ledger Statement — canonical journal by day/asset.
  2. Bank Statement Reco (INR) — amount + UTR matching vs. bank CSV.
  3. Chain Reco (USDT) — tx hash, confirmations, fee audit.

A Reconciliation Runner correlates journal entries with external statements using deterministic keys and tolerances (time, amount, fee deltas). Failures open tickets automatically.


9) Failure Modes & Recovery


10) Merchant UX (Next.js + Tremor)


11) Results

MetricBeforeAfter
Avg settlement cycle (USDT)6–12h45–90m
FX dispute ticketsHighNear-zero
Manual reconciliationsFrequentRare
Failed payouts resolvedDaysHours

12) Lessons Learned

  1. Post first, deliver next: separate accounting finality from network finality.
  2. Make FX explicit: line-item every fee and spread.
  3. Idempotency everywhere: reference keys across FX, ledger, payouts.
  4. Automate re-co: humans approve exceptions, not routine matches.

13) What’s Next


Appendix A — Orchestrator State Machine (Sketch)

stateDiagram-v2
  [*] --> REQUESTED
  REQUESTED --> FX_LOCKED: getQuote()
  FX_LOCKED --> POSTED: postLedger()
  POSTED --> DELIVERING: dispatchTransfers()
  DELIVERING --> SETTLED: confirmations ok / bank UTR matched
  DELIVERING --> PARTIAL: timeout or partial success
  PARTIAL --> SETTLED: compensating entries
  POSTED --> FAILED: fx/ledger error
  REQUESTED --> FAILED: validation error

Authored by the Protize Engineering Team — November 2025.

← Back to Case Studies