BitForgeNet Guest Tickets and Door Check-in

Description

BitForgeNet Guest Tickets runs the evening from the first booking to the last
guest through the door. It was built for clubs, bars and party promoters — the
people for whom an event is a door, a list, and a queue outside.

Nothing is capped and nothing is metered. There is no per-ticket fee, no
external service to sign up for, no account to create, and no telemetry. Your
guest list lives in your own database, on your own server.

Who it is for

  • Clubs, bars and late-night venues
  • Party and concert promoters
  • Private events, galas and weddings
  • Associations, schools and community evenings
  • Anyone taking bookings by card, by transfer, by WhatsApp or in cash

Every guest is a person, not a number

A booking for five asks for five names, and each one gets their own ticket with
its own QR code. One code cannot let five people in, and the door knows who is
standing in front of it.

Tickets that look like tickets

Each one is drawn at 100 x 250 mm, 300 dpi, with the QR engraved into the
artwork, and delivered as a PDF by email. Mail servers strip attachments more
often than they admit, so every message also carries a download link for each
guest.

The door works

Open the check-in station on any phone — no app to install. Point it at a
ticket and it answers in one screen: valid, already used, or not for tonight.
Counters update live, several phones can scan the same event at once, and when
the venue’s wifi gives up — it will — there is a printable roll-call list with
every guest and every ticket number on it.

Payment on your terms

Two ways, and neither is the lesser one.

Take the money yourself: a booking arrives pending, you confirm it however you
actually get paid — bank transfer, WhatsApp, cash at the office — and the
tickets go out the moment you do. Nothing is ever issued for money you have not
received.

Or let the card do it: add your own Stripe key and the guest pays on Stripe’s
page, comes back confirmed, and gets their tickets without you touching
anything. Their places are held while they pay and released on their own if
they walk away, so the same seat is never sold twice. The money goes straight
from the guest to your own Stripe account — this plugin is never in between,
and takes nothing.

What the free plugin does

Everything below is in this plugin. There is nothing to unlock.

  • Unlimited events and unlimited tickets. No cap, no per-ticket fee.
  • Event editor — a four-step wizard to create one, six tabs to refine it:
    dates, capacity, price, registration window, description, artwork.
  • Organizers library — name, logo, colours, contact. Reused across events.
  • Venues library — address, capacity, notes. Reused across events.
  • Public booking page — one shortcode, [bitforgenet_registration]. Asks
    for the name of every person coming, respects capacity and the registration
    window, and confirms on screen.
  • Bookings screen — search, filter by event and status, confirm payment,
    add an internal note, resend an email, cancel.
  • Personal QR tickets — one per guest, rendered as a PDF, sent by email
    with a download link alongside.
  • Built-in ticket design, generated in the colour of your choice and
    painted on demand at 300 dpi.
  • Door check-in station for any phone, opened with a per-event door code,
    with live counters and multi-station scanning.
  • Printable roll-call list for the evenings the network fails.
  • CSV export with a column picker — bookings or guests, one event or all,
    every field the plugin holds, and it remembers what you ticked.
  • Tools and data — a system check that tells you why a ticket or an email
    did not arrive, a test-ticket email, a database check, and an
    archive-and-clear that copies every booking into archive tables before
    emptying the live ones, behind a one-time code sent to an address you
    nominate.
  • Rooms and places — describe the room once and the plugin hands out the
    places: a plain capacity, or named zones with a capacity and a price each
    (VIP, balcony, standing, whatever you call them). The seat a guest is given
    is printed on their ticket.
  • Card payment with Stripe — the guest pays on Stripe’s own page and comes
    back with their booking confirmed. Their places are held while they pay and
    released on their own if they never finish, so the same seat is never sold
    twice. Optional: an event paid at the door or by transfer works exactly as
    before, and the money goes straight from the guest to your own Stripe
    account — this plugin is never in between and takes nothing.
  • Searchable archive of everything that has been cleared.
  • Activity log — who did what, and when.
  • Delete-all-data on uninstall, if you tick it. Off by default.

BitForgeNet Pro

Pro is a separate plugin, bought from us and installed alongside this one. It
does not unlock anything here — this plugin is complete on its own. Pro adds
capabilities that are not in it at all:

  • Ticket studio — bring in your own artwork, generate colour variations of
    it, and move every printed field where you want it with a visual field map.
  • The floor plan editor — draw the room itself: the stage, curved rows,
    round tables, standing areas, aisles, and a seat numbering that runs whichever
    way your venue counts. Rooms described as a capacity or as named zones are in
    the free plugin; what Pro adds is drawing one.
  • The floor, live — every table and row on one screen while the evening
    fills, and a booking placed at a table by hand or on the plan itself.
  • Price categories — VIP, table, early bird, member: several prices on one
    event instead of one.
  • Discount codes — fixed or percentage, limited by date or by number of
    uses.
    Pro is announced at https://bitforgenet.dev/

