Payment Card Security (PCI DSS)
If we touch payment card data, we fall under PCI DSS, a strict standard with real audits and penalties. The most important strategy is to handle as little card data as possible. Let a certified provider (for example, Stripe) take the card details so they never reach our systems. This cuts our obligations sharply. What you do not store, you cannot leak.
PCI DSS governs how cardholder data is processed, stored, and transmitted. The scope of your obligations depends entirely on how much card data your systems touch. The best move is to keep that scope small: use a PCI-compliant payment provider's hosted fields/tokenisation, so raw card numbers go straight to them and we only ever handle a token. That keeps most of PCI scope off our platform.
This connects Secrets/Encryption, Data Classification (cardholder data is highly sensitive), Tokenisation (see Data Masking), and Vendor & Third-Party Risk (the provider's compliance). When in doubt about anything touching cards, ask. PCI is not an area to improvise in.
Minimise what you touch
- AlwaysUse a PCI-compliant payment provider's hosted fields / tokenisation, so raw card data goes directly to them and never passes through or lands in our systems.
- DoWork with tokens or references for cards, not the numbers themselves, and let the provider handle storage and charging (see Data Masking & Redaction).
- DoVerify the provider's PCI compliance and keep the integration within their compliant patterns (see Vendor & Third-Party Risk).
- NeverStore, log, or transmit full card numbers (PAN), CVV/security codes, or full track data in our systems. CVV must never be stored at all (see Observability & Logging Hygiene).
// our form posts the PAN + CVV to our API, we forward to the gateway
log.Info($"charging card {pan}"); // and we logged it
We have just pulled our entire platform into PCI scope and logged a card number and CVV: a severe PCI violation and breach. Card data should never have reached our servers, let alone our logs.
// provider's hosted field captures the card in the browser -> provider
// our server only ever sees a token:
charge(provider, token, amount); // no PAN/CVV touches us
Raw card data goes straight to the certified provider. We handle a token, keeping the card environment, and most PCI scope, off our systems entirely.
If card data is genuinely in scope
- DoIf any cardholder data must touch our systems, treat it as the most sensitive class: strong encryption in transit and at rest, strict least-privilege access, network segmentation, and full audit (see Cryptography, Network & Resource Isolation, Audit Trails).
- DoKeep the cardholder-data environment tightly scoped and separated from the rest, to limit PCI scope and the impact of any breach.
- DoKeep the evidence PCI requires (access controls, scans, segmentation, logging) as part of certification readiness (see Marketplace & Certification Readiness, Vulnerability Management).
- AlwaysEscalate and get expert or compliance input before building anything that handles raw card data. Do not pull PCI scope into the system by accident.
Self-review checklist
- AskDoes raw card data ever touch our systems — and could the provider's hosted fields/tokenisation keep it out entirely?
- AskIs a PAN or (especially) a CVV ever stored, logged, or transmitted by us?
- AskIf card data is genuinely in scope, is it encrypted, segmented, access-controlled, and audited?
- AskHave I got compliance/expert input before building anything that handles cards?