File manager - Edit - /var/www/order.cmtc.ac.th/user/checkout.php
Back
<?php session_start(); include('../config/db.php'); include('../includes/check_timer.php'); // ✅ ตรวจสอบว่ามี session การชำระเงินค้างอยู่หรือไม่ $checkout_locked = false; if (isset($_SESSION['checkout_expire']) && time() < $_SESSION['checkout_expire']) { $checkout_locked = true; // ยังอยู่ในระยะเวลาชำระเงิน } // ✅ ตรวจสอบว่ามีเวลานับถอยหลังจาก checkout.php หรือไม่ $checkout_active = false; if (isset($_SESSION['checkout_expire'])) { if (time() < $_SESSION['checkout_expire']) { $checkout_active = true; } else { // ถ้าหมดเวลาแล้วให้ล้างค่า unset($_SESSION['checkout_expire']); } } // ✅ หากคลิกปุ่มยกเลิก if (isset($_GET['cancel_booking']) && $_GET['cancel_booking'] == 1) { if (isset($_SESSION['cart']) && count($_SESSION['cart']) > 0) { foreach ($_SESSION['cart'] as $pid => $qty) { $pid = intval($pid); $qty = intval($qty); // คืนยอด reserved กลับสินค้า $conn->query("UPDATE products SET reserved = GREATEST(reserved - $qty, 0) WHERE id = $pid"); } } // ล้าง session ทั้งหมดที่เกี่ยวข้อง unset($_SESSION['cart']); unset($_SESSION['checkout']); unset($_SESSION['checkout_expire']); // กลับไปหน้าแรก (หรือหน้า index.php) header("Location: ../index.php?cancel_success=1"); exit; } // ✅ เมื่อคลิก "ยกเลิกเหรียญในตะกร้า" if (isset($_GET['cancel']) && $_GET['cancel'] == 1) { if (isset($_SESSION['cart'])) { foreach ($_SESSION['cart'] as $pid => $qty) { $pid = intval($pid); $qty = intval($qty); $conn->query("UPDATE products SET reserved = GREATEST(reserved - $qty, 0) WHERE id = $pid"); } } unset($_SESSION['cart']); unset($_SESSION['checkout']); unset($_SESSION['checkout_expire']); header("Location: ../index.php"); exit; } // ✅ ตรวจสอบตะกร้า if(!isset($_SESSION['cart']) || count($_SESSION['cart']) == 0){ header("Location: ../index.php"); exit; } // ✅ ถ้ายังไม่มีเวลาให้เริ่มนับ (ครั้งแรกเท่านั้น) if (!isset($_SESSION['checkout_expire'])) { $_SESSION['checkout_expire'] = time() + (30 * 60); //$_SESSION['checkout_expire'] = time() + (5 * 60); } // ✅ ถ้าหมดเวลา if (time() > $_SESSION['checkout_expire']) { foreach($_SESSION['cart'] as $pid => $qty){ $pid = intval($pid); $qty = intval($qty); $conn->query("UPDATE products SET reserved = GREATEST(reserved - $qty, 0) WHERE id = $pid"); } unset($_SESSION['cart'], $_SESSION['checkout'], $_SESSION['checkout_expire']); header("Location: expired.php"); exit; } // ✅ ถ้ามีการส่งฟอร์ม (เก็บข้อมูลลง session) if ($_SERVER['REQUEST_METHOD'] === 'POST') { $_SESSION['checkout'] = [ 'fullname' => $_POST['fullname'] ?? '', 'phone' => $_POST['phone'] ?? '', 'address' => $_POST['address'] ?? '', 'zipcode' => $_POST['zipcode'] ?? '', 'receive_method' => $_POST['receive_method'] ?? '', 'payment_bank' => $_POST['payment_bank'] ?? '' ]; } extract($_SESSION['checkout'] ?? []); // ✅ ดึงสินค้าในตะกร้า $ids = implode(",", array_keys($_SESSION['cart'])); $res = $conn->query("SELECT * FROM products WHERE id IN ($ids)"); $items = []; $total = 0.00; while($r = $res->fetch_assoc()){ $pid = (int)$r['id']; $qty = (int)$_SESSION['cart'][$pid]; $sum = (float)$r['price'] * $qty; $total += $sum; $items[] = [ 'id' => $pid, 'name' => $r['name'], 'qty' => $qty, 'price' => (float)$r['price'], 'sum' => $sum ]; } // ✅ ข้อมูลบัญชีพร้อมเพย์จาก “ถุงเงิน” $account_name = "เหรียญที่ระลึก-ทำบุญอาคารอเนกประสงค์"; $owner_name = "วิทยาลัยเทคนิคเชียงใหม่"; $merchant_id = "010753700088820"; // ← Merchant ID จากถุงเงิน (ยืนยันว่า 15 หลัก) $cmtc_coins = "CMTCCOINS"; // ✅ ฟอร์แมตจำนวนเงิน 2 ตำแหน่ง (เช่น 119.00) $amount = number_format($total, 2, '.', ''); $amount_gen = number_format($total, 0, '.', ''); $amount_num=strlen($amount_gen); //echo "amount_gen=$amount_gen amount_num=$amount_num<br>"; // ✅ สร้างรหัส QR Payload ตามโครงสร้างด้านบน // ✅ สร้างภาพ QR ด้วย PHP QR Code และสุ่มชื่อไฟล์ require_once '../libs/phpqrcode/qrlib.php'; $tmpDir = '../libs/phpqrcode/tmp'; if (!is_dir($tmpDir)) { @mkdir($tmpDir, 0777, true); } // สุ่มชื่อไฟล์กันซ้ำ $qrFilename = 'qr_' . date('YmdHis') . '_' . bin2hex(random_bytes(3)) . '.png'; $tempFile = $tmpDir . '/' . $qrFilename; $Q1="00020101021130750016A000000677010112011501075370008820502194M099400W70423284XK0309CMTCCOINS5303764540"; if($amount_num==3){ $Q2="6"; $Q4=".005802TH6208070400006304691B"; } if($amount_num==4){ $Q2="7"; $Q4=".005802TH620807040000630449B5"; } if($amount_num==5){ $Q2="8"; $Q4=".005802TH620807040000630449B5"; } if($amount_num==6){ $Q2="9"; $Q4=".005802TH620807040000630449B5"; } $Q3="$amount_gen"; //ตรวจสอบว่าเป็นการชำระเงินแบบไหน if($payment_bank=="ธนาคารกรุงไทย"){ $qr_string="$Q1$Q2$Q3$Q4"; }else{ $qr_string="00020101021130750016A000000677010112011501075370008820502194M099400W70423284XK0309CMTCCOINS53037645802TH62080704000063047D50"; } //echo "$qr_string<br>"; // ระดับ ECC: M, ขนาด 6, margin 2 //QRcode::png($qr_string, $tempFile, QR_ECLEVEL_M, 6, 2); QRcode::png($qr_string, $tempFile, QR_ECLEVEL_M, 6, 2); // ✅ เหลือเวลา $remaining_seconds = max(0, $_SESSION['checkout_expire'] - time()); ?> <?php include('template_user_header.php'); ?> <?php include('includes/timer_bar.php'); ?> <!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <title>🧾 ยืนยันการชำระเงิน</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <style> body,*{font-family:'Kanit',sans-serif!important;} .qr-box { text-align:center; border:1px dashed #ccc; border-radius:10px; padding:20px; background:#fafafa; } .qr-box img { width:220px; margin:10px auto; } .summary-box { background:#fff; border-radius:10px; padding:20px; box-shadow:0 2px 6px rgba(0,0,0,0.1); } .summary-save { background:#fff; border-radius:10px; padding:20px; box-shadow:0 2px 6px rgba(0,0,0,0.1); } .btn-back { background: linear-gradient(45deg,#999,#ccc); color:#000; font-weight:600; border:none; } .btn-back:hover { background: linear-gradient(45deg,#ccc,#bbb); } /* ✅ preview slip */ #slipPreview { display: none; margin-top: 10px; border: 2px dashed #ccc; border-radius: 10px; max-width: 100%; max-height: 320px; object-fit: contain; } #clearSlip { display: none; margin-top: 8px; } /* ✅ countdown timer */ .timer-box { background: #f8f9fa; padding: 10px 15px; border-radius: 10px; text-align: center; margin-bottom: 15px; font-weight: 600; color: #dc3545; } .btn-danger { background: linear-gradient(45deg, #dc3545, #ff6b6b); border: none; font-weight: 600; color: #fff; } .btn-danger:hover { opacity: 0.9; } </style> </head> <body class="bg-light"> <div class="text-end mb-3"> <?php if($checkout_locked){?> <button type="button" id="cancelBookingBtn" class="btn btn-danger px-3 py-2"> ❌ ยกเลิกรายการจอง </button> <?php } ?> <button type="button" id="saveImageBtn" class="btn btn-primary px-3 py-2"> บันทึกการสั่งจองและ QR ชำระเงิน </button> </div> <div class="container py-1"> <div class="summary-box"> <div class="summary-save"> <h4 class="mb-3">📋 สรุปรายการสั่งจอง</h4> <div class="mb-4"> <h6 class="text-secondary mb-2">👤 ข้อมูลผู้จอง</h6> <p><b>ชื่อ-นามสกุล:</b> <?=htmlspecialchars($fullname)?></p> <p><b>เบอร์โทรศัพท์:</b> <?=htmlspecialchars($phone)?></p> <p><b>วิธีรับเหรียญ:</b> <?=htmlspecialchars($receive_method)?></p> <?php if($receive_method == 'จัดส่งทางไปรษณีย์'): ?> <p><b>ที่อยู่จัดส่ง:</b> <?=nl2br(htmlspecialchars($address))?></p> <p><b>รหัสไปรษณีย์:</b> <?=htmlspecialchars($zipcode)?></p> <?php endif; ?> </div> <table class="table table-bordered mt-3 bg-white"> <thead class="table-secondary text-center"> <tr><th>ชื่อเหรียญ</th><th>จำนวน</th><th>ราคา/หน่วย</th><th>รวม</th></tr> </thead> <tbody> <?php foreach($items as $it): ?> <tr> <td><?=$it['name']?></td> <td class="text-center"><?=$it['qty']?></td> <td class="text-end"><?=number_format($it['price'],2)?></td> <td class="text-end"><?=number_format($it['sum'],2)?></td> </tr> <?php endforeach; ?> <tr class="table-light"> <th colspan="3" class="text-end">ยอดรวม</th> <th class="text-end text-success"><?=number_format($total,2)?></th> </tr> </tbody> </table> <?php if($checkout_locked){?> <?php }else{ ?> <div class="text-start my-4"> <a href="index.php" class="btn btn-back px-4 py-2">🔙 กลับไปแก้ไขข้อมูล / เหรียญ / เลือกชำระเงิน</a> </div> <?php } ?> <h4 class="text-secondary mb-2">💳 ชำระเงิน : QR <?=$payment_bank?></h4> <!-- ✅ QR สำหรับโอน --> <div class="qr-box mt-4"> <h6>📱 สแกน QR Code เพื่อชำระเงิน</h6> <img src="<?=$tempFile?>" alt="QR PromptPay"> <div class="account-info"> <p><b><?=$owner_name?></b><br>ชื่อบัญชี: <b><?=$account_name?></b> <br>รหัสธุรกรรมถุงเงิน: <b><?=$cmtc_coins?></b></p> <p>ยอดชำระ<h1><span class="text-success"><b><?=number_format($total,0)?></b> บาท</span></h1></p> <small class="text-muted">* กรุณาแนบสลิปหลังจากชำระเงิน</small> </div> </div> <!-- ✅ ฟอร์มแนบสลิป --> <form method="post" action="upload_slip.php" enctype="multipart/form-data" class="mt-4"> <input type="hidden" name="fullname" value="<?=htmlspecialchars($fullname)?>"> <input type="hidden" name="phone" value="<?=htmlspecialchars($phone)?>"> <input type="hidden" name="address" value="<?=htmlspecialchars($address)?>"> <input type="hidden" name="zipcode" value="<?=htmlspecialchars($zipcode)?>"> <input type="hidden" name="receive_method" value="<?=htmlspecialchars($receive_method)?>"> <input type="hidden" name="total" value="<?=htmlspecialchars($total)?>"> <?php foreach($items as $i): ?> <input type="hidden" name="product_name[]" value="<?=htmlspecialchars($i['name'])?>"> <input type="hidden" name="qty[]" value="<?=$i['qty']?>"> <input type="hidden" name="price[]" value="<?=$i['price']?>"> <?php endforeach; ?> </div> <div class="mb-3 mt-4"> <label>📎 แนบสลิปชำระเงิน <span style="color:#CC1D00">(เฉพาะไฟล์รูปภาพ)</span></label> <input type="file" id="slipInput" name="slip" class="form-control" accept="image/*" required> <img id="slipPreview" alt="ตัวอย่างสลิป"> <button type="button" id="clearSlip" class="btn btn-outline-danger btn-sm">ล้างรูป</button> </div> <button type="submit" class="btn btn-success w-100 py-2">💾 ส่งหลักฐานการชำระเงิน</button> </form> </div> </div> <script> // ✅ แสดง preview รูป const slipInput = document.getElementById('slipInput'); const slipPreview = document.getElementById('slipPreview'); const clearBtn = document.getElementById('clearSlip'); slipInput.addEventListener('change', function(e){ const file = e.target.files[0]; if(!file) { slipPreview.style.display = 'none'; clearBtn.style.display = 'none'; return; } if(!file.type.startsWith('image/')) { alert('❌ กรุณาเลือกเฉพาะไฟล์รูปภาพ (jpg, png, webp...)'); slipInput.value = ''; slipPreview.style.display = 'none'; clearBtn.style.display = 'none'; return; } const reader = new FileReader(); reader.onload = function(ev) { slipPreview.src = ev.target.result; slipPreview.style.display = 'block'; clearBtn.style.display = 'inline-block'; }; reader.readAsDataURL(file); }); clearBtn.addEventListener('click', function(){ slipInput.value = ''; slipPreview.src = ''; slipPreview.style.display = 'none'; clearBtn.style.display = 'none'; }); // ✅ นับเวลาถอยหลัง 30 นาที let timeLeft = <?=$remaining_seconds?>; const countdownEl = document.getElementById('countdown'); function formatTime(sec){ const m = Math.floor(sec / 60); const s = sec % 60; return m.toString().padStart(2,'0') + ':' + s.toString().padStart(2,'0'); } const timer = setInterval(()=>{ if(timeLeft <= 0){ clearInterval(timer); alert("หมดเวลาการทำรายการ กรุณาทำรายการใหม่อีกครั้ง"); window.location.href = "expired.php"; } else { countdownEl.textContent = formatTime(timeLeft); timeLeft--; } }, 1000); </script> <script> // ✅ ฟังก์ชันบันทึกภาพเฉพาะส่วนสรุปรายการ + SweetAlert แจ้งผล document.getElementById('saveImageBtn')?.addEventListener('click', function() { const element = document.querySelector('.summary-save'); const btn = this; btn.disabled = true; btn.innerHTML = "⏳ กำลังบันทึกรูป..."; html2canvas(element, { scale: 2, useCORS: true }).then(canvas => { const imageData = canvas.toDataURL("image/png"); const link = document.createElement("a"); const fileName = "สรุปรายการสั่งจอง_" + new Date().toISOString().slice(0,19).replace("T","-") + ".png"; link.download = fileName; link.href = imageData; link.click(); // ✅ แสดง SweetAlert แจ้งผล Swal.fire({ title: '✅ บันทึกสำเร็จแล้ว!', text: 'ไฟล์ถูกบันทึกลงในเครื่องของคุณ', icon: 'success', confirmButtonText: 'ตกลง', confirmButtonColor: '#28a745', timer: 2500 }); btn.disabled = false; btn.innerHTML = "📸 บันทึกรูปภาพสรุปการสั่งจอง"; }).catch(err => { Swal.fire({ title: '❌ เกิดข้อผิดพลาด', text: 'ไม่สามารถบันทึกรูปภาพได้ กรุณาลองใหม่อีกครั้ง', icon: 'error', confirmButtonText: 'ตกลง', confirmButtonColor: '#dc3545' }); btn.disabled = false; btn.innerHTML = "📸 บันทึกรูปภาพสรุปการสั่งจอง"; }); }); // ✅ ยืนยันการยกเลิกรายการจอง ด้วย SweetAlert2 document.getElementById('cancelBookingBtn')?.addEventListener('click', function() { Swal.fire({ title: '⚠️ ต้องการยกเลิกรายการจองทั้งหมดหรือไม่?', text: 'ระบบจะคืนเหรียญกลับคลัง และยกเลิกเวลานับถอยหลังทันที', icon: 'warning', showCancelButton: true, confirmButtonText: 'ยืนยันการยกเลิก', cancelButtonText: 'ปิดหน้าต่าง', confirmButtonColor: '#d33', cancelButtonColor: '#6c757d' }).then((result) => { if (result.isConfirmed) { Swal.fire({ title: '⏳ กำลังดำเนินการ...', text: 'กรุณารอสักครู่', icon: 'info', showConfirmButton: false, allowOutsideClick: false, didOpen: () => { Swal.showLoading(); window.location.href = '?cancel_booking=1'; } }); } }); }); </script> </div> <?php include("../footer.php"); ?> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.42 |
proxy
|
phpinfo
|
Settings