File manager - Edit - /home/webapp69.cm.in.th/u69319090039/Shop39/app/Controllers/Seller/SellerPaymentController.php
Back
<?php class SellerPaymentController extends Controller { /** * Display Payment Settings page * GET /seller/payment-settings */ public function settings(): void { $seller = Auth::sellerProfile(); $db = Database::getInstance(); // Ensure table exists safely $db->exec(" CREATE TABLE IF NOT EXISTS seller_payment_settings ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, seller_id INT UNSIGNED NOT NULL UNIQUE, account_name VARCHAR(150) NOT NULL, bank_name VARCHAR(100) NOT NULL, bank_account VARCHAR(100) NOT NULL, promptpay_number VARCHAR(50) NULL, qr_code VARCHAR(255) NULL, payment_method ENUM('bank_transfer', 'promptpay', 'both') NOT NULL DEFAULT 'both', status ENUM('active', 'inactive') NOT NULL DEFAULT 'active', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (seller_id) REFERENCES seller_profiles (id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; "); $stmt = $db->prepare("SELECT * FROM seller_payment_settings WHERE seller_id = :sid LIMIT 1"); $stmt->execute(['sid' => $seller['id']]); $paymentSettings = $stmt->fetch(); $this->render('seller/payment/settings', [ 'title' => 'การรับเงิน / Payment Settings', 'seller' => $seller, 'paymentSettings' => $paymentSettings ], 'seller'); } /** * Save/Update Payment Settings * POST /seller/payment-settings/update */ public function updateSettings(): void { $this->validateCsrf(); $seller = Auth::sellerProfile(); $db = Database::getInstance(); $accountName = trim(Security::sanitizeString($_POST['account_name'] ?? '')); $bankName = trim(Security::sanitizeString($_POST['bank_name'] ?? '')); $bankAccount = trim(Security::sanitizeString($_POST['bank_account'] ?? '')); $promptpay = trim(Security::sanitizeString($_POST['promptpay_number'] ?? '')); $paymentMethod = trim(Security::sanitizeString($_POST['payment_method'] ?? 'both')); if (empty($accountName) || empty($bankName) || empty($bankAccount)) { Session::setFlash('danger', 'กรุณากรอกชื่อบัญชี ธนาคาร และเลขบัญชีให้ครบถ้วน'); $this->redirect('seller/payment-settings'); return; } if (!in_array($paymentMethod, ['bank_transfer', 'promptpay', 'both'])) { $paymentMethod = 'both'; } // Check existing $stmt = $db->prepare("SELECT * FROM seller_payment_settings WHERE seller_id = :sid LIMIT 1"); $stmt->execute(['sid' => $seller['id']]); $existing = $stmt->fetch(); $qrPath = $existing['qr_code'] ?? null; // Handle QR Code Upload if (!empty($_FILES['qr_code']['name']) && $_FILES['qr_code']['error'] === UPLOAD_ERR_OK) { $ext = strtolower(pathinfo($_FILES['qr_code']['name'], PATHINFO_EXTENSION)); $allowed = ['jpg', 'jpeg', 'png', 'webp']; if (!in_array($ext, $allowed)) { Session::setFlash('danger', 'ไฟล์ QR Code ต้องเป็นรูปแบบ JPG, JPEG, PNG หรือ WEBP เท่านั้น'); $this->redirect('seller/payment-settings'); return; } $targetDir = SITE_ROOT . '/public/uploads/qrcodes/'; if (!file_exists($targetDir)) { mkdir($targetDir, 0777, true); } $fileName = 'qr_seller_' . $seller['id'] . '_' . time() . '.' . $ext; if (move_uploaded_file($_FILES['qr_code']['tmp_name'], $targetDir . $fileName)) { $qrPath = 'uploads/qrcodes/' . $fileName; } } if ($existing) { $upSql = "UPDATE seller_payment_settings SET account_name = :aname, bank_name = :bname, bank_account = :bacc, promptpay_number = :ppay, qr_code = :qr, payment_method = :pmethod, updated_at = NOW() WHERE seller_id = :sid"; $upStmt = $db->prepare($upSql); $upStmt->execute([ 'aname' => $accountName, 'bname' => $bankName, 'bacc' => $bankAccount, 'ppay' => $promptpay, 'qr' => $qrPath, 'pmethod' => $paymentMethod, 'sid' => $seller['id'] ]); } else { $inSql = "INSERT INTO seller_payment_settings (seller_id, account_name, bank_name, bank_account, promptpay_number, qr_code, payment_method) VALUES (:sid, :aname, :bname, :bacc, :ppay, :qr, :pmethod)"; $inStmt = $db->prepare($inSql); $inStmt->execute([ 'sid' => $seller['id'], 'aname' => $accountName, 'bname' => $bankName, 'bacc' => $bankAccount, 'ppay' => $promptpay, 'qr' => $qrPath, 'pmethod' => $paymentMethod ]); } // Also sync to seller_profiles table for compatibility $profStmt = $db->prepare("UPDATE seller_profiles SET promptpay_number = :ppay, bank_account = :bacc WHERE id = :sid"); $profStmt->execute([ 'ppay' => $promptpay, 'bacc' => ($bankName ? "{$bankName} " : "") . $bankAccount, 'sid' => $seller['id'] ]); Session::setFlash('success', 'บันทึกข้อมูลการรับเงินและ QR Code เรียบร้อยแล้ว'); $this->redirect('seller/payment-settings'); } /** * Display Seller Wallet & Payouts page * GET /seller/wallet */ public function wallet(): void { $seller = Auth::sellerProfile(); $db = Database::getInstance(); // Ensure seller_payouts table exists $db->exec(" CREATE TABLE IF NOT EXISTS seller_payouts ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, seller_id INT UNSIGNED NOT NULL, amount DECIMAL(10,2) NOT NULL, payment_method VARCHAR(50) NOT NULL DEFAULT 'bank_transfer', bank_name VARCHAR(100) NULL, bank_account VARCHAR(100) NULL, promptpay_number VARCHAR(50) NULL, qr_code VARCHAR(255) NULL, status ENUM('pending', 'processing', 'completed', 'rejected') NOT NULL DEFAULT 'pending', transaction_reference VARCHAR(150) NULL, admin_note TEXT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (seller_id) REFERENCES seller_profiles (id) ON DELETE CASCADE, INDEX idx_payouts_seller (seller_id, status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; "); // 1. Total Sales from all completed/delivered orders $salesStmt = $db->prepare(" SELECT COALESCE(SUM(total_amount), 0) FROM orders WHERE seller_id = :sid AND status IN ('delivered', 'completed') "); $salesStmt->execute(['sid' => $seller['id']]); $totalSales = (float)$salesStmt->fetchColumn(); // 2. Pending Payouts (currently in process) $pPendingStmt = $db->prepare(" SELECT COALESCE(SUM(amount), 0) FROM seller_payouts WHERE seller_id = :sid AND status IN ('pending', 'processing') "); $pPendingStmt->execute(['sid' => $seller['id']]); $pendingPayout = (float)$pPendingStmt->fetchColumn(); // 3. Completed Payouts (already transferred) $pCompletedStmt = $db->prepare(" SELECT COALESCE(SUM(amount), 0) FROM seller_payouts WHERE seller_id = :sid AND status = 'completed' "); $pCompletedStmt->execute(['sid' => $seller['id']]); $completedPayout = (float)$pCompletedStmt->fetchColumn(); // 4. Available Balance to withdraw (Total sales from completed orders minus all requested/completed payouts) $availableBalance = max(0.00, $totalSales - $completedPayout - $pendingPayout); // Fetch payment settings $settStmt = $db->prepare("SELECT * FROM seller_payment_settings WHERE seller_id = :sid LIMIT 1"); $settStmt->execute(['sid' => $seller['id']]); $paymentSettings = $settStmt->fetch(); // Fetch Payout history for this seller strictly $historyStmt = $db->prepare(" SELECT * FROM seller_payouts WHERE seller_id = :sid ORDER BY id DESC "); $historyStmt->execute(['sid' => $seller['id']]); $payoutHistory = $historyStmt->fetchAll(); $this->render('seller/payment/wallet', [ 'title' => 'ยอดเงินร้านค้าและการถอนเงิน (Seller Wallet & Payouts)', 'seller' => $seller, 'totalSales' => $totalSales, 'pendingPayout' => $pendingPayout, 'completedPayout' => $completedPayout, 'availableBalance' => $availableBalance, 'paymentSettings' => $paymentSettings, 'payoutHistory' => $payoutHistory ], 'seller'); } /** * Submit Payout Request * POST /seller/wallet/request-payout */ public function requestPayout(): void { $this->validateCsrf(); $seller = Auth::sellerProfile(); $db = Database::getInstance(); $amount = (float)($_POST['amount'] ?? 0); if ($amount <= 0) { Session::setFlash('danger', 'กรุณาระบุจำนวนเงินที่ต้องการถอนให้ถูกต้อง'); $this->redirect('seller/wallet'); return; } // Get Payment settings $settStmt = $db->prepare("SELECT * FROM seller_payment_settings WHERE seller_id = :sid LIMIT 1"); $settStmt->execute(['sid' => $seller['id']]); $settings = $settStmt->fetch(); if (!$settings || empty($settings['bank_account'])) { Session::setFlash('warning', 'กรุณาตั้งค่าบัญชีธนาคารสำหรับรับเงินก่อนทำรายการถอน'); $this->redirect('seller/payment-settings'); return; } // Check available balance on SERVER side $salesStmt = $db->prepare("SELECT COALESCE(SUM(total_amount), 0) FROM orders WHERE seller_id = :sid AND status IN ('delivered', 'completed')"); $salesStmt->execute(['sid' => $seller['id']]); $totalSales = (float)$salesStmt->fetchColumn(); $pPendingStmt = $db->prepare("SELECT COALESCE(SUM(amount), 0) FROM seller_payouts WHERE seller_id = :sid AND status IN ('pending', 'processing')"); $pPendingStmt->execute(['sid' => $seller['id']]); $pendingPayout = (float)$pPendingStmt->fetchColumn(); $pCompletedStmt = $db->prepare("SELECT COALESCE(SUM(amount), 0) FROM seller_payouts WHERE seller_id = :sid AND status = 'completed'"); $pCompletedStmt->execute(['sid' => $seller['id']]); $completedPayout = (float)$pCompletedStmt->fetchColumn(); $availableBalance = max(0.00, $totalSales - $completedPayout - $pendingPayout); if ($amount > $availableBalance) { Session::setFlash('danger', 'ยอดเงินที่สามารถถอนได้ไม่เพียงพอ (ยอดที่ถอนได้: ฿' . number_format($availableBalance, 2) . ')'); $this->redirect('seller/wallet'); return; } // Insert Payout Record $inStmt = $db->prepare(" INSERT INTO seller_payouts (seller_id, amount, payment_method, bank_name, bank_account, promptpay_number, qr_code, status) VALUES (:sid, :amt, :pmethod, :bname, :bacc, :ppay, :qr, 'pending') "); $inStmt->execute([ 'sid' => $seller['id'], 'amt' => $amount, 'pmethod' => $settings['payment_method'] ?? 'bank_transfer', 'bname' => $settings['bank_name'] ?? '', 'bacc' => $settings['bank_account'] ?? '', 'ppay' => $settings['promptpay_number'] ?? '', 'qr' => $settings['qr_code'] ?? null ]); Session::setFlash('success', 'ส่งคำขอถอนเงินจำนวน ฿' . number_format($amount, 2) . ' เรียบร้อยแล้ว กรุณารอผู้ดูแลระบบดำเนินการโอนเงิน'); $this->redirect('seller/wallet'); } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.26 |
proxy
|
phpinfo
|
Settings