Geen iframe. Geen scripts.

Een betaalknop die gewoon een anchor-tag is

Stripe Buy Button is een iframe. PayPal Buttons is een JavaScript-SDK. Snipcart is een runtime. Elke 'makkelijke' payment-embed van vandaag is een externe script die cookies, tracking en CSP-uitzonderingen meebrengt. Zo lever je een echte betaalknop zonder dat alles.

Payment button without an iframe
Hidden cost

Wat een iframe-betaalknop je kost

Een iframe-checkout embedden lijkt onschuldig — één <iframe> in je HTML en je bent klaar. De verborgen kosten komen later. De iframe trekt externe JavaScript binnen die op elke pagina met de knop draait. Die JavaScript zet cookies. Die cookies triggeren je GDPR-banner. De banner blokkeert rendering tot de gebruiker accepteert. De geaccepteerde scripts laden over het netwerk en verslechteren je Largest Contentful Paint. Je CSP moet expliciet de externe origins toelaten. Je security-team flagt het bij de volgende audit. Je bent twee minuten kwijt geweest aan een knop embedden en hebt daarmee een middag aan compliance-werk gekocht.

  • Iframes laden externe JavaScript die in jouw origin-context draait.
  • Externe scripts zetten cookies en triggeren GDPR-consent-banners.
  • CSP-regels vragen expliciete script-src en frame-src uitzonderingen.
  • Lighthouse straft render-blocking externe scripts af.
  • Subresource Integrity (SRI) is onpraktisch voor vendor-SDK's die wijzigen.
  • Security-audits flaggen elke externe script als supply-chain risico.
The fix

Hoe een script-vrije betaalknop eruitziet

PayRequest's Betaalknop bestaat uit twee dingen: een <link>-tag naar een CSS-bestand op PayRequest's CDN, en een <a>-anchor met een className. Geen <iframe>, geen <script>, geen inline JavaScript, geen popup-opener call, geen postMessage-handshake, geen externe cookies. De knop is HTML en CSS — dezelfde primitieven waarmee het web in 1995 begon. Klanten klikken; de browser navigeert naar je eigen checkout in een nieuw tabblad. Dat is de hele architectuur.

Nul externe JavaScript

Geen <script>-tags van PayRequest draaien op je pagina. Geen tracking-pixel, geen analytics-beacon, geen SDK-runtime.

Nul cookies vóór de klik

Tot een klant klikt, zet PayRequest geen cookies op je origin. GDPR-consent-banners blijven schoon.

CSP-vriendelijk by-design

Je script-src kan 'self' blijven. Je frame-src kan 'none' blijven. Het enige wat erbij komt is een style-src voor PayRequest's CSS-CDN — en dat is optioneel met hash-based CSP.

Lighthouse blijft groen

Geen render-blocking scripts. De stylesheet is klein (paar KB gzipped) en async-cacheable. Performance, Accessibility, Best Practices en SEO scores bewegen niet.

The network audit

Wat er daadwerkelijk laadt op je pagina

Vergelijk het netwerk- en security-profiel van populaire payment-embeds. De PayRequest-kolom is wat je DevTools Network-paneel toont als de knop rendert.

EmbedIframesExterne JSCookies vóór klikCSP-aanpassingenLighthouse-impact
Stripe Buy Button
1+Stripe.js (~90 KB)Jascript-src + frame-srcRender-blocking script
PayPal Smart Buttons SDK
1+ bij klikPayPal SDK (~150 KB)Jascript-src + frame-srcZware main-thread cost
Snipcart
0Snipcart runtime (~120 KB)Jascript-src + style-srcRuntime hydration
Lemon Squeezy overlay
1 (lazy)Lemon.jsJascript-src + frame-srcLazy maar meetbaar
PayRequest BetaalknopBest
00 KBGeenalleen style-src (optioneel)Geen
CSP diff

Je CSP, voor en na

De meeste teams botsen op Content-Security-Policy op het moment dat ze beseffen dat hun payment-embed invasiever is dan verwacht. Dit is hoe het beleid verandert als je een iframe-knop wisselt voor de PayRequest-anchor.

Met Stripe Buy Button
script-src 'self' https://js.stripe.com;
frame-src https://js.stripe.com https://hooks.stripe.com;
connect-src 'self' https://api.stripe.com https://maps.googleapis.com;
Drie directives hebben expliciete uitzonderingen nodig. script-src is de security-team blocker.
Met PayPal SDK
script-src 'self' https://www.paypal.com https://www.paypalobjects.com;
frame-src https://www.paypal.com;
connect-src 'self' https://www.paypal.com;
Vergelijkbaar met Stripe — drie directives, allemaal extern.
Met PayRequest Betaalknop
style-src 'self' https://payrequest.app;
/* Geen script-src wijzigingen. Geen frame-src wijzigingen. */
Alleen style-src verandert — en alleen omdat de stylesheet op een CDN staat. Inline-host de CSS en zelfs dat is niet nodig.
GDPR

GDPR-consent: niets om te vragen

GDPR/ePrivacy-consent-banners bestaan omdat de meeste analytics- en embed-scripts tracking-cookies droppen vóór de gebruiker akkoord is. PayRequest's knop dropt geen cookies op je pagina tot de klant klikt (en op dat moment navigeert hij naar PayRequest's domein, waar PayRequest's eigen cookiebeleid geldt). Op jouw origin is de knop functioneel niet te onderscheiden van een gewone hyperlink — en gewone hyperlinks hebben geen consent nodig.

  • Geen analytics, geen marketing-tags, geen remarketing-pixels van PayRequest.
  • Consent-banners kunnen hun standaard 'reject all'-gedrag behouden zonder de knop te breken.
  • Je DPA-scope krimpt: de externe verwerker (PayPal/Stripe/Mollie via PayRequest) komt pas na de klik in beeld, op PayRequest's domein.
  • ePrivacy 'cookie wall'-regels zijn niet van toepassing omdat geen cookies pre-klik worden gezet.
