verifyWebhookSignature($request)) { Log::warning('Invalid courier webhook signature'); return response()->json(['error' => 'Invalid signature'], 401); } try { $payload = $request->json()->all(); Log::info('Courier webhook received', [ 'shipment_id' => $payload['shipment_id'] ?? 'unknown', 'status' => $payload['status'] ?? 'unknown', ]); // Find order by waybill ID $order = Order::where('courier_waybill_id', $payload['waybill_id'] ?? null)->first(); if (! $order) { Log::warning('Order not found for courier webhook', [ 'waybill_id' => $payload['waybill_id'] ?? 'unknown', ]); return response()->json(['error' => 'Order not found'], 404); } // Handle status updates match ($payload['status'] ?? null) { 'collected' => $this->handleParcelCollected($order, $payload), 'in_transit' => $this->handleParcelInTransit($order, $payload), 'delivered' => $this->handleParcelDelivered($order, $payload), 'failed_delivery' => $this->handleParcelFailedDelivery($order, $payload), default => Log::info('Unhandled courier status', ['status' => $payload['status'] ?? 'unknown']), }; return response()->json(['success' => true]); } catch (\Exception $e) { Log::error('Error processing courier webhook', ['error' => $e->getMessage()]); return response()->json(['error' => 'Processing failed'], 500); } } /** * Handle parcel collected status */ private function handleParcelCollected(Order $order, array $payload): void { $order->update([ 'courier_status' => 'collected', 'status' => 'in_transit', ]); ParcelCollected::dispatch($order, $order->courier_waybill_id); Log::info('Parcel collected', ['order_id' => $order->id]); } /** * Handle parcel in transit status */ private function handleParcelInTransit(Order $order, array $payload): void { $order->update([ 'courier_status' => 'in_transit', ]); ParcelInTransit::dispatch($order, $order->courier_waybill_id); Log::info('Parcel in transit', ['order_id' => $order->id]); } /** * Handle parcel delivered status */ private function handleParcelDelivered(Order $order, array $payload): void { $order->update([ 'courier_status' => 'delivered', 'delivered_at' => now(), 'status' => 'completed', ]); ParcelDelivered::dispatch($order, $order->courier_waybill_id); Log::info('Parcel delivered', ['order_id' => $order->id]); } /** * Handle parcel failed delivery status */ private function handleParcelFailedDelivery(Order $order, array $payload): void { $reason = $payload['failure_reason'] ?? 'Unknown reason'; $order->update([ 'courier_status' => 'failed', 'delivery_failure_reason' => $reason, ]); ParcelFailedDelivery::dispatch($order, $order->courier_waybill_id, $reason); Log::info('Parcel delivery failed', [ 'order_id' => $order->id, 'reason' => $reason, ]); } /** * Verify webhook signature (placeholder) */ private function verifyWebhookSignature(Request $request): bool { // TODO: Implement Shiplogic HMAC verification // Compare signature with hash of request body using COURIER_WEBHOOK_SECRET // For now, accept all return true; } }