src/FMT/Infrastructure/Service/Payments/Dwolla/Listener/HandleWebhooksListener.php line 61

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace FMT\Infrastructure\Service\Payments\Dwolla\Listener;
  4. use FMT\Infrastructure\Helper\CaseHelper;
  5. use FMT\Infrastructure\Helper\LogHelper;
  6. use FMT\Infrastructure\Service\Mapper\Mapper;
  7. use FMT\Infrastructure\Service\Payments\Dwolla\Exception\AuthenticationFailedException;
  8. use FMT\Infrastructure\Service\Payments\Dwolla\Item\Webhook;
  9. use Symfony\Component\HttpFoundation\Response;
  10. use Symfony\Component\HttpKernel\Event\RequestEvent;
  11. /**
  12.  * Class HandleWebhooksListener
  13.  */
  14. class HandleWebhooksListener
  15. {
  16.     /**
  17.      * @var Mapper
  18.      */
  19.     protected $mapper;
  20.     /**
  21.      * @var string
  22.      */
  23.     protected $webhooksRoute;
  24.     /**
  25.      * @var string
  26.      */
  27.     protected $webhooksToken;
  28.     /**
  29.      * @var string
  30.      */
  31.     protected $webhooksController;
  32.     /**
  33.      * @param Mapper $mapper
  34.      * @param string $webhooksRoute
  35.      * @param string $webhooksToken
  36.      * @param string $webhooksController
  37.      */
  38.     public function __construct(
  39.         Mapper $mapper,
  40.         string $webhooksRoute,
  41.         string $webhooksToken,
  42.         string $webhooksController
  43.     ) {
  44.         $this->mapper $mapper;
  45.         $this->webhooksRoute $webhooksRoute;
  46.         $this->webhooksToken $webhooksToken;
  47.         $this->webhooksController $webhooksController;
  48.     }
  49.     /**
  50.      * @param RequestEvent $event
  51.      */
  52.     public function onKernelRequest(RequestEvent $event)
  53.     {
  54.         $request $event->getRequest();
  55.         if ($this->webhooksRoute !== $request->getRequestUri() || !$request->isMethod('POST')) {
  56.             return;
  57.         }
  58.         try {
  59.             $signature $request->headers->get('x-request-signature-Sha-256''');
  60.             $this->authenticate($signature$request->getContent());
  61.             $topic $request->headers->get('x-dwolla-topic');
  62.             $action CaseHelper::toCase($topicCaseHelper::SNAKE_CASECaseHelper::CAMEL_CASE);
  63.             LogHelper::info([sprintf('Received webhook with topic "%s"'$topic)]);
  64.             if (!method_exists($this->webhooksController$action)) {
  65.                 $action 'other';
  66.             }
  67.             $webhook $this->mapper->map($request->toArray(), Webhook::class);
  68.             $request->attributes->set('_controller'$this->webhooksController '::' $action);
  69.             $request->attributes->set('webhook'$webhook);
  70.             $request->attributes->set('_dwolla_webhook'true);
  71.             $event->stopPropagation();
  72.         } catch (AuthenticationFailedException $e) {
  73.             $event->setResponse(new Response(null403));
  74.         }
  75.     }
  76.     /**
  77.      * @param string $requestSignature
  78.      * @param string $requestBody
  79.      *
  80.      * @throws AuthenticationFailedException
  81.      */
  82.     protected function authenticate(string $requestSignaturestring $requestBody): void
  83.     {
  84.         $hmac hash_hmac('sha256'$requestBody$this->webhooksToken);
  85.         if ($hmac !== $requestSignature) {
  86.             throw new AuthenticationFailedException();
  87.         }
  88.     }
  89. }