File manager - Edit - /home/webapp69.cm.in.th/u69319090015/Shop/process-order.php
Back
<?php require_once 'config.php'; // Redirect if cart is empty if (empty($_SESSION['cart'])) { header("Location: index.php"); exit; } // Check POST request if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header("Location: checkout.php"); exit; } // Collect and sanitize shipping info $customer_name = trim(filter_input(INPUT_POST, 'customer_name', FILTER_DEFAULT)); $phone = trim(filter_input(INPUT_POST, 'phone', FILTER_DEFAULT)); $address = trim(filter_input(INPUT_POST, 'address', FILTER_DEFAULT)); // Basic validation if (empty($customer_name) || empty($phone) || empty($address)) { $_SESSION['checkout_error'] = "กรุณากรอกข้อมูลผู้รับและที่อยู่ให้ครบถ้วน"; header("Location: checkout.php"); exit; } // Placeholders for database transactions $order_id = null; $order_summary = []; $total_price = 0; $error_message = ''; try { // Start database transaction $pdo->beginTransaction(); // 1. Validate stock for all products in the cart foreach ($_SESSION['cart'] as $product_id => $quantity) { // SELECT FOR UPDATE locks the rows to prevent race conditions during checkout $stmt = $pdo->prepare("SELECT * FROM products WHERE id = ? FOR UPDATE"); $stmt->execute([$product_id]); $product = $stmt->fetch(); if (!$product) { throw new Exception("ไม่พบรหัสสินค้า: " . $product_id); } if ($product['stock'] < $quantity) { throw new Exception("สินค้า '" . $product['name'] . " (" . $product['size'] . ")' มีสต็อกไม่เพียงพอ (คงเหลือ " . $product['stock'] . " ชิ้น)"); } // Calculate price and accumulate $subtotal = $product['price'] * $quantity; $total_price += $subtotal; $order_summary[] = [ 'id' => $product_id, 'name' => $product['name'], 'size' => $product['size'], 'price' => $product['price'], 'quantity' => $quantity, 'subtotal' => $subtotal ]; } // 2. Insert into orders table $stmt = $pdo->prepare("INSERT INTO orders (customer_name, phone, address, total_price, payment_status) VALUES (?, ?, ?, ?, 'pending')"); $stmt->execute([$customer_name, $phone, $address, $total_price]); $order_id = $pdo->lastInsertId(); // 3. Insert into order_details and update product stock $stmtDetail = $pdo->prepare("INSERT INTO order_details (order_id, product_id, quantity) VALUES (?, ?, ?)"); $stmtUpdateStock = $pdo->prepare("UPDATE products SET stock = stock - ? WHERE id = ?"); foreach ($order_summary as $item) { // Insert details $stmtDetail->execute([$order_id, $item['id'], $item['quantity']]); // Deduct stock $stmtUpdateStock->execute([$item['quantity'], $item['id']]); } // Commit all changes $pdo->commit(); // Clear cart session since order is placed successfully $_SESSION['cart'] = []; } catch (Exception $e) { // Rollback the transaction on error $pdo->rollBack(); $error_message = $e->getMessage(); } // Render Order Result ?> <!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ผลการสั่งซื้อ - Minimalist Closet</title> <!-- Google Fonts --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <!-- Bootstrap 5 CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> <!-- Bootstrap Icons --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css"> <style> :root { --primary-color: #1a1a1a; --accent-color: #8f8270; --bg-color: #faf9f6; --card-bg: #ffffff; --text-muted: #757575; --font-display: 'Outfit', 'Sarabun', sans-serif; } body { font-family: var(--font-display); background-color: var(--bg-color); color: var(--primary-color); min-height: 100vh; display: flex; flex-direction: column; } .navbar { background-color: rgba(255, 255, 255, 0.85); backdrop-filter: blur(10px); border-bottom: 1px solid rgba(0, 0, 0, 0.05); } .navbar-brand { font-weight: 700; letter-spacing: 2px; color: var(--primary-color) !important; } .result-card { background-color: var(--card-bg); border: none; border-radius: 16px; box-shadow: 0 10px 30px rgba(0,0,0,0.03); padding: 40px; text-align: center; } .icon-wrapper { width: 80px; height: 80px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; margin-bottom: 24px; } .icon-success { background-color: #e8f5e9; color: #2e7d32; } .icon-error { background-color: #ffebee; color: #c62828; } .btn-dark-custom { background-color: var(--primary-color); color: #ffffff; border: 1px solid var(--primary-color); border-radius: 6px; font-weight: 500; padding: 12px 30px; letter-spacing: 0.5px; transition: all 0.2s ease; text-decoration: none; display: inline-block; } .btn-dark-custom:hover { background-color: var(--accent-color); border-color: var(--accent-color); color: white; } </style> <!-- Custom Theme & Dark Mode CSS --> <link rel="stylesheet" href="assets/css/style.css"> <script src="assets/js/theme-toggle.js"></script> </head> <body> <!-- Header Navbar --> <nav class="navbar navbar-expand-lg sticky-top navbar-light"> <div class="container"> <a class="navbar-brand d-flex align-items-center gap-2" href="index.php"> <img src="assets/images/logo.png" alt="CMTC Logo" style="height: 42px; width: auto;"> <div class="d-flex flex-column" style="line-height: 1.2;"> <span class="fs-6 fw-bold">วิทยาลัยเทคนิคเชียงใหม่</span> <span class="small text-muted" style="font-size: 0.75rem; letter-spacing: 1px;">MINIMALIST CLOSET</span> </div> </a> <div class="ms-auto"> <button type="button" class="theme-toggle-btn" id="themeToggleBtn" title="เปลี่ยนธีม (Light/Dark)"> <i class="bi bi-moon-stars-fill" id="themeIcon"></i> </button> </div> </div> </nav> <!-- Main Container --> <main class="container my-auto py-5"> <div class="row justify-content-center"> <div class="col-md-8 col-lg-6"> <?php if (empty($error_message)): ?> <!-- Success Card --> <div class="result-card"> <div class="icon-wrapper icon-success"> <i class="bi bi-check-lg fs-1"></i> </div> <h1 class="h3 fw-semibold text-uppercase mb-2">Order Confirmed!</h1> <p class="text-success fw-medium mb-4">สั่งซื้อเสร็จสิ้น สต็อกถูกอัปเดตเรียบร้อยแล้ว</p> <div class="text-start bg-light p-4 rounded-3 mb-4"> <div class="d-flex justify-content-between mb-2"> <span class="text-muted">รหัสสั่งซื้อ:</span> <span class="fw-bold">#<?= str_pad($order_id, 6, '0', STR_PAD_LEFT) ?></span> </div> <div class="d-flex justify-content-between mb-2"> <span class="text-muted">ชื่อลูกค้า:</span> <span><?= htmlspecialchars($customer_name) ?></span> </div> <div class="d-flex justify-content-between mb-2"> <span class="text-muted">เบอร์โทรศัพท์:</span> <span><?= htmlspecialchars($phone) ?></span> </div> <div class="mb-3"> <span class="text-muted d-block mb-1">ที่อยู่จัดส่ง:</span> <span class="text-secondary small d-block" style="line-height: 1.4;"><?= nl2br(htmlspecialchars($address)) ?></span> </div> <hr> <div class="d-flex justify-content-between pt-1"> <span class="fw-semibold">ยอดชำระเงินรวม:</span> <span class="fw-bold text-dark fs-5">฿<?= number_format($total_price, 2) ?></span> </div> </div> <a href="index.php" class="btn-dark-custom">กลับสู่หน้าหลัก</a> </div> <?php else: ?> <!-- Error/Failure Card --> <div class="result-card"> <div class="icon-wrapper icon-error"> <i class="bi bi-exclamation-triangle fs-1"></i> </div> <h1 class="h3 fw-semibold text-uppercase mb-2">Order Failed</h1> <p class="text-danger fw-medium mb-4">ไม่สามารถทำการสั่งซื้อได้</p> <div class="alert alert-danger border-0 mb-4" role="alert"> <?= htmlspecialchars($error_message) ?> </div> <div class="d-flex gap-2 justify-content-center"> <a href="cart.php" class="btn btn-outline-dark px-4 py-2.5">กลับไปแก้ไขตะกร้า</a> <a href="index.php" class="btn-dark-custom">กลับสู่หน้าหลัก</a> </div> </div> <?php endif; ?> </div> </div> </main> <!-- Footer --> <footer class="bg-white border-top py-4 text-center mt-auto"> <div class="container"> <p class="mb-1 text-muted">© 2026 Minimalist Closet. All Rights Reserved.</p> </div> </footer> <!-- Bootstrap 5 JS --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.25 |
proxy
|
phpinfo
|
Settings