The original checkout custom element.
The classic widget adds Octany checkout to any HTML page. You add an <octany-widget> element, load checkout.js from your Octany account, and Octany handles the payment flow.
§ 01.1 What you're embedding #
The integration uses a single hosted checkout.js script served from your Octany account at {octany-url}/js/checkout.js. The script registers the custom element and opens checkout when the visitor interacts with it.
<octany-widget>is the integration entrypoint you place on your page.- Octany renders the checkout experience and keeps payment handling inside Octany.
Communication uses browser postMessage events so the checkout can open, resize, redirect, and recover across common browser privacy restrictions.
§ 01.2 Install #
Two tags. The order matters — the script needs to be on the page before the element renders.
<!DOCTYPE html> <html> <head> <!-- Stylesheet exposes account-specific theme tokens --> <link rel="stylesheet" href="https://app.octany.com/100/checkout/appearance"> </head> <body> <!-- Drop the element wherever you want a "Subscribe" CTA --> <octany-widget url="https://app.octany.com" account-id="100" product-id="4662" success-url="https://example.se?success" abort-url="https://example.se?abort" type="iframe" ></octany-widget> <!-- Bundle injects the modal iframe and registers the element --> <script src="https://app.octany.com/js/checkout.js"></script> </body> </html>
The url attribute is your Octany host. The account-id is the numeric account ID used by the classic integration. The appearance stylesheet URL exposes your account's brand colors as CSS custom properties on the host page.
§ 01.3 Element attributes #
| Attribute | Required | Notes |
|---|---|---|
| url | yes | Octany host, e.g. https://app.octany.com. |
| account-id | yes | Numeric account ID. |
| product-id | yes | Single ID, or pipe-separated for tabbed multi-product (4662|4663). |
| type | yes | iframe (renders in place) or button (CTA that opens the modal). |
| success-url | Redirect after successful payment. | |
| abort-url | Redirect when user aborts. | |
| tab-title | Pipe-separated tab labels for multi-product (Bli månadsgivare|Engångsgåva). | |
| page-title | Pipe-separated heading per product, shown above the form. | |
| label | Button label when type="button". | |
| locale | sv, en, etc. Defaults to en. | |
| amount | Integer in öre/cents. Overrides product price for "name your price". | |
| custom-price | Boolean. Set to false to hide the "choose your own amount" checkbox on donation products and lock the visitor to the preset price. Default true. | |
| price-with-vat | Boolean. Display prices including VAT. | |
| price-description | Custom price-line label. | |
| reference-id | Use this to correlate. Lands on the resulting subscription/order and on every webhook. | |
| reference-name | Human-readable label shown alongside the resource in admin. | |
| email, first-name, last-name | Pre-fill customer fields. | |
| company, phone | Pre-fill business / contact fields. | |
| line1, line2, zip, city, country | Pre-fill billing address fields. | |
| personal-identity-number | Swedish personnummer pre-fill. | |
| accepted-terms | Pre-check the terms acceptance. | |
| method | Force a specific billing method (e.g. card, swish). | |
| use-spar | Boolean. Whether to look up Swedish address from SPAR. Default true. | |
| continue | Resume an existing checkout session by anonymous ID. | |
| metadata | JSON-encoded object passed through to the resulting order. | |
| version | 1 applies legacy z-index rules. | |
| safari-url-redirect | iOS Safari third-party-cookie workaround target. See note below. |
§ 01.4 Iframe vs. button #
The type attribute picks the rendering mode.
type="iframe"
The form renders in place where you put the element. Auto-resizes via postMessage from the inner iframe. Best for landing pages.
<octany-widget url="https://app.octany.com" account-id="100" product-id="4662" type="iframe"></octany-widget>
type="button"
Renders a CTA button. Clicking it opens the modal iframe full-screen. Best for "Subscribe" / "Donate" CTAs scattered across a page.
<octany-widget url="https://app.octany.com" account-id="100" product-id="4662" label="Become a member" type="button"></octany-widget>
§ 01.5 Multiple products in one flow #
Pipe-separate product-id and pair with matching tab-title / page-title. Useful for monthly + one-off donation flows in a single CTA.
<octany-widget url="https://app.octany.com" account-id="100" product-id="4662|4663" tab-title="Bli månadsgivare|Engångsgåva" page-title="Ge en gåva varje månad|Ge en engångsgåva" success-url="https://example.se?success" type="iframe"></octany-widget>
§ 01.6 Custom metadata #
The metadata attribute accepts a JSON-encoded object that lands on the order. Useful for campaign tags, source pages, or any structured field you'd otherwise stuff into reference_id. The widget watches the attribute via MutationObserver — if you change it after render, it propagates to the open modal.
<octany-widget url="https://app.octany.com" account-id="100" product-id="4662" metadata='{"campaign":"spring-2025","source":"footer"}' type="iframe"></octany-widget>
UTM parameters from the host page URL (utm_source, utm_medium, utm_campaign, utm_content, utm_term) are auto-captured and forwarded — you don't need to wire them.
§ 01.7 Success / abort URLs #
On success: the modal posts close-modal with { type: 'success', successUrl } and the host page navigates to your success-url. On abort, it navigates to abort-url if set, otherwise just closes the modal.
Placeholders in success-url
Before redirecting, the classic checkout substitutes a fixed set of placeholders in the URL. Use them when you want a per-order landing page without an extra round-trip to your backend.
| Placeholder | Replaced with |
|---|---|
{firstName} | Customer's first name. |
{lastName} | Customer's last name. |
{email} | Customer's email address. |
{customerId} | Octany customer ID. |
{orderId} | Resulting order ID (one-off purchases). |
{subscriptionId} | Resulting subscription ID (recurring products). |
{product} | Product name, URL-encoded. |
{total} | Total amount in öre/cents. |
<octany-widget url="https://app.octany.com" account-id="100" product-id="4662" success-url="https://example.se/thanks?order={orderId}&amount={total}" type="iframe"></octany-widget>
Which placeholders apply depends on the kind of checkout: {orderId} for one-off orders, {subscriptionId} for subscriptions. Unrecognised placeholders are left untouched.
UTM tags are not forwarded. The widget captures utm_source/medium/campaign/content/term from the host page URL and stores them on the resulting order's utm_parameters for attribution, but they are not appended to success-url. If you need UTMs on the redirect, put them in success-url yourself when you render the element.
order.paid / subscription.created.
§ 01.8 When to use something else #
The classic widget is solid for what it does. For a new build, look at the alternatives first:
- Donations and fundraising — use the modern Insamling experiences. Donation, 1-click Swish, and Greeting are purpose-built for campaign pages, editorial pages, and seasonal giving.
- SaaS, ecommerce, or multi-product carts — use Checkout. It exposes a hosted checkout URL, an embeddable cart, and the
window.OctanyJS API.
Migrating away is mostly mechanical: replace the <octany-widget> element with the relevant loader snippet or hosted-checkout link. Webhook handling on your backend stays identical.