Skip to content

Show the elements

One script, one root element, the components you compose inside it — and the single event that tells your page where to go next.

This is the browser half, and it is shorter than you might expect: load one script, compose the components where you want them, hand them the token your server obtained. The checkout runs itself from there.

<!doctype html>
<html lang="fr">
<body>
<payplug-session base-url="https://pay.example.com" elements-token="the token your server created">
<payplug-confirmation></payplug-confirmation>
<payplug-expired></payplug-expired>
<payplug-abort></payplug-abort>
<payplug-processing></payplug-processing>
<payplug-payment-methods></payplug-payment-methods>
<payplug-progress></payplug-progress>
</payplug-session>
<script type="module" src="https://cdn.example.com/payplug/payplug-elements.js"></script>
</body>
</html>

That is the whole integration. The split flow, the refusals, the abandon path, the waiting screen and the ending all come from the components — your page decides where things sit, and where your customer goes next.

One tag, served from our CDN:

<script type="module" src="https://cdn.example.com/payplug/payplug-elements.js"></script>

Nothing else to include: the script brings everything the components need.

Everything lives inside a single <payplug-session>. It renders nothing itself — it is the context the other components attach to:

<payplug-session
base-url="https://pay.example.com"
elements-token="the token your server created"
locale="fr"
partial-payment
individual-cancel
>
<!-- your components, in the order and the wrappers you choose -->
</payplug-session>

Two attributes are the whole wiring, and a server-rendered page prints them: base-url, where this platform answers, and elements-token, the session your server created. No JavaScript at all.

Attribute Effect
base-url Where this platform answers. With elements-token, it is the whole wiring.
elements-token The session your server created. Refresh it and the elements follow; both are needed before anything is fetched.
locale Language and amount formats — the 24 official EU languages plus Catalan. Absent, the browser’s language applies. Changing it re-renders the texts.
color-scheme dark or light to force one; absent, the customer’s OS preference decides.
theme URL of your token-override stylesheet — see styling.
partial-payment Lets your customer pay part of the total (the split flow).
individual-cancel Lets your customer cancel one authorized tranche.

Nothing renders until the first state arrives — no skeletons, no flash of empty boxes.

Each one watches the session and shows or hides itself; you never orchestrate visibility. All of them are technically optional, and a complete checkout composes them all.

Component Shows
<payplug-payment-methods> The methods list, and the form of the one your customer picks — it injects that form itself, so your page cannot fall out of step.
<payplug-cards>, <payplug-paypal>, <payplug-wero> A single method’s form. Compose one directly only when you do not compose the list above.
<payplug-processing> The waiting screen while a verdict is pending. Without it, that window shows nothing.
<payplug-progress> The authorized/remaining meter, the tranches, and the per-tranche cancel.
<payplug-abort> The way out once money is held, its confirmation dialog, and the “payment abandoned” screen.
<payplug-expired> The “session expired” screen. Sessions do expire — compose it.
<payplug-confirmation> The final “order confirmed” screen, with the recap of what was charged.
<payplug-cart> The order summary. Stays visible while everything else steps aside.

The full contract of each — attributes, properties, events — is in the component reference.

  • Order and wrappers: these are ordinary block elements in light DOM. Put them in your grid, your columns, your accordion.
  • Isolation goes both ways: your resets do not leak in, their styles do not leak out. The only styling inputs are the --payplug-* tokens — see styling.
  • The panel chrome is yours: the final screens style their content and deliberately leave the border, radius and padding around them to you.
  • Keep every component inside its <payplug-session>: they attach to the closest one.

The session emits a single DOM event, payplug:statuschange, on every status change — the first delivered state included, so a page mounting over an already-settled session can route straight away:

import type { StatusChangeDetail } from "@payplug/elements";
session.addEventListener("payplug:statuschange", (event) => {
const { status } = (event as CustomEvent<StatusChangeDetail>).detail;
if (status === "PAID") location.assign("/order/confirmed");
if (status === "ABORTED" || status === "EXPIRED") location.assign("/cart");
});

The final screens carry no “back to the shop” button on purpose: where your customer goes next is your decision, and this event is how you make it. The statuses are PENDING, CAPTURING, PAID, ABORTING, ABORTED, EXPIRING, EXPIRED, AWAITING and AWAITED_REFUSED — the terminal ones being PAID, ABORTED, EXPIRED and AWAITED_REFUSED.

AWAITING deserves a word: it is deferred financing under review, possibly for days. There is nothing to route yet — the components show their own waiting screen, and the ending reaches your server through the webhook.