You can either copy and paste our code snippet to get up and running in a second or use our JavaScript library for more advanced integrations. Our embedded checkout allows you to provide a seamless purchasing experience without redirecting users away from your site.
Code Snippet
The code snippet can be used on any website or CMS that allows you to insert HTML.
First, create a Checkout Link as described in the previous section. The code snippet can directly be copied from there by clicking on Copy Embed Code
.
The snippet looks like this:
<a
href="__CHECKOUT_LINK__"
data-polar-checkout
data-polar-checkout-theme="light"
>
Purchase
</a>
<script
src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@0.1/dist/embed.global.js"
defer
data-auto-init
></script>
This will display a Purchase
link which will open an inline checkout when clicked.
You can style the trigger element any way you want, as long as you keep the data-polar-checkout
attribute.
Import Library
If you have a more advanced project in JavaScript, like a React app, adding the <script>
tag may not be an option. In this case, you can install our dedicated library.
bash npm npm install @polar-sh/checkout bash pnpm pnpm add @polar-sh/checkout bash yarn yarn add @polar-sh/checkout
Then, you should import the PolarEmbedCheckout
helper class and manually call PolarEmbedCheckout.init()
. This will add the required handlers on elements having the data-polar-checkout
attribute.
Here is an example in React:
import { PolarEmbedCheckout } from '@polar-sh/checkout/embed'
import { useEffect } from 'react'
const PurchaseLink = () => {
useEffect(() => {
PolarEmbedCheckout.init()
}, [])
return (
<a
href="__CHECKOUT_LINK__"
data-polar-checkout
data-polar-checkout-theme="light"
>
Purchase
</a>
)
}
export default PurchaseLink
Instead of a Checkout Link, you can also use a Checkout Session URL created dynamically from the API.
For this to work, make sure to set the embed_origin
parameter correctly when creating the Checkout Session. For example, if your checkout page is served on the URL https://example.com/checkout
, you should set embed_origin
to https://example.com
.
Advanced Integration
For users who need more control over the embedded checkout flow, the PolarEmbedCheckout
class provides several advanced features.
Programmatically creating an embed
Instead of using declarative triggers with data-polar-checkout
attributes, you can programmatically create and control checkout instances:
import { PolarEmbedCheckout } from "@polar-sh/checkout/embed";
// Open checkout programmatically when needed
const openCheckout = async () => {
const checkoutLink = "__CHECKOUT_LINK__";
const theme = "light"; // or 'dark'
try {
// This creates the checkout iframe and returns a Promise
// that resolves when the checkout is fully loaded
const checkout = await PolarEmbedCheckout.create(checkoutLink, theme);
// Now you can interact with the checkout instance
return checkout;
} catch (error) {
console.error("Failed to open checkout", error);
}
};
// Example: Trigger checkout when a button is clicked
document.getElementById("buy-button").addEventListener("click", () => {
openCheckout();
});
Listening for checkout events
You can listen for checkout events to respond to user interactions:
import { PolarEmbedCheckout } from "@polar-sh/checkout/embed";
const openCheckoutWithEvents = async () => {
const checkout = await PolarEmbedCheckout.create("__CHECKOUT_LINK__");
// Listen for when the checkout is loaded
checkout.addEventListener("loaded", (event) => {
console.log("Checkout loaded");
// Call event.preventDefault() if you want to prevent the standard behavior
// event.preventDefault()
// Note: This would prevent removing the loader if it's still visible
});
// Listen for when the checkout has been closed
checkout.addEventListener("close", (event) => {
console.log("Checkout has been closed");
// Call event.preventDefault() if you want to prevent the standard behavior
// event.preventDefault()
});
// Listen for when the checkout has been confirmed (payment processing)
checkout.addEventListener("confirmed", (event) => {
console.log("Order confirmed, processing payment");
// Call event.preventDefault() if you want to prevent the standard behavior
// event.preventDefault()
// Note: This would prevent setting the checkout as non-closable
});
// Listen for successful completion
checkout.addEventListener("success", (event) => {
console.log("Purchase successful!", event.detail);
// Call event.preventDefault() if you want to prevent the standard behavior
// event.preventDefault()
// Note: For success event, this prevents automatic redirection if redirect is true
// If redirect is false, you can show your own success message
if (!event.detail.redirect) {
showSuccessMessage();
}
// Otherwise, the user will be redirected to the success URL (unless prevented)
});
return checkout;
};
React Integration with event handling
Here’s a more complete React example that handles checkout events:
import { PolarEmbedCheckout } from '@polar-sh/checkout/embed'
import { useState, useEffect } from 'react'
const CheckoutButton = () => {
const [checkoutInstance, setCheckoutInstance] = useState(null)
// Clean up checkout instance on unmount
useEffect(() => {
return () => {
if (checkoutInstance) {
checkoutInstance.close()
}
}
}, [checkoutInstance])
const handleCheckout = async () => {
try {
const checkout = await PolarEmbedCheckout.create(
'__CHECKOUT_LINK__',
'light'
)
setCheckoutInstance(checkout)
checkout.addEventListener('success', (event) => {
// Track successful purchase
analytics.track('Purchase Completed', {
productId: 'your-product-id',
// Add other analytics data
})
// Show success message or redirect
if (!event.detail.redirect) {
// Handle success in your app
}
})
checkout.addEventListener('close', (event) => {
// Clean up our reference when checkout is closed
setCheckoutInstance(null)
})
} catch (error) {
console.error('Failed to open checkout', error)
}
}
return (
<button onClick={handleCheckout}>
Complete Purchase
</button>
)
}
export default CheckoutButton
Programmatically closing checkout
In some cases, you might need to programmatically close the checkout - for instance, if you detect that a user needs to take an action elsewhere in your application first:
import { PolarEmbedCheckout } from "@polar-sh/checkout/embed";
// Example: open checkout and store the instance
let activeCheckout = null;
async function openCheckout() {
const checkout = await PolarEmbedCheckout.create("__CHECKOUT_LINK__");
activeCheckout = checkout;
return checkout;
}
// Later, close it programmatically when needed
function closeCheckout() {
if (activeCheckout) {
activeCheckout.close();
// The 'close' event will fire automatically
// Don't set activeCheckout to null here, as we'll handle that in the event listener
}
}
// Add a listener to update our reference when checkout is closed
function setupCheckout(checkout) {
checkout.addEventListener("close", (event) => {
// Reset our reference when checkout is closed
activeCheckout = null;
});
return checkout;
}
// Example usage
document.getElementById("open-checkout").addEventListener("click", async () => {
const checkout = await openCheckout();
setupCheckout(checkout);
});
document
.getElementById("close-checkout")
.addEventListener("click", closeCheckout);
Enabling Wallet Payment Methods (Apple Pay, Google Pay, etc.)
By default, wallet payment methods such as Apple Pay and Google Pay are not enabled when embedding our checkout form into your website. For security reasons, your website domain needs to be manually validated.
To enable wallet payment methods on your website, please email us with your organization slug and the domain you wish to allow.