Once you have listed the scripts on your checkout, the next question is which ones should be there at all. Requirement 6.4.3 asks you to justify each one in writing, and the cheapest way to answer a hard question is to remove the script instead. This page goes through the categories we actually see on payment pages, what each one is doing, and whether it earns its place next to a card field. Removing a script is usually a better answer than justifying it.

Start from the right question

Not "is this script dangerous", which nobody can answer about a file that changes weekly. The question is "what does this script get if it turns hostile tomorrow". On a checkout the answer is always the same. It can read every field on the page, watch every keystroke, move or cover the payment frame, and send what it collects anywhere. Every script on the page has that power, regardless of what it was put there to do, because that is what JavaScript on a page can do. So the question becomes whether the business value is worth handing that capability to one more supplier. Framed that way, a surprising number of tags come off the page in about ten minutes.

Your payment provider's script: keep it

This is the one script that unambiguously belongs. Stripe.js, Authorize.net's Accept.js, Braintree, PayPal and the rest render the card field and send the card details straight to the processor, which is the reason the number never touches your own server. Removing it does not make the page safer, it makes the page not work, and it usually moves you into a stricter SAQ. Load it directly from the vendor rather than through a tag manager, keep it on the page it is needed on, and write the obvious justification. One thing to know: these libraries are updated by their vendors, so an integrity hash is not an option on them, for the reasons in our guide to script integrity on payment pages.

Your own checkout code: keep it, and know where it comes from

Card formatting, expiry validation, the address lookup, the "same as billing" checkbox. This is code you wrote and deploy, and it belongs on the page. The useful discipline here is different from the third-party case: because it is yours, a change to it is either a deploy you made or a compromise, and there is no third possibility. So a first-party script whose contents change without a release behind it is worth treating as an incident and not as noise. If you build with content hashes in the filename, hash these with Subresource Integrity, because the URLs are immutable by construction.

Tag managers: the biggest single decision on the page

One line of HTML brings in the container. Twenty more scripts can be running by the time the page finishes loading, and none of them appear in your source. A tag manager is also the most common way a payment page acquires a script nobody at the company can explain. Publishing a container is a marketing action rather than a deployment, and the people who can do it are often not the people anybody would ask about a checkout. Google Tag Manager lets you scope triggers, so firing the marketing tags on every page except the checkout is usually a short change and it removes the problem rather than managing it. If the container does need to be on the checkout, then who can publish a container version becomes a real access control question. The answer should be a short list of people you would trust with a card form.

Analytics and advertising tags: usually the first to go

Google Analytics, Google Ads conversion tags, the Meta pixel, Microsoft Ads, LinkedIn Insight, TikTok, Pinterest, X. These are on checkouts for a real reason, which is that conversion is the event marketing most wants to measure, and that reason is worth taking seriously rather than dismissing. But you can usually get the conversion without the tag sitting on the page where the card is typed. Fire it on the thank-you page after the order completes, or move conversion measurement server-side. Both give you the number and neither puts an ad platform's script next to a card field. Where a tag genuinely has to stay, it needs a real justification with a name and a date on it. "Analytics" is not a justification. "Google Ads conversion tag, needed to attribute paid search spend, approved by the marketing lead in March, scoped to fire only on order completion" is one.

Session recorders and heatmaps: look at these hardest

Hotjar, Microsoft Clarity, FullStory and similar tools work by recording what happens in the browser, including what people type. They mask input fields by default and the vendors take that seriously. But the masking is configuration, and configuration can be changed by somebody who does not know what page they are changing it on. A session recorder on a checkout is one setting away from being a recording of card entry. That recording then lives in a third party's system that was never scoped as a cardholder data environment. There is nothing wrong with these products. They belong on your product pages and your funnel, not on the page with the card field.

Chat widgets and support tools: move them off

Intercom, Zendesk, HubSpot and the rest. The argument for having chat on a checkout is that people abandon carts when they have a question, and that is a genuine argument. The argument against is that a chat widget is a large third-party script with a lot of moving parts, and it renders its own UI over your page. A compromised one can render whatever it likes over your card form. If the business needs chat at the point of purchase, the compromise most merchants land on is chat everywhere up to the checkout, with the checkout itself clean. Whatever you decide, decide it deliberately and write it down.

Consent managers and cookie banners: keep, and check what they load

Cookiebot, OneTrust and similar tools usually have to be on every page, including the checkout, because that is what consent management means. Keep them, and watch the second-order effect. A consent manager's job is to load other scripts once consent is given, so it can be the route by which a tag arrives on your checkout without anybody adding it there. If your inventory lists the consent manager and stops, it describes one script and misses whatever the consent manager brings with it.

CAPTCHA and bot protection: keep

reCAPTCHA, hCaptcha and Cloudflare Turnstile are on checkouts to stop card testing, which is a real and current attack on payment pages. They belong there and the justification writes itself. Same note as the payment provider libraries: these are vendor-maintained scripts that update themselves, so plan for a Content Security Policy rather than an integrity hash.

Package CDNs: keep if pinned, and watch them differently

jQuery, a date picker, a card formatting helper, anything pulled from cdnjs, jsDelivr or unpkg. These are fine to keep and they are the best case for Subresource Integrity, because the version is in the URL and the file at that URL never changes. That also makes them the clearest signal there is. A package CDN serving different bytes under an unchanged versioned URL is not a vendor shipping a release. It is something you want to know about immediately. So these are the scripts where you should not accept routine changes to the body, unlike the vendor tags that legitimately update themselves. Better still, self-host the pinned copy. A file you build into your own deploy is one fewer supplier on the page.

Fonts, icons, and things that look harmless

A font loader or an icon set feels like it could not possibly matter, and that intuition is the reason it is worth a mention. A script tag is a script tag: the browser does not grade it by what the vendor's product page says it does. If a font service is loading JavaScript rather than a stylesheet on your checkout, it has the same capabilities as everything else on this page. Most font and icon needs can be met with a stylesheet or a self-hosted file, and that is a straightforward removal.

Anything you cannot identify

Every inventory has one, and it is the important row. A script from a host nobody recognizes, loaded by something else, from a vendor relationship that ended two years ago. Do not quietly leave it off the list because you cannot explain it. Write it down as it stands, with "not justified yet, origin unknown" as the reason, and then find out. Recording an open question is what an inventory is for. Leaving out the script nobody can explain is what fails an assessment, and it is also what hides a skimmer.

A working order for the cleanup

List what actually loads, using a real browser on the real checkout rather than a staging copy. Sort it by who controls each script, because the ones on somebody else's domain are the ones you cannot change. Remove everything the business can live without on that one page, which is usually the advertising tags, the session recorder and the chat widget. Pin and hash what is left with a stable URL. Put a Content Security Policy in front of the page for everything else. Write the justification for each script that stays, with a name and a date. Then watch the page, because the list you just built starts going out of date the moment somebody publishes a tag manager container.

Where to start

Our free payment page check reads your checkout once and lists the scripts written into its HTML. It shows which come from a domain other than yours and which carry an integrity attribute. No sign-up, and nothing is published. It reads the page source, so it will not show you what a tag manager adds at runtime. That makes it the floor of your inventory rather than the total. If you would rather have the page watched than checked once, our payment page monitoring loads it in a real browser every day, dates every script it finds, and holds your justifications against them.