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); ?>

Order Items

0): ?> 0): ?> 0): ?> 0): ?>
Product Price Qty Total
Subtotal
Shipping
Tax
Discount -
Wallet / Gift Card -
Total

Order Notes

No notes yet.

Process Refund

Up to (full order total). Enter a lower amount for a partial refund.

Order Status

Shipping Address


,

Payment

Method
Status 'success', 'failed' => 'error', 'refunded', 'partially_refunded' => 'warning', default => 'primary' }; ?>
Square Payment ID
Stripe ID ...

Timeline

Created
Updated