setting($k); $toggle = fn(string $k, string $label, string $help = '') => '
' . ($help ? '' . e($help) . '' : '') . '
'; $actions = '
Cancel
'; $upload = function (string $k, string $label, string $help) { $cur = upload_url(setting($k)); return '
' . ($cur ? '' : '') . '' . e($help) . '
'; }; $hours = fn(array $list, string $unit) => array_combine(array_map('strval', $list), array_map(fn($h) => $h . ' ' . $unit, $list)); ?>

Settings

Admins only. Every change is recorded in the audit log.

Ticket pages

Your theme's header and footer surround every ticket page. Use the shortcodes [gatecraft_events] [gatecraft_button event="page-address"] and [gatecraft_event slug="page-address"] (the whole event page with booking) on any page or post, including Elementor's Shortcode widget.

true, 'maxlength' => 40, 'help' => 'Events are listed at ' . home_url('/') . $gc_s('base_slug') . '/. Changing it breaks links people already have.']), allowed_html() ); ?>
Ticket bar

Identity

Your brand on the ticket pages, emails, tickets and calendar invites. The admin always uses the Gatecraft design.

true, 'maxlength' => 80]), allowed_html() ); ?> 200]), allowed_html() ); ?> ['theme' => 'Match my WordPress theme (recommended)', 'theme_brand' => 'Match my theme, but use my brand colour', 'brand' => 'Gatecraft style with my brand colour and font'], 'help' => 'Match my theme uses your theme\'s fonts, colours, button colour and page background, so event pages look like the rest of your site. The brand colour and font below apply to the other two styles.']), allowed_html() ); ?> ['inter' => 'Inter (default)', 'system' => 'System font of each device']]), allowed_html() ); ?>

Logos and images

JPG, PNG or WebP. Every image is re-encoded on upload to strip hidden data.

Colours and style

Text on buttons switches between black and white automatically to stay readable.

Button shape
'Rounded', 'pill' => 'Pill', 'square' => 'Square'] as $k => $l): ?>
['light' => 'Light header', 'brand' => 'Brand colour header', 'dark' => 'Dark header']]), allowed_html() ); ?> ['next' => 'Next event spotlight', 'solid' => 'Banner with headline and search', 'image' => 'Banner with image', 'none' => 'Nothing, events first'], 'help' => 'The spotlight shows your next event with its ticket prices. The banner suits an organiser with many events.']), allowed_html() ); ?>
Event list layout
$l): ?>
How events are shown on the home page and in the events shortcode.
Live preview
Upcoming events
Book in a minute
Sample event
Sat 14 Nov · Sample venue
Get tickets

Home page

The headline, introduction and search placeholder appear when the home page top section is a banner (Branding tab).

160, 'class' => 'span-all']), allowed_html() ); ?> 2, 'maxlength' => 400, 'class' => 'span-all']), allowed_html() ); ?> 80]), allowed_html() ); ?> 300]), allowed_html() ); ?> 300, 'class' => 'span-all', 'help' => 'Shown under your site name in Google results.']), allowed_html() ); ?>

Ticket labels and notices

Use {left} for the number left and {date} for the sale start.

40]), allowed_html() ); ?> 60]), allowed_html() ); ?> 0]), allowed_html() ); ?> 60]), allowed_html() ); ?> 40]), allowed_html() ); ?> $gc_s]); ?>

Booking page messages

Shown at the top of the booking page. {pay_deadline}, {amount} and {booking_reference} are available.

2, 'maxlength' => 500]), allowed_html() ); ?> $gc_s]); ?> 2, 'maxlength' => 500]), allowed_html() ); ?> 2, 'maxlength' => 500]), allowed_html() ); ?>

Footer and contact

200, 'placeholder' => setting('brand_name')]), allowed_html() ); ?> 40]), allowed_html() ); ?> 'https://instagram.com/…']), allowed_html() ); ?> 'https://x.com/…']), allowed_html() ); ?> 'https://facebook.com/…']), allowed_html() ); ?> 'https://linkedin.com/company/…']), allowed_html() ); ?> 'https://…']), allowed_html() ); ?> 3, 'class' => 'span-all', 'placeholder' => "Press kit | https://example.com/press\nContact us | mailto:hello@example.com", 'help' => 'One link per line, as: Label | https://address. An address can also start with mailto:. Up to ' . FOOTER_LINKS_MAX . ' links. Instagram, Facebook, X and LinkedIn show their own icons; the website and other links show a general icon.']), allowed_html() ); ?> $gc_s, 'toggle' => $toggle]); ?>

Sender

80, 'placeholder' => setting('brand_name')]), allowed_html() ); ?> 'WordPress default', 'help' => 'Leave empty to use WordPress or your SMTP plugin\'s sender. It must be allowed by your mail service.']), allowed_html() ); ?> setting('support_email') ?: 'support@…']), allowed_html() ); ?> 300]), allowed_html() ); ?>

Templates

Pick an email to edit its wording. Changes apply to emails sent from now on.

