Skip to content

PCI-DSS Scoping & Cardholder Data Demarcation ​


1. Executive Summary & Attestation of Compliance ​

Debelu facilitates credit/debit card transactions for e-commerce purchases across Nigeria using Mastercard, Visa, and Verve. To minimize regulatory risk, liability, and infrastructure complexity, Debelu's architecture is engineered for complete Cardholder Data Environment (CDE) isolation.

Debelu qualifies for PCI-DSS v4.0 Self-Assessment Questionnaire A (SAQ-A):

  • 100% Outsourced Payment Processing: All payment card data capture, processing, and transmission functions are delegated entirely to Paystack (a PCI-DSS Level 1 certified Service Provider).
  • Zero CDE Presence: Debelu's application servers, databases, logs, and serverless edge functions never receive, process, transmit, or store Primary Account Numbers (PAN), CVVs, or cardholder PINs.
  • Strict Client-Side Demarcation: Card input fields are rendered inside Paystack-hosted iframes or secure client SDKs originating directly from Paystack servers.
mermaid
graph TD
    subgraph Client Browser Boundary
        BUYER[Buyer Storefront Web / Mobile]
        IFRAME[Paystack Inline / Hosted Modal]
    end

    subgraph PCI-DSS Level 1 Certified Boundary [Inside CDE]
        PS_GATEWAY[Paystack Payment Gateway]
        SWITCH[Interswitch / NIBSS / Card Schemes]
    end

    subgraph Debelu Infrastructure Boundary [Strictly Outside CDE]
        FLY[Fly.io Express Backend API]
        SUPA[(Supabase Postgres Database)]
        LOGS[Winston / Sentry Log Streams]
    end

    BUYER -->|1. Initiate Checkout| FLY
    FLY -->|2. Generate Reference & Public Key| BUYER
    BUYER -->|3. Render Card Fields| IFRAME
    IFRAME -->|4. Direct Card Data (PAN, CVV)| PS_GATEWAY
    PS_GATEWAY -->|5. Authorize| SWITCH
    PS_GATEWAY -->>|6. Return Token & Reference| IFRAME
    IFRAME -->>|7. Non-Sensitive Reference Only| BUYER
    BUYER -->|8. POST /api/payments/verify (reference)| FLY
    FLY -->|9. Store last4 & authorization_code| SUPA

    style PS_GATEWAY fill:#d4edda,stroke:#28a745,stroke-width:2px
    style SWITCH fill:#d4edda,stroke:#28a745,stroke-width:2px
    style IFRAME fill:#d4edda,stroke:#28a745,stroke-width:2px
    style FLY fill:#f8d7da,stroke:#dc3545,stroke-width:1px
    style SUPA fill:#f8d7da,stroke:#dc3545,stroke-width:1px

2. SAQ-A Eligibility Checklist & Validation ​

Debelu satisfies all criteria established by the PCI Security Standards Council (PCI SSC) for SAQ-A eligibility:

SAQ-A RequirementArchitectural ImplementationVerification Method
1. No electronic storage of cardholder datapayments and transactions tables contain zero columns for PAN, CVV, or PIN. Only masked summary data (last4, card_type, bank) and gateway tokens (authorization_code) are persisted.Database schema linting in CI; automated column audits.
2. Entire card processing outsourcedThe web storefront imports Paystack Inline JS; card inputs execute inside Paystack's cross-origin iframe.Code review check verifying zero <input> elements for PAN on Debelu domains.
3. Direct transmission to gatewayForm submission triggers an HTTPS POST directly from buyer browser to https://api.paystack.co.Content Security Policy (connect-src, frame-src) verification.
4. Third-party is PCI-DSS compliantPaystack maintains annual Level 1 Service Provider Attestation of Compliance (AOC).Annual compliance review and AOC receipt verification by Debelu DPO.
5. Tamper-resistant payment pageStorefront assets are hosted on Cloudflare Pages with immutable commit hashes and subresource integrity (SRI).Automated CSP nonce injection ([vite.csp-nonce.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/apps/storefront/vite.csp-nonce.ts)).

3. Server-Side Scope Demarcation & Sanitization ​

