> ## Documentation Index
> Fetch the complete documentation index at: https://docs.payviox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Iframe integration

> Embed the Payviox payment form directly in your page using an iframe. Requires domain whitelisting. Configure width, height, border, transparency via iframeConfig. Handles payviox:redirect and payviox:close postMessage events for provider redirects and iframe dismissal. Includes standalone integration example without SDK.

## Overview

Iframe mode allows you to embed the Payviox payment flow directly into your website, providing a seamless user experience without redirecting customers away from your page.

<Warning>
  **Domain whitelisting required**: Your domain must be whitelisted in your Payviox dashboard settings to use iframe mode.
</Warning>

## How it works

<Steps>
  <Step title="Create payment session">
    Your application creates a payment session with iframe mode enabled.
  </Step>

  <Step title="Embed iframe">
    The SDK automatically creates and embeds an iframe in your specified target element.
  </Step>

  <Step title="Customer completes payment">
    Customer interacts with the payment form inside the iframe without leaving your page.
  </Step>

  <Step title="Handle completion">
    Listen for completion events via postMessage API to handle successful payments.
  </Step>
</Steps>

## Basic implementation

### Recommended: session created by your backend

Your server creates the session with your secret key, and the SDK embeds it — the [recommended integration](/quickstart/integration-methods), in iframe form:

```javascript theme={null}
const payviox = new Payviox('pk_live_your_key');

const { session_id } = await fetch('/api/checkout', { method: 'POST' }).then((r) => r.json());

payviox.openIframe(session_id, {
  iframeTarget: document.getElementById('payment-container'),
  width: '100%',
  height: '500px'
});
```

### Minimal iframe integration (no backend)

The SDK creates the session itself; it only needs a target container:

```javascript theme={null}
const payviox = new Payviox('your_api_token');

// Create session with iframe mode
await payviox.createSession({
  amount: 5000,
  currency: 'USD',
  customer: 'customer_abc123',
  description: 'Order #12345',
  paymentMethodId: 'stripe_credit',
  order_id: 'order_12345',
  items: [
    {
      name: 'Product A',
      quantity: 1,
      price: 5000
    }
  ]
}, {
  iframeMode: true,
  iframeConfig: {
    iframeTarget: document.getElementById('payment-container'),
    width: '100%',
    height: '500px'
  }
});
```

<Check>
  The payment form will be loaded directly inside the specified container element.
</Check>

## Configuration options

### Iframe configuration parameters

<ParamField body="iframeMode" type="boolean" required>
  Enable iframe integration mode. Must be set to `true`.
</ParamField>

<ParamField body="iframeConfig" type="object" required>
  Configuration object for iframe behavior and appearance.

  <Expandable title="Iframe configuration properties">
    <ParamField body="iframeTarget" type="HTMLElement" required>
      DOM element where the iframe will be inserted. Must be a valid HTML element.

      ```javascript theme={null}
      iframeTarget: document.getElementById('payment-container')
      ```
    </ParamField>

    <ParamField body="width" type="string" default="100%">
      Width of the iframe. Can be any valid CSS width value.

      ```javascript theme={null}
      width: '100%'  // or '500px', '80vw', etc.
      ```
    </ParamField>

    <ParamField body="height" type="string" default="400px">
      Height of the iframe. Can be any valid CSS height value.

      ```javascript theme={null}
      height: '600px'  // or '100vh', '80%', etc.
      ```
    </ParamField>

    <ParamField body="withoutBorder" type="boolean" default="false">
      Remove the default iframe border for a seamless integration.

      ```javascript theme={null}
      withoutBorder: true
      ```
    </ParamField>

    <ParamField body="transparentBackground" type="boolean" default="false">
      Make the iframe background transparent to match your page design.

      ```javascript theme={null}
      transparentBackground: true
      ```
    </ParamField>

    <ParamField body="style" type="string" default="">
      Additional CSS styles to apply to the iframe.

      ```javascript theme={null}
      style: 'box-shadow: 0 4px 6px rgba(0,0,0,0.1); border-radius: 12px;'
      ```
    </ParamField>
  </Expandable>
