Skip to content

Physical card issuance and bureau integration

ID MOD-124
System SD04
Repo bank-payments
Build status Built
Deployed No
Last commit bf93a9dc077dcf635ce42392eada92b9a139d8af

Purpose

Manages the full lifecycle of physical debit cards: ordering cards from the card bureau at account opening, handling replacements and renewals, card activation, PIN management, and card inventory tracking. Integrates with a card bureau (e.g. IDEMIA, Thales, ABnote) via their standard API for personalisation file submission and order tracking. Physical cards operate on the Visa or Mastercard network per the sponsor bank's card scheme membership.

PCI DSS scope

This module is in PCI DSS scope. Card personalisation data (PAN, expiry, CVV) must be handled per PCI DSS v4.0 requirements. Full PANs are never logged. Data in transit uses TLS 1.2+. The bureau API connection uses mTLS. PIN operations use the bank's Hardware Security Module (HSM) — PIN blocks are generated on the customer's device using the HSM's public key and decrypted only within the HSM. The module never touches a plaintext PIN.

Card lifecycle

ORDERED → PRODUCED → DISPATCHED → ACTIVE → FROZEN → CANCELLED

Parallel states: EXPIRED (triggers renewal 60 days before expiry date), LOST_STOLEN (triggers immediate cancellation and replacement order).

Data model

-- payments.physical_cards
CREATE TABLE payments.physical_cards (
  card_id             UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  account_id          UUID NOT NULL,                 -- cross-domain ref to SD01 accounts.accounts(id); application-layer only (no DB FK — cross-DB)
  customer_id         UUID NOT NULL,                 -- cross-domain ref to SD02 party.parties(party_id)
  card_type           TEXT NOT NULL DEFAULT 'debit'
                        CHECK (card_type IN ('debit','prepaid','credit')),
                      -- 'credit' added per ADR-058. Credit cards link to the SD05
                      -- credit facility engine (MOD-167) via credit_facility_id below.
  credit_facility_id  UUID,                          -- NULL for debit/prepaid. For credit cards,
                                                     -- application-layer ref to future MOD-167
                                                     -- credit_card_facilities(id). No DB FK —
                                                     -- cross-schema; set at card issuance.
  bin_range_type      TEXT NOT NULL DEFAULT 'sponsor'
                        CHECK (bin_range_type IN ('sponsor','principal')),
                      -- 'sponsor' = BIN held via sponsor bank (standard at launch per ADR-005).
                      -- 'principal' = direct scheme membership (Phase 4 option, deferred).
  scheme              TEXT NOT NULL CHECK (scheme IN ('visa','mastercard')),
  pan_last4           TEXT NOT NULL,                 -- full PAN never stored in Neon (PAY-006 / ADR-058)
  expiry_month        INT NOT NULL,
  expiry_year         INT NOT NULL,
  status              TEXT NOT NULL DEFAULT 'ordered'
                        CHECK (status IN ('ordered','produced','dispatched','active','frozen','cancelled','expired')),
  order_reference     TEXT,                          -- bureau order ID
  dispatch_tracking   TEXT,                          -- courier tracking number
  activated_at        TIMESTAMPTZ,
  cancelled_at        TIMESTAMPTZ,
  cancellation_reason TEXT,                          -- 'lost','stolen','expired','customer_request'
  replacement_for     UUID,                          -- previous card_id if this is a replacement
  created_at          TIMESTAMPTZ NOT NULL DEFAULT now()
);

Credit-ready columns (ADR-058): credit_facility_id and bin_range_type are included in the v1 schema even though no credit card product exists at launch. Adding them pre-build is a zero-cost change; adding them post-launch would require a production migration against a live card table. credit_facility_id is NULL for all debit and prepaid cards. When a credit card product is launched (Phase 2 per ADR-058), it is populated with the MOD-167 facility ID at card issuance time.

Key operations

1. New card order

Triggered at account opening or on customer request. The module generates personalisation data (name, PAN, expiry — PAN generated per scheme rules, CVV computed via HSM). Submits the personalisation file to the bureau API and records the order_reference. MOD-063 notifies the customer that their card has been ordered with an expected delivery window of 5–7 business days.

2. Card activation

The customer activates via the app (tap "Activate card" → biometric confirmation). The module calls the bureau to activate the PAN in the network and updates status to active. MOD-063 confirms activation. The card is simultaneously enrolled in Apple Pay and Google Pay via a tokenisation request to the card scheme.

3. PIN set

The customer sets their PIN via the in-app PIN pad. The PIN is encrypted on-device using the HSM's public key. The encrypted PIN block is sent to the HSM service, which translates it to a network PIN block for submission to the card scheme's PIN management network. The PIN is never known to the platform at any point.

4. Lost or stolen

The customer reports the card lost or stolen via the app or back office. The module immediately sets status to cancelled and calls MOD-078 to freeze all card transactions. A replacement card order is simultaneously created (new PAN, same account). The previous card is blocked at the network via the sponsor bank.

5. Renewal

60 days before card expiry a replacement card is auto-ordered. The new card is dispatched to the customer. The old card is cancelled on the expiry date. The customer is notified at 60 days and again on dispatch.

Requirements

FR-561 through FR-564.


Module dependencies

Depends on

Module Title Required? Contract Reason
MOD-078 Card & account controls Optional MOD-078 (card controls) consumes card lifecycle events emitted by MOD-124 — freeze, daily limits, and toggles apply once a card exists. MOD-124 can build and deploy without MOD-078 deployed; controls activation is additive.
MOD-063 Notification orchestration Required Card dispatch notifications, activation reminders, and PIN-related communications are dispatched via notification orchestration.
MOD-073 Document vault Required Card-related documents (terms, PCI disclosures) are delivered and stored via the document vault.
MOD-045 Secrets & key management Required All card bureau API credentials and PIN management HSM keys are stored and rotated via the secrets and key management module.

Required by

Module Title As Contract
MOD-123 ATM network integration Hard dependency
MOD-167 Credit card facility engine Hard dependency

Policies satisfied

Policy Title Mode How
PAY-003 Card Scheme Compliance Policy GATE Physical cards are produced only after passing card scheme compliance checks — the card personalisation file conforms to Visa/Mastercard scheme specifications before submission to the bureau.
PAY-006 PCI DSS Compliance Policy AUTO Card personalisation data is transmitted to the bureau using point-to-point encryption; full PANs are never stored in application logs or databases outside of PCI DSS-compliant storage.
DT-001 Information Security Policy GATE PIN set and PIN change operations forward encrypted PIN blocks to the processor's HSM via MOD-124's PIN management abstraction — PINs are never in plaintext within bank systems at any point in the processing chain.
CON-001 Customer Fairness & Conduct Policy AUTO Card replacement is initiated automatically when a card is reported lost or stolen, with no manual intervention required to trigger the bureau order.

Capabilities satisfied

(No capabilities mapped)


Part of SD04 — Payments Processing Platform Compiled 2026-05-22 from source/entities/modules/MOD-124.yaml