setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); } catch(PDOException $e) { die("Database connection failed: " . $e->getMessage()); } } // Get user data from session $username = $_SESSION['username']; $email = $_SESSION['email']; $tier = $_SESSION['tier']; $package = $_SESSION['package']; $balance = $_SESSION['balance']; $total_deposits = $_SESSION['total_deposits']; $total_withdrawals = $_SESSION['total_withdrawals']; $rewards = $_SESSION['rewards']; $earnings = $total_deposits - $total_withdrawals; $user_id = $_SESSION['user_id']; // Get user's available balance (balance minus any holds) $available_balance = $balance; $pending_withdrawals = 0; // Check for pending withdrawals try { $stmt = $pdo->prepare("SELECT SUM(amount) as pending_amount FROM withdrawals WHERE user_id = ? AND status IN ('pending', 'processing')"); $stmt->execute([$user_id]); $result = $stmt->fetch(PDO::FETCH_ASSOC); $pending_withdrawals = $result['pending_amount'] ?? 0; $available_balance = $balance - $pending_withdrawals; } catch (Exception $e) { // Log error but continue error_log("Error fetching pending withdrawals: " . $e->getMessage()); } // Get withdrawal destinations for this user $destinations = []; try { $stmt = $pdo->prepare("SELECT id, type, details, is_default FROM withdrawal_destinations WHERE user_id = ? AND is_active = 1 ORDER BY is_default DESC, created_at DESC"); $stmt->execute([$user_id]); $destinations = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log("Error fetching withdrawal destinations: " . $e->getMessage()); } // Process withdrawal request if ($_SERVER['REQUEST_METHOD'] == 'POST') { $data = json_decode(file_get_contents('php://input'), true); $amount = floatval($data['amount']); $destination_id = intval($data['destination_id']); $idempotency_key = $data['idempotency_key'] ?? ''; // Validate input if ($amount <= 0) { echo json_encode(['success' => false, 'message' => 'Invalid amount.']); exit; } if (empty($destination_id)) { echo json_encode(['success' => false, 'message' => 'Please select a withdrawal destination.']); exit; } if (empty($idempotency_key)) { echo json_encode(['success' => false, 'message' => 'Security error. Please refresh and try again.']); exit; } // Check if user has sufficient available balance if ($available_balance < $amount) { echo json_encode(['success' => false, 'message' => 'Insufficient available balance.']); exit; } // Check minimum and maximum limits $min_withdrawal = 100; $max_withdrawal = 70000; if ($amount < $min_withdrawal) { echo json_encode(['success' => false, 'message' => "Minimum withdrawal amount is {$min_withdrawal} KES."]); exit; } if ($amount > $max_withdrawal) { echo json_encode(['success' => false, 'message' => "Maximum withdrawal amount is {$max_withdrawal} KES."]); exit; } // Calculate fee (15 KES or 1.5%, whichever is higher) $fee = max(15, $amount * 0.015); $net_amount = $amount - $fee; // Start transaction $pdo->beginTransaction(); try { // Check for idempotency (prevent duplicate requests) $stmt = $pdo->prepare("SELECT id, status FROM withdrawals WHERE user_id = ? AND idempotency_key = ?"); $stmt->execute([$user_id, $idempotency_key]); $existing_withdrawal = $stmt->fetch(PDO::FETCH_ASSOC); if ($existing_withdrawal) { // Idempotent response - return existing withdrawal $pdo->commit(); echo json_encode([ 'success' => true, 'idempotent' => true, 'withdrawal_id' => $existing_withdrawal['id'], 'status' => $existing_withdrawal['status'], 'message' => 'Withdrawal request already processed.' ]); exit; } // Lock user row for update $stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ? FOR UPDATE"); $stmt->execute([$user_id]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!$user || $user['balance'] < $amount) { throw new Exception('Insufficient balance.'); } // Deduct from user balance $stmt = $pdo->prepare("UPDATE users SET balance = balance - ?, total_withdrawals = total_withdrawals + ? WHERE id = ?"); $stmt->execute([$amount, $amount, $user_id]); // Create withdrawal record $reference = "WDL-" . date('Ymd') . "-" . mt_rand(1000, 9999); $stmt = $pdo->prepare("INSERT INTO withdrawals (user_id, destination_id, amount, fee, net_amount, status, idempotency_key, reference) VALUES (?, ?, ?, ?, ?, 'pending', ?, ?)"); $stmt->execute([$user_id, $destination_id, $amount, $fee, $net_amount, $idempotency_key, $reference]); $withdrawal_id = $pdo->lastInsertId(); // Record transaction in ledger $new_balance = $user['balance'] - $amount; $stmt = $pdo->prepare("INSERT INTO ledger (user_id, change_amount, balance_after, type, reference, description) VALUES (?, ?, ?, 'withdrawal', ?, ?)"); $stmt->execute([$user_id, -$amount, $new_balance, $withdrawal_id, "Withdrawal request #{$withdrawal_id}"]); // Commit transaction $pdo->commit(); // Update session $_SESSION['balance'] -= $amount; $_SESSION['total_withdrawals'] += $amount; echo json_encode([ 'success' => true, 'withdrawal_id' => $withdrawal_id, 'reference' => $reference, 'message' => 'Withdrawal request submitted successfully! You will receive a confirmation message shortly.' ]); } catch (Exception $e) { $pdo->rollBack(); error_log("Withdrawal error: " . $e->getMessage()); echo json_encode(['success' => false, 'message' => 'Withdrawal failed: ' . $e->getMessage()]); } exit; } // Get recent withdrawals for this user $recent_withdrawals = []; try { $stmt = $pdo->prepare(" SELECT w.*, wd.details, wd.type FROM withdrawals w LEFT JOIN withdrawal_destinations wd ON w.destination_id = wd.id WHERE w.user_id = ? ORDER BY w.created_at DESC LIMIT 5 "); $stmt->execute([$user_id]); $recent_withdrawals = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log("Error fetching recent withdrawals: " . $e->getMessage()); } ?> Japanese Motors — Withdraw Funds
Jmotors

Withdrawal Details

Available Balance

KES

Pending Clearance

KES

Default

No withdrawal destinations found. Add one in settings.

Minimum: 100 KES | Maximum: 70,000 KES per day | Fee: 15 KES or 1.5% (whichever is higher)

Withdrawals are typically processed within 24-72 hours. You'll receive a confirmation message when completed.

Recent Withdrawals

No recent withdrawals

KES

| Ref:

View Full History

Quick Cashout

Withdrawal Information

What are the withdrawal limits?

Minimum withdrawal: 100 KES | Maximum per transaction: 70,000 KES | Daily limit: 70,000 KES | Weekly limit: 140,000 KES. Limits may vary based on your account level and verification status.

How long do withdrawals take?

M-Pesa withdrawals are typically processed within 24-72 hours. Bank transfers may take 1-3 business days. Delays can occur during weekends, holidays, or system maintenance.

Why was my withdrawal declined?

Withdrawals may be declined due to: insufficient balance, incorrect recipient details, security checks, exceeded limits, or account restrictions. Contact support if you need assistance.