Skip to content

Releases: HiEventsDev/Hi.Events

v2.0.0-rc.1

v2.0.0-rc.1 Pre-release
Pre-release

Choose a tag to compare

@daveearley daveearley released this 27 Aug 06:35
06d30d2

Hi.Events v2.0.0-rc.1

The biggest release since the project started. v2 adds recurring and multi-date events, embedded
checkout, product add-ons, a rebuilt check-in app, a documented REST API, and a redesigned organizer
dashboard, along with a set of platform upgrades that require action before you upgrade.

Read the Upgrading section before running this on an existing installation. There
are new minimum requirements and several one-way migrations.


Recurring and multi-date events

An event is no longer a single date. Every event now has one or more occurrences, and you can
generate them from a recurrence rule.

  • Daily, weekly, monthly and yearly schedules, with intervals, multiple times per day, and
    per-slot labels and durations. Monthly supports both "the 15th of the month" and "the last
    Friday of the month". The recurrence API additionally accepts excluded dates and one-off extra
    dates.
  • Set a schedule to end after a number of dates or on a specific date. Up to 1,200 occurrences per
    event.
  • Per-date capacity, per-date pricing overrides, per-date product visibility, and per-date venues.
  • Cancel a single date, refund its orders in one action, and notify the attendees. Orders that
    span several dates are left for manual refund. Cancelling writes the date back into the schedule
    as an exclusion so it does not reappear.
  • Bulk edit across dates: shift times, change duration, update capacity, relabel, or change venue,
    with options to only affect future dates and to skip dates you have edited by hand.
  • Attendees, orders, waitlist entries, reports and exports can all be filtered by date.
  • A new Occurrence Summary report breaks down sales, attendance and check-ins per date.

Buyers get a calendar and time-slot picker on the event page and in the embedded widget, with
remaining-capacity hints, sold-out states, and deep links straight to a specific date via
?occurrence_id=.

Single-date events keep working exactly as before. They get one occurrence created automatically and
the buyer never sees a date picker.

Embedded checkout

The embeddable widget now runs the entire checkout in a modal over your own page, from ticket
selection through payment to confirmation.

  • Rendered in a shadow DOM, so your site's CSS cannot break it and it cannot leak styles into your
    page. Full screen on mobile, a centred dialog on desktop.
  • Apple Pay and Google Pay work inside it. Payments that redirect away for authentication (3DS,
    wallets) come back straight into the modal rather than dumping the buyer on a bare page, and the
    redirect parameters are cleaned off your URL afterwards.
  • Closing the modal mid-checkout asks for confirmation and cancels the order. An accidental page
    reload or navigation is safe though: when the buyer returns in the same tab, the checkout reopens
    at the step they left off, as long as the reservation has not expired.
  • Set data-hievents-checkout="new-tab" if you would rather keep the old behaviour of opening
    checkout in a new tab.

The embed snippet has not changed. Existing embeds pick all of this up with no edits to your
site.

There is also a widget playground at /widget-test on dev builds (or in production with
WIDGET_TEST_PAGE_ENABLED=true) for trying colours, locales and checkout modes against a real
event, with a live log of the messages the widget sends to the host page.

Product add-ons

Attach add-ons to a ticket: merch, parking, a workshop upgrade. Add-ons appear nested under their
parent in the widget and stay inert until the parent is in the cart. Mark a product "add-on only"
and it will not appear as a standalone item.

Reusable locations and address autocomplete

Addresses were previously free text stored on each event. They are now a proper location library
per organizer, with a saved-venue picker and Google Places autocomplete.

Autocomplete is optional. Set GOOGLE_MAPS_API_KEY to turn it on. Without a key everything still
works, you just type the address in by hand.

Events can be in-person or online, and recurring events can have a different venue per date. The
public payload now returns a structured event_location object instead of the old
location_details blob.

Rebuilt check-in app

The scanner was reorganised into three tabs: Scan, Search and Stats.

  • Camera scanning is now inline rather than a separate screen, and USB scanner mode shows a live
    listening indicator and a visible input buffer.
  • A stats tab with totals, progress, and a live throughput figure over a rolling five-minute window.
  • An attendee detail sheet with check-in history.
  • A date filter for recurring events, so door staff only see the session they are working.
  • Haptic feedback, an offline indicator, and undo on accidental check-ins.
  • Check-in lists moved to a table view, and you can now control what an unauthenticated check-in
    link exposes: attendee notes, question answers, and order details are each off by default.

Payments moved to the organizer

Stripe Connect, VAT settings and fee configuration used to live on the account. They now live on the
organizer, so one account can run multiple organizers with separate payout destinations.

  • Reuse an existing Stripe connection across organizers in the same account (SaaS mode only), or
    connect each one separately.
  • Disconnect Stripe from an organizer without touching the Stripe account itself.
  • Existing connections are migrated automatically. Nobody has to reconnect.

You can also change an event's currency yourself now, as long as the event has no orders with a
monetary value.

Account deletion

