Files
comelifacciamo/public/checkout_process.php
T
2026-09-09 08:26:26 +02:00

194 lines
7.0 KiB
PHP

<?php
// checkout_process.php — Elabora il checkout: crea utente Owner + salone + profilo fiscale
// + abbonamento attivo, "paga" (SIMULATO), fa login e porta in area titolare.
// Tutto in transazione: o va a buon fine tutto, o non viene creato nulla.
ini_set('display_errors', 1);
error_reporting(E_ALL);
if (session_status() === PHP_SESSION_NONE) session_start();
require_once(__DIR__ . '/userarea/class/db-functions.php');
$pdo = DBHandlerSelect::getInstance()->getConnection();
// Ruolo Owner (da headscript: ROLE_OWNER = 2)
const ROLE_OWNER = 2;
function setFlash(string $type, string $text): void
{
$_SESSION['flash'] = ['type' => $type, 'text' => $text];
}
function backToCheckout(array $post, string $msg): void
{
// Ripopola il form e torna al checkout con l'errore
$_SESSION['checkout_old'] = $post;
setFlash('danger', $msg);
$plan = (int)($post['plan_id'] ?? 0);
$cycle = ($post['cycle'] ?? 'monthly') === 'yearly' ? 'yearly' : 'monthly';
header("Location: checkout.php?plan={$plan}&cycle={$cycle}");
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: pricing.php');
exit;
}
$post = $_POST;
// --- Raccolta dati ---
$plan_id = (int)($post['plan_id'] ?? 0);
$cycle = ($post['cycle'] ?? 'monthly') === 'yearly' ? 'yearly' : 'monthly';
$first_name = trim($post['first_name'] ?? '');
$last_name = trim($post['last_name'] ?? '');
$email = trim($post['email'] ?? '');
$password = (string)($post['password'] ?? '');
$password2 = (string)($post['password_confirm'] ?? '');
$shop_name = trim($post['shop_name'] ?? '');
$business_name = trim($post['business_name'] ?? '');
$vat_number = trim($post['vat_number'] ?? '');
$tax_code = trim($post['tax_code'] ?? '');
$address = trim($post['address'] ?? '');
$city = trim($post['city'] ?? '');
$province = trim($post['province'] ?? '');
$zip_code = trim($post['zip_code'] ?? '');
$pec = trim($post['pec'] ?? '');
$sdi_code = trim($post['sdi_code'] ?? '');
// --- Validazioni ---
if ($plan_id <= 0) {
header('Location: pricing.php');
exit;
}
if ($first_name === '' || $last_name === '' || $email === '' || $password === '') {
backToCheckout($post, 'Compila tutti i campi obbligatori dell\'account.');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
backToCheckout($post, 'Inserisci un indirizzo email valido.');
}
if (strlen($password) < 8) {
backToCheckout($post, 'La password deve avere almeno 8 caratteri.');
}
if ($password !== $password2) {
backToCheckout($post, 'Le due password non coincidono.');
}
if ($shop_name === '') {
backToCheckout($post, 'Inserisci il nome del salone.');
}
if ($business_name === '' || $vat_number === '' || $address === '' || $city === '' || $zip_code === '') {
backToCheckout($post, 'Compila tutti i dati di fatturazione obbligatori.');
}
// Normativa IT: almeno uno tra PEC e SDI
if ($pec === '' && $sdi_code === '') {
backToCheckout($post, 'Per la fattura elettronica inserisci almeno la PEC o il Codice SDI.');
}
if ($pec !== '' && !filter_var($pec, FILTER_VALIDATE_EMAIL)) {
backToCheckout($post, 'La PEC non è un indirizzo valido.');
}
try {
// Email già registrata?
$chk = $pdo->prepare("SELECT id FROM auth_users WHERE email = ?");
$chk->execute([$email]);
if ($chk->fetch()) {
backToCheckout($post, 'Esiste già un account con questa email. Prova ad accedere.');
}
// Piano valido + prezzo
$ps = $pdo->prepare("SELECT id, price FROM subscription_plans WHERE id = ? AND is_active = 1");
$ps->execute([$plan_id]);
$plan = $ps->fetch(PDO::FETCH_ASSOC);
if (!$plan) {
backToCheckout($post, 'Il piano selezionato non è più disponibile.');
}
// Slug salone univoco (generazione al volo, finché non c'è il sistema slug dedicato)
$baseSlug = strtolower(trim(preg_replace('/[^a-z0-9]+/i', '-', $shop_name), '-'));
if ($baseSlug === '') $baseSlug = 'salone';
$slug = $baseSlug;
$i = 1;
$slugChk = $pdo->prepare("SELECT id FROM shops WHERE slug = ?");
while (true) {
$slugChk->execute([$slug]);
if (!$slugChk->fetch()) break;
$slug = $baseSlug . '-' . (++$i);
}
// Durata abbonamento
$expires = $cycle === 'yearly'
? date('Y-m-d', strtotime('+1 year'))
: date('Y-m-d', strtotime('+1 month'));
// ---- TRANSAZIONE: tutto o niente ----
$pdo->beginTransaction();
// 1. Utente Owner
$hash = password_hash($password, PASSWORD_BCRYPT);
$insU = $pdo->prepare("
INSERT INTO auth_users (email, password, role_id, status, first_name, last_name, created_at)
VALUES (?, ?, ?, 'Active', ?, ?, NOW())
");
$insU->execute([$email, $hash, ROLE_OWNER, $first_name, $last_name]);
$user_id = (int)$pdo->lastInsertId();
// 2. Salone (indirizzo iniziale = indirizzo fiscale; modificabile poi dal profilo)
$insS = $pdo->prepare("
INSERT INTO shops (owner_id, name, slug, address, city, province, zip_code, email, active, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, NOW())
");
$insS->execute([$user_id, $shop_name, $slug, $address, $city, ($province ?: null), $zip_code, $email]);
$shop_id = (int)$pdo->lastInsertId();
// 3. Profilo fiscale
$insB = $pdo->prepare("
INSERT INTO billing_profiles
(user_id, shop_id, business_name, vat_number, tax_code, address, zip_code, city, province, pec, sdi_code)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$insB->execute([
$user_id,
$shop_id,
$business_name,
$vat_number,
($tax_code ?: null),
$address,
$zip_code,
$city,
($province ?: null),
($pec ?: null),
($sdi_code ?: null)
]);
// 4. Abbonamento attivo (pagamento SIMULATO riuscito)
$insSub = $pdo->prepare("
INSERT INTO shop_subscriptions (shop_id, plan_id, status, started_at, expires_at)
VALUES (?, ?, 'active', CURDATE(), ?)
");
$insSub->execute([$shop_id, $plan_id, $expires]);
$pdo->commit();
// --- Login: impostiamo la sessione userarea come fa il resto del sito ---
// NB: headscript usa Auth::user() (Laravel). Qui creiamo comunque le chiavi
// di sessione PHP native usate nelle pagine userarea, così l'utente è "dentro".
$_SESSION['iduserlogin'] = $user_id;
$_SESSION['nameuser'] = $first_name;
$_SESSION['surnameuser'] = $last_name;
$_SESSION['emailuser'] = $email;
setFlash('success', 'Benvenuto! Il tuo salone è attivo. Completa il profilo e inizia a ricevere prenotazioni.');
// Va in area titolare (l'agenda). Se la sessione Laravel non è attiva,
// la pagina rimanderà al login: in tal caso l'utente accede con le sue credenziali.
header('Location: userarea/appointments.php');
exit;
} catch (Throwable $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
error_log('checkout_process: ' . $e->getMessage());
backToCheckout($post, 'Si è verificato un errore durante l\'attivazione. Riprova.');
}