NDPA 2023 — controller Fastclinic Limited (RC 1919428)
FastCredits processes the personal-data fields it needs to operate the ledger — the FastLogin user identifier, the Paystack receipt email, the transaction metadata — under NDPA 2023 §25 lawful bases. The data controller is Fastclinic Limited, RC 1919428, registered in Lagos. The data-processing record is updated alongside every release that touches a new dataset or a new processor. We do not claim NDPC processor registration; that filing is in progress.
NDPA 2023 ↗PCI scope — Paystack as PCI-DSS-Level-1 processor
Card data never lands in FastCredits. Paystack holds PCI DSS Level 1 attestation and operates the card-present and card-not-present rails; the dashboard never sees a primary account number, a CVV, or a bank credential. FastCredits stores the Paystack reference, the credits amount, the user identifier, and the receipt email. The boundary between processor and ledger is the answer when a regulator asks about cardholder data scope.
Paystack PCI compliance ↗Append-only ledger — Postgres BEFORE-UPDATE/DELETE triggers
Every transaction row is immutable. A BEFORE-UPDATE trigger and a BEFORE-DELETE trigger on the transactions table raise the exception "transactions table is append-only" against any DML that tries to edit or remove a historical row. Balances never re-derive from history; balance_after and held_after are snapshotted on insert. The seven-year retention applies to the audit chain that wraps the ledger when FastCredits sits behind the consolidated audit posture.
Source — initial_schema migration ↗SERIALIZABLE isolation — Postgres-level integrity
Every write path runs at SERIALIZABLE isolation. On a 40001 serialization conflict, the repository retries the entire transaction up to five attempts with exponential backoff (five to two hundred milliseconds, jittered). The account row is pinned with SELECT FOR UPDATE inside every write transaction. The combination is the strongest concurrency guarantee Postgres ships and the right primitive for a financial ledger.
Postgres SERIALIZABLE docs ↗Idempotency by design — UNIQUE(account_id, reference)
A unique index on (account_id, reference) deduplicates every transaction. A duplicate insert returns errIdempotentHit and the repository re-reads the existing row. The reference grammar — capture:{originalRef}, release:{originalRef}, refund:{originalTxID} — is server-derived, never user-supplied, so the same logical operation produces the same reference and converges on the same row. The pattern follows Stripe's industry-standard idempotency-key design adapted to a server-derived reference.
Stripe — Idempotency keys ↗