Account owners can request deletion from Account settings, under Danger Zone.

  • 30 day grace period with a reminder email 7 days before the deletion runs, cancellable at any
    point.
  • Accounts that have never taken a completed order are deleted outright. Accounts that have are
    anonymised instead, so financial records stay intact.
  • Blocked while upcoming events still have completed orders, with the blocking events named.
  • Live events are moved to draft as soon as the request is made.

Deletions are executed by an hourly scheduled job, so schedule:run needs to be active.

REST API documentation

The API now ships an OpenAPI spec generated from the code itself.

Set API_DOCS_ENABLED=true and browse interactive docs at /docs/api on your own instance, or
export the spec with php artisan scramble:export. Off by default.

Announcements

Superadmins can post in-app banners or modals to users on their instance, targeted at everyone, at
specific accounts, or at specific users, with seen and dismissed counts. This is entirely local to
your installation. There is no remote feed and nothing is pushed into your install from outside.

Redesigned dashboards

  • Stat cards replaced with sparklines and period-over-period comparisons.
  • A new period selector covering both recent activity (last 7, 30, 90 days) and event lifetime
    (first 7, 30, 90 days, full event).
  • A rebuilt setup checklist with a progress bar, which disappears once you are done.
  • A publish flow that checks for missing pieces before you go live: it warns about missing tickets
    or dates, and blocks publishing when payments are not set up.
  • For recurring events, a hero panel for the next date with a live countdown that turns into a
    check-in shortcut once the date starts.

Checkout

  • The checkout header was rebuilt: a step counter, the event title, and a compact reservation timer
    that turns red as it runs down.
  • Ticket selection was redesigned. One-price tickets show inline without expanding, descriptions
    moved behind a Details toggle, fees and tax have a collapsible breakdown, and low stock shows a
    remaining-quantity hint.
  • The floating "Get tickets" button turns into a checkout button showing your cart total once you
    scroll past the ticket list, and its label is configurable per event.

Everything else

  • Nine new event categories (Family, Hobbies, Wellness, Spirituality, Outdoors, Tours, Film, Dance,
    Seasonal), and the category now sets the default wording. A wellness event says "Classes" and
    "Book Now" rather than "Tickets" and "Continue".
  • Fixed-amount promo codes can now discount the order total rather than each product.
  • Offline payment orders can be refunded, in full or in part. This records the refund and can
    optionally email the buyer, it does not move money.
  • Attendee tickets were redesigned, and cancelled or unpaid tickets now clearly show as void instead
    of displaying a scannable code.
  • Waitlists are date-aware. One person can hold a place on several dates, offers name the date, and
    cancelling a date releases its waitlist.
  • Product create and edit moved into a wide drawer with a live preview of the real widget that
    updates as you type.
  • The frontend loads less up front. Every date-formatting locale used to be bundled whether you used
    it or not and now loads on demand, the rich text editor is loaded only when a page needs it, and
    theme colours are computed on the server rather than in the browser. Event management pages also
    make fewer duplicate API calls.
  • k6 load test scripts (misc/k6/) and a split backend test suite, with the unit suite kept fast
    and database-free.

A comprehensive end-to-end test suite

This release was built alongside a new Playwright E2E suite: over 160 tests across 66 spec files,
driving the real application — Laravel backend, SSR frontend, Postgres, Redis and a mail catcher —
in a real browser. Registration, event creation, free and Stripe checkout, recurring schedules,
promo codes, questions, messaging, check-in, webhooks and more. Test data is arranged through the
REST API and every spec asserts on real page content, not just URL chan...

Read more

v1.11.1-beta

Choose a tag to compare

@daveearley daveearley released this 11 Aug 20:54
cfbf468

v1.11.1-beta

Security release — upgrading is recommended, especially for hosted or multi-tenant setups. Thanks to the researchers who reported these privately.

Security

  • Webhook SSRF — URLs were only checked at save time; redirects were followed anywhere and IPv6 transition addresses bypassed the filter. Delivery now re-validates, pins the resolved address, and checks every redirect hop — thanks @tonghuaroot, @de3erve, @JaimeRamirez-coder, @senti-man, @angelystor, @1amplant, @tikket1, @Fewword, @dizconnectz
  • Formula injection in exports — buyer-supplied names and answers were written as live spreadsheet formulas; now written as text — thanks @senti-man
  • Order completion race — concurrent requests could complete an order twice, duplicating attendees and exhausting capacity — thanks @tonghuaroot
  • Sale windows not enforced at checkout — products and price tiers could be bought before going on sale, after closing, or at an expired tier — thanks @angelystor
  • max_per_order bypass — the limit was applied per order line, so repeating a product multiplied it — thanks @angelystor
  • Product ownership not checked — questions, capacity assignments and check-in lists accepted products from other events, and cross-event edits detached the owner's products — thanks @Fewword
  • Promo code enumeration — the public lookup endpoint is now throttled — thanks @senti-man
  • Cross-event question tampering — editing or deleting a question via another event rewrote its product links and deleted its answers

Fixes

  • Order, attendee, product and check-in webhooks now dispatch on the queue instead of inline

Other changes

Upgrading

