DATA FOUNDATION / PHYSICAL ERD
ZarinPal merchant analytics schema
Two focused views keep the normalized payment model and operational state readable. The written physical-schema specification remains authoritative for every column, constraint, index, and lifecycle rule.
Payment facts and reference ownership
Payment facts physical entity relationships
Merchant categories classify merchants, merchants own terminals, terminals own payment sessions, sessions contain payment attempts, and attempts reference PSP and issuer-bank codes. Bootstrap sessions reference an import run.
1 N
1 N
1 N
1 N
1 N
N 1
N 0..1
ENTITY
merchant_categories
# id bigint source_category_key UK
ENTITY
merchants
# id bigint → category_id source_merchant_key UK
ENTITY
terminals
# id bigint → merchant_id source_terminal_key UK verification_type
ROOT
payment_sessions
# id bigint → merchant_id → terminal_id source_session_key UK amount_rial fee_amount_rial session_status created_at / expires_at → import_run_id
ENTITY
payment_attempts
# id bigint → payment_session_id try_seq UK per session try_status → psp_id switch_response_code? → issuer_bank_id? payer_card_key? init/verify_time_ms? try_created_at verified/settled_at?
ENTITY
import_runs
# id bigint source_sha256 + versions status + reconciliation
REF
psps
# id bigint source_psp_code UK
REF
issuer_banks
# id source_bank_code UK
# primary key→ foreign keyUK unique key? nullableBlue payment aggregate root
Identity, audit, and reporting calendar
Operational physical entity relationships
Merchants own demo users; users own server-side sessions, 30-day authentication audit events, and 90-day analytics access audit events; the reporting calendar remains an independent date dimension. The immutable MVP needs no cache revision entities.
1 N
1 N
1 N
1 N
ROOT
merchants
# id bigint → category_id source_merchant_key UK
ENTITY
merchant_users
# id bigint → merchant_id username_normalized UK password_hash disabled_at?
ENTITY
auth_sessions
# id bigint → merchant_user_id token_digest bytea UK idle_expires_at absolute_expires_at revoked_at?
ENTITY
auth_audit_events
# id bigint → merchant_user_id? event_type / outcome occurred_at expires_at (30 days)
ENTITY
analytics_access_audit_events
# id bigint → merchant_user_id + merchant_id event_type / result filter_fingerprint? row_count? / byte_count? expires_at (90 days)
ROOT
merchant_categories
# id bigint source_category_key UK title_fa
DIM
calendar_dates # gregorian_date + Jalali periods
Identity is demo-sized and replaceable by SSODataset snapshot comes from the completed import runCalendar contains no holiday dimension
Typography note: this standalone backend document uses a system fallback to remain self-contained. The product UI uses the licensed Git-tracked Iran Yekan X FaNum variable webfont. Diagram palette follows the approved ZarinPal-inspired light/dark semantic tokens.