Skip to content

πŸ”„ T+1 Settlement & Polars Reconciliation Engine

This document details the financial settlement rules, platform transfer workflows, and automated auditing engine powering apps/worker/src/reconciliation/[cite: 3].


πŸ—ΊοΈ Settlement & Auditing Architecture

graph TD
    subgraph Payment Capture
        Resident[Resident Portal] -->|Card Checkout| Gateway[PayTR Gateway]
        Gateway -->|Webhook Callback| API[apps/api: Go Backend]
        API -->|Record SETTLED| DB[(PostgreSQL: payment_intents)]
    end

    subgraph T+1 Platform Transfer
        Scheduler[internal/scheduler/transfer_scheduler.go] -->|Daily <= 10:00 AM| TransferAPI[PayTR /odeme/platform/transfer]
        TransferAPI -->|Direct Transfer| SubMerchant[Complex Bank IBAN]
        TransferAPI -->|Net Platform Fee| Company[Company Main Account]
    end

    subgraph Financial Reconciliation
        GatewayReport[PayTR Settlement CSV] --> PolarsEngine[apps/worker/reconciliation_engine.py]
        DB -->|Local payment_intents| PolarsEngine
        PolarsEngine --> AuditLedger[Reconciliation Audit Ledger]
    end

1. PayTR Platform Transfer Mechanics ($T+1$)

To eliminate manual bank transfers to individual residential complexes, funds flow through automated sub-merchant platform transfers[cite: 3]:

  1. Card Collection: The resident pays dues + intermediary service fee (e.g., β‚Ί1,500.00 dues + β‚Ί48.60 platform fee = β‚Ί1,548.60)[cite: 3].
  2. Transfer Timing ($T+1$ Rule): Platform transfers cannot be executed on the transaction day; requests can be submitted at the earliest on the following business day ($T+1$)[cite: 3].
  3. 10:00 AM Deadline: Per statutory payment institution rules, transfer requests must be dispatched to PayTR via the Platform Transfer API before 10:00 AM to process on the same settlement cycle[cite: 3, 4].
  4. Split Distribution: PayTR transfers the base assessment amount (β‚Ί1,500.00) directly to the residential complex's designated payout IBAN, deducts agreed gateway commission, and routes the net platform revenue to the primary company account[cite: 3].

2. Polars-Based Reconciliation Engine (reconciliation_engine.py)

Financial discrepancies, missed webhooks, or fractional cent variances are audited by cross-referencing PayTR's settlement report against PostgreSQL using high-performance Polars DataFrames[cite: 3].

Processing Flow

  • CSV Parsing: Reads incoming daily CSV exports (merchant_oid, settlement_amount, payout_date, gateway_status)[cite: 3].
  • Database Snapshot: Extracts all payment_intents records into a local DataFrame (df_local)[cite: 3].
  • Full Outer Join: Executes a full outer join on merchant_oid to capture records present in one system but absent in the other[cite: 3].

3. Classification Status Hierarchy

Every reconciled transaction is classified into one of the following audit states[cite: 3]:

Classification Status Audit Condition Meaning & Operational Action
MATCHED[cite: 3] gateway_status = SUCCESS AND local_status = SETTLED AND $\lvert \Delta \text{Amount} \rvert < 0.001$[cite: 3] Fully Reconciled. Amounts match exactly to the cent; ledger entry verified[cite: 3].
REFUND_MATCHED[cite: 3] gateway_status = REFUNDED AND local_status = REFUNDED AND $\lvert \Delta \text{Amount} \rvert < 0.001$[cite: 3] Refund Reconciled. Charge was reversed on both gateway and local ledger[cite: 3].
REFUND_DISCREPANCY[cite: 3] gateway_status = REFUNDED AND local_status != REFUNDED[cite: 3] Critical Audit Alert. Gateway reversed transaction, but local ledger remains marked as settled[cite: 3].
AMOUNT_DISCREPANCY[cite: 3] Amounts present on both sides, but $\lvert \Delta \text{Amount} \rvert \ge 0.001$[cite: 3] Pricing Mismatch. Discrepancy detected between collected amount and gateway report[cite: 3].
MISSING_IN_LOCAL_DB[cite: 3] Record in PayTR report, but missing in PostgreSQL (local_status IS NULL)[cite: 3] Missed Webhook. Payment succeeded at gateway, but callback failed to reach or commit to API[cite: 3].
MISSING_IN_GATEWAY_REPORT[cite: 3] Record in PostgreSQL, but missing in PayTR CSV (gateway_status IS NULL)[cite: 3] Unsettled / Cutoff. Intent created/settled locally but omitted from today's gateway report cutoff[cite: 3].
UNRESOLVED[cite: 3] Any edge case not matching the above rules[cite: 3] Manual Review Required. Handled directly by Lead Architect or financial operations[cite: 3].

4. Operational Execution & Runbooks

Running the Reconciliation Engine Locally

```bash

Execute daily audit against local settlement report

python3 apps/worker/src/reconciliation/reconciliation_engine.py ```[cite: 3]

Sample Summary Audit Output

text === RECONCILIATION AUDIT SUMMARY === --- Summary Breakdown --- shape: (3, 2) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β” β”‚ reconciliation_status ┆ len β”‚ β”‚ --- ┆ --- β”‚ β”‚ str ┆ u32 β”‚ β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•ͺ═════║ β”‚ REFUND_MATCHED ┆ 1 β”‚ β”‚ MISSING_IN_LOCAL_DB ┆ 2 β”‚ β”‚ MATCHED ┆ 1 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜[cite: 3]