Brussels Premier Padel 2027 · architecture technique
Ticketing Onebox TDS
Vue complète de l'intégration : vitrine, plateforme ambassadeurs, back-office, collecte analytics, webhooks signés et réconciliation. Chaque flux porte son contrat. Le dernier bloc liste ce qu'il faut fournir pour lancer le chantier.
1. Vue d'ensemble
Trait plein = appel synchrone. Trait pointillé = flux asynchrone (webhook, job, token). Le widget Onebox est le seul composant tiers exécuté dans le navigateur.
2. Les pages, une par une
Vitrine — bpp27.tero.be
Page
Rôle
Dépendances ticketing
/fr/billetterie/ · /nl/tickets/ · /en/tickets/
Configurateur : session → formule → zone → sièges → code
Comment une vente Onebox devient un chiffre dans le back-office et une ligne dans l'espace d'un ambassadeur. Ce schéma décrit le circuit complet, y compris les échecs.
1. Sources de vérité, et qui gagne en cas de conflit
Donnée
Source autoritaire
Copie locale
En cas de conflit
Commande payée
Onebox Orders API
orders_local
Onebox gagne ; écart journalisé
Billet vendu
Onebox (lignes de commande)
sales (1 ligne = 1 billet)
Onebox gagne ; ligne locale supprimée logiquement
Remboursement
Webhook REFUND + Orders API
sales.amount ajusté
compteur de paliers recalculé à la baisse
Attribution ambassadeur
Nous : code porté par la commande
orders_local.code
si absent : file de revue, jamais deviné
Trafic, comportement
Notre collecte first-party
analytics_events
GA4/Ads sont des copies sortantes
2. Contrats internes
Endpoint
Appelé par
Entrée
Sortie
Sécurité
POST /api/tickets/quote
Configurateur vitrine
session, formula, qty, code
prix, remise, disponibilité
Zod, rate-limit, origine
POST /api/orders
Vitrine (serveur)
session, seats, code, locale
order_code (BASKET)
idempotency-key
POST /api/webhooks/onebox
Onebox
headers ob-* + JSON
200 si signature valide
HMAC sha256, delivery-id unique
POST /api/analytics/collect
analytics.js
1 évènement + consent_version
204 / 400 / 403 / 413 / 415 / 429
origine, rate-limit, PII refusées
POST /jobs/onebox-backfill
Worker 02:00
from, to
traités, écarts
interne, RBAC system
3. Attribution du code — trois règles, dans l'ordre
Référence de commande. À la création de l'ordre, reference = BPP27-XXX-000. Si le webhook la renvoie, l'attribution est certaine : c'est le chemin nominal.
Session d'achat. Si la référence manque mais qu'un code est mémorisé côté client (cookie 30 j, consentement requis), on l'applique.
File de revue. Sinon la vente est marquée unattributed et apparaît dans /admin/ventes. Aucune attribution n'est devinée.
Cas limites tranchés : remboursement partiel ajuste le montant sans retirer la vente ; billet offert compte pour la session mais pas le revenu ; un code par commande (multi-codes refusé) ; deux codes différents = deux commandes.
4. Réconciliation — le filet, pas le moteur
Le webhook est le chemin nominal. Chaque nuit à 02:00 Europe/Bruxelles, le worker appelle Orders API sur la fenêtre écoulée (grâce 6 h), compare à orders_local et produit un rapport d'écart : commandes manquantes, statuts divergents, montants différents. Chaque écart crée un job de correction idempotent et une entrée d'audit. Le rapport d'écart est affiché dans /admin/ventes : non nul = incident, pas statistique.
5. Définitions des indicateurs
Indicateur
Définition exacte
Piège évité
Session
session_hash distinct, 30 min d'inactivité
confusion avec visite serveur
Conversion billets
commandes confirmées / sessions ayant atteint « devis prêt »
jamais > 100 %
Revenu
montants confirmés moins remboursements
hors billets offerts et frais
Ventes d'un ambassadeur
billets attribués sur la période du programme
hors période exclus du classement
Paliers atteints
cumul depuis le début, gelé à la clôture
un remboursement peut faire redescendre
6. Qui voit quoi, et avec quelle latence
Surface
Vue
Latence
Exclusions
Espace ambassadeur
son code, ses billets, progression, rang
< 1 min après webhook
autres codes, données acheteur
Classement
top 50 + sa ligne
temps réel
ventes non attribuées
/admin/ventes
commandes, écarts, remboursements
temps réel
—
/admin/entonnoir
6 étapes par code, taux chaînés
5 min
évènements sans consentement
/admin/stats
audience, sources, device, cohortes
5 min
tests internes
7. Pannes, symptômes, comportement attendu
Panne
Symptôme
Comportement
Webhook non reçu
vente absente de l'espace ambassadeur
rattrapage nocturne + écart affiché, jamais silencieux
Signature invalide
401 sur le webhook
rejet, alerte admin, pas de retry infini
Token Onebox expiré
catalog indisponible
cache 60 s + statut « erreur » dans /admin/integrations
Consentement refusé
trou dans les stats
affiché « non mesuré », jamais zéro
Worker en retard
compteurs en retard
heartbeat + âge du dernier job visibles
8. RGPD et sécurité
Jamais en base : nom, e-mail, IP, user-agent, gclid, numéro de commande en clair. Session = hash tronqué, code = hash pour les stats fines.
Consentement : aucun évènement avant accord, refus = purge de file, consent_version conservé comme preuve.
Rétention : 13 mois analytics, purge mensuelle outillée ; ventes selon obligation comptable.
Secrets : chiffrés au repos, jamais réaffichés, audit de chaque changement, masqués dans les exports.
Webhooks : HMAC obligatoire, idempotence par delivery-id, corps jamais cru sans vérification d'API.
9. Runbook du jour d'ouverture
Avant : /admin/integrations → Onebox « configuré », test token OK, webhook test reçu, écart de réconciliation à 0.
H-1 : vente de contrôle en production (montant minimum, code de test) → webhook, espace ambassadeur, /admin/stats.
H : surveiller /admin/ventes (écarts) et /admin/stats (sessions).
Écart : rejeu admin uniquement, idempotent et journalisé. Jamais de correction manuelle en base.
Après : réconciliation du lendemain à 0, sinon incident ouvert avec l'heure et la commande.
10. Ce qui reste à construire
Élément
État
Bloqué par
Webhooks Onebox + attribution
spécifié, non codé
secret HMAC + décision reference
Réconciliation nocturne
spécifiée
worker B-04
Envoi GA4 / Ads / Brevo
flags + tests prêts
clés + Consent Mode v2
Sous-ensemble polices (dérogation LCP)
à refaire
outillage fontTools
Décommissionnement Fever
planifié
fin de saison 2026
4. Ce qu'il faut pour lancer l'intégration
Compte & accès
Environnement test : api.oneboxtds.net
client_id, client_secret du seller channel
channel_id
Accès au back-office Onebox (événement, sessions, tarifs)
Domaines autorisés
bpp27.tero.be (widget)
staging-ambassador.bpp27.tero.be
architecture.bpp27.tero.be (cette page)
Sans ça, le widget refuse de s'initialiser
Données événement
Event Onebox ↔ nos 18 pages
8 jours / 2 sessions : mapping session_key
Formules A→G ↔ produits Onebox
Zones : Central / Fixed Seats / VIP
Grille tarifaire 2027 (bloquant commercial)
Webhooks
URL de réception + IP/plages si filtrage
Secret HMAC de signature
Abonnement : ORDER (PURCHASE, REFUND, CANCEL), TICKET, EVENT, SESSION
Fenêtre de retry et politique de rejeu
Certification
Parcours de certification Onebox (doc /docs/certification)
Scénarios à rejouer : achat, remboursement, hold expiré, rupture
Validation avant bascule production
Décisions produit
Qui crée l'ordre : nous (attribution fiable) ou le widget (plus simple, attribution fragile)
Champ libre reference accepté sur les lignes ?
Checkout hébergé ou maison
Remboursements : self-service admin ou Tero uniquement
Conformité
CGV et politique de rétention à valider
DPA Onebox / transferts
Consent Mode v2 avant GA4/Ads
Mention « prix à l'ouverture » tant que la grille n'est pas validée
Exploitation
Comptes admin Tero (noms + emails)
Adresse de contrôle des emails
Fenêtre de bascule + rollback
Qui répond en cas d'incident le jour J
5. Ordre de mise en œuvre
Lot
Contenu
Durée
Dépend de
L1
Module onebox dans le registre + OAuth2 serveur + bouton de test