Embeddable checkout
Sell ShowTix tickets inside your own website — a button, an inline widget, a plain iframe or a tracked link. Set-up, JavaScript API, events and CSP.
For developersLast updated
On this page
- Quick start
- Embed styles
- Button (overlay)
- Inline widget
- Plain iframe
- Tracked links & storefront
- JavaScript API
- Host-page events
- Theming
- Security & your site's CSP
- Payments in a frame
- Custom domains
- Troubleshooting
- "… refused to connect" or a blank frame
- Safari, private browsing and blocked cookies
- Apple Pay / Google Pay don't show
- My listener never fires
Put the full ShowTix buying experience — event list, seat maps, promo codes, checkout, Apple Pay and Google Pay — inside your own website, in your colours. No API key and no server code: one script tag.
Everything is set up in Settings → Embed & storefront (/settings/embed). Anyone in your organisation can view that page; only owners and admins can change it.
Quick start#
Allow your website
In Settings → Embed & storefront, add every address your site is served from under Allowed websites — for example
https://www.yourvenue.com.auandhttps://yourvenue.com.au. Browsers refuse to show the checkout on any site that isn't listed.Enter just the scheme and host (plus a port if you use one) — no path.
Subdomain wildcards work:
https://*.yourvenue.com.au.Addresses must use
https://; plainhttp://is only accepted forlocalhostwhile you test.Up to 20 addresses.
Add the loader once per page
Your organisation key is your ShowTix handle — the Slug shown in Settings → Organisation (the snippet generator fills it in). It's public — it only identifies whose events to show.
text<script src="https://showtix.com.au/embed/v1.js" data-showtix-org="your-org" async></script>
Copy-paste snippets
The Add to your site panel on the same page writes these for you — choose an Embed style and either All upcoming events or one event — and Look & feel shows a live preview of your theme.
Embed styles#
| Style | Best for | Needs JavaScript | Host-page events |
|---|---|---|---|
| Button → overlay | Most sites. Full-screen on phones. | Yes | Yes |
| Inline widget | A dedicated "Tickets" page. Resizes to fit. | Yes | Yes |
| Plain iframe | Site builders that block scripts. | No | No |
| Link / storefront | Emails, socials, link-in-bio. | No | — |
Button (overlay)#
Use your own button (any <button> or <a>) so it matches your site, or an empty <div> and the loader renders an accessible one. Optional attributes on the div: data-label, data-color, data-text-color, data-radius. Any button or inline element can also take data-org (show another organisation's events) and data-title (the frame's accessible title).
<!-- your own styled button -->
<a href="#" class="btn" data-showtix-button data-event="1234">Get tickets</a>
<!-- or let ShowTix render one -->
<div data-showtix-button data-label="All dates" data-color="#1d1a16"></div>The overlay traps focus, closes on Esc or a click outside, restores focus to the button and locks page scroll while open. Under 640px wide it goes full-screen.
Inline widget#
<div data-showtix-inline></div> <!-- all events -->
<div data-showtix-inline data-event="1234"></div> <!-- one event -->The frame grows and shrinks with its content, so there are no inner scrollbars; when the customer moves to the next step it scrolls back into view. Set a starting height with data-height="640" (the default).
Plain iframe#
<iframe
src="https://showtix.com.au/embed/your-org/events/1234?stx_single=1"
title="Tickets"
allow="payment *"
style="width:100%;height:900px;border:0"
></iframe>Use /embed/your-org for the full program. Keep allow="payment *" — without it Apple Pay and Google Pay can't appear. A plain iframe can't resize itself or tell your page about purchases.
Tracked links & storefront#
Claim a storefront address and every event gets a branded page at https://your-name.showtix.com.au — see storefronts and custom domains. Add UTM tags and sales are attributed to the campaign:
https://your-name.showtix.com.au/events/1234?utm_source=newsletter&utm_medium=email&utm_campaign=springThe button and inline embeds pass your page's own utm_source, utm_medium, utm_campaign, utm_content and utm_term through automatically; without them, sales are tagged with your site's hostname and utm_medium=embed.
From JavaScript, ShowTix.link({ event: "1234", utm_campaign: "spring" }) builds a tracked link to the event's embed page on showtix.com.au.
JavaScript API#
// open checkout from your own code (e.g. after a form)
ShowTix.open({ event: "1234" }); // one event
ShowTix.open({}); // whole program
ShowTix.open({ org: "another-org" }); // a different organisation's events
ShowTix.close();
ShowTix.mount(document.querySelector("#tickets"), { event: "1234" }); // inline, on demand
ShowTix.scan(); // bind elements added after load (SPAs do this automatically)
const off = ShowTix.on("checkout_completed", (detail) => { /* … */ });Host-page events#
Each step dispatches a CustomEvent that bubbles from your button or inline container up to document. Use them for analytics, conversion pixels or a thank-you message.
| Event | When | detail |
|---|---|---|
showtix:ready | A frame has loaded. | org, event, mode |
showtix:opened | The overlay opened. | org, event, mode |
showtix:event_viewed | An event page was shown. | + event_id, title |
showtix:checkout_started | The customer reached checkout. | + cart_id, event_id, total, currency, quantity |
showtix:checkout_completed | Payment succeeded and tickets were issued. | + order_id, event_id, total, currency, tickets |
showtix:closed | The overlay closed. | org, event, mode |
document.addEventListener("showtix:checkout_completed", (e) => {
const { order_id, total, currency } = e.detail;
gtag("event", "purchase", { transaction_id: order_id, value: Number(total), currency });
});Server-side truth
Browser events are for UX and analytics. To fulfil anything on your side, use the order.completed webhook — it's signed and retried. Orders placed through an embed carry sales_channel: "embed" and the website in channel_origin.
Theming#
Set your look once in Settings → Embed & storefront → Look & feel — brand colour, appearance (light, dark or match device), font, corner rounding and button text — and it applies to every embed and your storefront. Your logo comes from Settings → Organisation. Full details: Theming and branding.
Security & your site's CSP#
Framing is controlled with
Content-Security-Policy: frame-ancestorsbuilt from your allowed websites — an unlisted site gets a blocked frame, never a working checkout. The rest of ShowTix can't be framed at all.Only public identifiers ever reach the browser: your organisation key and event ids. No API keys.
The frame and your page talk with
postMessage; both sides check the other's origin and the exact window, so other scripts can't spoof purchase events.Card details are entered in Stripe's own fields and never touch your page or ours.
If your site sends a Content-Security-Policy, allow the loader and the frame:
Content-Security-Policy: script-src 'self' https://showtix.com.au; frame-src https://showtix.com.auThe loader uses no eval, injects no <style> tags and sets no cookies, so it works under strict policies. Stripe's payment frames load inside our frame, so you don't need to allow Stripe yourself.
Payments in a frame#
Cards, including 3-D Secure challenges, complete inside the frame — nothing redirects your page.
Apple Pay needs
allow="payment"on the iframe (the loader adds it) and works in Safari 17+ inside cross-origin frames. Whether it appears also depends on the customer's device and browser — card payments always work.Google Pay also needs
allow="payment"and appears in Chrome when the customer has a saved card.PayPal isn't available inside embeds. Embedded checkout takes cards, Apple Pay and Google Pay only.
Free tickets skip payment — the customer just confirms with Get my tickets.
Prices are in AUD and always include fees — what the customer sees is what they pay.
Custom domains#
Want tickets.yourvenue.com.au instead of a showtix.com.au address? Connect it under Your storefront → Your own domain and prove ownership with a DNS TXT record. The full steps — and what still needs our help — are in storefronts and custom domains.
Troubleshooting#
"… refused to connect" or a blank frame#
The page's address isn't in your allowed websites. Check the exact scheme and host (including www) and the port. For local testing add your dev address, e.g. http://localhost:8080. Changes can take up to a minute to reach every page. The browser console shows violates the following Content Security Policy directive: frame-ancestors.
Safari, private browsing and blocked cookies#
The checkout doesn't use cookies or cross-site storage — the order is carried in the frame's own address — so Safari's Intelligent Tracking Prevention and Chrome's third-party-cookie blocking don't affect it. A reload inside the frame resumes the same order.
Apple Pay / Google Pay don't show#
Make sure the iframe has allow="payment *" (plain-iframe users), the page is served over HTTPS, and the device has a wallet set up. Card payments always work regardless.
My listener never fires#
Plain iframes don't send events — use the loader. Listen on document (events bubble) and make sure the loader script isn't blocked by your CSP.
Was this article helpful?