Skip to main content
FASTCREDITS · FOR PATIENTS

One balance. Every Fastclinic service.

Top up once through Paystack. Pay for a Doorcta consult, a OneHealth records-access session, the next Fastclinic product. Holds release automatically when a service ends.

FastCredits gives you one balance — one credit equals one naira — that travels with your FastLogin identity across every Fastclinic product. Every transaction is idempotent, every hold releases automatically when a service ends or is cancelled, every receipt lands in your inbox from Paystack, and the ledger never charges you twice for the same action.
01 / 07

1 · Your balance, one place

Open the dashboard and you see one balance card: Your Balance, the credit count, and a held subline if any service has reserved credits for an in-flight session. The card uses the deterministic mapping — one credit equals one naira equals one hundred kobo — so the number is also a price. The balance follows your FastLogin identity, so signing in to any Fastclinic product reads the same number. Empty-state copy walks you through your first top-up.

Your balance1 credit = ₦1
Available
0credits
Get started by purchasing credits.
IdempotentAppend-only ledgerNo negative balance
Buy credits
Signed in via FastLogin
fastcredits.fastclinic.xyz/dashboard
02 / 07

2 · Buy credits

Choose a preset — five hundred, one thousand, two thousand, five thousand, ten thousand — or enter a custom amount between one hundred and one million. The modal shows you the naira figure (You pay ₦{amount}), the deterministic mapping (1 credit = ₦1), and a footer that names Paystack as the processor. Submit and the dashboard hands you off to Paystack to actually pay; we do not see your card details at any point in the flow.

Buy CreditsNo PCI scope · Paystack-hosted

1 credit = ₦1 (Nigerian Naira). Minimum purchase: 100 credits.

5001K2K5K10K
You pay₦2,000
Pay with Paystack

Secured by Paystack. Your card details are never stored.

PAYSTACK
fastcredits.fastclinic.xyz/dashboard
03 / 07

3 · Paystack checkout

Paystack handles the card, the bank transfer, the rails. We sit on a verifying screen until Paystack tells us the transaction succeeded. Card details never touch our servers — Paystack is the processor; we are the ledger. The verify endpoint double-checks the webhook so a single dropped network packet cannot leave you charged without credits, and the unique-index design means a refresh during checkout cannot leave you charged twice for the same payment.

Verifying your payment...

Polling /v1/me/purchase/verify · webhook + verify dual-confirm

Idempotent on referenceWebhook + verify fallback
VERIFYING
fastcredits.fastclinic.xyz/dashboard?payment=callback&reference=fcc_purchase_a1b2
04 / 07

4 · Credits land

Success arrives with a confirmation, the credit count added to your balance, and a Continue button back to the dashboard. The webhook is idempotent — a duplicate Paystack delivery resolves to the same row through the UNIQUE(account_id, reference) index — and the verify-fallback covers the rare case where the webhook is delayed. Paystack emails the receipt; FastCredits records the source service and the transaction reference.

Payment successful!

2,000 credits added to your balance.

Continue
Webhook delivered + verifiedIdempotent · 1 ledger row per reference
SUCCESS
fastcredits.fastclinic.xyz/dashboard?payment=callback&reference=fcc_purchase_a1b2
05 / 07

5 · Spend on a Doorcta consult

When a consult starts, Doorcta places a hold against your account for the consult's expected cost. The credits move from balance into held_total atomically. When the consult ends, Doorcta captures the hold and the credits become a real debit; if the consult is cancelled before it starts, Doorcta releases the hold and the credits return to balance. You are never charged for a consult that does not happen.

Doorcta consult · Dr. AdesinaService: doorcta
  1. 09:34:02Hold placed · 250 CREDITS · ref consult_42a8…
  2. 09:34:02balance ↓ 250 · held_total ↑ 250
  3. 09:42:18Consult ended · capture issued
  4. 09:42:18Captured 250 CREDITS · ref capture:consult_42a8…
  5. 09:42:18held_total ↓ 250 · balance unchanged
Two-step authorize-captureIdempotent on referenceAppend-only · 2 ledger rows
DOORCTA · CONSULT
fastcredits.fastclinic.xyz/dashboard
06 / 07

6 · Spend on a OneHealth grant

When a provider opens a session under a OneHealth grant you have approved, OneHealth places a hold whose lifetime is the session lifetime plus a one-hundred-twenty-second buffer. If you revoke the grant mid-session, the cascade releases the hold and the credits return to balance. The reconciler runs every five minutes and recovers any hold that landed in pending or failed state. Break-the-glass emergency sessions ship pre-captured at zero cost to you.

OneHealth grant · 24-hour sessionService: onehealth
  1. T+0:00:00Hold placed · 40 CREDITS · ref session_b9c1… · TTL 24h
  2. T+0:00:00balance ↓ 40 · held_total ↑ 40
  3. T+23:14:08Branch A · session ended naturally · capture issued
  4. T+23:14:08Captured · ref capture:session_b9c1…
  5. T+02:31:55Branch B · patient revoked grant mid-session
  6. T+02:31:55Released · ref release:session_b9c1… · balance restored
duration_seconds honoured (post-OH-09)409-on-retry = success (single-writer)
ONEHEALTH · GRANT
fastcredits.fastclinic.xyz/dashboard
07 / 07

7 · Auto top-up — coming 2026

Auto top-up is on the 2026 roadmap. Set a threshold and a top-up amount; when your balance crosses the threshold, FastCredits initiates a Paystack transaction against your stored card and credits the difference. Today the surface is mocked and badged Coming 2026 so you can see the shape; the underlying ledger primitives — idempotent transactions, deterministic references — already support it.

Auto Top-UpRoadmap · 2026-H1

