* @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\Customer\Action\ExpressCheckoutAction; use PsCheckout\Core\Customer\Request\ValueObject\ExpressCheckoutRequest; use PsCheckout\Core\Exception\PsCheckoutException; use PsCheckout\Core\PayPal\Order\Entity\PayPalOrder; use PsCheckout\Infrastructure\Controller\AbstractFrontController; use PsCheckout\Infrastructure\Repository\PayPalOrderRepository; use PsCheckout\Infrastructure\Validator\FrontControllerValidator; use PsCheckout\Utility\Common\InputStreamUtility; /** * This controller receive ajax call when customer click on an express checkout button * We retrieve data from PayPal in payload and save it in PrestaShop to prefill order page * Then customer must be redirected to order page to choose shipping method */ class ps_checkoutExpressCheckoutModuleFrontController extends AbstractFrontController { /** * {@inheritdoc} */ public function postProcess() { /** @var FrontControllerValidator $frontControllerValidator */ $frontControllerValidator = $this->module->getService(FrontControllerValidator::class); if (!$frontControllerValidator->isExpressCheckoutEnabled()) { $this->exitWithResponse([ 'httpCode' => 403, 'body' => 'Forbidden', ]); } // We receive data in a payload not in GET/POST /** @var InputStreamUtility $inputStreamUtility */ $inputStreamUtility = $this->module->getService(InputStreamUtility::class); $bodyContent = $inputStreamUtility->getBodyContent(); if (empty($bodyContent)) { $this->exitWithResponse([ 'httpCode' => 400, 'body' => 'Payload invalid', ]); } $requestData = json_decode($bodyContent, true); if (empty($requestData)) { $this->exitWithResponse([ 'httpCode' => 400, 'body' => 'Payload invalid', ]); } $expressCheckoutRequest = new ExpressCheckoutRequest($requestData); if (!$expressCheckoutRequest->getOrderId()) { $this->exitWithResponse([ 'httpCode' => 400, 'body' => 'Payload invalid', ]); } try { /** @var PayPalOrderRepository $payPalOrderReposistory */ $payPalOrderReposistory = $this->module->getService(PayPalOrderRepository::class); /** @var PayPalOrder|null $psCheckoutCart */ $payPalOrder = $payPalOrderReposistory->getOneBy(['id' => $expressCheckoutRequest->getOrderId()]); if (!$payPalOrder || $payPalOrder->getIdCart() !== $this->context->cart->id) { $this->exitWithResponse([ 'httpCode' => 400, 'body' => 'Payload invalid', ]); } if ($payPalOrder) { $payPalOrder->setFundingSource($expressCheckoutRequest->getFundingSource()) ->setIsExpressCheckout(true) ->setIsCardFields(false); $payPalOrderReposistory->save($payPalOrder); } /** @var ExpressCheckoutAction $expressCheckoutAction */ $expressCheckoutAction = $this->module->getService(ExpressCheckoutAction::class); $expressCheckoutAction->execute($expressCheckoutRequest); } catch (Exception $exception) { $this->exitWithExceptionMessage($exception); } catch (Throwable $exception) { $this->exitWithExceptionMessage(new PsCheckoutException( 'An error occurred while processing the express checkout.', PsCheckoutException::UNKNOWN, $exception )); } $this->exitWithResponse([ 'status' => true, 'httpCode' => 200, 'body' => $expressCheckoutRequest->getPayload(), 'exceptionCode' => null, 'exceptionMessage' => null, ]); } }