Let your customers securely add a payment method without leaving your site.
Getting a session token
Every embed is authenticated with a short-lived customer session token. Create it on your server to keep the Polar access token secret, then hand the token to the client.Implementation
Start by installing the SDK.Modal
PolarEmbedPaymentMethod.create() opens the embed as a full-screen modal overlay.
create() options:
| Option | Type | Default | Description |
|---|---|---|---|
sessionToken | string | — | Required. Customer session token. |
theme | 'light' | 'dark' | light | Colour scheme. |
setAsDefault | boolean | true | Whether the new card should become the customer’s default payment method. |
returnUrl | string | current URL | Where to return the customer after a redirect-based payment method (Amazon Pay, Klarna). Defaults to window.location.href. |
locale | string | 'en' | BCP47 locale for the embed UI and Stripe Elements (e.g. 'en', 'fr-FR'). Unsupported locales fall back to English. |
onLoaded | (event: CustomEvent) => void | — | Convenience callback for the loaded event. Equivalent to embed.addEventListener('loaded', …). |
Modal in React
Open the modal from a Client Component event handler:Inline embed (vanilla JS)
Mount a chrome-less, auto-resizing iframe into an element you control:createInline() accepts the same options as create() (except returnUrl) plus a required element (the container to mount into).
Inline embed (React)
Use the<PolarPaymentMethod /> component:
Code Snippet
The simplest integration: add the script and a trigger element withdata-polar-payment-method. Clicking the element opens the modal.
| Attribute | Value | Description |
|---|---|---|
data-polar-payment-method | string | Required. The session token. Clicking the element opens the modal. |
data-polar-payment-method-theme | light | dark | Optional theme override. |
data-polar-payment-method-set-as-default | true | false | Optional. Default true. Pass "false" to add the card without overriding the existing default. |
data-polar-payment-method-return-url | string | Optional. Return URL for redirect-based payment methods. Defaults to the current page. |
data-polar-payment-method-locale | string | Optional. BCP47 locale (e.g. 'en', 'fr-FR'). Unsupported locales fall back to English. |
Localization
The embed is fully localized, pass a BCP47 code via thelocale option (or data-polar-payment-method-locale attribute):
Events
All events are dispatched as cancelableCustomEvents on the embed instance. Call event.preventDefault() to opt out of the SDK’s default action.
| Event | Detail | Default action |
|---|---|---|
loaded | — | Removes the loader spinner once the iframe is ready. |
close | — | Tears down the iframe (unless locked by a pending confirmed). |
confirmed | — | Marks the modal as non-closable while Stripe is processing. |
success | { paymentMethodId: string } | Auto-closes the modal. Call preventDefault() to keep it open. |
error | { code: 'invalid_request' | 'unauthorized' | 'processing_failed' | 'unknown' } | Re-enables closing the modal after a failure. |
Redirect-based payment methods
Some payment methods authorise on the provider’s own site. The browser navigates the whole tab away and back toreturnUrl (defaults to the page the SDK was opened from), so the modal can’t survive the round-trip.
Read the outcome on the returned page with the static getRedirectResult():
usePaymentMethodRedirectResult hook to avoid writing your own effect:

