Skip to content

Data Model: Remittances

Status: Draft | Owner: Platform Team | Last Updated: 2026-04-03

Overview

Remittance domain model for Simpaisa's cross-border payment corridors. Handles FX quoting, AML/KYC compliance, and multi-provider corridor routing across PK, BD, NP, and IQ. Extends the canonical Payment entity with corridor-specific fields for regulatory compliance and foreign exchange.


Entity: Remittance

Extends Payment from the canonical model.

Field Type Description
id string ULID (inherited)
paymentId string FK → Payment (canonical)
corridor string Source→Target code (e.g. "AE→PK")
corridorConfigId string FK → CorridorConfig
fxQuoteId string FK → FXQuote
sourceAmount decimal Amount in source currency
sourceCurrency Currency Sender's currency
targetAmount decimal Amount in target currency
targetCurrency Currency Receiver's currency
amlStatus AMLStatus AML screening result
amlCheckId string FK → AMLCheck
senderKYC string FK → BeneficiaryKYC (sender)
receiverKYC string FK → BeneficiaryKYC (receiver)
senderId string Sender identity reference
receiverId string Receiver identity reference
purpose RemittancePurpose Purpose code (family support, salary, etc.)
status RemittanceStatus 9-state lifecycle
providerId string Downstream remittance partner
providerRef string Partner's transaction reference
complianceNotes string Regulatory notes (encrypted)
createdAt datetime Inherited
updatedAt datetime Inherited

Entity: FXQuote

Field Type Description
id string ULID
sourceCurrency string ISO 4217
targetCurrency string ISO 4217
sourceAmount decimal Quoted source amount
targetAmount decimal Quoted target amount
rate decimal Mid-market rate (precision 8)
markup decimal Simpaisa margin (basis points)
effectiveRate decimal Rate presented to customer
provider string Rate source (e.g. Reuters, XE)
lockedAt datetime Timestamp rate was locked
expiresAt datetime Quote expiry (typically 30s–5min)
status QuoteStatus QUOTED, LOCKED, EXECUTED, EXPIRED
usedByRemittanceId string FK → Remittance (nullable until used)

Entity: AMLCheck

Field Type Description
id string ULID
remittanceId string FK → Remittance
checkType AMLCheckType SANCTIONS, PEP, ADVERSE_MEDIA, VELOCITY
provider string Screening provider (e.g. Refinitiv)
senderScore int Risk score 0–100
receiverScore int Risk score 0–100
result AMLResult CLEAR, REVIEW, BLOCK
matchDetails string Matched entity details (encrypted)
checkedAt datetime Screening timestamp
reviewedBy string Compliance officer (nullable)
reviewedAt datetime Manual review timestamp (nullable)

Entity: BeneficiaryKYC

Field Type Description
id string ULID
fullName string Legal name as per ID
dateOfBirth date DoB for sanctions screening
nationality string ISO 3166-1 alpha-2
idType IDType PASSPORT, NATIONAL_ID, DRIVING_LICENCE
idNumber string Document number (encrypted)
idExpiry date Document expiry date
country string Country of residence
address string Residential address (encrypted)
riskRating RiskRating LOW, MEDIUM, HIGH
verifiedAt datetime KYC verification timestamp
expiresAt datetime KYC validity end (annual refresh)
status KYCStatus PENDING, VERIFIED, EXPIRED, REJECTED

Entity: CorridorConfig

Field Type Description
id string ULID
corridorCode string e.g. "AE→PK", "UK→BD"
sourceCurrency string ISO 4217
targetCurrency string ISO 4217
providers []string Ordered list of provider IDs (priority)
minAmount decimal Minimum transaction amount (source)
maxAmount decimal Maximum per-transaction (source)
dailyLimit decimal Daily aggregate limit per sender
monthlyLimit decimal Monthly aggregate limit per sender
amlProvider string AML screening provider for this corridor
requiredKYCLevel string KYC tier required (BASIC, ENHANCED)
status CorridorStatus ACTIVE, SUSPENDED, CLOSED
regulatoryNotes string Country-specific compliance notes