Reporting a security issue

If you find something, write to the address on
https://bitforgenet.dev/ and it will be looked at, fixed and credited here by
name unless you would rather not be. Please test against your own installation
rather than somebody else’s.

Thank you to Alik for the two issues fixed in 1.2.1.

Privacy

The plugin stores what a booking needs — names, email address, phone number —
in your own database, on your own server. Email goes out through WordPress,
which means through whatever mail service your site already uses. There is no
account to create with us and no telemetry: nothing is ever sent to BitForgeNet.

External services

The plugin uses one external service, and only if you set it up yourself.

Stripe — used only when you enter a Stripe secret key under Settings
Payments and turn card payment on for an event. Until then no connection to
Stripe is ever made.

When a guest chooses to pay by card, the plugin asks Stripe to open a payment
page and sends what that page has to show: the amount, the currency, the event
title, the booking reference, the number of tickets in each category, and the
guest’s email address so Stripe can send them a receipt. The guest is then
taken to a page hosted by Stripe, where they enter their card details. No card
number ever reaches your site or this plugin. Stripe tells your site the result
in a signed message, and the plugin reads the payment status back from Stripe
before it confirms anything.

Stripe is a service of Stripe, Inc.
Terms: https://stripe.com/legal/ssa
Privacy: https://stripe.com/privacy

Installation

Requirements

  • WordPress 5.8 or later
  • PHP 7.4 or later
  • The GD extension, for rendering the tickets
  • A working mail setup on the site — an SMTP plugin if your host’s mail is
    unreliable

Steps

  1. Plugins -> Add New, search for BitForgeNet Guest Tickets, install and
    activate. Or upload the ZIP under Plugins -> Add New -> Upload Plugin.
  2. Open BitForgeNet -> Settings and set your currency, your From address
    and your payment instructions.
  3. Open BitForgeNet -> Tools & data, run the system check, then send
    yourself a test ticket. Do this before your first real booking, not after.
  4. Create your first event with BitForgeNet -> Events -> New event.
  5. Put the booking form on a page with the shortcode
    [bitforgenet_registration].
  6. On the night, open BitForgeNet -> Door scanner, note the door code, and
    give the link and the code to whoever is on the door.

FAQ

Is there a limit on events, guests or tickets?

No. Nothing in this plugin is capped or metered, and there is no per-ticket
fee. What your server can hold is the limit.

Do guests need an account?

No. A guest fills in the form, receives their tickets by email, and shows the
QR code at the door.

Does it need WooCommerce?

No. It has its own booking form and its own bookings screen, and it works on a
site with no shop on it.

Can I take payment online?

Yes, with Stripe, and it is in this plugin — not in Pro. Put your own Stripe
secret key in Settings Payments and turn card payment on for the events you
want it on. The guest pays on a page hosted by Stripe, no card number touches
your site, and the money goes straight to your own Stripe account: this plugin
is never in between and takes nothing per ticket, ever.

Until you enter a key, nothing changes and no connection to Stripe is made. A
booking arrives pending and you confirm it once you have been paid — by
transfer, by WhatsApp, or in cash — exactly as before.

Do I have to make guests pay by card?

No. It is a choice per event, and you can also let a guest reserve now and pay
later: they get both buttons. If you would rather nothing be reserved until it
is paid for, there is a single setting for that.

Does one booking give one QR code for everybody?

No, and that is the point. A booking for five produces five tickets with five
different codes, each carrying the name of the person it belongs to.

The tickets are not arriving.

The plugin sends through WordPress, so anything that fixes email for the rest
of your site fixes it here. Run Tools & data -> System check first: it says
whether the failure is in the rendering or in the sending. If your host’s mail
is unreliable, install an SMTP plugin and connect a real mailbox — it will be
picked up automatically.

The email arrives but the PDF is missing.

Your mail server is stripping the attachment. Lower the attachment ceiling in
Settings; every email already carries a download link per guest, so the guest
still gets their ticket.

Does the door scanner need internet?

It needs to reach your own website, the same as any other page. For the
evenings when the venue’s wifi is not to be trusted, print the roll-call list
first: it carries every guest and every ticket number, and it works on paper.