Lighthouse

Lighthouse, in de praktijk

Bytes die je niet verstuurt zijn de snelste bytes. De volledige integratie van de Betaalknop is ~3KB CSS over het netwerk en 0KB JavaScript. Hieronder wat we typisch zien op de pagina van een PayRequest-klant die een Stripe Buy Button vervangt door een PayRequest-anchor.

Lighthouse-metricMet Stripe Buy ButtonMet PayRequest-knopVerandering
Performance-score7894+16
Largest Contentful Paint2,4s1,6s-0,8s
Total Blocking Time320ms40ms-280ms
JS-payload~110 KB0 KB-110 KB
Externe requests8–121 (CSS)-7 tot -11

Cijfers zijn typisch, geen belofte — je baseline hangt af van de rest van je stack. De richting telt.

Walkthrough

Hoe je een script-vrije betaalknop levert

01

Maak een Smart Link in PayRequest

Log in → Betaalpagina → Smart Links → Nieuw. Stel het bedrag in, kies methodes. Kopieer de URL.

30 sec
02

Voeg de stylesheet toe aan je <head>

Plak <link rel="stylesheet" href="https://payrequest.app/embed/button.css" />. Als je CSP externe CDN's verbiedt, kopieer je het CSS-bestand naar je eigen statische assets en self-host het.

10 sec
03

Plaats de anchor waar de CTA hoort

<a class="pr-btn pr-btn--default" href="..." target="_blank" rel="noopener">Betaal</a>. Dat is de hele HTML — geen <script>, geen <iframe>, geen <noscript>-fallback om te schrijven.

10 sec
04

Verifieer in DevTools

Open Network → herlaad. De enige PayRequest-request die je zou moeten zien is het CSS-bestand. Geen fetch, geen XHR, geen eval, geen postMessage. Je security-team gaat dit waarderen.

30 sec
05

Audit en lever

Draai Lighthouse op de pagina. Vergelijk met de vorige snapshot. Update je CSP om de iframe/script-uitzonderingen voor de oude vendor te verwijderen. Klaar.

5 min
Who needs this

Wie een script-vrije betaalknop nodig heeft

Statische blogs en marketingsites

Hugo, Jekyll, Astro en 11ty sites die er trots op zijn nul JavaScript te leveren. De Betaalknop houdt dat zo.

Privacy-first producten en EU-SaaS

Bedrijven met 'geen externe trackers' in hun positionering kunnen dat niet ongedaan maken met een payment-iframe.

Lighthouse-perfecte landingspagina's

Marketingteams die Core Web Vitals jagen, willen geen payment-SDK die 200ms TBT kost.

Interne tools achter strikte CSP

Enterprise admin-dashboards met dichtgetimmerde CSP die geen script-src uitzonderingen voor vendor-SDK's mogen toevoegen.

FAQ

Veelgestelde vragen

Is de Betaalknop echt een anchor-tag, geen verborgen iframe?+
Ja. View source op elke PayRequest-knop en je ziet <a href="..." class="pr-btn ...">. Er is geen JavaScript die hem runtime omwisselt voor een iframe, geen postMessage-handshake, geen shadow DOM. Het is een gewone hyperlink die toevallig als knop is gestyled.
Betekent dat dat de checkout zelf op PayRequest's domein draait?+
Ja — en dat is het hele punt. De klant klikt, de browser navigeert naar payrequest.me/jouwhandle/... in een nieuw tabblad, en de checkout draait daar. PayPal/Stripe-SDK's doen het omgekeerde: zij draaien vendor-code op jouw domein. PayRequest draait PayRequest-code op PayRequest's domein. Jouw domein blijft schoon.
Kan ik de stylesheet self-hosten om zelfs de style-src CDN-uitzondering te vermijden?+
Ja. Download het CSS-bestand van https://payrequest.app/embed/button.css en serveer het vanuit je eigen statische assets. Pas de <link rel="stylesheet"> href aan. Je CSP heeft geen externe entry meer nodig.
Scoort Lighthouse echt beter alleen door één iframe weg te halen?+
Op de meeste sites: ja. De grootste winst komt van het verwijderen van de externe JavaScript-bundle (Stripe.js ~90KB, PayPal SDK ~150KB, Snipcart ~120KB) en de network round-trips daaromheen. Total Blocking Time, LCP en Performance-score verbeteren als die bytes het kritieke pad verlaten.
Hoe zit het met analytics en conversie-tracking — heb ik daar geen script voor nodig?+
Nee. PayRequest tracket elke Smart Link-klik en conversie server-side en toont ze in je dashboard. Voor attributie aan een specifieke pagina voeg je een query-string toe (?source=prijs) en PayRequest groepeert conversies per parameter. Geen client-side analytics nodig.
Werkt dit met strict-CSP (met nonce of hash)?+
Ja. Omdat er geen inline scripts en geen externe scripts zijn, werkt strict-CSP met nonces of hashes zonder uitzonderingen. De knop is een van de zeldzame integraties die niet vecht met strict CSP.
Script-free payments

Lever betalingen zonder een runtime te leveren

Maak een account, maak een Smart Link, voeg twee regels HTML toe. Geen iframe, geen SDK, geen GDPR-banner-update, geen CSP-uitzondering. Gewoon een knop die werkt.