DEV Community

Mortal
Mortal

Posted on

What your checkout page actually loads — and why it decides your PCI scope

If you take card payments through Stripe, Braintree, Adyen or Shopify Payments, your PCI obligations depend on one question that nobody explains clearly: does card data ever touch your page, or only the provider's iframe?

Get it right and you are on SAQ A — roughly twenty questions about policies and third parties. Get it wrong and you are on SAQ A-EP or SAQ D — a much longer questionnaire, plus scans and evidence you probably do not have.

The awkward part is that the answer is not in your code review. It is in what the checkout page loads at runtime: a script injected by an A/B testing tool can put a card field in your DOM without anyone on your team writing input[name="cardnumber"].

So I wrote a small extension that reads the page and reports what is there: payment iframes, third-party origins, and any card fields sitting directly on the page. It runs entirely in the tab — no network calls, no storage, no telemetry.

What it reports:

  • SAQ A likely — a known provider iframe (Stripe, Braintree, Adyen, Shopify Payments, PayPal, …) is present and no direct card inputs were found.
  • SAQ D / A-EP likely — card number / CVV / expiry inputs appear directly on the page.
  • Inconclusive — custom checkout, shadow DOM, or a page it cannot classify.

It also flags missing HTTPS, mixed content, and multiple live providers.

PCI Scope Lens popup showing

Listing image

Install (manual load, unpacked, v0.1.2): https://github.com/mortal7520/pci-scope-lens/releases/tag/v0.1.2

Source: https://github.com/mortal7520/pci-scope-lens

Prefer not to install anything? There is a plain 10-question checklist: https://mortal7520.github.io/pci-scope-lens/checklist.html

I built it, so treat this as a tool announcement with a long explanation attached. If your checkout comes back "inconclusive", that is the interesting case — tell me what it loaded.

Top comments (0)