No migrations or config changes. Three behaviour changes worth knowing: webhooks to endpoints that redirect to internal addresses now fail; webhook delivery runs on the queue, so a non-sync connection needs a worker; export cells starting with =, +, - or @ render as text.

Full Changelog: v.1.11.0-beta...v1.11.1-beta

v.1.11.0-beta

Choose a tag to compare

@daveearley daveearley released this 09 Jul 16:54
8da9fee

What's Changed

🌍 Translations & Localization

  • Added Slovak (sk) translation and fixed missing strings across all locales by @pipozzz in #1210
  • Improved French translation by @lionep in #1240

🎟️ Ticketing & Checkout

  • Prevented purchase of hidden products via public checkout by @daveearley in #1259 (Thanks to @0xh3lix for the report.)
  • Rendered offline payment instruction tokens by @realicon23 in #1235
  • Prefilled public checkout from URL query params, including name, email, and optional locking by @skvost in #1234

🔐 Security & Privacy

⚙️ Configuration & Infrastructure

New Contributors

Full Changelog: v.1.10.0-beta...v.1.11.0-beta

v.1.10.0-beta

Choose a tag to compare

@daveearley daveearley released this 01 Jul 21:27
619cbf0

What's Changed

🌍 Translations & Localization

🎟️ Ticketing & Checkout

  • Added ticket date display options by @daveearley in #1214
  • Added organizer setting to hide the checkout “Copy my details to attendees” control by @giuliosmall in #1218
  • Fixed issue where unrelated capacity assignments could block checkout by @realicon23 in #1222
  • Rejected negative product quantities during order creation by @daveearley in #1231
  • Enforced promo code usage limits at order reservation by @daveearley in #1233

🔐 Security & Privacy

  • Sanitized question and organizer descriptions on write by @daveearley in #1232
  • Hid attendee email addresses from the public check-in resource by @realicon23 in #1229

🧪 Tests & Maintenance

  • Aligned email template token assertions with current dot-notation tokens by @mrjbj in #1190

New Contributors

Full Changelog: v1.9.0-beta...v.1.10.0-beta

v1.9.0-beta

Choose a tag to compare

@daveearley daveearley released this 28 Apr 20:45
34f3b6a

What's Changed

  • feat: add organizer tracking pixels with cookie consent by @daveearley in #1166
  • feat: add date range event dashboard charts by @mrjbj in #1161
  • feat: add homepage font controls by @manaskumar3003 in #1169
  • fix: unhide hidden categories in event manage view by @Viburnum in #1138
  • fix: wrap hardcoded "at" in order summary email in translations by @dalsoop in #1171
  • fix: prevent SSR crash on unhandled locale in LanguageSwitcher by @dalsoop in #1170
  • fix: handle CHARGE_REFUNDED and REFUND_CREATED events for non-SaaS Stripe refunds by @mrjbj in #1156
  • fix: preserve sized image dimensions after page reload by @mrjbj in #1158
  • i18n: update Italian translations by @albanobattistella in #1151

New Contributors

v1.8.0-beta

Choose a tag to compare

@daveearley daveearley released this 07 Apr 17:06
6bb839c

What's Changed

New Contributors ❤️

Full Changelog: v1.7.1-beta...v1.8.0-beta

v1.7.1-beta

Choose a tag to compare

@daveearley daveearley released this 28 Mar 14:13
8a5c9d2

What's Changed

New Contributors

Full Changelog: v1.7.0-beta...v1.7.1-beta

v1.7.0-beta

Choose a tag to compare

@daveearley daveearley released this 18 Mar 22:28
1c690c1

What’s Changed


Upgrade Notes

To support waitlists and scheduled messages, you must ensure the Laravel scheduler is running.

If you are using the all-in-one Docker image, the scheduler is already included.
If you are running the backend image or from source, you will need to run it yourself.

See Laravel docs for setup:
https://laravel.com/docs/12.x/scheduling#running-the-scheduler

If the scheduler is not running, waitlists will not release tickets and scheduled messages will not be sent.


New Contributors


Full Changelog
v1.6.0-beta.1...v1.7.0-beta

v1.6.0-beta.1

Choose a tag to compare

@daveearley daveearley released this 26 Jan 22:55
ac7aec0

What's Changed

Feat

Fix

  • fix(orders): error when marking offline order as paid (#1007) by @daveearley
  • fix(checkout): missing “Complete Order” button (#1009) by @nitinog10
  • fix(settings): notify_organizer_of_new_orders toggle not persisting (#1022) by @daveearley

Chore

  • chore(frontend): bump @tabler/icons-react from 2.47.0 to 3.35.0 (#842) by @dependabot[bot]
  • chore(backend): bump laravel/vapor-core from 2.40.0 to 2.41.0 (#817) by @dependabot[bot]

Other

New Contributors

Full Changelog: v1.5.1-beta.1...v1.6.0-beta.1

v1.5.1-beta.1

Choose a tag to compare

@daveearley daveearley released this 08 Jan 22:10
ecb7f08

What's Changed

Full Changelog: v1.5.0-beta.1...v1.5.1-beta.1