Commit graph

2 commits

Author SHA1 Message Date
2f8a602bbd feat: attach a self-describing ticket card to the email (1.6.1-aio.10)
Some checks failed
lint.yml / feat: attach a self-describing ticket card to the email (1.6.1-aio.10) (pull_request) Failing after 0s
The v1.6.1-aio.9 mail still scored 8.4/10 on mail-tester: the remaining
deduction was HTML_IMAGE_ONLY (1.8) — an HTML part whose only content of
note is a remote <img>. Remote images are also blocked by default in most
clients until the reader opts in, and a bare QR saved from that mail says
nothing about what it opens.

- New `qr.py` module (QR + logo helpers moved out of views_api) with
  `render_ticket_card`: site title, event name, when/where, the branded
  QR, name on ticket, ticket id and the door instruction, laid out with
  the bundled DejaVu Sans; `format_event_when` gives "Fri 19 Feb 2027,
  16:00 - 20:00"; filenames are `ticket-<event-slug>-<id8>.png`.
- `GET /events/api/v1/ticket-card/{ticket_id}` serves the same PNG
  (anonymous, like the QR endpoint); the email's "Ticket image" link
  now points there.
- The ticket email becomes multipart/mixed: text + HTML alternatives
  (URLs as links, no <img>) plus the card as a PNG attachment, which
  clients show inline at the end of the message and which works offline
  at the door.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
2026-09-08 16:40:25 +02:00
f77ad28bdd feat: return buyers to the calling app after Stripe, branded QR endpoint
`_resolve_frontend_root` honours `CreateTicket.frontend_url` when its
origin is one of LNBITS_CORS_ALLOWED_ORIGINS, the LNbits base URL or
LNBITS_CUSTOM_FRONTEND_URL (400 otherwise — a silent fallback would send
the buyer to the wrong app), and falls back to request.base_url as before.
Under that root the fiat path now parameterises the hosted checkout via
`extra["checkout"]` (lnbits StripeCheckoutOptions): success_url
`/events/{id}?checkout=success&tickets=<ids>`, cancel_url
`/events/{id}?checkout=cancelled`, customer_email, an event-named line
item and event_id/quantity/ticket_ids metadata. Ticket ids are minted
before the invoice so the success URL can carry them (the payment_hash
only exists afterwards). ticket_base_url on the rows uses the same root,
so the emailed link lands in the webapp when the webapp was the client.

Purchases are gated on `effective_payment_methods(event)` (checked after
the free-ticket short-circuit, which charges nothing on any rail).

New anonymous `GET /events/api/v1/qr/{ticket_id}` returns a PNG of
`ticket://<id>` — port of upstream v1.6.8's endpoint without ticket-image
compositing — built at error-correction H with the instance QR logo
(`lnbits_qr_logo`) pasted in the centre, matching the client-side QRs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
2026-09-06 19:53:05 +02:00