Top up automatically when balance drops below a threshold. Charges your saved Paystack card. Cancel anytime.

Preset thresholds
5001K2K5K
Saved card•••• 4242 (Paystack)
Cancel
Save

Coming 2026 · today, top up manually from the dashboard

Coming 2026
fastcredits.fastclinic.xyz/dashboard/auto-topup
What you get

One balance across every Fastclinic product

One credit equals one naira. Top up once through Paystack and spend on a Doorcta consult, a OneHealth records-access session, or the next Fastclinic product. The balance follows your FastLogin identity. There is no per-product wallet to keep topped up and no per-product invoicing to chase.

Idempotent payments by design

A UNIQUE(account_id, reference) index on the transactions table deduplicates every write. A retried Paystack webhook, a refresh during checkout, two browser tabs racing — all converge on exactly one ledger row. You can never be charged twice for the same action.

Paystack receipts in your inbox

Paystack handles the rail and emails the receipt. FastCredits stores the reference, the amount, the timestamp, and the source service that drove the transaction. The transaction history in the dashboard shows every credit movement with relative-time labels — Just now, 12m ago, 3h ago, 2d ago, then a localised date.

Holds that release automatically

Authorize-capture holds protect you against being charged for a service that does not complete. PlaceHold reserves credits at session start; CaptureHold finalises only the actual cost; ReleaseHold returns the reserve to balance on cancel or expiry. The ExpireHolds worker sweeps any hold whose deadline has passed.

Capabilities

Ledger
  • Immutable transactions · BEFORE UPDATE/DELETE triggers
  • 5 transaction types · purchase, debit, refund, hold, release
  • balance_after / held_after snapshot per row
  • Append-only history · never re-derived
  • related_tx_id chains refund→debit, capture→hold
  • Currency code CREDITS · single allowed value
Concurrency
  • SERIALIZABLE isolation on every write
  • 40001 auto-retry · max 5 attempts
  • Backoff 5–200ms exponential with jitter
  • Optimistic version on accounts · bumped per write
  • SELECT FOR UPDATE on account row
  • No advisory locks · row lock is enough
Idempotency
  • UNIQUE(account_id, reference) index on transactions
  • capture:{ref} · release:{ref} · refund:{txID} grammar
  • Single-writer 409-is-success invariant
  • Webhook idempotency on Paystack reference
  • errIdempotentHit re-reads existing row
  • Refunds idempotent on refund:{txID}
Holds
  • DefaultHoldTTL 10 minutes · max 24 hours
  • Partial index WHERE status = 'active'
  • ExpireHolds background worker
  • Two-step authorize-capture pattern
  • release:{ref} returns held to balance
  • capture:{ref} finalises the debit
Cache & performance
  • Redis balance cache · prefix credits:balance:
  • TTL 5 minutes · best-effort fill on miss
  • Balance-only · held_total never cached
  • Invalidate on every write
  • Falls back to Postgres on cache outage
  • JWKS cache 5 minutes · singleflight on unknown kid
Compliance & residency
  • NDPA 2023 compliant · controller Fastclinic Limited
  • African data residency · single Nigerian region
  • Paystack as PCI-DSS-Level-1 processor
  • No PCI scope on FastCredits
  • Documented data-processing record
  • Append-only ledger · 7-year retention

Integrations

Fastclinic
FastLogin

Every FastCredits API call carries a Hydra-issued OAuth2 access token from fastlogin.fastclinic.xyz. The dashboard UI uses the fastcredits-public authorization-code-with-PKCE client, scoped to openid credits:read credits:write. Service callers (Doorcta, OneHealth, the FastLogin webhook itself) use the fastcredits-server client_credentials grant, scoped to services:credits. The middleware classifies tokens by client_id rather than sub-non-empty because Hydra 2.x stamps sub equal to client_id on client_credentials tokens. Account auto-creation runs on FastLogin's post-registration webhook with both 201 and 409 treated as success.

Fastclinic
Doorcta

Doorcta calls FastCredits at consultation start to PlaceHold against the patient's account, scoped to services:credits, with a duration that bounds the consult. On consultation end, Doorcta calls CaptureHold with the actual amount; on patient cancel, Doorcta calls ReleaseHold and the held credits return to balance. The Doorcta integration shape is locked at the API contract — POST /v1/accounts/:id/hold, POST /v1/holds/:id/{capture,release} — even though the active Doorcta caller is on the 2026 roadmap. The reference grammar (capture:{ref}, release:{ref}) makes every retry idempotent.

Fastclinic
OneHealth

OneHealth places a hold at session start and captures on session end. The hold TTL is computed from the session lifetime plus a one-hundred-twenty-second buffer rather than the FastCredits ten-minute default — pre-OH-09 the default silently overrode the requested duration, which is now honoured. Suspend-all and revoke cascade to ReleaseHold; the OneHealth session reconciler ticks every five minutes and recovers any hold that landed in pending or failed state. Break-the-glass sessions ship with capture_state=captured so cost cannot become a deterrent against legitimate emergency access.

External
Paystack

Paystack is the cash on-ramp. The dashboard initialises a Paystack transaction with the user's email, the amount in kobo (one hundred times credits), the reference, the callback URL, and metadata that pins the account_id, the user_id, and the credits_amount. The browser is redirected to Paystack's authorisation_url. The webhook is double-verified — X-Paystack-Signature HMAC-SHA512 over the raw body, then a server-side verify call before crediting the account. The unique index on (account_id, reference) handles duplicate webhook deliveries.

Compliance & safety

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

Plain answers

Top up once. Spend everywhere.

One balance. One naira to one credit. Idempotent every time. Holds that release when a service ends. Paystack as the processor. Get a FastLogin account and the FastCredits balance is created the moment you finish registration.