JavaScript API Reference
The onsite script exposes window.ezsubscriptions after https://sm.ezoic.com/min.js loads. Because the script loads asynchronously, put API calls inside the cmd queue:
<script>
window.ezsubscriptions = window.ezsubscriptions || {};
ezsubscriptions.cmd = ezsubscriptions.cmd || [];
ezsubscriptions.cmd.push(function (api) {
// api is the resolved ezsubscriptions API.
});
</script>
<script src="https://sm.ezoic.com/min.js" async defer></script>
Methods that return promises can reject if a network request fails. Wrap access checks and checkout-launching calls in try / catch when your page needs a custom fallback.
Readiness 🔗
ezsubscriptions.cmd
🔗
Queues callbacks until the script is ready. Each callback receives the resolved API object.
ezsubscriptions.cmd.push(function (api) {
api.showPaywall({ offer: "premium-plan" });
});
Callbacks pushed after the script is ready run immediately.
ezsubscriptions.ready
🔗
Boolean value that is true after the API is ready.
if (window.ezsubscriptions?.ready) {
window.ezsubscriptions.showPaywall({ offer: "premium-plan" });
}
Access Methods 🔗
hasAccess(query)
🔗
Checks whether the current visitor has an active entitlement for an access key.
const access = await ezsubscriptions.hasAccess("premium-access");
You can pass the access key directly or as an object:
await ezsubscriptions.hasAccess("premium-access");
await ezsubscriptions.hasAccess({ tier: "premium-access" });
Parameters:
query: string | { tier: string }— access key from your publisher-managed offer.
Returns:
{
decision: "allowed" | "denied" | "login_required" | "expired" | "revoked" | "unknown_product",
reasonCode: string
}
Show protected content only when decision is allowed. Treat every other decision as no current access.
Anonymous visitors return login_required without a network request.
This promise can reject if the visitor is signed in and the access request fails.
getAccessTiers()
🔗
Returns the access keys currently held by the visitor.
const tiers = await ezsubscriptions.getAccessTiers();
if (tiers.includes("pro")) {
enableProFeatures();
}
Parameters: none.
Returns:
string[]
Anonymous visitors return [] without a network request.
This promise can reject if the visitor is signed in and the access-tier request fails.
Paywall Methods 🔗
showPaywall(options)
🔗
Opens Ezoic's pre-built paywall and checkout experience.
For publisher-managed offers, pass the offer key with offer:
await ezsubscriptions.showPaywall({
offer: "premium-plan",
onSuccess: function (result) {
window.location.reload();
},
onError: function (error) {
console.log(error.message);
},
});
Parameters:
options?: objectoptions.offer?: string— offer key from your publisher-managed offer. This is the normal option for publisher-managed access. It is the offer key, not the access key you pass tohasAccess.options.dismissible?: boolean— whentrue, the visitor can close the paywall andonCancelcan fire. When omitted orfalse, the paywall is blocking.options.onSuccess?: (result: CheckoutResult) => void— fires after checkout completes and access is established.options.onCancel?: () => void— fires when a dismissible paywall is closed before checkout completes.options.onError?: (error: CheckoutError) => void— fires when a checkout attempt fails. It may fire more than once if the visitor retries.options.config?: PageConfig— advanced support-directed option. Most publisher-managed integrations should omit this.options.path?: string— advanced support-directed option. Not needed for offer-key checkout.
Returns:
Promise<void>
When offer is provided, the widget loads that offer's products, re-checks visitor access, and renders nothing if the visitor already holds an access key the offer grants or if there are no active products to sell.
hide()
🔗
Unmounts the paywall and donation surfaces.
ezsubscriptions.hide();
Parameters: none.
Returns: void.
Donation Methods 🔗
showDonations(options)
🔗
Mounts the donation launcher and registers openDonation() / closeDonation().
await ezsubscriptions.showDonations({
onSuccess: function (result) {
console.log("Donation complete", result.amountCents);
},
});
Parameters:
options?: objectoptions.onSuccess?: (result: CheckoutResult) => void— fires after donation checkout completes.options.onCancel?: () => void— fires when the visitor closes the donation dialog before checkout completes.options.onError?: (error: CheckoutError) => void— fires when a checkout attempt fails. It may fire more than once if the visitor retries.options.config?: PageConfig— advanced support-directed option. Most publisher-managed donation integrations should omit this.
Returns:
Promise<void>
Call showDonations() before calling openDonation().
openDonation(options)
🔗
Opens the donation dialog after showDonations() has mounted the donation launcher.
ezsubscriptions.openDonation({ amountCents: 2500 });
Parameters:
options?: objectoptions.amountCents?: number— preselected donation amount in cents. For example,2500means$25.00. The configured minimum still applies.options.productId?: string— optional donation product ID. Most publisher-managed donation integrations should omit this because a site has one active donation in the current dashboard flow.
Returns: void.
If amountCents is missing, invalid, or below the configured minimum, the widget falls back to the normal donation picker.
closeDonation()
🔗
Closes the donation dialog.
ezsubscriptions.closeDonation();
Parameters: none.
Returns: void.
Callback Payloads 🔗
CheckoutResult
🔗
Passed to onSuccess.
{
productExternalId: string,
priceExternalId: string,
productType: "subscription" | "one_time" | "donation",
amountCents: number,
offer?: string
}
amountCentsis the requested base amount in cents. Taxes, discounts, or payment-provider adjustments can change the final charged total.offeris set to the offer key when checkout was opened withshowPaywall({ offer }).- A callback that throws is logged and does not break the widget.
CheckoutError
🔗
Passed to onError.
{
message: string
}
Checkout stays open for retry after an error, so onError can fire more than once.