Embedded Checkout
Embed the RoxPay checkout directly in your application using an iframe.
By default, payment links redirect customers to a RoxPay-hosted checkout page. With embedded checkout, you can render the checkout inside an iframe within your own application for a seamless experience.
For the recommended integration (iframe helpers, Apple Pay bridge, typed callbacks), use the Checkout SDK public script instead of wiring postMessage by hand.
Enabling Embedded Mode
Set Type to "embedded" when creating a payment link:
curl -X POST https://app.roxpay.eu/api/v4/payments/link \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Purpose": "Order #12345",
"Amount": 2999,
"Type": "embedded",
"SuccessRedirectUrl": "https://yourshop.com/success",
"FailureRedirectUrl": "https://yourshop.com/failure",
"CancelRedirectUrl": "https://yourshop.com/cancel"
}'
The response PaymentUrl will point to an embeddable checkout page.
Embedding in Your App
<iframe
src="PAYMENT_URL"
width="100%"
height="600"
frameborder="0"
allow="payment"
></iframe>
React Example
function EmbeddedCheckout({ paymentUrl }: { paymentUrl: string }) {
return (
<div className="checkout-container">
<iframe
src={paymentUrl}
style={{ width: '100%', height: 600, border: 'none' }}
allow="payment"
title="RoxPay Checkout"
/>
</div>
);
}
Handling Completion
When the customer completes (or cancels) the payment in the embedded iframe, they are redirected to your configured redirect URLs inside the iframe. To break out of the iframe:
Option 1: Listen for redirect in the iframe
Configure your success/failure pages to send a postMessage to the parent window:
// On your success page (loaded inside the iframe)
window.parent.postMessage(
{ type: 'roxpay-payment-complete', status: 'success' },
'https://yourshop.com'
);
// In your parent app
window.addEventListener('message', (event) => {
if (event.origin !== 'https://yourshop.com') return;
if (event.data.type === 'roxpay-payment-complete') {
// Update UI, show confirmation, etc.
}
});
Option 2: Use webhooks
Rely on webhooks for the authoritative payment result, and use the redirect only for UX:
// Poll or wait for webhook confirmation
const { status } = await checkTransactionStatus(transactionId);
if (status === 'SETTLED') {
showConfirmation();
}
Standard vs Embedded
| Feature | Standard | Embedded |
|---|---|---|
| Customer leaves your site | Yes (redirect) | No (iframe) |
| Implementation complexity | Low | Medium |
| Custom styling | Limited (via custom_css metadata) | Full control of surrounding page |
| 3D Secure | Handled by RoxPay | Handled within iframe |
| Mobile experience | Native redirect | Responsive iframe |
Constraints
Type: "embedded"works with card, SEPA, Pay by Bank, and redirect rails (klarna,paypal,ideal,bancontact). Pay by Bank and redirect methods open the bank/issuer flow in the top window (window.top) when embedded in an iframe — the Checkout SDK iframe usesallow-top-navigation-by-user-activationfor this. Card and SEPA stay inside the iframe.- Embedded with
PaymentMethods: ["klarna"]or["paypal"]renders a single-rail checkout; mixed["card","klarna","paypal"]shows a chooser inside the iframe (same as hosted, now supported viaCheckoutPaymentMethodList). - The iframe must be served over HTTPS and set
allow="payment"for Apple Pay / Google Pay (the Checkout SDK does this by default). - Some browsers may block third-party cookies in iframes — RoxPay handles this gracefully
- Recommended minimum iframe height: 500px (720px for card + wallet buttons)
Prefer the Checkout SDK
Mounting a raw iframe works, but the Checkout SDK sets allow="payment", handles Apple Pay parent fallback, and maps iframe events to onSuccess / onError. Prefer it for new integrations.