Writing
Complianceregulated

Your payment page just entered PCI scope — what a server-driven UI must not do

Since March 2025, PCI DSS 4.0 §6.4.3 and §11.6.1 require every payment-page script to be inventoried, justified, and tamper-monitored. Why a dynamic, eval-driven UI is squarely in scope — and how a versioned, no-eval contract gets you out of it.

On 31 March 2025 a set of PCI DSS 4.0 requirements stopped being “best practice” and became mandatory. Two of them — §6.4.3 and §11.6.1 — are about the scripts running on your payment page. If your checkout screen is driven from the server, they are about you, and most teams haven’t noticed yet.

What changed on 31 March 2025

The requirements exist because of Magecart-style skimming: attackers inject a few lines into a checkout page and quietly exfiltrate card data. So the standard now asks two things of every script on a payment page.

§6.4.3 — every script must be inventoried, carry a documented business justification, be explicitly authorized, and have its integrity assured on an ongoing basis. Including third-party scripts. §11.6.1 — you must run a change- and tamper-detection mechanism that alerts you to unauthorized changes to the payment page’s headers and script content, evaluated at least weekly.

Read together, they draw a hard line: the code on your payment page has to be known, justified, and watched. Code that appears at runtime — that no one reviewed, inventoried, or authorized — is exactly what these controls exist to catch.

Why a server-driven UI is squarely in scope

Server-driven UI is attractive for checkout precisely because you can change the screen without a frontend deploy. But “the screen can change without a deploy” is the same sentence an auditor reads as “the payment page can change without a review.” And if the UI layer evaluates expressions at runtime, you’ve added the other thing the standard flags: code generated from strings, in the browser, that wasn’t there when the page was inventoried.

A dynamic, eval-driven UI turns §6.4.3 into a moving target and §11.6.1 into a constant alert. You end up justifying and re-verifying a surface that shifts under you.

Make the screen a reviewable artifact

The fix isn’t to give up server-driven UI. It’s to make the screen a versioned artifact instead of a live, mutable payload. When the contract is a file in version control and carries no expression language, two problems disappear at once: there’s nothing generated from strings to inventory, and every change to the payment screen is a diff with an author and a reviewer.

git — checkout screen, change control
// the payment screen is a file, not a live payload
~ git log --oneline -- screens/checkout.contract.json
a1f4e2c feat(checkout): add saved-card selector  // reviewed, approved
9c07b13 fix(checkout): tighten billing address copy

“Prove this screen behaves the way it was approved” stops being a monitoring problem and becomes a diff you hand the auditor. It’s the difference between watching a server for drift and reading a commit.

The honest part

This doesn’t make you PCI compliant, and it isn’t your §11.6.1 monitoring — you still run tamper detection and own your CSP. What it removes is an entire category of the problem: a UI layer that generates code at runtime, and a payment screen that can change without a review. You can’t monitor your way out of those; you design them out, or you don’t.

Checkout is the page where the policy is strictest and the blast radius is largest. A contract that ships zero eval, renders on your own components, and changes only through a reviewable diff is the version of server-driven UI you can put in front of an auditor. The PCI DSS case, in depth