src/Controller/WebhookController.php line 22

  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Carrier;
  4. use App\Entity\CarrierStatus;
  5. use App\Entity\Order;
  6. use App\Entity\TrackingInformation;
  7. use App\Manager\OrderTrackingManager;
  8. use App\Repository\OrderRepository;
  9. use App\Repository\TrackingInformationRepository;
  10. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  11. use Symfony\Component\HttpFoundation\JsonResponse;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\Routing\Annotation\Route;
  14. class WebhookController extends AbstractController
  15. {
  16.     #[Route('/webhooks/delhivery/sync'name'webhooks_delhivery_sync'methods: ['POST'])]
  17.     public function createShipment(Request $requestOrderRepository $orderRepositoryTrackingInformationRepository $trackingInformationRepositoryOrderTrackingManager $orderTrackingManager): JsonResponse
  18.     {
  19.         // Check for Authorization header
  20.         $authHeader $request->headers->get('Authorization');
  21.         if (!$authHeader || !str_starts_with($authHeader'Bearer ')) {
  22.             return new JsonResponse(['error' => 'Authorization header is missing or invalid'], 401);
  23.         }
  24.         // Extract and validate token
  25.         $token substr($authHeader7); // Remove 'Bearer ' prefix
  26.         if ($token !== $this->getParameter('shipflick.webhook.delhivery.token')) {
  27.             return new JsonResponse(['error' => 'Invalid API token'], 403);
  28.         }
  29.         // Decode JSON payload
  30.         $payload json_decode($request->getContent(), true);
  31.         if (json_last_error() !== JSON_ERROR_NONE) {
  32.             return new JsonResponse(['error' => 'Invalid JSON'], 400);
  33.         }
  34.         // Validate payload fields
  35.         $requiredFields = [
  36.             'shipment_remark''location''count''lrnum''mwn',
  37.             'cl_uuid''name''package_type''expected_delivery_date',
  38.             'promised_delivery_date''timestamp''status',
  39.         ];
  40.         foreach ($requiredFields as $field) {
  41.             if (!isset($payload[$field])) {
  42.                 return new JsonResponse(['error' => "Missing required field: $field"], 400);
  43.             }
  44.         }
  45.         $order $orderRepository->findOneBy(['LRNo' => $payload['lrnum']]);
  46.         if($order instanceof Order) {
  47.             $statusDateTime \DateTimeImmutable::createFromFormat("Y-m-d\TH:i:s.u"$payload['timestamp']);
  48.             $mappedStatus $orderTrackingManager->translateCarrierStatus($order->getCarrier(), $payload['status']);
  49.             $trackingDuplication $trackingInformationRepository->findBy(['shippingOrder' => $order'carrierUpdatedAt' => $statusDateTime'status' => $mappedStatus]) ?: false;
  50.             if (!$trackingDuplication) {
  51.                 $trackingInfo = new TrackingInformation();
  52.                 $trackingInfo->setShippingOrder($order);
  53.                 $trackingInfo->setStatus($mappedStatus);
  54.                 $trackingInfo->setLocation($payload['location']);
  55.                 $trackingInfo->setRemarks("scan_remark: " $payload['shipment_remark']);
  56.                 $trackingInfo->setCarrierUpdatedAt($statusDateTime);
  57.                 $trackingInfo->setStatus($mappedStatus);
  58.                 $orderRepository->save($order);
  59.             }
  60.         }
  61.         return new JsonResponse(['message' => 'Shipment status updated successfully'], 201);
  62.     }
  63. }