Do I need to install an app on the door phone?

No. The station is a web page. Open the link in the phone’s browser, enter the
door code, and allow the camera.

Can two people scan at once?

Yes. Every station checks the same database, so a ticket used at one door is
already used at the other.

The camera stays black on the door phone.

The page must be served over HTTPS — browsers refuse the camera otherwise. If
the site is already on HTTPS, a security plugin or your CDN is probably sending
a blanket camera policy; the scanner screen re-states its own, so clearing the
CDN cache usually settles it.

Can I use my own ticket artwork?

The free plugin generates its design for you, in the colour you choose.
Bringing in your own artwork and placing the printed fields yourself is what
the ticket studio in BitForgeNet Pro does.

Can I clear the test bookings before going live?

Yes. Tools & data -> Archive and clear copies every booking, guest, ticket
and scan into archive tables and then empties the live ones. Events, venues,
organizers and designs are untouched. It asks for a one-time code sent to an
address you set, so it cannot be run by accident.

Is it translated?

Every string in the plugin is translatable. Translations are welcome at
https://translate.wordpress.org/projects/wp-plugins/bitforgenet-guest-tickets/

Where do I get help?

The support forum on this page, or contact@bitforgenet.dev

Reviews

There are no reviews for this plugin.

Contributors & Developers

“BitForgeNet Guest Tickets and Door Check-in” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

1.2.1

Two security fixes, both reported responsibly by Alik, who tested 1.0.9 in
an isolated environment and sent a clear, accurate write-up of each. Both were
real. Thank you.

Bookings for one event now happen one at a time. Counting the free seats
and taking one were two separate steps, and between two steps another request
fits: two people clicking at the same instant could both be told there was one
seat left, and both take it. The capacity check was never wrong — it was just
on the wrong side of a gap. That gap is now closed with a lock held for the
length of a booking, per event, so a busy night with four events does not queue
into one line. Every capacity rule is now inside it: the event’s own capacity,
each price category, and each area of the room. (CWE-362.)

Forwarding headers are no longer believed by default. The plugin recognises
a visitor by their address in order to count how often they book. It used to
read CF-Connecting-IP, X-Real-IP or X-Forwarded-For if they were present —
but those are written by whoever is making the request, so anybody could invent
one and get a fresh allowance. Only the address the connection actually came
from is used now. If your site really is behind Cloudflare or a reverse proxy,
say so under Settings Anti-abuse, and the panel shows you what your server is
actually sending so the choice is not a guess. Naming your proxies in
wp-config.php as BFNET_TRUSTED_PROXIES narrows it further. Where a list of
forwarded addresses is read, the plugin now takes the entry the nearest proxy
wrote rather than the one at the front, which is the one a visitor can invent.
(CWE-799.)

Also: a second booking limit counted per email address, so getting around
the per-connection one is no longer enough on its own.

1.2.0

Everything below arrived since 1.0.9. It was built and tested over several
internal builds; this is the first of them anyone is offered, because a version
that was superseded the same week is not a version worth installing.

Rooms and places. An event can now describe where people sit. Three levels,
and nobody is made to climb them: a plain capacity, named zones with a capacity
and a price each, or — with Pro — a drawn floor plan. Seats are worked out
from a rule rather than stored, so a four thousand seat auditorium is twenty
rows in your database and not four thousand. The numbering runs whichever way
your venue counts: left to right, right to left, odd and even out from the
centre, alternating by row. It can skip row I and O, skip 13, start anywhere,
and carry a prefix.

Card payment with Stripe. Set your own secret key and a guest can pay on
Stripe’s own page. No card number reaches your site. A payment is confirmed by
reading it back from Stripe and by a signed message Stripe sends your site —
never by the browser that came back. Your places are held for the length of the
payment session and released on their own if nobody finishes, so the same seat
cannot be sold twice. Card payment is optional, per event: an evening paid at
the door works exactly as it did before.

When the ticket goes out, per event. Acknowledge the booking now and send
the ticket once you have decided where somebody sits, or — when the event has
a room — send it straight away with the place printed on it.

The booking page no longer depends on a page. If a direct link to an event
has nowhere to open, the plugin renders the booking form itself inside your
theme. It also creates the booking page for you, once, rather than leaving a
link that opens nothing.

