Placeful 2.5 — security hardening, reconciliation & voucher sales
Highlights
- Supplier-document reconciliation — scan bolla and fatture by phone or upload, AI-assisted data extraction (multi-page sessions, FatturaPA XML), and a three-way match queue that ties each supplier invoice to its delivery note and bank movement. PSD2 bank feeds via GoCardless/Enable Banking keep transactions in sync.
- Voucher sales & redemption — sell balance vouchers on promo codes, track purchases, and let guests redeem them at checkout with remainder collection. Legacy codes re-mint to the stronger 12-character space on next save.
- Assistant everywhere — the AI assistant gains 23 read tools and 20 staged write tools spanning orders, staff ops, door queue, marketing and reconciliation; every write is previewed and confirmed before it lands.
Security
- Full-codebase security audit — every staff and guest surface was re-audited: cross-tenant reads are pinned to the mounted company, server-owned Livewire props are locked against tampering, and privileged actions re-authorize on every request.
- Credential & token hygiene — API tokens carry scoped abilities and expire on a configurable TTL; widget claim links bind to the browser that started them; social sign-in passes the two-factor challenge; password-reset URLs are disallowed in robots.txt so a leaked link is never crawled.
- Data-protection depth — erasure and access requests require a verified mailbox before running, demo personas can never mint sessions or API tokens, and exports land on a private disk with 7-day retention instead of public URLs.
- Safer integrations — outbound webhooks sign payloads and re-validate endpoints against SSRF on every delivery, and Google Calendar teardown skips remote deletes when the connection is already gone instead of erroring per mirror.
Operations
- Webhook platform — outbound signed webhooks with HMAC verification, per-secret rotation, replay, and a delivery log; endpoints are SSRF-validated at registration and re-checked at every delivery.
- Kitchen printing — ESC/POS over a local print bridge or the browser, per-station routing, job leases with an autonomous reaper, and print-job retention.
WhatsApp & messaging
- WhatsApp outbound — Meta-approved template sends for booking confirmations, reminders and reconfirmation links, a campaign leg with per-recipient delivery state, and an inbox that groups threads by counterparty with consent-safe staff replies (STOP always wins).
- Consent receipts — every channel grant/revoke writes an append-only receipt; START opens the channel only — marketing needs an explicit opt-in (guest editor toggle or the booking-form checkbox). Message bodies and payloads are scrubbed past the retention horizon.
Widgets & embedding
- Unified embed builder — one settings surface generates script, button and iframe embeds for every widget: booking calendar, gift vouchers, private-event inquiries and email capture. Per-widget styling and audience filters stay, now behind a single mode picker.
- Every widget rides the secure pipeline — inquiry and capture embeds now mint the same short-lived, origin-bound session as the booking calendar and render inside
/embed, with locale, UTM attribution and live kill-switch checks on every render. - Per-mode kill switches — switch off any single widget surface from settings and every embed, snippet, direct URL and bare public page refuses it instantly, without touching the others.
- Direct forms go allowlist-bound —
/capture/{company}and/inquiry/{company}stay publicly reachable, but once allowed domains are configured they can only be framed by those sites (frame-ancestors), closing the clickjacking gap on lead and signup forms. The/embediframe itself is now bound to the validated host too, and the stable/w/{key}URL shows a readable "Widget unavailable" page instead of raw JSON when a plan, domain or kill switch refuses it. - Cross-company widget isolation — a signed-in user of another company renders a public widget as an ordinary visitor (no staff powers, company context never switches); the validated embed origin is re-checked against a timestamped marker that stays fresh for six idle hours while the iframe token still expires after 15 minutes; and
php artisan widget:allowlist-auditreports active widget-enabled integrations with an empty allowed-domains list before rollout.
Privacy & data
- Erasure & export coverage — aggregator inbounds, supplier document lines, and kitchen-print rows join the company export archive and anonymization graphs.
- Audit hardening — bank account and match-state mutations, plus promo redemption decisions, are now audited with the actor stamped.