
Pci Dss Compliance
- 59 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Meet PCI-DSS payment-security requirements by scoping your environment, choosing the right SAQ, and implementing required controls.
About
Guides PCI-DSS compliance by correctly scoping the cardholder-data environment, selecting the appropriate SAQ, and implementing required security controls. A developer uses it to make a store's payment handling compliant.
- Environment scoping and SAQ selection
- Implementation of required PCI-DSS controls
Pci Dss Compliance by the numbers
- 59 all-time installs (skills.sh)
- Ranked #1,229 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill pci-dss-complianceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 59 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Meet PCI-DSS payment-security requirements by scoping your environment, choosing the right SAQ, and implementing required controls.
Files
PCI-DSS Compliance
Overview
PCI-DSS (Payment Card Industry Data Security Standard) applies to any merchant that accepts card payments. The scope and complexity of your compliance obligations depend almost entirely on how card data flows through your systems. Merchants who use hosted payment forms (Shopify Payments, Stripe Checkout, PayPal hosted) can qualify for the simplest assessment (SAQ A, ~22 controls). Merchants who run custom payment pages face the most complex assessment (SAQ D, ~330 controls). The single most important PCI decision is: choose a payment method that minimizes your scope.
When to Use This Skill
- When accepting credit card payments and need to determine your PCI compliance scope
- When selecting between SAQ A, SAQ A-EP, SAQ D, or other questionnaire types
- When implementing tokenization to reduce PCI scope
- When setting up logging, monitoring, and alerting infrastructure for PCI audit readiness
- When preparing for a QSA (Qualified Security Assessor) audit or completing an SAQ
Core Instructions
Step 1: Determine your PCI scope based on payment method
The most important decision in PCI compliance is how card data flows through your environment:
| Integration Method | SAQ Type | Approx. Controls | Who This Applies To |
|---|---|---|---|
| Fully hosted checkout (Shopify Payments, Stripe Checkout, PayPal hosted) | SAQ A | ~22 | Card data never touches your server; customer is redirected to the processor's payment page |
| JavaScript tokenization on your page (Stripe Elements, Braintree Drop-in) | SAQ A-EP | ~191 | Card data is entered in an iframe on your page; your server never sees raw card numbers |
| Your server touches card data | SAQ D | ~330 | Card data passes through your application server |
Recommendation: Always choose SAQ A when possible. Use Shopify Payments, Stripe Checkout, or a PayPal-hosted checkout. Moving from SAQ D to SAQ A reduces your annual compliance effort by ~85%.
Step 2: Platform-specific PCI setup
---
Shopify
Shopify is a PCI-DSS Level 1 Service Provider. When you use Shopify Payments or any payment gateway through Shopify's checkout, Shopify handles PCI compliance for the payment processing environment.
Your PCI scope as a Shopify merchant:
- Using Shopify's hosted checkout and Shopify Payments: SAQ A — Shopify handles everything
- You are responsible only for: ensuring your Shopify admin access is secured (strong passwords, 2FA), not storing cardholder data in apps or spreadsheets, and vetting third-party apps for security
Completing your SAQ A on Shopify: 1. Download the SAQ A from the PCI Security Standards Council (pcisecuritystandards.org) 2. Shopify's merchant PCI compliance documentation is at help.shopify.com/en/manual/payments/pci-compliance 3. Shopify provides an Attestation of Compliance (AoC) for their platform — use this as evidence for your acquirer
Key controls you still own:
- Admin account security: 2FA for all Shopify staff accounts (Settings → Users → require 2FA)
- Not storing card numbers anywhere outside Shopify (no spreadsheets, no third-party databases)
- Vetting installed apps for data security practices
---
WooCommerce
WooCommerce itself is not PCI-compliant — compliance depends on your hosting, payment gateway, and implementation choices.
Minimize scope: use a hosted payment gateway:
Option A — Stripe Checkout (hosted redirect) → SAQ A
// Use WooCommerce Stripe Gateway in "Stripe Checkout" mode
// In WooCommerce → Settings → Payments → Stripe → Stripe Checkout: enable
// Customer is redirected to stripe.com for payment; SAQ A appliesOption B — Stripe Elements in WooCommerce → SAQ A-EP
- The official WooCommerce Stripe plugin uses Stripe Elements by default
- Card data is captured in a Stripe iframe; your server receives only a payment token
- This is SAQ A-EP (more controls than SAQ A but far fewer than SAQ D)
WooCommerce hosting requirements for SAQ A-EP: Your web hosting must meet minimum PCI requirements: 1. SSL/TLS: Ensure your hosting provider uses TLS 1.2+ and an up-to-date certificate 2. Patching: Keep WordPress, WooCommerce, plugins, and PHP up to date 3. Managed hosting: WP Engine, Nexcess, and Kinsta are PCI-aware managed hosts with relevant controls 4. Wordfence: Install Wordfence Security for malware scanning and WAF protection (Requirement 5, 6)
What to verify for WooCommerce PCI:
- No credit card numbers logged in WooCommerce order notes or custom fields
- WooCommerce debug logging does not capture payment data (disable debug logging in production)
- All admin accounts have strong, unique passwords and 2FA
- All plugins updated within 30 days of available security patches
---
BigCommerce
BigCommerce is a PCI-DSS Level 1 certified platform. Using BigCommerce's hosted checkout and supported payment gateways puts you in SAQ A territory.
Completing compliance on BigCommerce:
- BigCommerce provides an AoC for their platform infrastructure
- For merchants using BigCommerce Payments or a supported payment gateway through BigCommerce checkout: SAQ A applies
- For custom payment integrations or custom checkout pages: the scope increases; consult a QSA
Key BigCommerce settings: 1. Go to Store Settings → Security — ensure HTTPS is enforced on all pages 2. Go to Account Settings → Users — ensure all admin accounts have unique IDs and strong passwords 3. Enable 2FA for admin accounts under account security settings 4. Review installed apps — only grant apps the minimum permissions they need
---
Custom / Headless
For custom storefronts, your PCI scope is determined by how you integrate payment processing. Use Stripe Elements or Braintree Drop-in UI to stay in SAQ A-EP territory.
SAQ A-EP implementation with Stripe Elements:
// Client-side: Stripe handles card data in an iframe — your code never sees card numbers
const stripe = await loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
const elements = stripe.elements({ clientSecret });
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');
// On submit — Stripe creates a PaymentMethod on their servers
const { error, paymentIntent } = await stripe.confirmPayment({
elements,
confirmParams: { return_url: `${window.location.origin}/order-confirmation` },
});
// Your server never receives a card number — only a paymentMethodId or paymentIntentIdKey controls for SAQ A-EP (custom storefronts):
# Requirement 4: TLS 1.2+ only, strong cipher suites
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;Content Security Policy for payment pages (Requirement 6.4.3 in PCI-DSS v4.0):
// Strict CSP on checkout pages — only authorized scripts allowed
const csp = [
`default-src 'self'`,
`script-src 'self' 'nonce-${nonce}' https://js.stripe.com`,
`frame-src https://js.stripe.com https://hooks.stripe.com`,
`connect-src 'self' https://api.stripe.com`,
`object-src 'none'`,
].join('; ');
response.headers.set('Content-Security-Policy', csp);Audit logging (Requirement 10):
// Log every authentication event, admin action, and access to payment data
interface AuditEntry {
timestamp: string;
userId: string;
userIp: string;
action: string;
resource: string;
outcome: 'success' | 'failure';
}
// Ship logs to an immutable store: CloudWatch Logs, Datadog, or S3 with Object Lock
// Requirement 10.7: Retain logs for 12 months; 3 months immediately availablePCI-DSS controls checklist:
| Requirement | Key Engineering Task |
|---|---|
| Req 3: Protect stored data | No raw card numbers stored; use Stripe/Braintree tokens only |
| Req 4: Encrypt transmissions | TLS 1.2+; HSTS headers; no mixed content |
| Req 6: Secure development | Dependency scanning (npm audit, Snyk) in CI; SAST; script inventory on payment pages |
| Req 7–8: Access control | Role-based access; unique IDs; MFA for admin; password policy |
| Req 10: Logging | All auth events, admin actions, and CDE access logged with user ID, timestamp, IP |
| Req 11: Vulnerability management | Quarterly external scans by ASV; annual penetration test |
Best Practices
- Minimize your Cardholder Data Environment (CDE) — use hosted payment forms to qualify for SAQ A and reduce from ~330 controls to ~22; this is the highest-leverage PCI decision
- Never store raw card numbers — always use tokenization; if you never see card data, most PCI requirements don't apply to your servers
- Ship logs to immutable storage — use append-only log destinations (S3 with Object Lock, CloudWatch Logs) so attackers cannot tamper with audit trails
- Enforce MFA for all admin access — PCI-DSS v4.0 Requirement 8.4.2 mandates MFA for all access to the CDE
- Automate vulnerability scanning — run dependency audits in CI/CD and schedule quarterly ASV scans; manual processes are consistently missed
- Document your script inventory — PCI-DSS v4.0 Requirement 6.4.3 requires a documented inventory of all scripts on payment pages with business justification
Common Pitfalls
| Problem | Solution |
|---|---|
| Selected SAQ A but using Stripe Elements | Stripe Elements (JavaScript on your page) is SAQ A-EP, not SAQ A; only a fully hosted redirect (Stripe Checkout) qualifies for SAQ A |
| Debug logging enabled in production captures payment data | Disable WordPress/WooCommerce debug logging in production; WC_DEBUG and WP_DEBUG must be false |
| TLS 1.0/1.1 still enabled on load balancer | Verify with nmap --script ssl-enum-ciphers -p 443 yourstore.com; disable TLS 1.0/1.1 in your load balancer and CDN |
| Third-party scripts on checkout page not inventoried | PCI v4.0 requires a documented inventory; audit with browser dev tools; remove non-essential scripts from payment pages |
| No incident response plan | PCI Requirement 12.10.1 requires a documented IR plan tested annually; create a basic one even if you've never had an incident |
Related Skills
- @secure-checkout
- @fraud-detection
- @account-security
- @financial-audit-trail
{
"context": "Tests whether the agent produces an audit logging module that matches PCI-DSS Requirement 10 specifics: the correct AuditLogEntry fields, all required event types from Requirement 10.2, immutable/tamper-proof log storage rationale, and correct retention figures.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Timestamp field ISO 8601",
"max_score": 7,
"description": "AuditLogEntry type/interface includes a timestamp field that is described as ISO 8601 format (with timezone)"
},
{
"name": "UserId field",
"max_score": 5,
"description": "AuditLogEntry includes a userId field identifying who performed the action"
},
{
"name": "UserIp field",
"max_score": 5,
"description": "AuditLogEntry includes a field capturing the source IP address of the actor"
},
{
"name": "Outcome field",
"max_score": 6,
"description": "AuditLogEntry includes an outcome field with success/failure values (not just a boolean)"
},
{
"name": "Resource field",
"max_score": 5,
"description": "AuditLogEntry includes a resource (or equivalent) field identifying what was affected"
},
{
"name": "Log authentication events",
"max_score": 8,
"description": "AuditLogger includes a method to log authentication events (both successful and failed login attempts)"
},
{
"name": "Log cardholder data access",
"max_score": 7,
"description": "AuditLogger includes a method to log access to cardholder data"
},
{
"name": "Log admin actions",
"max_score": 7,
"description": "AuditLogger includes a method to log administrative actions"
},
{
"name": "Log privilege escalation",
"max_score": 7,
"description": "AuditLogger includes a method to log privilege or role changes"
},
{
"name": "Log access denied",
"max_score": 7,
"description": "AuditLogger logs access-denied events (failed authorisation attempts) with outcome: 'failure'"
},
{
"name": "Immutable transport rationale",
"max_score": 12,
"description": "log-transport.ts includes a comment or description explaining that the chosen transport is append-only or tamper-proof (e.g. S3 Object Lock, CloudWatch Logs, or equivalent)"
},
{
"name": "Retention 12 months",
"max_score": 10,
"description": "retention-policy.md states that logs must be retained for a minimum of 12 months"
},
{
"name": "Retention 3 months accessible",
"max_score": 10,
"description": "retention-policy.md states that at least 3 months of logs must be immediately accessible (online/queryable)"
},
{
"name": "Tamper-proof principle",
"max_score": 4,
"description": "Either retention-policy.md or log-transport.ts notes that log files must not be modifiable after writing (tamper-evident or immutable storage)"
}
]
}
Audit Logging Module for PCI-Compliant Admin Panel
Problem/Feature Description
Meridian Commerce operates an e-commerce platform that processes credit card payments via Stripe. Their security team has received a finding from an external assessor: the admin panel has no structured audit logging. Currently, when an admin user logs in, updates an order, or grants another user elevated access, no trace is recorded anywhere. The assessor noted that this would be a blocking issue during a PCI-DSS assessment.
The team needs a TypeScript audit logging module that can be dropped into their Express-based admin panel. The module must produce log entries that satisfy the auditor's requirements, write those logs to a destination that cannot be tampered with after the fact, and cover all the specific admin-panel event types the assessor flagged. The logging infrastructure must also have a documented retention approach: the assessor asked specifically how long audit records are kept and how quickly historical records can be retrieved.
Output Specification
Produce the following files:
audit-logger.ts— A TypeScript module containing:- An interface or type definition for audit log entries
- An
AuditLoggerclass with a constructor that accepts a transport - Methods to log: authentication events, access to cardholder data, admin actions, privilege escalation changes, and access-denied events
- Each log entry must capture enough information to satisfy PCI auditor requirements
log-transport.ts— A short TypeScript module showing how the AuditLogger would be wired to a tamper-proof log destination. You do not need to implement a real cloud client — a concrete class with awrite(entry)stub is sufficient. Include a comment explaining why this destination is suitable for PCI compliance.
retention-policy.md— A short document (bullet points are fine) describing the log retention approach that satisfies PCI-DSS requirements, including how long logs must be kept and how quickly a subset of recent logs must be retrievable.
{
"context": "Tests whether the agent implements the correct four RBAC admin roles with appropriate permission scopes, the PCI-specific password policy values, MFA requirements for admin access, and logging of both authentication failures and access-denied events.",
"type": "weighted_checklist",
"checklist": [
{
"name": "VIEWER role defined",
"max_score": 5,
"description": "rbac.ts defines a VIEWER role (or equivalent name) with read-only permissions that does NOT include access to payment configuration"
},
{
"name": "OPERATOR role defined",
"max_score": 5,
"description": "rbac.ts defines an OPERATOR role (or equivalent) with permissions covering orders and inventory management"
},
{
"name": "ADMIN role defined",
"max_score": 5,
"description": "rbac.ts defines an ADMIN role with full/wildcard access including user management"
},
{
"name": "PAYMENT_ADMIN role defined",
"max_score": 5,
"description": "rbac.ts defines a PAYMENT_ADMIN role (or equivalent) with access to payment and refund operations but scoped away from general admin functions"
},
{
"name": "Auth failure logged",
"max_score": 10,
"description": "Middleware logs an authentication failure event (unauthenticated request) via audit logger before returning 401"
},
{
"name": "Access denied logged",
"max_score": 10,
"description": "Middleware logs an access-denied event (authenticated but unauthorised request) via audit logger before returning 403"
},
{
"name": "Password min length 12",
"max_score": 8,
"description": "Password policy object sets minimum length to 12 characters"
},
{
"name": "Password complexity all four",
"max_score": 8,
"description": "Password policy requires all four character classes: uppercase letters, lowercase letters, numbers, and special characters"
},
{
"name": "Password max age 90 days",
"max_score": 7,
"description": "Password policy sets maximum password age to 90 days"
},
{
"name": "Password history count 4",
"max_score": 7,
"description": "Password policy prevents reuse of the last 4 passwords"
},
{
"name": "Lockout after 6 attempts",
"max_score": 7,
"description": "Password policy sets account lockout after 6 failed authentication attempts"
},
{
"name": "Lockout duration 30 minutes",
"max_score": 7,
"description": "Password policy sets account lockout duration to 30 minutes"
},
{
"name": "MFA requirement documented",
"max_score": 8,
"description": "security-notes.md states that MFA is required for all admin access to the CDE (admin panel)"
},
{
"name": "Quarterly access review documented",
"max_score": 8,
"description": "security-notes.md describes the requirement to review and revoke user access on a quarterly basis"
}
]
}
Admin Panel Access Control for Vantage Store
Problem/Feature Description
Vantage Store is a growing e-commerce company preparing for their first PCI-DSS assessment. The engineering team has been asked to implement a proper access control system for the admin panel. Currently, all admin users have the same level of access, which is a red flag for the assessor. Different members of the team have different business roles: some only need to view orders, some manage inventory and fulfil orders, some are responsible for payment configuration, and a small group of superusers need unrestricted access for technical maintenance.
The assessor also flagged that the admin panel has no password policy at all — users can set any password and never change it. The assessor provided a specific list of password requirements that Vantage Store must meet. Additionally, given that the admin panel provides access to order information and payment configuration, the assessor noted that login to the admin panel must require more than just a password.
Output Specification
Produce the following files:
rbac.ts— A TypeScript module implementing role-based access control for the admin panel. It should define the set of admin roles and the permissions each role has. It should also include a middleware function that enforces authentication and authorisation on admin routes, logging both failed authentication and authorisation events via an audit logger instance.
password-policy.ts— A TypeScript module that exports a password policy configuration object and a function that validates a candidate password against that policy. Include a comment on each policy field explaining the compliance rationale.
security-notes.md— A short document listing the MFA requirement for admin access and the periodic access review obligation required by PCI-DSS, with a brief explanation of what is required for each.
{
"context": "Tests whether the agent correctly maps payment integration architectures to PCI SAQ types, applies the SAQ A preference for scope reduction, correctly distinguishes SAQ A from SAQ A-EP, and identifies the right number of controls for each SAQ type.",
"type": "weighted_checklist",
"checklist": [
{
"name": "SAQ D identification",
"max_score": 8,
"description": "Correctly identifies that Approach C (card data passes through own server) requires SAQ D"
},
{
"name": "SAQ D control count",
"max_score": 6,
"description": "States that SAQ D involves approximately 330 controls"
},
{
"name": "SAQ A identification",
"max_score": 8,
"description": "Correctly identifies that Approach A (fully hosted redirect / Stripe Checkout) qualifies for SAQ A"
},
{
"name": "SAQ A control count",
"max_score": 6,
"description": "States that SAQ A involves approximately 22 controls"
},
{
"name": "SAQ A-EP identification",
"max_score": 10,
"description": "Correctly identifies that Approach B (JS tokenization on your own page / Stripe Elements) requires SAQ A-EP, NOT SAQ A"
},
{
"name": "SAQ A-EP control count",
"max_score": 6,
"description": "States that SAQ A-EP involves approximately 191 controls"
},
{
"name": "Hosted redirect recommendation",
"max_score": 12,
"description": "Recommends Approach A (fully hosted payment page / Stripe Checkout) as the preferred option for scope reduction"
},
{
"name": "Scope reduction rationale",
"max_score": 10,
"description": "Explains that the key reason for recommending the hosted redirect is that card data never reaches ShopFast's servers"
},
{
"name": "Server-side code sketch",
"max_score": 10,
"description": "Code sketch uses stripe.checkout.sessions.create() (or equivalent hosted session API) and redirects the customer to the session URL"
},
{
"name": "Correct SAQ A scope description",
"max_score": 8,
"description": "Correctly describes the residual SAQ A controls (e.g. protecting the redirect link, not storing card data, maintaining the website environment) rather than overstating them"
},
{
"name": "SAQ A-EP not conflated with SAQ A",
"max_score": 8,
"description": "Document does NOT incorrectly claim that Stripe Elements (JS on your own page) qualifies for SAQ A"
},
{
"name": "Tokenization principle",
"max_score": 8,
"description": "Notes that using the recommended approach means card numbers are never stored, processed, or transmitted through ShopFast's systems"
}
]
}
Payment Compliance Scope Analysis for ShopFast
Problem/Feature Description
ShopFast is a mid-size online retailer that has been processing payments by passing card numbers through their own server to their payment gateway. Their compliance officer has just flagged that they are undergoing an acquisition due diligence process and the buyer is asking for a PCI-DSS compliance status report. The engineering team has been tasked with preparing a technical memo that outlines their current compliance posture and proposes a path to reduced compliance scope.
The team is evaluating three possible payment integration approaches, each with different implications for how card data flows through ShopFast's infrastructure. They want to understand what PCI SAQ (Self-Assessment Questionnaire) type each approach would qualify them for, and they want a concrete recommendation for which approach minimizes their ongoing compliance burden. The recommendation needs to include a rationale that a non-technical compliance officer can understand.
Output Specification
Produce a compliance analysis document named pci_scope_analysis.md that covers:
1. An evaluation of the following three payment integration patterns, with the SAQ type that applies to each and the approximate number of controls required:
- Approach A: Redirect customers to a fully hosted payment page provided by the processor (the processor hosts the entire payment form on their domain)
- Approach B: Embed a payment form built with the processor's JavaScript SDK directly on your checkout page (your page loads JS from the processor and it collects card details in an iframe)
- Approach C: Collect card numbers on your own form and POST them to your backend, which then calls the processor API
2. A clear recommendation for which approach ShopFast should adopt going forward, with reasoning.
3. A short code sketch (TypeScript or pseudocode is fine) showing how the recommended integration approach would be initialised at the server side.
4. A summary of what SAQ controls ShopFast would still need to satisfy under the recommended approach.
{
"name": "finsi/pci-dss-compliance",
"version": "0.1.0",
"summary": "PCI-DSS requirements mapping, SAQ selection, and implementation checklist",
"skills": {
"pci-dss-compliance": {
"path": "SKILL.md"
}
}
}