Fixed

  • A booking link opened an empty page on sites that had never added the
    shortcode themselves.
  • Guest rows two and after on the manual booking screen were greyed out instead
    of hidden, because the plugin’s own stylesheet beat the browser’s rule.
  • The Reserve button was clipped by themes with their own line height.
  • Sold-out categories were still offered for booking; a category is now closed
    by the room as well as by its own capacity, and the last place is re-counted
    at the moment the booking is written rather than only when the page was
    drawn.
  • Reverting a booking to awaiting payment cleared the check-ins but kept them
    in the history, named.

Also added

  • Add a guest by hand, for the bookings that arrive by phone.
  • A live floor view of the evening — what is taken, what has arrived, and what
    is full — with the room drawn as the organizer drew it.
  • The confirmation screen says which address the email went to, and to look in
    the spam folder.
  • Keyboard in the plan editor: undo, redo, delete, escape, shift to select
    several, and a number beside every slider.

1.0.9

  • The logo printed on the ticket, on the door’s code screen and beside an
    organizer with no artwork of its own is the anvil alone. It had been the full
    lockup, wordmark included, which the renderer fits inside its box: a wide
    image with words in it shrank to a smudge nobody could read
  • The plugin’s page is rewritten. The feature list now says what this plugin
    actually does — the organizer and venue libraries, the export column picker,
    the system check and the archive were all shipped and none of them were
    mentioned, while three of them were wrongly described as belonging to Pro.
    The Pro section says what Pro adds instead of hinting at it, and the FAQ
    answers fifteen questions rather than five. No code changed for this

1.0.8

  • Every template under admin/views/ and public/views/ states once, at the top of
    the file, that the PrefixAllGlobals naming rule does not apply to it. A
    template is included from a method, never at file scope, so its variables
    belong to that method’s scope rather than the global one, and PHPCS — reading
    each file on its own — has no way to see where the include happens. No
    variable was renamed and nothing behaves differently

1.0.7

  • The plugin is renamed. It was submitted as “2KEvents”, and “2K” is a
    registered trademark of Take-Two Interactive that we have no right to lead a
    name with. The display name, the slug, the text domain, the shortcodes and
    every PHP prefix now read BitForgeNet — the name of the site that publishes
    it, bitforgenet.dev
  • Every stylesheet and script the plugin prints goes out through the enqueue
    API. The door station and the two screens around it are their own HTML
    documents, served on their own endpoint before the theme runs, so they had
    carried their CSS and JS inside the page. They now register handles and print
    them by name, the two runtime values arriving through wp_add_inline_style()
    and wp_add_inline_script()
  • The admin menu icon is assembled from the mark at runtime and has no file
    behind it, so it registers a style handle with no source rather than printing
    a style tag into the head, and moves to admin_enqueue_scripts
  • The code prefix is five characters. It was three, which is under the four the
    directory asks for

1.0.6

  • Finished the tidy-up the last two releases started: every code-quality
    suppression in the plugin is now either stated once for a whole file or
    written on the single line it covers, and none of them can change the
    meaning of another one elsewhere in the same file. No behaviour changes

1.0.5

  • Fixed suppression comments that did not cover what they appeared to cover.
    One kind switched every code-quality rule back on rather than the one it had
    switched off, quietly undoing notes written elsewhere in the same file; the
    other sat above a nine-line statement instead of around it. No behaviour
    changes for anyone using the plugin

1.0.4

  • Request input is now read the way it should be read: eight admin screens
    applied the integer cast to the whole expression rather than to the value,
    and the export column list is sanitised where it arrives rather than three
    calls later
  • The design proof screen now checks its parameter exists before reading it
  • Every file that queries the plugin’s own tables says so once, at the top,
    with the reason
  • Dropped a call asking WordPress to load translations it already loads by
    itself, and closed a hatch that let the QR encoder run outside WordPress

1.0.3

  • Fixed translatable strings that a translator could not have got right. The
    guest counter on an order wrote its two numbers as bare placeholders, which
    a language that reorders the words has no way to move, and several strings
    carrying a placeholder had no note saying what the placeholder holds.

1.0.2

  • The plugin header pointed at a placeholder address. It now points at the
    plugin’s own page, and the author is named.
  • The address authorised to reset the plugin’s data shipped with a developer’s
    own address already filled in. It now starts empty, and the tool refuses to
    run until an administrator sets one.
  • Added the full text of the SIL Open Font License beside the bundled Poppins
    and Lora fonts, as that licence requires.

1.0.1

  • Fixed the door station refusing every scan with “Station closed”. The page
    opened and showed the event, but each scan was posted to an address that no
    longer said which event the station was watching, so the server treated it as
    a station that had signed out. Nobody could be checked in

1.0.0

  • First release.