Skip to Content
Embedded Checkout

Embedded Checkout (white-label)

Embed Payylo’s group-payment flow directly in your own checkout — your brand, your domain. Your secret API key stays on your backend; the browser only ever holds a short-lived, group-scoped token.

There are two API-only ways to take a group payment without writing a card form:

  • Hosted checkout — create the group payment, redirect the payer to the returned checkout_url. Zero front-end work.
  • Embedded widget — mount the slot picker + card form inside your own page with the vanilla <script> loader (js.payylo.com/v1.js).

Both render the card form (Stripe Elements, Rede via Evervault, or Redsys hosted 3-D Secure) depending on the merchant’s connected provider.

Hosted checkout (simplest)

Create the group payment server-side and redirect the payer to checkout_url:

curl https://api.payylo.com/v1/group-payments \ -H "Authorization: Bearer $PAYYLO_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "group_name": "Flight SkyHop 123", "total_amount": 240.00, "currency": "EUR", "expires_at": "2026-06-22T18:00:00Z", "distribution": { "type": "equally", "number_of_slots": 3 } }' # → { "group_payment": { "id": "…" }, "checkout_url": "https://checkout.payylo.com/g/…" }

Redirect the customer to checkout_url. You’re notified of completion via webhooks (group_payment.paid, etc.).

How the embedded widget works

  1. Your backend creates the group payment via the REST API (secret key) and mints a group-scoped session token.
  2. The embedded component uses that token to read the group and take the payment.
  3. Capture and state transitions are driven server-side; you receive webhooks (group_payment.paid, etc.).

The secret key never reaches the browser. The session token can only read/pay its own group — never refund, never another group.

Backend session endpoint

Expose an endpoint on your server that (1) creates the group payment and (2) mints a session token, then returns the token to the browser. Both calls use your secret key:

# 1. Create the group payment (secret key, server-side) curl https://api.payylo.com/v1/group-payments \ -H "Authorization: Bearer $PAYYLO_SECRET_KEY" \ -H "Content-Type: application/json" \ -d '{ "group_name": "Flight SkyHop 123", "total_amount": 240.00, "currency": "EUR", "expires_at": "2026-06-22T18:00:00Z", "distribution": { "type": "equally", "number_of_slots": 3 } }' # → { "group_payment": { "id": "<group_payment_id>", … }, … } # 2. Mint a browser-safe, group-scoped session token for that group curl -X POST \ https://api.payylo.com/v1/group-payments/<group_payment_id>/session \ -H "Authorization: Bearer $PAYYLO_SECRET_KEY" # → { "token": "…", "group_payment_id": "…", "expires_in": 3600 }

Your endpoint (e.g. POST /api/payylo/session) should return { token, groupPaymentId } to the browser — that’s all the widget needs.

Exact request/response shapes for these and every other endpoint are in the interactive API Reference.

Vanilla JS (any site, no framework)

Load the script, then create and mount the widget programmatically. This is the recommended approach — same shape as Stripe/Adyen/PayPal: a factory with callbacks, and you control where/when it mounts.

<div id="payylo"></div> <script type="module" src="https://js.payylo.com/v1.js"></script> <script> const widget = Payylo.create({ createSession: () => fetch('/api/payylo/session', { method: 'POST' }).then(r => r.json()), payerEmail: 'user@example.com', theme: { accentColor: '#0ea5e9' }, onComplete: group => location.assign(`/booking/${group.id}/confirmed`), onError: err => console.error(err), }); const handle = widget.mount('#payylo'); // selector or HTMLElement // handle.unmount(); ← e.g. when closing a modal / leaving the page (SPAs) </script>

No-code shortcut (data attributes)

For landing pages or no-code setups, add data-payylo-group-pay to a container and it auto-mounts on load (only data-session-url is required):

<div data-payylo-group-pay data-session-url="/api/payylo/session" data-redirect-url="/booking/{id}/confirmed" ></div> <script type="module" src="https://js.payylo.com/v1.js"></script>

Completion and errors are emitted as DOM events on the container:

const el = document.querySelector('[data-payylo-group-pay]'); el.addEventListener('payylo:complete', e => console.log('paid', e.detail)); el.addEventListener('payylo:error', e => console.error(e.detail.message));

Payment methods

The card form rendered depends on the merchant’s active gateway:

ProviderIn-browser experience
StripeStripe Elements + 3-D Secure (confirmCardPayment)
RedeEvervault <Card> encrypts the PAN client-side (PCI SAQ-A)
RedsysSigned redirect to the bank’s hosted 3-D Secure page

Use the sandbox test cards to try each one.

Need another provider? Payylo’s gateway layer is built on a PSP-adapter pattern, so new providers can be onboarded on demand. If you need a specific gateway, contact us and we’ll confirm timelines.

Security model recap

Where it lives
Secret API key (sk_…)Your backend only
Session tokenThe browser (group-scoped, short-lived)
Card dataEncrypted client-side (Stripe/Evervault) or at the bank (Redsys)
The moneyThe merchant’s connected PSP account
Last updated on