fetch("SELECT * FROM orders WHERE order_id = :id", ['id' => $orderId]); if (!$order) { setFlash('error', 'Order not found'); header('Location: /admin/orders.php'); exit; } // Handle status update if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; if ($action === 'update_status') { $status = $_POST['status'] ?? ''; $trackingNumber = $_POST['tracking_number'] ?? ''; $updateData = ['order_status' => $status]; if ($trackingNumber) { $updateData['tracking_number'] = $trackingNumber; } db()->update('orders', $updateData, 'order_id = :id', ['id' => $orderId]); setFlash('success', 'Order status updated'); header('Location: /admin/order.php?id=' . $orderId); exit; } if ($action === 'add_note') { $note = trim($_POST['note'] ?? ''); if ($note) { $existingNotes = $order['notes'] ?? ''; $newNote = '[' . date('M j, Y g:i A') . '] ' . $note; $allNotes = $existingNotes ? $existingNotes . "\n" . $newNote : $newNote; db()->update('orders', ['notes' => $allNotes], 'order_id = :id', ['id' => $orderId]); setFlash('success', 'Note added'); header('Location: /admin/order.php?id=' . $orderId); exit; } } if ($action === 'process_refund') { $refundAmount = (float) ($_POST['refund_amount'] ?? 0); $reason = trim($_POST['refund_reason'] ?? ''); if ($order['payment_method'] !== 'square' || empty($order['square_payment_id'])) { setFlash('error', 'This order has no Square payment to refund.'); header('Location: /admin/order.php?id=' . $orderId); exit; } if ($order['payment_status'] !== 'paid' && $order['payment_status'] !== 'partially_refunded') { setFlash('error', 'Only paid orders can be refunded.'); header('Location: /admin/order.php?id=' . $orderId); exit; } if ($refundAmount <= 0 || $refundAmount > (float) $order['total']) { setFlash('error', 'Invalid refund amount.'); header('Location: /admin/order.php?id=' . $orderId); exit; } try { $result = squareRefundPayment($order['square_payment_id'], $refundAmount, $reason ?: ('Order #' . $order['order_number'])); $refund = $result['refund'] ?? []; $refundStatus = $refund['status'] ?? ''; if (in_array($refundStatus, ['PENDING', 'COMPLETED'], true)) { $isFullRefund = $refundAmount >= (float) $order['total']; $newPaymentStatus = $isFullRefund ? 'refunded' : 'partially_refunded'; db()->update('orders', ['payment_status' => $newPaymentStatus, 'order_status' => $isFullRefund ? 'refunded' : $order['order_status']], 'order_id = :id', ['id' => $orderId] ); // Restore any wallet credit that was applied, proportionally on a full refund if ($isFullRefund && !empty($order['wallet_amount_used']) && (float) $order['wallet_amount_used'] > 0 && !empty($order['customer_id'])) { $walletAmount = (float) $order['wallet_amount_used']; $cust = db()->fetch("SELECT wallet_balance FROM customers WHERE customer_id = :id", ['id' => $order['customer_id']]); if ($cust) { $newBalance = (float) $cust['wallet_balance'] + $walletAmount; db()->update('customers', ['wallet_balance' => $newBalance], 'customer_id = :id', ['id' => $order['customer_id']]); db()->insert('wallet_transactions', [ 'transaction_id' => generateId('wt_'), 'customer_id' => $order['customer_id'], 'amount' => $walletAmount, 'balance_after' => $newBalance, 'type' => 'refund', 'description' => 'Refund for Order #' . $order['order_number'], ]); } } $existingNotes = $order['notes'] ?? ''; $newNote = '[' . date('M j, Y g:i A') . '] Refunded ' . formatCurrency($refundAmount) . ' via Square (refund ID: ' . ($refund['id'] ?? 'unknown') . ')' . ($reason ? ' — ' . $reason : ''); $allNotes = $existingNotes ? $existingNotes . "\n" . $newNote : $newNote; db()->update('orders', ['notes' => $allNotes], 'order_id = :id', ['id' => $orderId]); setFlash('success', formatCurrency($refundAmount) . ' refunded successfully.'); } else { setFlash('error', 'Refund did not complete (status: ' . $refundStatus . ').'); } } catch (Exception $e) { setFlash('error', 'Refund failed: ' . $e->getMessage()); } header('Location: /admin/order.php?id=' . $orderId); exit; } } $items = json_decode($order['items'], true) ?? []; $shippingAddress = json_decode($order['shipping_address'], true) ?? []; $statuses = ['pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded']; $canRefund = $order['payment_method'] === 'square' && !empty($order['square_payment_id']) && in_array($order['payment_status'], ['paid', 'partially_refunded'], true); ?>
| Product | Price | Qty | Total |
|---|---|---|---|
| = htmlspecialchars($item['name']) ?> = htmlspecialchars($item['name']) ?> | = formatCurrency($item['price']) ?> | = $item['quantity'] ?> | = formatCurrency($item['total']) ?> |
| Subtotal | = formatCurrency($order['subtotal']) ?> | ||
| Shipping | = formatCurrency($order['shipping_cost']) ?> | ||
| Tax | = formatCurrency($order['tax']) ?> | ||
| Discount | -= formatCurrency($order['discount']) ?> | ||
| Wallet / Gift Card | -= formatCurrency($order['wallet_amount_used']) ?> | ||
| Total | = formatCurrency($order['total']) ?> | ||
= htmlspecialchars($order['notes']) ?>
No notes yet.
= htmlspecialchars($order['customer_name']) ?>
= htmlspecialchars($order['customer_email']) ?>
= htmlspecialchars($order['customer_phone']) ?>
View Customer
= htmlspecialchars($shippingAddress['address'] ?? '') ?>
= htmlspecialchars($shippingAddress['city'] ?? '') ?>,
= htmlspecialchars($shippingAddress['state'] ?? '') ?>
= htmlspecialchars($shippingAddress['zip'] ?? '') ?>