true, 'maxlength' => 200]), allowed_html() ); ?> true, 'maxlength' => 200]), allowed_html() ); ?> true, 'rows' => 7, 'maxlength' => 5000, 'help' => 'Each line becomes a paragraph. Empty variables are removed.']), allowed_html() ); ?> 60, 'help' => 'Leave empty for no button.']), allowed_html() ); ?>
Insert a variable
Cancel
Preview with sample data

Payment methods

Buyers choose one of the methods you allow for each event. You can limit them per event on the event's Details tab.

['1' => '1 day', '2' => '2 days', '3' => '3 days', '5' => '5 days', '7' => '7 days', '14' => '14 days'], 'help' => 'Never later than the day before the event. Close to the event, konbini is not offered.']), allowed_html() ); ?>
Offline payments

The buyer pays outside the system, for example by PayPay, cash or bank transfer, following your instructions. The booking shows as "Payment to confirm" until you confirm it on the booking page. The buyer then gets their QR tickets by email. In instructions you can use {amount} and {booking_reference}.

$gc_m): ?> 'r' . $i, 'm' => $gc_m]); ?>

Checkout rules

['optional' => 'Optional', 'required' => 'Required', 'hidden' => 'Do not ask']]), allowed_html() ); ?> $hours([10, 15, 20, 30, 45, 60], 'minutes'), 'help' => 'Seats held while the buyer is on the payment page.']), allowed_html() ); ?> $hours([12, 24, 48, 72, 120, 168, 336], 'hours'), 'help' => 'Seats stay reserved this long. Unconfirmed bookings then expire and the seats go back on sale.']), allowed_html() ); ?> $gc_s, 'hours' => $hours]); ?>

Prices and tax

true, 'help' => 'Change it under Regional. Locked once the first booking exists.']), allowed_html() ); ?> 200]), allowed_html() ); ?> ['none' => 'No tax line', 'inclusive' => 'Ticket prices include tax', 'exclusive' => 'Add tax on top of ticket prices'], 'help' => 'Applies to new bookings. Past bookings keep the tax they were made with.']), allowed_html() ); ?> 'decimal', 'maxlength' => 6, 'help' => 'For example 10 for Japanese consumption tax, or 20 for UK VAT.']), allowed_html() ); ?> 60, 'placeholder' => 'Consumption tax, VAT']), allowed_html() ); ?> 40, 'placeholder' => 'T1234567890123 or GB123456789', 'help' => 'Printed on invoices. In Japan this is the qualified invoice issuer number (T and 13 digits).']), allowed_html() ); ?>

Staying in touch

Buyers who agree join your Audience list, where you can send them news about future events. The wording they agreed to is kept with each person.

['required' => 'Required to book', 'optional' => 'Optional checkbox', 'off' => 'Do not ask'], 'help' => 'Required: nobody can book without agreeing. Before selling in the EU or UK, ask your adviser: there, agreement to marketing must be optional. Important notices about an event someone booked can be sent either way.']), allowed_html() ); ?> 3, 'maxlength' => 500, 'class' => 'span-all', 'help' => '{brand_name} is replaced with your brand name.']), allowed_html() ); ?>
$gc_s, 'toggle' => $toggle]); ?>

Staff alerts

In-app alerts appear in the bell menu for managers and admins.

$l): ?>
WhenIn appEmail
aria-label=" in app"> In app only aria-label=" by email">
['50' => '50% sold', '75' => '75% sold', '90' => '90% sold', '100' => '100% sold']]), allowed_html() ); ?> ['staff' => 'All managers and admins, plus the addresses below', 'list' => 'Only the addresses below']]), allowed_html() ); ?> 'span-all', 'placeholder' => 'ops@company.com, box-office@company.com']), allowed_html() ); ?>

Automatic emails

$gc_s, 'toggle' => $toggle]); ?>

Automatic emails need the background job (cron) described in the README.

Sign-in methods

['0' => 'Never: ask every time', '7' => 'For 7 days', '14' => 'For 14 days', '30' => 'For 30 days'], 'help' => 'Staff can tick "Remember this browser" when they enter their code, and are not asked again on that browser until then. Their password is still needed. Changing the password or resetting the authenticator forgets every remembered browser.']), allowed_html() ); ?>
$gc_s, 'toggle' => $toggle]); ?>

Protection from bots

Sessions and limits

['30' => '30 minutes', '60' => '1 hour', '120' => '2 hours', '480' => '8 hours', '1440' => '24 hours']]), allowed_html() ); ?> ['2' => '2 hours', '4' => '4 hours', '8' => '8 hours', '12' => '12 hours', '24' => '24 hours']]), allowed_html() ); ?> 3, 'max' => 20]), allowed_html() ); ?> 1, 'max' => 1440]), allowed_html() ); ?> 5, 'max' => 200]), allowed_html() ); ?> 3, 'class' => 'span-all', 'placeholder' => "203.0.113.10\n198.51.100.0/24", 'help' => 'Limits the Tickets pages in wp-admin. One per line. Empty means no restriction. Your current address is ' . client_ip() . '.']), allowed_html() ); ?>

