storeManager = $storeManager; $this->customerSession = $customerSession; $this->formKeyValidator = $formKeyValidator; $this->instantPurchaseOptionLoadingFactory = $instantPurchaseOptionLoadingFactory; $this->productRepository = $productRepository; $this->placeOrder = $placeOrder; $this->orderRepository = $orderRepository; } /** * Place an order for a customer. * * @return JsonResult */ public function execute() { $request = $this->getRequest(); if (!$this->doesRequestContainAllKnowParams($request)) { return $this->createResponse($this->createGenericErrorMessage(), false); } if (!$this->formKeyValidator->validate($request)) { return $this->createResponse($this->createGenericErrorMessage(), false); } $paymentTokenPublicHash = (string)$request->getParam('instant_purchase_payment_token'); $shippingAddressId = (int)$request->getParam('instant_purchase_shipping_address'); $billingAddressId = (int)$request->getParam('instant_purchase_billing_address'); $carrierCode = (string)$request->getParam('instant_purchase_carrier'); $shippingMethodCode = (string)$request->getParam('instant_purchase_shipping'); $productId = (int)$request->getParam('product'); $productRequest = $this->getRequestUnknownParams($request); try { $customer = $this->customerSession->getCustomer(); $instantPurchaseOption = $this->instantPurchaseOptionLoadingFactory->create( $customer->getId(), $paymentTokenPublicHash, $shippingAddressId, $billingAddressId, $carrierCode, $shippingMethodCode ); $store = $this->storeManager->getStore(); $product = $this->productRepository->getById( $productId, false, $store->getId(), false ); $orderId = $this->placeOrder->placeOrder( $store, $customer, $instantPurchaseOption, $product, $productRequest ); } catch (NoSuchEntityException $e) { return $this->createResponse($this->createGenericErrorMessage(), false); } catch (Exception $e) { return $this->createResponse( $e instanceof LocalizedException ? $e->getMessage() : $this->createGenericErrorMessage(), false ); } $order = $this->orderRepository->get($orderId); $message = __('Your order number is: %1.', $order->getIncrementId()); return $this->createResponse($message, true); } /** * Creates error message without exposing error details. * * @return string */ private function createGenericErrorMessage(): string { return (string)__('Something went wrong while processing your order. Please try again later.'); } /** * Checks if all parameters that should be handled are passed. * * @param RequestInterface $request * @return bool */ private function doesRequestContainAllKnowParams(RequestInterface $request): bool { foreach (self::$knownRequestParams as $knownRequestParam) { if ($request->getParam($knownRequestParam) === null) { return false; } } return true; } /** * Filters out parameters that handled by controller. * * @param RequestInterface $request * @return array */ private function getRequestUnknownParams(RequestInterface $request): array { $requestParams = $request->getParams(); $unknownParams = []; foreach ($requestParams as $param => $value) { if (!isset(self::$knownRequestParams[$param])) { $unknownParams[$param] = $value; } } return $unknownParams; } /** * Creates response with a operation status message. * * @param string $message * @param bool $successMessage * @return JsonResult */ private function createResponse(string $message, bool $successMessage): JsonResult { /** @var JsonResult $result */ $result = $this->resultFactory->create(ResultFactory::TYPE_JSON); $result->setData([ 'response' => $message ]); if ($successMessage) { $this->messageManager->addSuccessMessage($message); } else { $this->messageManager->addErrorMessage($message); } return $result; } }