</ParamField>

## Handling iframe events

When using iframe mode, the payment page communicates with the parent window via the [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. The SDK handles these events automatically, but you can also listen for them directly if you are embedding the iframe without the SDK.

### Event types

| Event type         | Description                                                                          | Payload                                                 |
| ------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------- |
| `payviox:redirect` | Payment requires a full-page redirect (to a payment provider or success/failure URL) | `{ type: 'payviox:redirect', redirect: 'https://...' }` |
| `payviox:close`    | Customer clicked "Back to merchant" — the iframe should be removed                   | `{ type: 'payviox:close' }`                             |

<Note>
  **Redirect-type payments** (PayPal, Pallapay, etc.) cannot be displayed inside an iframe due to security restrictions (`X-Frame-Options`). When the customer selects one of these methods, the payment page sends a `payviox:redirect` event to navigate the full page to the provider.
</Note>

### Standalone integration (without SDK)

If you embed the Payviox iframe manually without using the SDK, you must listen for these events yourself:

```javascript theme={null}
const PAYVIOX_ORIGIN = 'https://secure.payviox.com';

window.addEventListener('message', (event) => {
  if (event.origin !== PAYVIOX_ORIGIN) return;

  if (event.data?.type === 'payviox:redirect') {
    // Payment requires full-page redirect (provider or success/failure URL)
    window.location.href = event.data.redirect;
  } else if (event.data?.type === 'payviox:close') {
    // Customer wants to go back — remove the iframe
    document.getElementById('payment-container').innerHTML = '';
  }
});
```

<Warning>
  Always validate `event.origin` against `https://secure.payviox.com` before acting on any message.
</Warning>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Iframe not displaying">
    **Possible causes:**

    * Domain not whitelisted
    * Invalid iframe target element
    * Content Security Policy blocking iframe

    **Solution:**

    ```javascript theme={null}
    // Verify that target element exists
    const target = document.getElementById('payment-container');
    if (!target) {
      console.error('Payment container not found');
    }

    // Check console for CSP errors
    // Add to your HTML if needed:
    // <meta http-equiv="Content-Security-Policy" 
    //       content="frame-src https://secure.payviox.com;">
    ```
  </Accordion>

  <Accordion title="Iframe height not adjusting">
    **Solution**: Set a fixed minimum height or use viewport units:

    ```javascript theme={null}
    iframeConfig: {
      height: '600px',  // or 'max(600px, 80vh)'
      style: 'min-height: 500px;'
    }
    ```
  </Accordion>

  <Accordion title="Messages not received">
    **Solution**: Ensure you're listening before creating the session:

    ```javascript theme={null}
    // First configure the listener
    window.addEventListener('message', handlePaymentMessage);

    // Then create the session
    await payviox.createSession(params, iframeConfig);
    ```
  </Accordion>
</AccordionGroup>

## Best practices

<Tip>
  **Recommended practices for iframe integration:**

  1. **Provide visual feedback**: Show loading states while the iframe loads
  2. **Handle errors gracefully**: Display user-friendly messages for errors
  3. **Mobile optimization**: Test on various screen sizes
  4. **Accessibility**: Ensure keyboard navigation works properly
  5. **Performance**: Initialize iframes only when needed (lazy loading)
</Tip>

## Next steps

<CardGroup cols={2}>
  <Card title="Error handling" icon="triangle-exclamation" href="/sdk/error-handling">
    Handle payment errors gracefully
  </Card>

  <Card title="Payment methods" icon="credit-card" href="/sdk/payment-methods">
    Discover available payment options
  </Card>

  <Card title="Testing" icon="flask" href="/sdk/testing">
    Test iframe integration
  </Card>

  <Card title="Webhooks" icon="webhook" href="/sdk/webhooks">
    Process server-side events
  </Card>
</CardGroup>