Remittance 9-State Machine

┌──────────┐
│ CREATED  │
└────┬─────┘
     │ lock FX quote
     ▼
┌──────────┐
│FX_LOCKED │
└────┬─────┘
     │ initiate AML
     ▼
┌────────────┐
│AML_PENDING │
└──┬──────┬──┘
   │      │
 clear   block
   │      │
   │      ▼
   │  ┌──────────┐
   │  │AML_BLOCKED│──────────────┐
   │  └──────────┘               │
   ▼                             │
┌────────────┐                   │
│ AUTHORISED │                   │
└────┬───────┘                   │
     │ submit to provider        │
     ▼                           │
┌────────────┐                   │
│ PROCESSING │                   │
└──┬──────┬──┘                   │
   │      │                      │
 success  failure                │
   │      │                      │
   ▼      ▼                      │
┌──────────┐  ┌────────┐        │
│COMPLETED │  │ FAILED │        │
└──────────┘  └────────┘        │
                  │              │
                  ▼              ▼
             ┌──────────────────────┐
             │      CANCELLED       │
             └──────────────────────┘

Key Transitions: - CREATED → FX_LOCKED: FX quote accepted and locked - FX_LOCKED → AML_PENDING: AML/sanctions screening initiated - AML_PENDING → AUTHORISED: All checks clear - AML_PENDING → AML_BLOCKED: Sanctions hit or high-risk alert - AUTHORISED → PROCESSING: Submitted to corridor provider - PROCESSING → COMPLETED: Provider confirms delivery - PROCESSING → FAILED: Provider rejects or timeout - FAILED → CANCELLED: Funds returned, FX quote released - AML_BLOCKED → CANCELLED: Compliance review rejects


Entity Relationships (ERD)

┌──────────────┐1    N┌─────────────┐1    1┌──────────┐
│CorridorConfig│──────│  Remittance │──────│  FXQuote │
└──────────────┘      └──────┬──────┘      └──────────┘
                          │1    │1
                          │     │
                         1│    1│
                    ┌─────┴┐  ┌┴───────────┐
                    │AMLChk│  │BeneficiaryKYC│
                    └──────┘  └────────────┘
                              (sender + receiver)

Enumerations

Enum Values
RemittanceStatus CREATED, FX_LOCKED, AML_PENDING, AML_BLOCKED, AUTHORISED, PROCESSING, COMPLETED, FAILED, CANCELLED
AMLStatus NOT_CHECKED, PENDING, CLEAR, REVIEW, BLOCKED
AMLCheckType SANCTIONS, PEP, ADVERSE_MEDIA, VELOCITY
AMLResult CLEAR, REVIEW, BLOCK
QuoteStatus QUOTED, LOCKED, EXECUTED, EXPIRED
KYCStatus PENDING, VERIFIED, EXPIRED, REJECTED
RiskRating LOW, MEDIUM, HIGH
RemittancePurpose FAMILY_SUPPORT, SALARY, EDUCATION, MEDICAL, TRADE, OTHER
CorridorStatus ACTIVE, SUSPENDED, CLOSED

SurrealDB Table Mapping

DEFINE TABLE remittance SCHEMAFULL;
DEFINE FIELD paymentId       ON remittance TYPE record<payment>;
DEFINE FIELD corridor        ON remittance TYPE string;
DEFINE FIELD corridorConfigId ON remittance TYPE record<corridor_config>;
DEFINE FIELD fxQuoteId       ON remittance TYPE record<fx_quote>;
DEFINE FIELD sourceAmount    ON remittance TYPE decimal;
DEFINE FIELD sourceCurrency  ON remittance TYPE string;
DEFINE FIELD targetAmount    ON remittance TYPE decimal;
DEFINE FIELD targetCurrency  ON remittance TYPE string;
DEFINE FIELD amlStatus       ON remittance TYPE string;
DEFINE FIELD amlCheckId      ON remittance TYPE option<record<aml_check>>;
DEFINE FIELD senderKYC       ON remittance TYPE record<beneficiary_kyc>;
DEFINE FIELD receiverKYC     ON remittance TYPE record<beneficiary_kyc>;
DEFINE FIELD status          ON remittance TYPE string
  ASSERT $value IN ['CREATED','FX_LOCKED','AML_PENDING','AML_BLOCKED','AUTHORISED','PROCESSING','COMPLETED','FAILED','CANCELLED'];
