Serve materializzazione - È necessaria una materializzazione del planning
booking
Prenotazione con caparra Stripe
Prenotazione online con incasso caparra non rifondibile via Stripe a conferma slot, saldo a saldo successivo o on-site.
Cosa fa questo modulo
Modulo «Prenotazione con caparra Stripe» (deposit on booking): durante la finalizzazione della prenotazione (slot calendario, camera, noleggio, lezione, sopralluogo, sala, mezzo, servizio) il cliente paga una caparra (importo fisso o % del totale, configurabile globalmente o per tipologia risorsa/servizio) tramite Stripe come condizione necessaria per confermare il booking. Architettura pagamento: integrazione Stripe via `stripe/stripe-php` SDK con Payment Intent API (`payment_intents.create` con `amount`, `currency=eur`, `capture_method=automatic` per incasso immediato, oppure `manual` con `payment_intents.capture` differita su conferma operatore per workflow approvazione; `customer` Stripe creato/recuperato per ricliente con email match; `metadata` con `booking_id`, `risorsa_id`, `tipo=deposit`; `description` umana «Caparra prenotazione #1234 — Camera Suite Vista Mare»; `statement_descriptor` per estratto conto carta cliente; `automatic_payment_methods.enabled=true` per Stripe abilitare metodi configurati nel dashboard come carte, Apple Pay, Google Pay, SEPA, Klarna, Bancontact, iDEAL secondo paese cliente; SCA/3DS gestita nativamente da Stripe con redirect/popup `confirmPayment` lato client Stripe.js). Frontend checkout: integrazione Stripe Elements (Payment Element unico component drop-in con styling custom matching brand cliente, oppure Card Element + altri metodi separati per UI granulare) o Stripe Checkout (pagina hosted Stripe più rapida da integrare, meno personalizzabile, redirect esterno con success_url/cancel_url verso pagine app); validazione client-side prima di submit (campi cliente nome/cognome/email/telefono/data slot/risorsa obbligatori), creazione Payment Intent server-side via endpoint dedicato `POST /booking/{id}/deposit/intent` che ritorna `client_secret` al frontend, conferma payment lato client via `stripe.confirmPayment({elements, confirmParams: {return_url}})`, gestione esito redirect su `/booking/{id}/payment-result` che verifica status Payment Intent via webhook o polling. Flusso prenotazione: utente seleziona slot/risorsa/data → form dati cliente (nome, cognome, email, telefono, note, eventuali campi custom per tipo prenotazione come numero ospiti, accessori noleggio, etichetta lezione, opzione assicurazione) → riepilogo con dettaglio totale stimato + caparra evidenziata + saldo residuo + politica cancellazione/rimborso esplicita («caparra non rifondibile in caso di no-show o cancellazione tardiva entro N giorni dalla data, rimborsabile se cancellazione entro M giorni prima oppure se la struttura/operatore cancella per cause sue») → spunta accettazione T&C e privacy/GDPR con timestamp e IP tracciati → pagamento Stripe → conferma. Stato prenotazione: stati gestiti `draft` (form aperto, slot non bloccato), `pending_payment` (Payment Intent creato, slot riservato temporaneamente per N minuti con job di rilascio automatico, vedi sotto), `confirmed` (caparra incassata, slot definitivo, email/SMS/WhatsApp conferma cliente, notifica operatore), `cancelled_by_customer` (cliente annulla, gestione rimborso secondo policy), `cancelled_by_business` (struttura annulla, rimborso integrale automatico), `no_show` (cliente non si presenta, caparra trattenuta), `completed` (servizio erogato), `refunded_partial`/`refunded_full` (a seguito di rimborso). Slot locking: nel momento in cui il cliente avvia il pagamento (Payment Intent creato), lo slot viene riservato con timestamp `slot_reserved_until` (default 15 min, configurabile) per evitare doppia prenotazione simultanea; job scheduler ogni minuto rilascia slot scaduti senza pagamento confermato e cancella relativi Payment Intent (`payment_intents.cancel` con cancellation_reason=`abandoned`). Webhook Stripe: endpoint `/stripe/webhook` verificato con firma Stripe (`Stripe-Signature` header + `STRIPE_WEBHOOK_SECRET` in `.env`), gestione eventi `payment_intent.succeeded` (booking → confirmed, email conferma, evento creato in agenda, eventuale sync con #8325 calendar sync), `payment_intent.payment_failed` (notifica cliente con motivo specifico carta declined/insufficient funds, slot rilasciato dopo timeout), `payment_intent.requires_action` (3DS pending, attesa azione cliente), `charge.refunded` (booking → refunded, registrazione causale rimborso), `charge.dispute.created` (apertura chargeback, freeze operativo + alert admin), `payout.paid` (estratto conto bonifici Stripe→banca). Importi e calcolo caparra: tabella `pricing_rules` con regole flessibili (caparra fissa €50 per noleggio scooter, 30% per soggiorni hotel >3 notti, 100% per eventi premium con pagamento anticipato totale, soglia minima/massima caparra in valore assoluto), supporto multi-valuta (EUR default, USD/GBP/CHF se cliente target internazionale), gestione IVA (caparra come acconto fiscale con causale `acconto`, fattura/ricevuta proforma emessa immediatamente, fattura definitiva al saldo collegata), arrotondamento configurabile (€0.01/€0.50/€1). Rimborsi: pannello admin con pulsante «Rimborsa» per booking che chiama `refunds.create` con `payment_intent`+`amount` (totale o parziale), motivo configurabile (`duplicate`/`fraudulent`/`requested_by_customer`/custom), tracking rimborso con stato `pending`/`succeeded`/`failed`, notifica cliente automatica con email contenente importo+data+riferimento Stripe per estratto conto, policy automatiche (es. cancellazione entro 7gg = rimborso 100% trigger automatico, entro 3gg = 50%, sotto = 0%). Saldo residuo: dopo il check-in/erogazione servizio l'operatore può incassare il saldo via stesso modulo (Payment Intent dedicato linkato al booking originale via metadata `parent_booking_id`+`tipo=saldo`), oppure registrare incasso saldo on-site con metodo alternativo (POS, contanti, bonifico) marcando booking come `paid_in_full` senza ricevere ulteriore importo via Stripe. Multi-account Stripe (multi-tenant): per app B2B che servono più strutture/operatori, Stripe Connect Standard o Express con onboarding link `accounts.create` + `account_links.create` per ciascun merchant (struttura ricettiva, noleggio, studio professionale) con caparra incassata direttamente sul conto del merchant, fee piattaforma trattenuta via `application_fee_amount` (es. 3% del transato per piattaforma SaaS), payout automatici T+2 sul conto bancario merchant senza passaggio intermediario nei conti app. Email e ricevute: invio automatico ricevuta Stripe nativa (`receipt_email` impostato) + ricevuta custom branded app via #8331 mail transazionali (template `booking_confermato_con_caparra` con dettaglio slot+importo caparra incassato+saldo residuo+QR code check-in+istruzioni arrivo+contatti struttura+link cancellazione self-service), reminder pre-data (24h/72h prima) via #8331 o #8332 SMS con dettaglio caparra già pagata, email rimborso con riferimento Stripe. Cancellazione self-service cliente: link unico in email conferma `/booking/{token}/cancel` con token firmato Laravel (`URL::temporarySignedRoute`) che apre pagina con dettaglio prenotazione+policy+pulsante annulla, calcolo automatico rimborso secondo policy, conferma cancellazione + rimborso automatico se applicabile + notifica struttura. Admin booking management: pannello backend con datatable booking (filtri stato+data+risorsa+importo+search nome/email cliente), dettaglio singolo booking con timeline eventi (created/payment_intent_created/payment_succeeded/email_sent/reminder_sent/cancelled/refunded), allegati documenti caricati cliente in pre-checkin, note operatore interne, log pagamenti Stripe con link diretto a dashboard Stripe per ogni transazione, azione manuale «marca no-show», «marca completata», «rimborso manuale», «rinegozia importo» con audit trail. Gestione errori e UX: messaggi errore Stripe localizzati in italiano (es. `card_declined` → «Pagamento rifiutato dalla tua banca. Prova con un'altra carta o contatta l'istituto bancario.»), retry payment con stesso slot riservato per evitare perdita customer, fallback metodi alternativi se carta primaria fallisce (proposta automatica Apple Pay/Google Pay/SEPA), pagina success con grafica conferma + dettaglio booking + link aggiungi calendario Google/iCal + condividi su WhatsApp + recensione post-servizio. Reportistica: dashboard con KPI giornaliero/settimanale/mensile (booking confermati, caparre incassate, no-show rate, cancellation rate per finestra temporale, conversion rate da carrello a payment_succeeded, average deposit value, refund rate, dispute rate, payment failure rate per metodo/banca, abbandono checkout per step), export Excel/CSV (via #8328) di transazioni per commercialista con causale acconto/saldo separate, riconciliazione automatica payout Stripe vs movimenti banca via webhook `payout.paid`. Sicurezza e PCI: nessun dato carta toccato dal server applicativo (Stripe Elements/Checkout PCI DSS SAQ-A compliance), HTTPS forzato su tutto il flusso checkout, webhook con verifica firma constant-time, idempotency key per ogni Payment Intent create per evitare double charge in caso di retry network, rate limiting su endpoint pagamento per anti-fraud, integrazione Stripe Radar (gestito da Stripe) per scoring rischio transazione con regole custom (block IP da geo non operative, max N tentativi/ora per email/IP, mismatch billing/shipping), captcha invisibile (hCaptcha/reCloudflare Turnstile) su form prenotazione. Compliance: ricevuta fiscale o fattura elettronica via integrazione con sistemi italiani (interfaccia con Aruba/FattureInCloud/Fatturapa via API per emissione automatica documento al `payment_intent.succeeded` con tipo `acconto`), gestione IVA per cessione servizio, tracciatura consenso GDPR + cookie banner + memorizzazione tokenized payment method (Stripe Customer) solo previo consenso esplicito «salva carta per acquisti futuri», diritto cancellazione cliente con anonimizzazione record mantenendo aggregati per contabilità. Multi-canale prenotazione: stesso modulo serve checkout pubblico web (sito vetrina embed widget JS), area cliente loggato (#8326), app mobile native (futura, via API Sanctum), telefonata operatore che crea booking per conto cliente con link pagamento Stripe inviato via SMS/WhatsApp/email (`payment_links.create` Stripe link permanente o `checkout.sessions.create` URL temporanea). UI/UX componenti riutilizzabili: blade component `<x-booking-form />` con slot calendario integrato (FullCalendar) + form cliente + riepilogo + Stripe Element, blade `<x-booking-status-badge />`, blade `<x-payment-result-page />`, livewire component `<livewire:admin-booking-table />` con realtime updates su nuovi pagamenti via Echo+Pusher. Comando artisan: `php artisan booking:cleanup-expired-reservations` (rilascio slot scaduti, default scheduler ogni minuto), `php artisan booking:send-reminders` (cron orario, scansione booking da 24h/72h con reminder non ancora inviato), `php artisan stripe:reconcile {date}` (verifica match Stripe API balance transactions vs DB locale, alert mismatch). Casi d'uso: noleggio veicoli (Holiday Self Drive: caparra €100 a noleggio confermato, saldo + cauzione al ritiro on-site), hotel/B&B/case vacanza (caparra 30% a prenotazione, saldo al check-in con possibilità saldo Stripe pre-arrivo per check-in contactless), ristoranti con prenotazione tavoli grandi gruppi (caparra €20 a persona per gruppi >8 per ridurre no-show), studi medici/professionali (caparra prima visita per ridurre cancellazioni last minute), eventi/corsi/workshop (caparra €30 ridotta non rifondibile per blocco posto), sale riunioni/coworking (pagamento anticipato slot orario), noleggio attrezzature sportive (cauzione + caparra). Differenza da pagamento totale anticipato (rigido, customer abandons checkout su importi alti, no flessibilità saldo on-site): caparra è compromesso UX-conversion. Differenza da prenotazione gratuita senza caparra (no-show rate 20-40%, slot persi, perdita revenue): caparra non rifondibile è deterrente forte (no-show rate <5% tipico). Differenza da preautorizzazione carta (hold senza incasso, max 7gg validità, complessità gestione decay, customer vede importo bloccato senza addebito generando confusione): caparra incassa subito, semplice, definitiva. Differenza da link pagamento manuale via PayPal/bonifico (friction alta, conferma manuale operatore, no integrazione con calendario, no automation): qui flow completamente automatico end-to-end. Estensioni future: subscription/abbonamenti ricorrenti (Stripe Subscriptions con caparra+addebito mensile per palestre/coworking/abbonamenti lezioni), buy-now-pay-later via Klarna/Scalapay/Pagolight per importi alti, gift card prepagate con voucher code applicabile a caparra, upselling in checkout (assicurazione annullamento, extra servizi opzionali, upgrade categoria) con incremento caparra dinamico, dynamic pricing caparra basato su rischio cliente (cliente fidelizzato con storico → caparra ridotta o nulla, prima prenotazione → caparra piena), integrazione AI risk scoring (#8336 search + ML model su feature comportamentali). Costo: 2-3 giorni integrazione Stripe SDK + Payment Intent + Stripe Elements/Checkout + webhook handler + verifica firma, 2 giorni stati booking + slot locking + job cleanup + email conferma + reminder, 1-2 giorni rimborsi + cancellazione self-service + policy automatiche, 1-2 giorni admin panel booking management + dashboard KPI + export, 1 giorno multi-account Stripe Connect (se richiesto multi-tenant), 1-2 giorni testing flussi (success, declined, 3DS, abbandono, rimborso parziale, chargeback simulato via Stripe test mode), 1 giorno integrazione fatturazione elettronica italiana (se richiesta). Dipendenze: account Stripe attivo (gratuito setup, fee transazione 1.5%+€0.25 EU cards, custom per merchant alto volume), dominio HTTPS verificato per webhook, base #8331 mail transazionali per conferme, opzionale #8325 calendar sync per riflesso evento su agenda operatore, opzionale #8332 SMS/#8333 WhatsApp per reminder/conferme su canale preferito cliente.