Always-on protection

Built in. Listed so you can confirm it.

Secret keys go in wp-config.php, not the database, and are never shown here. Someone who gets into a WordPress admin account still cannot read or change them in the browser. Add them above the line /* That's all, stop editing! */:

define('GATECRAFT_STRIPE_SECRET', 'sk_live_…');
define('GATECRAFT_STRIPE_WEBHOOK_SECRET', 'whsec_…');
define('GATECRAFT_GOOGLE_SHEETS_KEY', '/path/outside/web/root/sheets-key.json');
$v === '' ? 'Not set' : (strlen($v) > 12 ? substr($v, 0, 7) . '…' . substr($v, -4) : 'Set'); $blocks = [ ['Stripe payments', cfg('stripe_secret') !== '' && cfg('stripe_webhook_secret') !== '', ['Mode' => str_starts_with((string)cfg('stripe_secret'), 'sk_live') ? 'Live' : (cfg('stripe_secret') ? 'Test' : 'Not set'), 'Secret key' => $mask((string)cfg('stripe_secret')), 'Webhook secret' => cfg('stripe_webhook_secret') ? 'Set on server' : 'Not set', 'Webhook address to register' => url('/webhooks/stripe'), 'Webhook events' => 'checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed', 'Last card payment' => $lastWebhook ? fmt_dt($lastWebhook) : 'None yet']], ['Email sending', true, ['Delivery' => 'WordPress mail (wp_mail). Install an SMTP plugin for reliable delivery.', 'From address' => setting('mail_from_address') ?: 'WordPress default', 'Queue' => (int)($queue['queued'] ?? 0) . ' waiting, ' . (int)($queue['failed'] ?? 0) . ' failed, ' . (int)($queue['sent'] ?? 0) . ' sent']], ]; $blocks = (array)apply_filters('gatecraft_integration_blocks', $blocks); // add-ons add their services ?>

$v): ?>
$toggle]); ?> version_label(true), 'Edition' => edition_label(), 'WordPress' => get_bloginfo('version'), 'PHP' => PHP_VERSION, 'Database' => $db->db_server_info(), 'Database schema' => (string)get_option('gatecraft_db_version', ''), 'Site time zone' => wp_timezone_string(), ]; $parts = [ ['php-qrcode, by chillerlan', 'MIT or Apache 2.0', 'QR codes on tickets', 'https://github.com/chillerlan/php-qrcode'], ['php-settings-container, by chillerlan', 'MIT', 'Used by php-qrcode', 'https://github.com/chillerlan/php-settings-container'], ['jsQR, by Cosmo Wolfe', 'Apache 2.0', 'Door scanner', 'https://github.com/cozmo/jsQR'], ['Inter, by Rasmus Andersson', 'SIL Open Font License 1.1', 'Typeface', 'https://github.com/rsms/inter'], ]; ?>

Gatecraft

Sell tickets for your own events: priced categories, card and offline payments, QR tickets by email and a phone camera door scanner.

Gatecraft is released under the GNU General Public License, version 2 or later, as WordPress requires. The bundled components below keep their own licenses.

Version and environment

Include this when you ask for support.

$v): ?>

Bundled components

ComponentLicenseUsed for

Policies

Each one becomes a page linked from the footer and checkout once it has text.

8]), allowed_html() ); ?> 5]), allowed_html() ); ?> 8]), allowed_html() ); ?> 300]), allowed_html() ); ?> 4, 'help' => 'For sales in Japan the Specified Commercial Transactions Act notice usually goes here. Check the wording with your adviser.']), allowed_html() ); ?>

Time and formats

Applies to the site, emails and exports.

true, 'help' => 'Uses Settings, General in WordPress. Set it before you create events.']), allowed_html() ); ?> ['en' => ldate('D j M Y'), 'ymd' => ldate('Y/m/d (D)'), 'us' => ldate('D, M j, Y')]]), allowed_html() ); ?> ['24' => '24-hour (19:00)', '12' => '12-hour (7:00 pm)']]), allowed_html() ); ?> ['JPY' => 'JPY, Japanese yen', 'USD' => 'USD, US dollar', 'EUR' => 'EUR, euro', 'GBP' => 'GBP, pound sterling', 'AUD' => 'AUD', 'CAD' => 'CAD', 'SGD' => 'SGD', 'INR' => 'INR'], 'help' => 'Locked once the first booking exists.']), allowed_html() ); ?>

Languages

English is always on. With Japanese on, each person can choose their language: visitors with the switcher in the page header, signed-in people on their account page, and staff in the admin menu. Each event can also have its own default language.

$toggle]); ?>
array_filter(GATECRAFT_LANGUAGES, fn($k) => language_installed($k), ARRAY_FILTER_USE_KEY), 'help' => 'For visitors who have not chosen one, and for emails to people without a preference.']), allowed_html() ); ?>

Data

'Off by default, so removing the plugin by mistake does not lose bookings.']), allowed_html() ); ?>