* @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ if (!defined('_PS_VERSION_')) { exit; } use PsCheckout\Core\Exception\PsCheckoutException; use PsCheckout\Core\PayPal\Order\Action\CreatePayPalOrderAction; use PsCheckout\Core\PayPal\Order\Configuration\PayPalOrderStatus; use PsCheckout\Core\PayPal\Order\Request\ValueObject\CreatePayPalOrderRequest; use PsCheckout\Infrastructure\Action\AddProductToCartAction; use PsCheckout\Infrastructure\Adapter\Context; use PsCheckout\Infrastructure\Controller\AbstractFrontController; use PsCheckout\Infrastructure\Repository\PayPalOrderRepository; use PsCheckout\Utility\Common\InputStreamUtility; /** * This controller receives ajax call to create a PayPal Order */ class Ps_CheckoutCreateModuleFrontController extends AbstractFrontController { /** * @see FrontController::postProcess() */ public function postProcess() { try { /** @var Context $context */ $context = $this->module->getService(Context::class); // BEGIN Express Checkout $requestData = []; /** @var InputStreamUtility $inputStreamUtility */ $inputStreamUtility = $this->module->getService(InputStreamUtility::class); $bodyContent = $inputStreamUtility->getBodyContent(); if (!empty($bodyContent)) { $requestData = json_decode($bodyContent, true); } $requestData['isExpressCheckout'] = (isset($requestData['isExpressCheckout']) && $requestData['isExpressCheckout']) || empty($this->context->cart->id_address_delivery); $createPayPalOrderRequest = new CreatePayPalOrderRequest($requestData); if ($this->shouldCreateCart($createPayPalOrderRequest)) { try { /** @var AddProductToCartAction $addProductToCartAction */ $addProductToCartAction = $this->module->getService(AddProductToCartAction::class); $addProductToCartAction->execute($createPayPalOrderRequest); } catch (PsCheckoutException $exception) { $this->exitWithResponse([ 'status' => false, 'httpCode' => 400, 'body' => [ 'error' => [ 'message' => 'Failed to update cart quantity.', ], ], ]); } } // END Express Checkout if (!isset($context->getCart()->id)) { $this->exitWithResponse([ 'httpCode' => 404, 'body' => 'Cart not found', ]); } // Validate PUI amount limits (5 EUR < amount < 2500 EUR) if ($createPayPalOrderRequest->getFundingSource() === 'pay_upon_invoice') { $cart = $context->getCart(); $cartTotal = (float) $cart->getOrderTotal(true, \Cart::BOTH); if ($cartTotal <= 5.00 || $cartTotal >= 2500.00) { $this->exitWithResponse([ 'status' => false, 'httpCode' => 400, 'body' => [ 'error' => [ 'message' => $this->module->l('The payment is not valid: the amount is not eligible.', 'create'), ], ], ]); } } if ($createPayPalOrderRequest->isExpressCheckout() || empty($context->getCart()->id_address_delivery)) { /** @var PayPalOrderRepository $payPalOrderRepository */ $payPalOrderRepository = $this->module->getService(PayPalOrderRepository::class); $payPalOrder = $payPalOrderRepository->getOneByCartId((int) $context->getCart()->id); if ($payPalOrder && $payPalOrder->isExpressCheckout() && in_array( $payPalOrder->getStatus(), [ PayPalOrderStatus::CREATED, PayPalOrderStatus::APPROVED, PayPalOrderStatus::PAYER_ACTION_REQUIRED, ], true )) { $this->exitWithResponse([ 'status' => true, 'httpCode' => 200, 'body' => [ 'orderID' => $payPalOrder->getId(), ], 'exceptionCode' => null, 'exceptionMessage' => null, ]); } } /** @var CreatePayPalOrderAction $createPayPalOrderAction */ $createPayPalOrderAction = $this->module->getService(CreatePayPalOrderAction::class); $createPayPalOrderAction->execute((int) $context->getCart()->id, $createPayPalOrderRequest); /** @var PayPalOrderRepository $payPalOrderRepository */ $payPalOrderRepository = $this->module->getService(PayPalOrderRepository::class); $payPalOrder = $payPalOrderRepository->getOneByCartId((int) $context->getCart()->id); if (!$payPalOrder) { $this->exitWithResponse([ 'httpCode' => 404, 'body' => 'PayPal order not found', ]); } $this->exitWithResponse([ 'status' => true, 'httpCode' => 200, 'body' => [ 'orderID' => $payPalOrder->getId(), ], 'exceptionCode' => null, 'exceptionMessage' => null, ]); } catch (Exception $exception) { $this->exitWithExceptionMessage($exception); } catch (Throwable $exception) { $this->exitWithExceptionMessage(new PsCheckoutException( 'An error occurred while creating the PayPal order.', PsCheckoutException::UNKNOWN, $exception )); } } /** * @param CreatePayPalOrderRequest $checkoutRequest * * @return bool */ private function shouldCreateCart(CreatePayPalOrderRequest $checkoutRequest): bool { return $checkoutRequest->getQuantityWanted() !== null || $checkoutRequest->getIdProduct() !== null || $checkoutRequest->getIdProductAttribute() !== null || $checkoutRequest->getIdCustomization() !== null; } }