Skip to content

Canonical Data Model

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

Overview

Simpaisa's canonical data model provides a unified, market-agnostic representation of payment data across all products (Pay-Ins, Pay-Outs, Remittances, Cards) and markets (PK, BD, NP, IQ, EG). Based on Open Banking UK Payment Initiation API v3.1 and ISO 20022 message standards, extended for multi-market mobile money and wallet ecosystems.

Target stack: Go structs → SurrealDB tables → Temporal workflow state.


Core Entity: Payment

The root entity from which all product-specific transactions inherit.

Field Type Description ISO 20022 Mapping
id string ULID, globally unique MsgId
type PaymentType Enum: PAY_IN, PAY_OUT, REMITTANCE, CARD PmtTpInf.LclInstrm
amount decimal Transaction amount (precision 4) InstdAmt.Value
currency Currency ISO 4217 code InstdAmt.Ccy
status PaymentStatus Lifecycle state TxSts
merchantId string Owning merchant reference CdtrSchmeId
channelId string Payment channel/provider PmtMtd
debtorAccount Account Payer account DbtrAcct
creditorAccount Account Payee account CdtrAcct
createdAt datetime Creation timestamp (UTC) CreDtTm
updatedAt datetime Last modification (UTC)
traceId string Distributed tracing ID (W3C)
idempotencyKey string Client-supplied dedup key EndToEndId
metadata map Arbitrary key-value pairs SplmtryData

Entity: Transaction

Extends Payment with channel-specific execution details.

Field Type Description
paymentId string FK → Payment
channelRef string Provider's transaction reference
channelStatus string Raw status from provider
requestPayload bytes Encrypted request sent to provider
responsePayload bytes Encrypted response from provider
attemptNumber int Retry attempt (1-based)
latencyMs int Round-trip time to provider
settledAt datetime Settlement confirmation timestamp

Entity: Merchant

Field Type Description
id string ULID
name string Legal entity name
tier MerchantTier STANDARD, PREMIUM, ENTERPRISE
status MerchantStatus PENDING, ACTIVE, SUSPENDED, CLOSED
markets []string ISO 3166-1 alpha-2 codes
products []string Enabled product lines
kybStatus KYBStatus Know-Your-Business verification state
createdAt datetime Onboarding timestamp

Entity: Beneficiary

Field Type Description
id string ULID
name string Full legal name
account Account Destination account
bank string Bank/institution name
bankCode string SWIFT/BIC or local bank code
country string ISO 3166-1 alpha-2
status BeneficiaryStatus ACTIVE, SUSPENDED, BLOCKED

Entity: Account

Polymorphic account supporting IBAN, MSISDN, and wallet identifiers.

Field Type Description
id string ULID
accountType AccountType IBAN, MSISDN, WALLET, CARD_TOKEN
identifier string The account number/MSISDN/wallet ID
bankCode string SWIFT/BIC (nullable for wallets)
currency Currency Default currency
country string ISO 3166-1 alpha-2
holderName string Account holder name

Entity: Currency

Field Type Description
code string ISO 4217 (PKR, BDT, NPR, IQD)
numericCode int ISO 4217 numeric
name string Full currency name
decimals int Minor units (2 for most; 3 for IQD)
symbol string Display symbol

Entity: FXRate

Field Type Description
id string ULID
sourceCurrency string ISO 4217
targetCurrency string ISO 4217
rate decimal Mid-market rate (precision 8)
markup decimal Simpaisa margin
effectiveRate decimal rate + markup
provider string Rate source
validFrom datetime Rate validity start
validTo datetime Rate validity end

Entity: Channel

Field Type Description
id string ULID
name string e.g. JazzCash, bKash, Raast
type ChannelType MOBILE_WALLET, BANK, CARD_ACQUIRER
country string Operating market
status ChannelStatus ACTIVE, DEGRADED, MAINTENANCE, DOWN
healthScore int 0–100 real-time health

Entity: Webhook

Field Type Description
id string ULID
merchantId string FK → Merchant
url string HTTPS callback URL
events []string Subscribed event types
secret string HMAC-SHA256 signing secret
status WebhookStatus ACTIVE, PAUSED, FAILED
failureCount int Consecutive delivery failures

Entity: AuditEntry

Field Type Description
id string ULID
entityType string e.g. Payment, Merchant
entityId string FK to the audited entity
action string CREATE, UPDATE, STATUS_CHANGE, DELETE
actorId string User or system identity
actorType ActorType USER, SYSTEM, WEBHOOK, CRON
diff map Before/after field changes
timestamp datetime Event timestamp (UTC)
traceId string Correlation with Payment.traceId

Enumerations

Enum Values
PaymentType PAY_IN, PAY_OUT, REMITTANCE, CARD
PaymentStatus CREATED, PENDING, AUTHORISED, PROCESSING, COMPLETED, FAILED, REVERSED, EXPIRED, CANCELLED
MerchantTier STANDARD, PREMIUM, ENTERPRISE
MerchantStatus PENDING, ACTIVE, SUSPENDED, CLOSED
AccountType IBAN, MSISDN, WALLET, CARD_TOKEN
ChannelType MOBILE_WALLET, BANK, CARD_ACQUIRER, REMITTANCE_CORRIDOR
ChannelStatus ACTIVE, DEGRADED, MAINTENANCE, DOWN
ActorType USER, SYSTEM, WEBHOOK, CRON
KYBStatus NOT_STARTED, IN_PROGRESS, VERIFIED, REJECTED

ISO 20022 Field Mapping

Simpaisa Field ISO 20022 Element OB UK Path
Payment.id GrpHdr.MsgId Data.PaymentId
Payment.amount CdtTrfTxInf.Amt.InstdAmt Data.Initiation.InstructedAmount
Payment.currency CdtTrfTxInf.Amt.InstdAmt[@Ccy] Data.Initiation.InstructedAmount.Currency
Payment.debtorAccount DbtrAcct.Id.IBAN Data.Initiation.DebtorAccount
Payment.creditorAccount CdtrAcct.Id.IBAN Data.Initiation.CreditorAccount
Payment.status TxInfAndSts.TxSts Data.Status
Payment.traceId GrpHdr.CreDtTm (extended)
Payment.idempotencyKey PmtId.EndToEndId Data.Initiation.EndToEndIdentification

Entity Relationship Diagram

┌──────────┐       ┌─────────────┐       ┌───────────┐
│ Merchant │1────N │   Payment   │1────N │Transaction│
└──────────┘       └─────────────┘       └───────────┘
     │1                  │1    │1
     │                   │     │
     N                   │     N
┌──────────┐        1    │  ┌──────────┐
│  APIKey  │    ┌────────┘  │AuditEntry│
└──────────┘    │           └──────────┘
                N
          ┌──────────┐     ┌─────────┐
          │  Account │     │ Channel │
          └──────────┘     └─────────┘
                                │1
          ┌──────────┐          │
          │  FXRate  │          N
          └──────────┘    ┌───────────┐
                          │ Webhook   │
          ┌──────────┐    └───────────┘
          │Beneficiary│
          └──────────┘

SurrealDB Conventions

  • Table names: snake_case (e.g., payment, audit_entry)
  • Record IDs: payment:ulid() — SurrealDB native record links
  • Relations modelled as graph edges: merchant->has_payment->payment
  • All monetary amounts stored as decimal type with explicit precision
  • IQD amounts stored with 3-decimal precision; all others with 2-decimal
  • Timestamps: ISO 8601 UTC with datetime type
  • Soft deletes via deletedAt field; no physical deletes on financial records