To ensure Debelu servers on Fly.io remain strictly outside the CDE, multiple layers of defensive data filtering are enforced:

3.1 Automated Regex Log Scrubbing ​

Winston application loggers and Sentry SDKs pass all outgoing log messages through a strict PII and PAN regex sanitizer:

typescript
// Scrub potential 13-19 digit credit card numbers (Luhn candidate strings)
const PAN_REGEX = /\b(?:\d[ -]*?){13,19}\b/g;

function sanitizeLogPayload(data: unknown): unknown {
  if (typeof data === 'string') {
    return data.replace(PAN_REGEX, '[POTENTIAL CARD NUMBER REDACTED]');
  }
  // Deep traversal for objects and arrays...
}

3.2 Database Schema Isolation ​

The public.payments table stores only non-sensitive gateway reference tokens:

sql
CREATE TABLE public.payments (
    id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
    order_id uuid REFERENCES public.orders(id),
    user_id uuid REFERENCES public.profiles(id),
    amount numeric NOT NULL,
    currency text DEFAULT 'NGN',
    payment_method text,
    gateway_reference text UNIQUE NOT NULL, -- e.g. "checkout-..."
    last4 varchar(4),                      -- e.g. "4081"
    card_type varchar(20),                 -- e.g. "mastercard"
    bank varchar(50),                      -- e.g. "Access Bank"
    status text NOT NULL,
    verified_at timestamptz
);

4. Webhook Integrity & Signature Verification ​

Inbound payment webhooks communicate critical financial status changes. An attacker forging a charge.success webhook could attempt to force escrow release without payment.

Debelu defends against this attack vector via cryptographic HMAC verification:

mermaid
sequenceDiagram
    autonumber
    participant Paystack as Paystack Cloud
    participant Edge as Edge Function / Backend API
    participant DB as Postgres Escrow Store

    Paystack->>Edge: 1. POST /paystack-webhook (x-paystack-signature, rawBody)
    Edge->>Edge: 2. Compute HMAC SHA-512(rawBody, PAYSTACK_SECRET_KEY)
    Edge->>Edge: 3. crypto.timingSafeEqual(computedHash, headerSignature)
    alt Signature Valid
        Edge->>DB: 4. Check processed_webhook_events(event_id)
        alt Not Yet Processed
            Edge->>DB: 5. Lock Escrow & Transition payment_status='paid'
            Edge-->>Paystack: 6. HTTP 200 OK
        else Already Processed
            Edge-->>Paystack: 6. HTTP 200 OK (Idempotent bypass)
        end
    else Signature Invalid
        Edge-->>Paystack: 4. HTTP 401 Unauthorized (Reject forged webhook)
    end

Timing-Safe Verification Implementation ​

typescript
import crypto from 'node:crypto';

export function verifyPaystackSignature(rawBody: Buffer, signature: string, secret: string): boolean {
  const hash = crypto.createHmac('sha512', secret).update(rawBody).digest('hex');
  if (hash.length !== signature.length) return false;
  return crypto.timingSafeEqual(Buffer.from(hash, 'utf-8'), Buffer.from(signature, 'utf-8'));
}

5. Security Maintenance & Periodic Audit SLA ​

To maintain valid SAQ-A qualification under PCI-DSS v4.0, Debelu enforces the following scheduled compliance reviews:

FrequencyCompliance ActivityResponsible PartyOutput Artifact
QuarterlyExternal Vulnerability Scan by an Approved Scanning Vendor (ASV) across all public domains (api.debelu.com, debelu.com).Platform Security Lead / ASVASV Clean Scan Report (Passing)
Bi-AnnualReview of third-party payment scripts and CSP headers for supply-chain integrity (Magecart defense).Frontend Engineering LeadContent Security Policy Audit Receipt
AnnualCompletion and filing of PCI-DSS Self-Assessment Questionnaire A (SAQ-A) and Attestation of Compliance (AOC).Head of Engineering & Legal CounselExecuted SAQ-A & AOC Certificate
ContinuousAutomated CI static analysis scanning for forbidden card keywords (pan, cvv, cardNumber) in DB migrations.CI/CD PipelineAutomated GitHub Actions Security Gate

Released under Proprietary Enterprise License.