How POCtix actually works.
The technical deep-dive for operators who've been burned before and want to verify the architecture before trusting their door scan and their money to a new platform.
POCtix uses Stripe Connect destination charges, which means buyer money lands in your Stripe account directly — we never have custody of your funds. The door scanner is a browser page that caches valid pass tokens locally, so it works offline once loaded. Refunds happen through Stripe's standard refund flow; a webhook fires back to us and voids the QR pass + releases capacity automatically. Buyer emails are yours, exportable as CSV anytime. There is no native app to install, on either side.
1. How the money moves
This is the part that should matter most to anyone who lived through the Brown Paper Tickets payout incident in 2020 or any platform-holds-funds disaster since.
POCtix uses Stripe Connect's destination charges pattern. When a buyer pays:
Stripe→POCtix Stripe account ($2.00 application fee)
Your Stripe→Your bank (standard next-day payout)
The money never lives in our account. Stripe routes it directly to your Stripe-Connected account on the same charge, deducting $2.00 as the application_fee_amount on the way through. We have no way to hold, freeze, or delay your funds — Stripe is the payment processor and you have the Stripe account.
application_fee line item of $2.00, and a payout schedule controlled by your Stripe account settings — not by us.
If POCtix vanished tomorrow:
- Every cleared charge already in your Stripe stays in your Stripe.
- Your pending payouts to your bank continue on Stripe's normal schedule.
- You lose the ability to sell new tickets, but you don't lose the money from tickets already sold.
This is structurally different from the legacy ticketing model where the platform takes the buyer's money, holds it in their account for days or weeks, and ACHes it to you after some event. Patreon, Lyft, DoorDash, and many other marketplace businesses use the same Stripe Connect destination-charges pattern for the same reason — eliminate platform-custody risk for the merchant.
2. How the buyer flow works
From the buyer's perspective, POCtix is just Stripe Checkout with a POCtix-themed confirmation page after:
- Buyer visits the event page (e.g.,
/e/your-event-slug) — pure HTML, no SPA framework, loads in <500ms. - Clicks a ticket tier, gets redirected to Stripe Checkout (your branding via the Stripe account settings + our application fee).
- Pays with card or Apple Pay / Google Pay. Stripe handles 3-D Secure, fraud, declines.
- Returns to
/passes/{order_id}— sees their QR codes immediately, can save them to Apple Wallet (when the cert is live). - Receives an HTML email within ~10 seconds: your venue logo, the event image, every event detail, an inline QR PNG (works offline in the email client, no fetch required).
The buyer never installs an app. They never need a POCtix account. They can verify their tickets later by clicking a "find my tickets" link that emails them a magic login, no password to remember.
3. How the door scanner works (the offline part)
Door staff opens /scan in their phone's browser. No app install, no card reader, no per-station hardware.
The scanner is a small page that uses the browser's camera API to read QR codes. Each scanned token is validated against a local cache of valid tokens for the event — so once the page is loaded, scanning works without internet connectivity. Critical for remote venues, Bush Alaska lodges, North Shore beach events, anywhere cell service is unreliable.
/scan with WiFi→load valid tokens for eventCamera reads QR→validate token locally→green tick
Network returns→scan results sync to server
Other scanner behaviors:
- Two-second debounce — same QR can't double-redeem within 2 seconds (prevents accidental double-scans).
- Already-redeemed warning — if a pass has been scanned earlier in the night, you see "Already scanned 7:34 PM" not just a green tick. Catches duplicate-ticket fraud and bouncer mistakes.
- Refunded pass = red X — if a buyer was refunded, their QR is voided server-side; door staff sees explicit "Refunded — do not admit."
- Multiple staff scanning at once — works fine. Each staff member's scans sync independently. No "scanner conflict" mode.
/scan on your phone with WiFi, scan a test ticket, then turn on airplane mode and scan another. Both work. Re-enable network, watch them sync.
4. How refunds work end-to-end
Refunds are designed so that any path you might use (in-platform button, Stripe dashboard, Stripe CLI, a customer's chargeback) all converge to the same downstream state — pass voided, capacity released, status updated.
Stripe processes refund→fires
charge.refunded webhookPOCtix webhook handler→delete pass(es), release capacity, mark order refunded
Door scanner shows the voided pass as red X if attempted
The webhook is the source of truth. The "Refund" button in our admin is a convenience that calls Stripe's refund API — but the actual pass-void logic is webhook-driven, so refunds initiated any way (admin, Stripe dashboard, Stripe Atlas, a chargeback the cardholder initiates with their bank) all void the QR correctly.
/admin/events/{id} and the capacity counter goes back up. We didn't do anything special — the webhook fired and our handler ran.
5. How emails get delivered
Two-provider delivery infrastructure: a primary transactional API and a fallback SMTP path. If the primary returns an error or doesn't respond in a few seconds, we transparently fall back to the secondary path. Either way the buyer gets their confirmation email within ~10 seconds of payment.
The email itself is full HTML with:
- Your venue logo (uploaded via
/admin/organizers) - The event image (uploaded via event detail page)
- All event details: name, venue, date/time with timezone, ticket type breakdown
- One inline QR PNG per pass (base64-embedded — works offline in the email client, no remote fetch required)
- A buyer-facing link to
/passes/{order_id}to view all their passes - "Purchased on {source_site}" attribution if the order came through a sub-site like AlohaCalendar or LFE
- Plain-text body fallback for email clients that don't render HTML
6. How buyer authentication works
There are no buyer passwords. Buyers use magic-link login:
- Buyer visits
/login, enters their email. - Server emails them a one-time login token (15-minute expiry).
- They click the link, get a signed session cookie, see all their past tickets at
/account.
This is the same pattern Slack, Notion, Substack, and many others use. Better than passwords for B2C buyer accounts because there's nothing to forget, nothing to reuse across sites, nothing to leak in a database breach.
7. Rate limiting + security
Brief notes (full details are intentionally vague to avoid helping attackers):
- Per-IP rate limits on all public POST endpoints (login, organizer inquiry, ticket lookup, checkout). Burst limits enforced via
slowapiusing the Cloudflare-forwarded client IP. - Cloudflare in front of the origin — DDoS protection, WAF rules, edge caching for static content.
- Admin endpoints behind HTTP Basic auth over HTTPS.
- Stripe webhook signature verification — every incoming webhook is verified against the signing secret before processing.
- Sentry error tracking wired (init conditional on env var) — when something breaks, we know within seconds, not when a venue calls.
8. How your data stays yours
Three things make this real, not marketing:
- Buyer email CSV export. Anytime, from
/admin/orders.csv. Every buyer email is yours. We don't use them to market other venues. We don't sell them to third parties. We don't have a "discovery feed" that sends your buyers to events at other venues. - Stripe Connect direct. Your customer payment data lives in your Stripe — including buyer name, billing address, card token. We see the order metadata; Stripe sees the card.
- No vendor lock-in on event data. If you leave POCtix, your future events go elsewhere — but every past ticket scan, refund record, and buyer email is exportable as CSV. We don't hold your historical data hostage.
9. What we don't have (yet)
Being honest about gaps:
- Reserved seating with a seat picker. Tiered capacity yes, individual seat assignment no. Deferred until a real assigned-seat venue asks.
- Native mobile apps for buyer or staff. Browser-only on both sides. Deferred until web scanner shows operational gaps.
- OTA integration (Viator, GetYourGuide, TripAdvisor). We're for direct sales; OTA listings stay on those platforms.
- Discovery marketplace. We're plumbing, not a marketplace. If you need a buyer-discovery layer, use Bandsintown / DICE / Eventbrite alongside POCtix.
- Multi-currency. USD only currently. Multi-currency requires per-venue Stripe Connect account configuration; on roadmap.
- Per-venue custom domains (e.g.,
tickets.yourbar.com). Architected but not yet exposed; ask if you need this.
10. The stack, briefly
If you're the kind of operator who cares: Python/FastAPI backend, PostgreSQL via asyncpg, Jinja2 templates, Stripe Python SDK, Cloudflare CDN, Docker on a Vultr VPS in the US. No serverless cold-starts, no Vercel egress fees, no Mongo. Old-school architecture chosen because it's what we know how to keep running without paging anyone at 2 AM.
The architecture in one sentence
If you give us your Stripe Connect account, we hand you a fully-functional ticketing platform where buyer money goes to your Stripe (not ours), buyer emails go to your CSV export (not our marketing list), and door scans work even when your venue's WiFi doesn't — all for a flat $2.00 per ticket sold.
Verify the architecture by running a real event.
Apply, connect Stripe, create your first event. Every claim on this page is testable in production.
Apply to join vs EventbriteQuestions about the architecture this page didn't cover? Email [email protected]. If you find a security issue, please report it privately to the same address before disclosing publicly.