Iframe Payments (Iframe SDK)
Iframe mode allows you to embed a card payment form (manual entry) and Apple Pay / Google Pay buttons directly on your page - without redirecting to an external payment gateway.
Advantages:
- No redirect - the customer never leaves your page
- Full UX control - form/button embedded in your layout
- Just a few lines of code - quick integration via JavaScript SDK
- Security - card data encrypted with RSA on the iframe side, merchant never touches card data
Integration via iframe does not require PCI DSS certification - card data is entered and encrypted exclusively on the dpay iframe side and never reaches your server. If you need full control over the form and process card data on your side, see Server-to-Server (S2S) integration - this option requires PCI DSS certification.
Supported methods
| Method | Description | method value |
|---|---|---|
| Card (manual entry) | Form with fields: card number, expiry date, CVC | CARD |
| Apple Pay | Apple Pay button | APPLE_PAY |
| Google Pay | Google Pay button | GOOGLE_PAY |
Flow diagram
Quick start
Step 1: Register the payment
Register the transaction using the standard API:
curl -X POST https://api-payments.dpay.pl/api/v1_0/payments/register \
-H "Content-Type: application/json" \
-d '{
"transactionType": "transfers",
"service": "abc123",
"value": "49.99",
"url_success": "https://myshop.com/success",
"url_fail": "https://myshop.com/error",
"url_ipn": "https://myshop.com/api/ipn",
"checksum": "..."
}'
Save the transactionId from the response.
Step 2: Add the SDK to your page
<script src="https://gateway.dpay.pl/sdk/dpay-iframe-sdk.js"></script>
For the test environment use: https://gateway.snd.dpay.pl/sdk/dpay-iframe-sdk.js
Step 3: Check method availability (optional)
For Apple Pay and Google Pay, it is worth checking whether the given method is available on the customer's device:
if (DPayIframeSDK.isApplePayAvailable()) {
// Show Apple Pay button
}
if (DPayIframeSDK.isGooglePayAvailable()) {
// Show Google Pay button
}
Apple Pay availability:
- iOS, macOS, Windows, Linux - available
- Android - not available
Google Pay availability:
- Android, Desktop, iOS (Chrome/Edge) - available
- iOS Safari - not available
Step 4: Initialize the SDK
const sdk = new DPayIframeSDK({
transactionId: 'your-transaction-id',
method: 'CARD', // or 'APPLE_PAY', 'GOOGLE_PAY'
containerId: 'payment-container',
onIframeReady: (data) => {
console.log('Iframe ready', data);
},
onPaymentSuccess: (data) => {
console.log('Payment successful!', data);
window.location.href = '/success';
},
onPaymentError: (data) => {
console.error('Payment error:', data.error);
},
});
sdk.init();
SDK configuration
Required parameters
| Parameter | Type | Description |
|---|---|---|
transactionId | string | Transaction UUID from Step 1 |
method | string | Payment method: CARD, APPLE_PAY or GOOGLE_PAY |
containerId or container | string / HTMLElement | DOM element ID or element reference where the iframe will be embedded |
Optional parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
locale | string | 'pl' | Form language |
environment | string | 'production' | Environment: 'production' or 'sandbox' |
baseUrl | string | automatic | Gateway base URL (set automatically based on environment) |
iframeStyles | object | {} | Custom CSS styles for the iframe |
timeout | number | 300000 | Timeout in milliseconds (default 5 min) |
debug | boolean | false | Debug logging in the browser console |
autoResize | boolean | true | Automatic iframe height adjustment to content |
CARD-specific parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
threeDsMode | string | 'iframe' | 3D Secure mode: 'iframe' (within frame) or 'redirect' (redirect) |
firstName | string | '' | Cardholder first name (pre-fill) |
lastName | string | '' | Cardholder last name (pre-fill) |
email | string | '' | Cardholder email (pre-fill) |
Callbacks
| Callback | Parameters | Description |
|---|---|---|
onIframeReady | { transactionId, method } | Iframe loaded and ready |
onPaymentStarted | { transactionId, method } | User started the payment |
onPaymentSuccess | { transactionId, status } | Payment completed successfully |
onPaymentError | { transactionId, error, code? } | Payment error |
onPaymentCancelled | { transactionId } | User cancelled the payment |
on3dsRedirect | { ... } | 3D Secure redirect (CARD with threeDsMode: 'redirect' only) |
onIframeReady | { transactionId, method } | Iframe ready for use |
onIframeError | { error } | Iframe loading error |
onIframeResize | { height } | Iframe resize (handled automatically when autoResize: true) |
SDK methods
init()
Initializes the SDK, creates the iframe and renders the form/button in the container.
sdk.init();
destroy()
Removes the iframe and cleans up event listeners. Call when unmounting the component.
sdk.destroy();
reload()
Reloads the iframe (e.g. after a configuration change).
sdk.reload();
getStatus()
Returns the current SDK status.
const status = sdk.getStatus();
// {
// status: 'idle' | 'loading' | 'ready' | 'processing' | 'success' | 'error',
// isInitialized: boolean,
// transactionId: string,
// method: string
// }
sendMessage(message)
Sends a message to the iframe via postMessage.
sdk.sendMessage({ type: 'custom:action', data: { ... } });
Events (postMessage)
The SDK communicates with the iframe via window.postMessage. Events are handled automatically and forwarded to the appropriate callbacks.
| Event type | Callback | Description |
|---|---|---|
iframe:ready | onIframeReady | Iframe loaded and ready |
iframe:resize | onIframeResize | Iframe content size changed |
iframe:error | onIframeError | Iframe error |
payment:started | onPaymentStarted | Payment started |
payment:success | onPaymentSuccess | Payment successful |
payment:error | onPaymentError | Payment error |
payment:cancelled | onPaymentCancelled | Payment cancelled |
payment:3ds-redirect | on3dsRedirect | 3DS redirect |
Integration examples
- Vanilla JS
- React
- Vue
<!DOCTYPE html>
<html>
<head>
<title>Payment</title>
</head>
<body>
<div id="payment-container"></div>
<script src="https://gateway.dpay.pl/sdk/dpay-iframe-sdk.js"></script>
<script>
const sdk = new DPayIframeSDK({
transactionId: 'abc-123-def',
method: 'CARD',
containerId: 'payment-container',
onPaymentSuccess: (data) => {
window.location.href = '/success';
},
onPaymentError: (data) => {
alert('Payment error: ' + data.error);
},
});
sdk.init();
</script>
</body>
</html>
import { useEffect, useRef } from 'react';
function PaymentIframe({ transactionId, method = 'CARD' }) {
const containerRef = useRef(null);
const sdkRef = useRef(null);
useEffect(() => {
const sdk = new window.DPayIframeSDK({
transactionId,
method,
container: containerRef.current,
onPaymentSuccess: (data) => {
console.log('Payment successful:', data);
},
onPaymentError: (data) => {
console.error('Error:', data.error);
},
});
sdk.init();
sdkRef.current = sdk;
return () => sdk.destroy();
}, [transactionId, method]);
return <div ref={containerRef} />;
}
<template>
<div ref="paymentContainer"></div>
</template>
<script>
export default {
props: ['transactionId', 'method'],
mounted() {
this.sdk = new window.DPayIframeSDK({
transactionId: this.transactionId,
method: this.method || 'CARD',
container: this.$refs.paymentContainer,
onPaymentSuccess: (data) => {
this.$emit('success', data);
},
onPaymentError: (data) => {
this.$emit('error', data);
},
});
this.sdk.init();
},
beforeUnmount() {
this.sdk?.destroy();
},
};
</script>
CARD integration (manual entry)
The CARD method displays a full card payment form in the iframe. The form collects:
- Cardholder first and last name
- Email address
- Card number
- Expiry date
- CVC/CVV code
Card data is RSA-encrypted on the iframe side - your page never has access to raw card data. You do not need PCI DSS certification.
Pre-filling cardholder data
You can pre-fill cardholder data if you already have it (e.g. from the order process):
const sdk = new DPayIframeSDK({
transactionId: 'abc-123-def',
method: 'CARD',
containerId: 'payment-container',
firstName: 'Jan',
lastName: 'Kowalski',
email: 'jan@example.com',
onPaymentSuccess: (data) => {
window.location.href = '/success';
},
});
sdk.init();
3D Secure handling
The threeDsMode parameter controls how 3D Secure verification is handled:
'iframe'(default) - 3DS verification takes place inside the iframe, the customer does not leave the page'redirect'- the customer is redirected to the bank's page, then returns tourl_success/url_fail
const sdk = new DPayIframeSDK({
transactionId: 'abc-123-def',
method: 'CARD',
containerId: 'payment-container',
threeDsMode: 'iframe', // or 'redirect'
on3dsRedirect: (data) => {
// Called only with threeDsMode: 'redirect'
console.log('3DS redirect:', data);
},
onPaymentSuccess: (data) => {
window.location.href = '/success';
},
});
sdk.init();
Security
Content Security Policy (CSP)
Add the dpay gateway domain to the frame-src directive:
<meta http-equiv="Content-Security-Policy"
content="frame-src https://gateway.dpay.pl https://gateway.snd.dpay.pl;">
HTTPS
The Iframe SDK requires your page to run on HTTPS. Apple Pay and Google Pay do not work on HTTP pages.
Iframe sandbox attributes
The SDK automatically sets iframe security attributes:
sandbox="allow-scripts allow-same-origin allow-forms allow-popups"
allow="payment"
Origin validation
The SDK automatically validates the origin of postMessage messages to prevent unauthorized scripts from intercepting the communication.
Troubleshooting
Iframe does not load
- Check CSP headers -
frame-srcmust include the dpay gateway domain - Verify
baseUrl/environmentin the SDK configuration - Check the Network tab in DevTools
Apple Pay / Google Pay button does not appear
- Use
DPayIframeSDK.isApplePayAvailable()/isGooglePayAvailable()to check availability on the given device - Verify that the transaction has the appropriate payment channel
- Enable
debug: trueand check the browser console
Payment does not start
- Make sure your page runs on HTTPS
- Verify that
transactionIdis valid and the transaction has not expired - Use the
onIframeErrorcallback for diagnostics
CARD form does not display correctly
- Verify that the container has sufficient width (min. 320px)
- With
autoResize: false, manually set the iframe height (min. 580px for the CARD form) - Do not set
overflow: hiddenon the container - it may clip 3DS modal windows