DEFINE FIELD createdAt       ON remittance TYPE datetime DEFAULT time::now();

DEFINE INDEX idx_remit_corridor ON remittance FIELDS corridor;
DEFINE INDEX idx_remit_status   ON remittance FIELDS status;
DEFINE INDEX idx_remit_sender   ON remittance FIELDS senderKYC;

DEFINE TABLE fx_quote SCHEMAFULL;
DEFINE FIELD sourceCurrency ON fx_quote TYPE string;
DEFINE FIELD targetCurrency ON fx_quote TYPE string;
DEFINE FIELD sourceAmount   ON fx_quote TYPE decimal;
DEFINE FIELD targetAmount   ON fx_quote TYPE decimal;
DEFINE FIELD rate           ON fx_quote TYPE decimal;
DEFINE FIELD markup         ON fx_quote TYPE decimal;
DEFINE FIELD effectiveRate  ON fx_quote TYPE decimal;
DEFINE FIELD lockedAt       ON fx_quote TYPE datetime;
DEFINE FIELD expiresAt      ON fx_quote TYPE datetime;
DEFINE FIELD status         ON fx_quote TYPE string;

DEFINE TABLE aml_check SCHEMAFULL;
DEFINE FIELD remittanceId ON aml_check TYPE record<remittance>;
DEFINE FIELD checkType    ON aml_check TYPE string;
DEFINE FIELD provider     ON aml_check TYPE string;
DEFINE FIELD senderScore  ON aml_check TYPE int;
DEFINE FIELD receiverScore ON aml_check TYPE int;
DEFINE FIELD result       ON aml_check TYPE string;
DEFINE FIELD checkedAt    ON aml_check TYPE datetime;

DEFINE TABLE beneficiary_kyc SCHEMAFULL;
DEFINE FIELD fullName     ON beneficiary_kyc TYPE string;
DEFINE FIELD dateOfBirth  ON beneficiary_kyc TYPE datetime;
DEFINE FIELD nationality  ON beneficiary_kyc TYPE string;
DEFINE FIELD idType       ON beneficiary_kyc TYPE string;
DEFINE FIELD idNumber     ON beneficiary_kyc TYPE string;  -- encrypted at app layer
DEFINE FIELD riskRating   ON beneficiary_kyc TYPE string;
DEFINE FIELD status       ON beneficiary_kyc TYPE string;
DEFINE FIELD verifiedAt   ON beneficiary_kyc TYPE option<datetime>;

DEFINE TABLE corridor_config SCHEMAFULL;
DEFINE FIELD corridorCode   ON corridor_config TYPE string;
DEFINE FIELD sourceCurrency ON corridor_config TYPE string;
DEFINE FIELD targetCurrency ON corridor_config TYPE string;
DEFINE FIELD providers      ON corridor_config TYPE array<string>;
DEFINE FIELD minAmount      ON corridor_config TYPE decimal;
DEFINE FIELD maxAmount      ON corridor_config TYPE decimal;
DEFINE FIELD dailyLimit     ON corridor_config TYPE decimal;
DEFINE FIELD monthlyLimit   ON corridor_config TYPE decimal;
DEFINE FIELD status         ON corridor_config TYPE string;

DEFINE INDEX idx_corridor_code ON corridor_config FIELDS corridorCode UNIQUE;