vendor/shopware/storefront/Controller/CheckoutController.php line 195

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Controller;
  3. use Shopware\Core\Checkout\Cart\Error\Error;
  4. use Shopware\Core\Checkout\Cart\Exception\CartTokenNotFoundException;
  5. use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
  6. use Shopware\Core\Checkout\Cart\Exception\OrderNotFoundException;
  7. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  8. use Shopware\Core\Checkout\Order\SalesChannel\OrderService;
  9. use Shopware\Core\Checkout\Payment\Exception\InvalidOrderException;
  10. use Shopware\Core\Checkout\Payment\Exception\PaymentProcessException;
  11. use Shopware\Core\Checkout\Payment\Exception\UnknownPaymentMethodException;
  12. use Shopware\Core\Checkout\Payment\PaymentService;
  13. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  14. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  15. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  16. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  17. use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
  18. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  19. use Shopware\Storefront\Framework\AffiliateTracking\AffiliateTrackingListener;
  20. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoader;
  21. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoader;
  22. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoader;
  23. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoader;
  24. use Symfony\Component\HttpFoundation\RedirectResponse;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. /**
  30.  * @RouteScope(scopes={"storefront"})
  31.  */
  32. class CheckoutController extends StorefrontController
  33. {
  34.     /**
  35.      * @var CartService
  36.      */
  37.     private $cartService;
  38.     /**
  39.      * @var CheckoutCartPageLoader
  40.      */
  41.     private $cartPageLoader;
  42.     /**
  43.      * @var CheckoutConfirmPageLoader
  44.      */
  45.     private $confirmPageLoader;
  46.     /**
  47.      * @var CheckoutFinishPageLoader
  48.      */
  49.     private $finishPageLoader;
  50.     /**
  51.      * @var OrderService
  52.      */
  53.     private $orderService;
  54.     /**
  55.      * @var PaymentService
  56.      */
  57.     private $paymentService;
  58.     /**
  59.      * @var OffcanvasCartPageLoader
  60.      */
  61.     private $offcanvasCartPageLoader;
  62.     /**
  63.      * @var EntityRepositoryInterface
  64.      */
  65.     private $orderRepository;
  66.     public function __construct(
  67.         CartService $cartService,
  68.         CheckoutCartPageLoader $cartPageLoader,
  69.         CheckoutConfirmPageLoader $confirmPageLoader,
  70.         CheckoutFinishPageLoader $finishPageLoader,
  71.         OrderService $orderService,
  72.         PaymentService $paymentService,
  73.         OffcanvasCartPageLoader $offcanvasCartPageLoader,
  74.         EntityRepositoryInterface $orderRepository
  75.     ) {
  76.         $this->cartService $cartService;
  77.         $this->cartPageLoader $cartPageLoader;
  78.         $this->confirmPageLoader $confirmPageLoader;
  79.         $this->finishPageLoader $finishPageLoader;
  80.         $this->orderService $orderService;
  81.         $this->paymentService $paymentService;
  82.         $this->offcanvasCartPageLoader $offcanvasCartPageLoader;
  83.         $this->orderRepository $orderRepository;
  84.     }
  85.     /**
  86.      * @Route("/checkout/cart", name="frontend.checkout.cart.page", options={"seo"="false"}, methods={"GET"})
  87.      */
  88.     public function cartPage(Request $requestSalesChannelContext $context): Response
  89.     {
  90.         $page $this->cartPageLoader->load($request$context);
  91.         return $this->renderStorefront('@Storefront/storefront/page/checkout/cart/index.html.twig', ['page' => $page]);
  92.     }
  93.     /**
  94.      * @Route("/checkout/confirm", name="frontend.checkout.confirm.page", options={"seo"="false"}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
  95.      */
  96.     public function confirmPage(Request $requestSalesChannelContext $context): Response
  97.     {
  98.         if (!$context->getCustomer()) {
  99.             return $this->redirectToRoute('frontend.checkout.register.page');
  100.         }
  101.         if ($this->cartService->getCart($context->getToken(), $context)->getLineItems()->count() === 0) {
  102.             return $this->redirectToRoute('frontend.checkout.cart.page');
  103.         }
  104.         $page $this->confirmPageLoader->load($request$context);
  105.         return $this->renderStorefront('@Storefront/storefront/page/checkout/confirm/index.html.twig', ['page' => $page]);
  106.     }
  107.     /**
  108.      * @Route("/checkout/finish", name="frontend.checkout.finish.page", options={"seo"="false"}, methods={"GET"})
  109.      *
  110.      * @throws CustomerNotLoggedInException
  111.      * @throws MissingRequestParameterException
  112.      * @throws OrderNotFoundException
  113.      */
  114.     public function finishPage(Request $requestSalesChannelContext $context): Response
  115.     {
  116.         if (!$context->getCustomer()) {
  117.             return $this->redirectToRoute('frontend.checkout.register.page');
  118.         }
  119.         $page $this->finishPageLoader->load($request$context);
  120.         if ($page->isPaymentFailed() === true) {
  121.             $this->addFlash(
  122.                 'danger',
  123.                 $this->trans(
  124.                     'checkout.finishPaymentFailed',
  125.                     [
  126.                         '%editOrderUrl%' => $this->generateUrl('frontend.account.edit-order.page', ['orderId' => $request->get('orderId')]),
  127.                     ]
  128.                 )
  129.             );
  130.         }
  131.         return $this->renderStorefront('@Storefront/storefront/page/checkout/finish/index.html.twig', ['page' => $page]);
  132.     }
  133.     /**
  134.      * @Route("/checkout/order", name="frontend.checkout.finish.order", options={"seo"="false"}, methods={"POST"})
  135.      */
  136.     public function order(RequestDataBag $dataSalesChannelContext $contextRequest $request): Response
  137.     {
  138.         if (!$context->getCustomer()) {
  139.             return $this->redirectToRoute('frontend.checkout.register.page');
  140.         }
  141.         $formViolations null;
  142.         $orderId null;
  143.         try {
  144.             $this->addAffiliateTracking($data$request->getSession());
  145.             $orderId $this->orderService->createOrder($data$context);
  146.             $finishUrl $this->generateUrl('frontend.checkout.finish.page', ['orderId' => $orderId]);
  147.             $errorUrl $this->generateUrl('frontend.checkout.finish.page', [
  148.                 'orderId' => $orderId,
  149.                 'changedPayment' => false,
  150.                 'paymentFailed' => true,
  151.             ]);
  152.             $response $this->paymentService->handlePaymentByOrder($orderId$data$context$finishUrl$errorUrl);
  153.             return $response ?? new RedirectResponse($finishUrl);
  154.         } catch (ConstraintViolationException $formViolations) {
  155.         } catch (Error $blockedError) {
  156.         } catch (PaymentProcessException InvalidOrderException UnknownPaymentMethodException $e) {
  157.             return $this->forwardToRoute('frontend.checkout.finish.page', ['orderId' => $orderId'changedPayment' => false'paymentFailed' => true]);
  158.         }
  159.         return $this->forwardToRoute('frontend.checkout.confirm.page', ['formViolations' => $formViolations]);
  160.     }
  161.     /**
  162.      * @Route("/widgets/checkout/info", name="frontend.checkout.info", methods={"GET"}, defaults={"XmlHttpRequest"=true})
  163.      *
  164.      * @throws CartTokenNotFoundException
  165.      */
  166.     public function info(Request $requestSalesChannelContext $context): Response
  167.     {
  168.         $page $this->offcanvasCartPageLoader->load($request$context);
  169.         return $this->renderStorefront('@Storefront/storefront/layout/header/actions/cart-widget.html.twig', ['page' => $page]);
  170.     }
  171.     /**
  172.      * @Route("/checkout/offcanvas", name="frontend.cart.offcanvas", options={"seo"="false"}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
  173.      *
  174.      * @throws CartTokenNotFoundException
  175.      */
  176.     public function offcanvas(Request $requestSalesChannelContext $context): Response
  177.     {
  178.         $page $this->offcanvasCartPageLoader->load($request$context);
  179.         return $this->renderStorefront('@Storefront/storefront/component/checkout/offcanvas-cart.html.twig', ['page' => $page]);
  180.     }
  181.     private function addAffiliateTracking(RequestDataBag $dataBagSessionInterface $session): void
  182.     {
  183.         $affiliateCode $session->get(AffiliateTrackingListener::AFFILIATE_CODE_KEY);
  184.         $campaignCode $session->get(AffiliateTrackingListener::CAMPAIGN_CODE_KEY);
  185.         if ($affiliateCode !== null && $campaignCode !== null) {
  186.             $dataBag->set(AffiliateTrackingListener::AFFILIATE_CODE_KEY$affiliateCode);
  187.             $dataBag->set(AffiliateTrackingListener::CAMPAIGN_CODE_KEY$campaignCode);
  188.         }
  189.     }
  190. }