status == 'succeeded') { // NOTE: In a real application, you should not trust the amount from the client. // You should fetch the plan from your database based on a stored reference to ensure the price is correct. // For this example, we'll assume the amount is correct. $metadata = $paymentIntent->metadata; $plan_id = $metadata->plan_id ?? null; $customer_name = $metadata->customer_name ?? null; $customer_address = $metadata->customer_address ?? null; $customer_email = $paymentIntent->receipt_email; if (empty($plan_id) || empty($customer_name) || empty($customer_address) || empty($customer_email)) { // This indicates a problem, as the metadata or email was not set correctly. // Flag for manual review. error_log("Missing metadata or email for successful payment {$payment_intent_id}."); $message = "Your payment was successful, but there was an error processing your order details. Please contact support."; } else { $pdo = db(); // Parse name into first and last $name_parts = explode(' ', $customer_name, 2); $first_name = $name_parts[0]; $last_name = $name_parts[1] ?? ''; // For address, we'll just put the whole thing in the street_address for now. // A real app would use a proper address parser or separate fields on the form. $street_address = $customer_address; // Generate a temporary password hash. In a real app, you'd send a password reset link. $temp_password = password_hash(bin2hex(random_bytes(16)), PASSWORD_DEFAULT); // Check if customer already exists $stmt = $pdo->prepare("SELECT id FROM customers WHERE email = ?"); $stmt->execute([$customer_email]); $existing_customer = $stmt->fetch(); if ($existing_customer) { $customer_id = $existing_customer['id']; // Optional: Update customer details if they have changed $update_stmt = $pdo->prepare("UPDATE customers SET first_name = ?, last_name = ?, street_address = ? WHERE id = ?"); $update_stmt->execute([$first_name, $last_name, $street_address, $customer_id]); } else { // Create new customer $stmt = $pdo->prepare( "INSERT INTO customers (first_name, last_name, email, password_hash, street_address) VALUES (?, ?, ?, ?, ?)" ); $stmt->execute([$first_name, $last_name, $customer_email, $temp_password, $street_address]); $customer_id = $pdo->lastInsertId(); } // Create the order $stmt = $pdo->prepare("INSERT INTO orders (customer_id, plan_id, stripe_payment_intent, status) VALUES (?, ?, ?, ?)"); $stmt->execute([$customer_id, $plan_id, $payment_intent_id, 'succeeded']); $message = 'Payment succeeded! Your order has been placed.'; // Send confirmation email require_once __DIR__ . '/mail/MailService.php'; $subject = 'Your Australia Broadband Internet Order Confirmation'; $html_body = "
Thank you for your order. Your new internet service is being processed.
" . "Order Details:
" . "You will receive further updates from us shortly.
"; $text_body = "Welcome, " . $customer_name . "! Thank you for your order. Your new internet service is being processed. Order Details: Plan ID: " . $plan_id . ", Payment ID: " . $payment_intent_id . ". You will receive further updates from us shortly."; MailService::sendMail($customer_email, $subject, $html_body, $text_body); } } else { $message = "Payment was not successful. Status: {$paymentIntent->status}"; } } catch (\Stripe\Exception\ApiErrorException $e) { $message = 'Error retrieving payment intent: ' . $e->getMessage(); } catch (PDOException $e) { // If the DB insert fails, we have a problem. The customer was charged but the order wasn't created. // A real app needs robust error handling here, like logging the error and flagging for manual review. error_log("Failed to create order in DB after successful payment {$payment_intent_id}: " . $e->getMessage()); $message = "Your payment was successful, but there was an error creating your order. Please contact support."; } } ?>