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

# Migrate to SDK 2.0

> What changes now that the checkout renders inside an iframe, and how to update your integration.

Starting with version 2.0.0, the PayNext checkout renders inside a secure iframe served from `https://cdn-sdk.paynext.com`. Card details and payment provider scripts stay inside that iframe, separate from your page. You mount the checkout, configure it, and receive callbacks exactly as before.

<Note>
  The checkout runtime loads from the PayNext CDN, so the iframe applies to every integration once it's released, whichever `@paynext/sdk` version you have installed. Version 2.0.0 removes the `className` style option from the TypeScript types.
</Note>

## Replace `className`

Your page's CSS classes don't exist inside the iframe, so `className` can't style the checkout. Version 2.0.0 removes it from `HTMLStyles` and from every style option built on it: the `Input` field, label, error and container, `SubmitButton`, `BackButton`, and the wallet and payment method buttons.

* **TypeScript**: passing `className` is a compile error after you upgrade.
* **JavaScript or an earlier SDK version**: the checkout ignores `className` and logs a console warning that names each place it was set.

Move each class to `styles` for static appearance, or to `cssVariables` for theme-wide tokens and interactive states. Inline styles can't target `:hover` or `:focus`, so use these tokens for the common cases:

| Class-based styling | Replacement |
| :- | :- |
| Hover on the Pay button, the **Card** method button, and the saved payment method's Pay button | `'--paynext-sdk-button-hover-opacity'` in `cssVariables` (applies to all three) |
| Input focus ring, such as `focus:ring-2` | `'--paynext-sdk-input-focus-shadow'` in `cssVariables` |
| Input focus border, such as `focus:border-blue-500` | `'--paynext-sdk-border-focus'` in `cssVariables` |
| Hover and focus on the Cash App, Amazon Pay, Pix, UPI, BLIK, Venmo, Apple Pay, and Back buttons | No replacement — their hover and focus states can't be customized |
| Colors, spacing, borders, and layout | The matching properties in `styles` |

<Note>
  A `background` or `backgroundColor` you set in `styles` is applied inline, so it also replaces the button's built-in hover background.
</Note>

<CodeGroup>
  ```ts Before (1.x) theme={"system"}
  const styles: StylesConfig = {
    Input: {
      field: { className: 'bg-slate-50 rounded-lg focus:ring-2 focus:ring-blue-500' }
    },
    SubmitButton: { className: 'bg-blue-600 font-semibold hover:bg-blue-700' }
  }
  ```

  ```ts After (2.0) theme={"system"}
  const styles: StylesConfig = {
    cssVariables: {
      '--paynext-sdk-input-focus-shadow': '0 0 0 2px #3b82f6',
      '--paynext-sdk-button-bg': '#2563eb',
      '--paynext-sdk-button-hover-opacity': '0.85'
    },
    Input: {
      field: { styles: { backgroundColor: '#f8fafc', borderRadius: '8px' } }
    },
    SubmitButton: { styles: { fontWeight: '600' } }
  }
  ```
</CodeGroup>

See [Customize the Appearance](/sdk-reference/web-sdk/customization/appearance) for every style option and [CSS Variables](/sdk-reference/web-sdk/customization/theme#css-variables) for the full token list.

## Style the Checkout Only Through the SDK

Nothing on your page reaches inside the iframe. Pass everything the checkout needs through `styles` and `cssVariables`:

* **Stylesheets and selectors**: rules in your CSS, including selectors on `data-paynext-*` attributes, don't apply to the checkout.
* **CSS custom properties**: a value such as `var(--color-primary)` doesn't resolve inside the iframe. Pass the actual color instead.
* **Fonts**: the checkout uses the system font stack and doesn't load your page's web fonts. To change it, set `fontFamily` in `styles` to a font installed on the customer's device, with a system fallback.
* **Per-theme overrides**: values in `cssVariables` apply in both themes and don't change after mount, even when the theme does. To use different values for light and dark, mount with the set that matches the theme, and remount when your page switches themes. See [Override per Theme](/sdk-reference/web-sdk/customization/theme#override-per-theme).

Version 2.0.0 also removes the `container.focus` option of `Input`. It never had an effect, so remove it from your configuration; the focus tokens above style focused fields.

## Size the Container

The iframe takes the full width of the element you mount it into and resizes its height to fit the checkout as its content changes. Set the width on your container, and don't give the container a fixed height.

During 3D Secure and wallet payments, the checkout temporarily covers the whole page to show the provider's window, then returns to its place.

## Update Your Content Security Policy

If your page sets a Content Security Policy, allow `https://cdn-sdk.paynext.com` in `frame-src` as well as `script-src`:

```http Content-Security-Policy theme={"system"}
script-src 'self' https://cdn-sdk.paynext.com;
frame-src https://cdn-sdk.paynext.com;
```

Merge these sources into your existing directives rather than replacing them.

If your page also sends a `Permissions-Policy` header that restricts `payment`, add the checkout's origin to it. Otherwise Apple Pay, Google Pay, and other browser payment sheets can't open inside the checkout iframe:

```http Permissions-Policy theme={"system"}
payment=(self "https://cdn-sdk.paynext.com")
```

## Apple Pay on Older Safari Versions

Safari supports Apple Pay inside an iframe from Safari 17 and iOS 17. On earlier versions, the Apple Pay button doesn't appear, and customers can pay with your other enabled methods.

Apple still validates your own domain, so keep it registered with Apple as before.

## Upgrade the Package

<Steps>
  <Step title="Install version 2">
    ```bash theme={"system"}
    npm install @paynext/sdk@2
    ```
  </Step>

  <Step title="Remove className options">
    Fix the TypeScript errors on `className`, using the replacements above.
  </Step>

  <Step title="Check the console">
    Open your checkout page and confirm that the browser console shows no PayNext `className` warning.
  </Step>
</Steps>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.