src/Controller/WebhookController.php line 61
<?php
namespace App\Controller;
use App\Entity\Carrier;
use App\Entity\CarrierStatus;
use App\Entity\Order;
use App\Entity\TrackingInformation;
use App\Manager\OrderTrackingManager;
use App\Repository\OrderRepository;
use App\Repository\TrackingInformationRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class WebhookController extends AbstractController
{
#[Route('/webhooks/delhivery/sync', name: 'webhooks_delhivery_sync', methods: ['POST'])]
public function createShipment(Request $request, OrderRepository $orderRepository, TrackingInformationRepository $trackingInformationRepository, OrderTrackingManager $orderTrackingManager): JsonResponse
{
// Check for Authorization header
$authHeader = $request->headers->get('Authorization');
if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
return new JsonResponse(['error' => 'Authorization header is missing or invalid'], 401);
}
// Extract and validate token
$token = substr($authHeader, 7); // Remove 'Bearer ' prefix
if ($token !== $this->getParameter('shipflick.webhook.delhivery.token')) {
return new JsonResponse(['error' => 'Invalid API token'], 403);
}
// Decode JSON payload
$payload = json_decode($request->getContent(), true);
if (json_last_error() !== JSON_ERROR_NONE) {
return new JsonResponse(['error' => 'Invalid JSON'], 400);
}
// Validate payload fields
$requiredFields = [
'shipment_remark', 'location', 'count', 'lrnum', 'mwn',
'cl_uuid', 'name', 'package_type', 'expected_delivery_date',
'promised_delivery_date', 'timestamp', 'status',
];
foreach ($requiredFields as $field) {
if (!isset($payload[$field])) {
return new JsonResponse(['error' => "Missing required field: $field"], 400);
}
}
$order = $orderRepository->findOneBy(['LRNo' => $payload['lrnum']]);
if($order instanceof Order) {
$statusDateTime = \DateTimeImmutable::createFromFormat("Y-m-d\TH:i:s.u", $payload['timestamp']);
$mappedStatus = $orderTrackingManager->translateCarrierStatus($order->getCarrier(), $payload['status']);
$trackingDuplication = $trackingInformationRepository->findBy(['shippingOrder' => $order, 'carrierUpdatedAt' => $statusDateTime, 'status' => $mappedStatus]) ?: false;
if (!$trackingDuplication) {
$trackingInfo = new TrackingInformation();
$trackingInfo->setShippingOrder($order);
$trackingInfo->setStatus($mappedStatus);
$trackingInfo->setLocation($payload['location']);
$trackingInfo->setRemarks("scan_remark: " . $payload['shipment_remark']);
$trackingInfo->setCarrierUpdatedAt($statusDateTime);
$trackingInfo->setStatus($mappedStatus);
$orderRepository->save($order);
}
}
return new JsonResponse(['message' => 'Shipment status updated successfully'], 201);
}
}