<?php
declare(strict_types=1);
namespace App\Controller\Front\Stripe;
use App\Application\Service\Helper\LogWriterService;
use App\Application\Service\Session\SessionService;
use App\Manager\System\OrderManager;
use App\Message\StripeResponseMessage;
use App\Service\Order\OrderPaymentService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Stripe\Webhook;
use Stripe\Exception\SignatureVerificationException;
use Stripe\Exception\UnexpectedValueException;
class StripeResponseController extends AbstractController
{
private LogWriterService $logWriterService;
private MessageBusInterface $messageBus;
private OrderManager $orderManager;
private SessionService $sessionService;
private OrderPaymentService $orderPaymentService;
public function __construct(
LogWriterService $logWriterService,
MessageBusInterface $messageBus,
OrderManager $orderManager,
SessionService $sessionService,
OrderPaymentService $orderPaymentService
) {
$this->logWriterService = $logWriterService;
$this->messageBus = $messageBus;
$this->orderManager = $orderManager;
$this->sessionService = $sessionService;
$this->orderPaymentService = $orderPaymentService;
}
/**
* @Route("stripe/{orderId}/checkout", methods={"GET"}, name="stripe_checkout_session_response")
*/
public function checkoutSessionResponse(int $orderId): Response
{
$message = __METHOD__.' - Procesamos la respuesta del CheckoutSession de Stripe para el pedido '.$orderId;
$this->logWriterService->logOrderPayment($message);
$order = $this->orderManager->findOneById($orderId);
if (!$order) {
$this->logWriterService->logOrderPaymentError(__METHOD__.' - El pedido '.$orderId.' no existe.');
return $this->redirect(BASE_URL);
}
$paidOrderIds = $this->sessionService->get('paidOrderIds') ? (array)$this->sessionService->get('paidOrderIds') : [];
$paidOrderIds[] = $order->getId();
$paidOrders = \array_map(function (int $paidOrderId) {
return $this->orderManager->getOneById($paidOrderId);
}, $paidOrderIds);
$this->orderPaymentService->manageOrdersInSessionOnPaymentSuccess(
$paidOrders,
$order,
(bool)$order->getCart()->getCartParent()
);
if ($order->getCart()->getVirtual()) {
$this->logWriterService->logOrderPayment(__METHOD__.' - Redirecting to services_order_creation route');
return $this->redirectToRoute('services_order_creation', ['validateCart' => 0]);
}
$this->logWriterService->logOrderPayment(__METHOD__.' - Redirecting to products_order_creation route');
return $this->redirectToRoute('products_order_creation', ['validateCart' => 0]);
}
/**
* @Route("stripe/webhook/notification", name="webhook_stripe_notification", methods={"POST"})
*/
public function checkNotification(Request $request): Response
{
$webhookSecret = $this->getParameter('stripe_webhook_key');
$sigHeader = $request->headers->get('Stripe-Signature');
$notificationRequest = \json_decode($request->getContent(), true);
$this->logWriterService->logOrderPayment('LLega webhook Stripe. Request: '.$request->getContent().' y la firma es: '.$sigHeader);
$sandbox = (bool)$this->getParameter('stripe_sandbox');
$livemode = $notificationRequest['data']['object']['livemode'];
if ($sandbox !== ($livemode === false)) {
$this->logWriterService->logOrderPaymentError('Error Webhook Stripe: La variable stripe_sandbox con valor '.(int)$sandbox.' no coincide con el valor de livemode en el webhook Stripe: '.$livemode);
return new Response('Invalid livemode', Response::HTTP_BAD_REQUEST);
}
try {
$event = Webhook::constructEvent($request->getContent(), $sigHeader, $webhookSecret);
} catch (UnexpectedValueException $exception) {
$this->logWriterService->logOrderPaymentError('Error Webhook Stripe: Invalid payload: '.$exception->getMessage());
return new Response('Invalid payload', Response::HTTP_BAD_REQUEST);
} catch (SignatureVerificationException $exception) {
$this->logWriterService->logOrderPaymentError('Error Webhook Stripe: Invalid signature: '.$exception->getMessage());
return new Response('Invalid signature', Response::HTTP_BAD_REQUEST);
}
$this->logWriterService->logOrderPayment('Webhook Stripe vĂ¡lido. Mandamos mensaje a Rabbit');
$stripeResponseMessage = new StripeResponseMessage($event);
$this->messageBus->dispatch($stripeResponseMessage);
return new Response(
null,
Response::HTTP_OK
);
}
}