First upload

This commit is contained in:
Nikolai Fesenko
2025-02-02 13:37:56 +01:00
commit 8d227c9191
3281 changed files with 362319 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderActionData
{
/**
* Request object
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $request = null;
/**
* Order object
*
* @var \OxidEsales\PayPalModule\Model\Order
*/
protected $order = null;
/**
* Sets dependencies.
*
* @param \OxidEsales\PayPalModule\Core\Request $request
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*/
public function __construct($request, $order)
{
$this->request = $request;
$this->order = $order;
}
/**
* Returns Request object
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Returns PayPal Order object
*
* @return \OxidEsales\PayPalModule\Model\Order
*/
public function getOrder()
{
return $this->order;
}
/**
* returns action amount
*
* @return string
*/
public function getAuthorizationId()
{
return $this->getOrder()->oxorder__oxtransid->value;
}
/**
* returns comment
*
* @return string
*/
public function getComment()
{
return $this->getRequest()->getRequestParameter('action_comment');
}
/**
* Returns order status
*
* @return string
*/
public function getOrderStatus()
{
return $this->getRequest()->getRequestParameter('order_status');
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderCaptureActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* returns action type
*
* @return string
*/
public function getType()
{
return $this->getRequest()->getRequestParameter('capture_type');
}
/**
* returns action amount
*
* @return string
*/
public function getAmount()
{
$amount = $this->getRequest()->getRequestParameter('capture_amount');
$validDecimalAmount = preg_replace('/,(?=\d{0,2}$)/', '.', $amount) ?? $amount;
return $validDecimalAmount ? $validDecimalAmount : $this->getOrder()->getPayPalOrder()->getRemainingOrderSum();
}
/**
* returns currency
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class.
*/
class OrderReauthorizeActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* Returns action amount.
*
* @return string
*/
public function getAmount()
{
return $this->getOrder()->getPayPalOrder()->getRemainingOrderSum();
}
/**
* Returns currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderRefundActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* @var \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
public $paymentBeingRefunded = null;
/**
* Returns action type.
*
* @return string
*/
public function getType()
{
return $this->getRequest()->getRequestParameter('refund_type');
}
/**
* Returns action amount.
*
* @return string
*/
public function getTransactionId()
{
return $this->getRequest()->getRequestParameter('transaction_id');
}
/**
* Returns amount to refund.
*
* @return float
*/
public function getAmount()
{
$amount = $this->getRequest()->getRequestParameter('refund_amount');
$validDecimalAmount = preg_replace('/,(?=\d{0,2}$)/', '.', $amount) ?? $amount;
return $validDecimalAmount ? $validDecimalAmount : $this->getPaymentBeingRefunded()->getRemainingRefundAmount();
}
/**
* Returns currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
/**
* Returns payment to refund.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function getPaymentBeingRefunded()
{
if (is_null($this->paymentBeingRefunded)) {
$this->paymentBeingRefunded = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$this->paymentBeingRefunded->loadByTransactionId($this->getTransactionId());
}
return $this->paymentBeingRefunded;
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Data;
/**
* PayPal order action factory class
*/
class OrderVoidActionData extends \OxidEsales\PayPalModule\Model\Action\Data\OrderActionData
{
/**
* Returns action amount.
*
* @return string
*/
public function getAmount()
{
return $this->getOrder()->getPayPalOrder()->getRemainingOrderSum();
}
/**
* Returns currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getOrder()->getPayPalOrder()->getCurrency();
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action class
*/
abstract class OrderActionHandler
{
/**
* @var object
*/
protected $data = null;
/**
* @var \OxidEsales\PayPalModule\Core\PayPalService
*/
protected $payPalService = null;
/**
* PayPal order
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $payPalRequestBuilder = null;
/**
* Sets data object.
*
* @param object $data
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Returns Data object
*
* @return object
*/
public function getData()
{
return $this->data;
}
/**
* Sets PayPal request builder
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequestBuilder $builder
*/
public function setPayPalRequestBuilder($builder)
{
$this->payPalRequestBuilder = $builder;
}
/**
* Returns PayPal request builder
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequestBuilder
*/
public function getPayPalRequestBuilder()
{
if ($this->payPalRequestBuilder === null) {
$this->payPalRequestBuilder = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequestBuilder::class);
}
return $this->payPalRequestBuilder;
}
/**
* Sets PayPal service
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $service
*/
public function setPayPalService($service)
{
$this->payPalService = $service;
}
/**
* Returns PayPal service
*
* @return \OxidEsales\PayPalModule\Core\PayPalService
*/
public function getPayPalService()
{
if ($this->payPalService === null) {
$this->payPalService = oxNew(\OxidEsales\PayPalModule\Core\PayPalService::class);
}
return $this->payPalService;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action capture class
*/
class OrderCaptureActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; calls PayPal if not set
*
* @return mixed
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->doCapture($request);
}
/**
* Returns PayPal request; initializes if not set
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setAuthorizationId($data->getAuthorizationId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$requestBuilder->setCompleteType($data->getType());
$requestBuilder->setComment($data->getComment());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action reauthorize class
*/
class OrderReauthorizeActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request.
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\Response\ResponseDoRefund|\OxidEsales\PayPalModule\Model\Response\Response
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->doReAuthorization($request);
}
/**
* Returns PayPal request; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setAuthorizationId($data->getAuthorizationId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action refund class
*/
class OrderRefundActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; calls PayPal if not set
*
* @return mixed
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->refundTransaction($request);
}
/**
* Returns PayPal request; initiates if not set
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setTransactionId($data->getTransactionId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$requestBuilder->setRefundType($data->getType());
$requestBuilder->setComment($data->getComment());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action\Handler;
/**
* PayPal order action void class.
*/
class OrderVoidActionHandler extends \OxidEsales\PayPalModule\Model\Action\Handler\OrderActionHandler
{
/**
* PayPal Request.
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $payPalRequest = null;
/**
* Returns PayPal response; initiates if not set.
*
* @return mixed
*/
public function getPayPalResponse()
{
$service = $this->getPayPalService();
$request = $this->getPayPalRequest();
return $service->doVoid($request);
}
/**
* Returns PayPal request; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$requestBuilder = $this->getPayPalRequestBuilder();
$data = $this->getData();
$requestBuilder->setAuthorizationId($data->getAuthorizationId());
$requestBuilder->setAmount($data->getAmount(), $data->getCurrency());
$requestBuilder->setComment($data->getComment());
$this->payPalRequest = $requestBuilder->getRequest();
}
return $this->payPalRequest;
}
/**
* Sets PayPal request.
*
* @param \OxidEsales\PayPalModule\Core\Request $payPalRequest Request object.
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action class
*/
abstract class OrderAction
{
/**
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $_oOrder = null;
/**
* @var string
*/
protected $orderStatus = null;
/**
* @var \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler
*/
protected $handler = null;
/**
* Sets handler and order.
*
* @param \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler $handler
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*/
public function __construct($handler, $order)
{
$this->handler = $handler;
$this->order = $order;
}
/**
* Returns \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler object.
*
* @return \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler
*/
public function getHandler()
{
return $this->handler;
}
/**
* Returns \OxidEsales\PayPalModule\Model\PayPalOrder object.
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder
*/
public function getOrder()
{
return $this->order;
}
/**
* Returns formatted date
*
* @return string
*/
public function getDate()
{
$utilsDate = \OxidEsales\Eshop\Core\Registry::getUtilsDate();
return date('Y-m-d H:i:s', $utilsDate->getTime());
}
/**
* Processes PayPal action
*/
abstract public function process();
}

View File

@@ -0,0 +1,144 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action factory class
*/
class OrderActionFactory
{
/**
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $_oRequest = null;
/**
* @var \OxidEsales\PayPalModule\Model\Order
*/
protected $order = null;
/**
* Sets dependencies
*
* @param \OxidEsales\PayPalModule\Core\Request $request
* @param \OxidEsales\PayPalModule\Model\Order $order
*/
public function __construct($request, $order)
{
$this->request = $request;
$this->order = $order;
}
/**
* Returns Request object
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Returns Order object
*
* @return \OxidEsales\PayPalModule\Model\Order
*/
public function getOrder()
{
return $this->order;
}
/**
* Creates action object by given action name.
*
* @param string $action
*
* @return object
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalInvalidActionException
*/
public function createAction($action)
{
$method = "get" . ucfirst($action) . "Action";
if (!method_exists($this, $method)) {
/** @var \OxidEsales\PayPalModule\Core\Exception\PayPalInvalidActionException $exception */
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalInvalidActionException::class);
throw $exception;
}
return $this->$method();
}
/**
* Returns capture action object
*
* @return \OxidEsales\PayPalModule\Model\Action\OrderCaptureAction
*/
public function getCaptureAction()
{
$order = $this->getOrder();
$request = $this->getRequest();
$data = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderCaptureActionData::class, $request, $order);
$handler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler::class, $data);
$reauthorizeData = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderReauthorizeActionData::class, $request, $order);
$reauthorizeHandler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler::class, $reauthorizeData);
$action = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderCaptureAction::class, $handler, $order->getPayPalOrder(), $reauthorizeHandler);
return $action;
}
/**
* Returns refund action object
*
* @return \OxidEsales\PayPalModule\Model\Action\OrderRefundAction
*/
public function getRefundAction()
{
$order = $this->getOrder();
$data = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderRefundActionData::class, $this->getRequest(), $order);
$handler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderRefundActionHandler::class, $data);
$action = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderRefundAction::class, $handler, $order->getPayPalOrder());
return $action;
}
/**
* Returns void action object
*
* @return \OxidEsales\PayPalModule\Model\Action\OrderVoidAction
*/
public function getVoidAction()
{
$order = $this->getOrder();
$data = oxNew(\OxidEsales\PayPalModule\Model\Action\Data\OrderVoidActionData::class, $this->getRequest(), $order);
$handler = oxNew(\OxidEsales\PayPalModule\Model\Action\Handler\OrderVoidActionHandler::class, $data);
$action = oxNew(\OxidEsales\PayPalModule\Model\Action\OrderVoidAction::class, $handler, $order->getPayPalOrder());
return $action;
}
}

View File

@@ -0,0 +1,154 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action capture class
*/
class OrderCaptureAction extends \OxidEsales\PayPalModule\Model\Action\OrderAction
{
/**
* @var \OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler
*/
protected $reauthorizeHandler = null;
/**
* Sets dependencies.
*
* @param \OxidEsales\PayPalModule\Model\Action\Handler\OrderCaptureActionHandler $handler
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
* @param \OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler $reauthorizeHandler
*/
public function __construct($handler, $order, $reauthorizeHandler)
{
parent::__construct($handler, $order);
$this->reauthorizeHandler = $reauthorizeHandler;
}
/**
* Returns reauthorize action handler.
*
* @return \OxidEsales\PayPalModule\Model\Action\Handler\OrderReauthorizeActionHandler
*/
public function getReauthorizeHandler()
{
return $this->reauthorizeHandler;
}
/**
* Processes PayPal response.
*/
public function process()
{
$this->reauthorize();
$handler = $this->getHandler();
$response = $handler->getPayPalResponse();
$data = $handler->getData();
$this->updateOrder($response, $data);
$payment = $this->createPayment($response);
$paymentList = $this->getOrder()->getPaymentList();
$payment = $paymentList->addPayment($payment);
$this->addComment($payment, $data->getComment());
}
/**
* Reauthorizes payment if order was captured at least once.
*/
protected function reauthorize()
{
$order = $this->getOrder();
if ($order->getCapturedAmount() > 0) {
$handler = $this->getReauthorizeHandler();
try {
$response = $handler->getPayPalResponse();
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getAuthorizationId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('re-authorization');
$payment->setStatus($response->getPaymentStatus());
$order->getPaymentList()->addPayment($payment);
} catch (\OxidEsales\PayPalModule\Core\Exception\PayPalResponseException $e) {
// Ignore PayPal response exceptions
}
}
}
/**
* Updates order with PayPal response info.
*
* @param object $response
* @param object $data
*/
protected function updateOrder($response, $data)
{
$order = $this->getOrder();
$order->addCapturedAmount($response->getCapturedAmount());
$order->setPaymentStatus($data->getOrderStatus());
$order->save();
}
/**
* Creates Payment object with PayPal response data.
*
* @param object $response
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
protected function createPayment($response)
{
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getTransactionId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('capture');
$payment->setStatus($response->getPaymentStatus());
$payment->setAmount($response->getCapturedAmount());
$payment->setCurrency($response->getCurrency());
return $payment;
}
/**
* Adds comment to given Payment object.
*
* @param object $payment
* @param string $comment
*/
protected function addComment($payment, $commentContent)
{
if ($commentContent) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($commentContent);
$payment->addComment($comment);
}
}
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action refund class
*/
class OrderRefundAction extends \OxidEsales\PayPalModule\Model\Action\OrderAction
{
/**
* Processes PayPal response
*/
public function process()
{
$handler = $this->getHandler();
$response = $handler->getPayPalResponse();
$data = $handler->getData();
$order = $this->getOrder();
$order->addRefundedAmount($response->getRefundAmount());
$order->setPaymentStatus($data->getOrderStatus());
$order->save();
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getTransactionId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('refund');
$payment->setStatus($response->getPaymentStatus());
$payment->setAmount($response->getRefundAmount());
$payment->setCurrency($response->getCurrency());
$refundedPayment = $data->getPaymentBeingRefunded();
$refundedPayment->addRefundedAmount($response->getRefundAmount());
$refundedPayment->save();
$payment = $order->getPaymentList()->addPayment($payment);
if ($data->getComment()) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($data->getComment());
$payment->addComment($comment);
}
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Action;
/**
* PayPal order action void class
*/
class OrderVoidAction extends \OxidEsales\PayPalModule\Model\Action\OrderAction
{
/**
* Processes PayPal response
*/
public function process()
{
$handler = $this->getHandler();
$response = $handler->getPayPalResponse();
$data = $handler->getData();
$order = $this->getOrder();
$amount = $order->getRemainingOrderSum();
$order->setVoidedAmount($amount);
$order->setPaymentStatus($data->getOrderStatus());
$order->save();
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setDate($this->getDate());
$payment->setTransactionId($response->getAuthorizationId());
$payment->setCorrelationId($response->getCorrelationId());
$payment->setAction('void');
$payment->setStatus('Voided');
$payment->setAmount($amount);
$payment = $order->getPaymentList()->addPayment($payment);
if ($data->getComment()) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($data->getComment());
$payment->addComment($comment);
}
}
}

View File

@@ -0,0 +1,190 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal oxAddress class
*
* @mixin \OxidEsales\Eshop\Application\Model\Address
*/
class Address extends Address_parent
{
/**
* Creates user shipping address from PayPal data and set to session.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details PayPal data.
* @param string $userId user id.
*/
public function createPayPalAddress($details, $userId)
{
$addressData = $this->prepareDataPayPalAddress($details);
if ($addressId = $this->existPayPalAddress($addressData)) {
\OxidEsales\Eshop\Core\Registry::getSession()->setVariable("deladrid", $addressId);
} else {
$this->oxaddress__oxuserid = new \OxidEsales\Eshop\Core\Field($userId);
$this->oxaddress__oxfname = new \OxidEsales\Eshop\Core\Field($addressData['oxfname']);
$this->oxaddress__oxlname = new \OxidEsales\Eshop\Core\Field($addressData['oxlname']);
$this->oxaddress__oxstreet = new \OxidEsales\Eshop\Core\Field($addressData['oxstreet']);
$this->oxaddress__oxstreetnr = new \OxidEsales\Eshop\Core\Field($addressData['oxstreetnr']);
$this->oxaddress__oxaddinfo = new \OxidEsales\Eshop\Core\Field($addressData['oxaddinfo']);
$this->oxaddress__oxcity = new \OxidEsales\Eshop\Core\Field($addressData['oxcity']);
$this->oxaddress__oxcountryid = new \OxidEsales\Eshop\Core\Field($addressData['oxcountryid']);
$this->oxaddress__oxstateid = new \OxidEsales\Eshop\Core\Field($addressData['oxstateid']);
$this->oxaddress__oxzip = new \OxidEsales\Eshop\Core\Field($addressData['oxzip']);
$this->oxaddress__oxfon = new \OxidEsales\Eshop\Core\Field($addressData['oxfon']);
$this->save();
\OxidEsales\Eshop\Core\Registry::getSession()->setVariable("deladrid", $this->getId());
}
}
/**
* Prepare address data array from PayPal response data.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details - PayPal data
*
* @return array
*/
public function prepareDataPayPalAddress($details)
{
$addressData = array();
$fullName = oxNew(\OxidEsales\PayPalModule\Core\FullName::class, $details->getShipToName());
$addressData['oxfname'] = $fullName->getFirstName();
$addressData['oxlname'] = $fullName->getLastName();
$street = $this->splitShipToStreetPayPalAddress($details->getShipToStreet());
$addressData['oxstreet'] = $street['street'];
$addressData['oxstreetnr'] = $street['streetnr'];
$addressData['oxcity'] = $details->getShipToCity();
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$countryId = $country->getIdByCode($details->getShipToCountryCode());
$addressData['oxcountryid'] = $countryId;
if ($details->getShipToState()) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$stateId = $state->getIdByCode($details->getShipToState(), $countryId);
}
$addressData['oxstateid'] = $stateId;
$addressData['oxzip'] = $details->getShipToZip();
$addressData['oxfon'] = $details->getShipToPhoneNumber();
$addressData['oxaddinfo'] = $details->getShipToStreet2();
return $addressData;
}
/**
* Check required fields.
*
* @param array $addressData - PayPal data.
*
* @return bool
*/
protected function checkRequiredFieldsPayPalAddress($addressData)
{
$reqFields = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('aMustFillFields');
$result = true;
foreach ($reqFields as $field) {
if (strpos($field, 'oxaddress__') === 0 && empty($addressData[str_replace('oxaddress__', '', $field)])) {
return false;
}
}
return $result;
}
/**
* Checks if exists PayPal address.
*
* @param array $addressData
*
* @return bool|string
*/
protected function existPayPalAddress($addressData)
{
$db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$query = "SELECT `oxid` FROM `oxaddress` WHERE 1 ";
$query .= " AND `oxfname` = " . $db->quote($addressData['oxfname']);
$query .= " AND `oxlname` = " . $db->quote($addressData['oxlname']);
$query .= " AND `oxstreet` = " . $db->quote($addressData['oxstreet']);
$query .= " AND `oxstreetnr` = " . $db->quote($addressData['oxstreetnr']);
$query .= " AND `oxcity` = " . $db->quote($addressData['oxcity']);
$query .= " AND `oxcountryid` = " . $db->quote($addressData['oxcountryid']);
$query .= " AND `oxstateid` = " . $db->quote($addressData['oxstateid']);
$query .= " AND `oxzip` = " . $db->quote($addressData['oxzip']);
$query .= " AND `oxfon` = " . $db->quote($addressData['oxfon']);
if ($addressId = $db->getOne($query)) {
return $addressId;
}
return false;
}
/**
* Split street nr from address
*
* @param string $shipToStreet address string
*
* @return array
*/
public function splitShipToStreetPayPalAddress($shipToStreet)
{
$address = array();
$shipToStreet = trim($shipToStreet);
// checking if street number is at the end of the address
preg_match("/(.*\S)\s+(\d+\s*\S*)$/", $shipToStreet, $address);
// checking if street name and number was found
if (!empty($address[1]) && $address[2]) {
$address['street'] = $address[1];
$address['streetnr'] = $address[2];
return $address;
}
// checking if street number is at the begining of the address
preg_match("/(\d+\S*)\s+(.*)$/", $shipToStreet, $address);
// checking if street name and number was found
if (!empty($address[1]) && $address[2]) {
$address['street'] = $address[2];
$address['streetnr'] = $address[1];
return $address;
}
// it is not possible to resolve address, so assign it without any parsing
$address['street'] = $shipToStreet;
$address['streetnr'] = "";
return $address;
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal oxArticle class
*
* @mixin \OxidEsales\Eshop\Application\Model\Article
*/
class Article extends Article_parent
{
/**
* Check if Product is virtual: is non material and is downloadable
*
* @return bool
*/
public function isVirtualPayPalArticle()
{
$virtual = true;
// non material products
if (!$this->oxarticles__oxnonmaterial->value) {
$virtual = false;
} elseif (isset($this->oxarticles__oxisdownloadable) &&
!$this->oxarticles__oxisdownloadable->value
) {
$virtual = false;
}
return $virtual;
}
/**
* Gets stock amount for article
*
* @return float
*/
public function getStockAmount()
{
return $this->oxarticles__oxstock->value;
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal Current item Article container class.
*/
class ArticleToExpressCheckoutCurrentItem
{
/**
* Article id
*
* @var string
*/
protected $articleId;
/**
* Select list
*
* @var array
*/
protected $selectList;
/**
* Persistent param
*
* @var array
*/
protected $persistParam;
/**
* Article amount
*
* @var integer
*/
protected $articleAmount;
/**
* Method sets persistent param.
*
* @param array $persistParam
*/
public function setPersistParam($persistParam)
{
$this->persistParam = $persistParam;
}
/**
* Method returns persistent param.
*
* @return array
*/
public function getPersistParam()
{
return $this->persistParam;
}
/**
* Method sets select list.
*
* @param array $selectList
*/
public function setSelectList($selectList)
{
$this->selectList = $selectList;
}
/**
* Method returns select list.
*
* @return array
*/
public function getSelectList()
{
return $this->selectList;
}
/**
* Method sets article id.
*
* @param string $articleId
*/
public function setArticleId($articleId)
{
$this->articleId = $articleId;
}
/**
* Method returns article id.
*
* @return string
*/
public function getArticleId()
{
return $this->articleId;
}
/**
* Method sets article amount.
*
* @param int $articleAmount
*/
public function setArticleAmount($articleAmount)
{
$this->articleAmount = $articleAmount;
}
/**
* Method returns article amount.
*
* @return int
*/
public function getArticleAmount()
{
return (int) $this->articleAmount;
}
}

View File

@@ -0,0 +1,139 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal Current item Article validator class.
*/
class ArticleToExpressCheckoutValidator
{
/**
* Item that will be validated.
*
* @var object
*/
protected $itemToValidate;
/**
* User basket
*
* @var \OxidEsales\Eshop\Application\Model\Basket
*/
protected $basket;
/**
*Sets current item of details page.
*
* @param object $itemToValidate
*/
public function setItemToValidate($itemToValidate)
{
$this->itemToValidate = $itemToValidate;
}
/**
* Returns details page current item.
*
* @return \OxidEsales\PayPalModule\Model\ArticleToExpressCheckoutCurrentItem|object
*/
public function getItemToValidate()
{
return $this->itemToValidate;
}
/**
* Method sets basket object.
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket
*/
public function setBasket($basket)
{
$this->basket = $basket;
}
/**
* Methods returns basket object.
*
* @return \OxidEsales\Eshop\Application\Model\Basket
*/
public function getBasket()
{
return $this->basket;
}
/**
* Method returns if article valid
*
* @return bool
*/
public function isArticleValid()
{
$valid = true;
if ($this->isArticleAmountZero() || $this->isSameItemInBasket()) {
$valid = false;
}
return $valid;
}
/**
* Check if same article is in basket.
*
* @return bool
*/
protected function isSameItemInBasket()
{
$basketContents = $this->getBasket()->getContents();
foreach ($basketContents as $basketItem) {
if ($this->isArticleParamsEqual($basketItem)) {
return true;
}
}
return false;
}
/**
* Checks if Article params equals with current items params.
*
* @param \OxidEsales\Eshop\Application\Model\BasketItem $basketItem
*
* @return bool
*/
protected function isArticleParamsEqual($basketItem)
{
return ($basketItem->getProductId() == $this->getItemToValidate()->getArticleId() &&
$basketItem->getPersParams() == $this->getItemToValidate()->getPersistParam() &&
$basketItem->getSelList() == $this->getItemToValidate()->getSelectList());
}
/**
* Checks if article amount 0.
*
* @return bool
*/
protected function isArticleAmountZero()
{
$articleAmount = $this->getItemToValidate()->getArticleAmount();
return 0 == $articleAmount;
}
}

View File

@@ -0,0 +1,285 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
use OxidEsales\Eshop\Application\Model\Article as EshopArticle;
/**
* PayPal basket class
*
* @mixin \OxidEsales\Eshop\Application\Model\Basket
*/
class Basket extends Basket_parent
{
/**
* Checks if products in basket ar virtual and does not require real delivery.
* Returns TRUE if virtual
*
* @return bool
*/
public function isVirtualPayPalBasket()
{
$isVirtual = true;
$products = $this->getBasketArticles();
foreach ($products as $product) {
if (!$product->isVirtualPayPalArticle()) {
$isVirtual = false;
break;
}
}
return $isVirtual;
}
/**
* Checks if fraction quantity items (with 1.3 amount) exists in basket.
*
* @return bool
*/
public function isFractionQuantityItemsPresent()
{
$fractionItemsPresent = false;
foreach ($this->getContents() as $basketItem) {
$amount = $basketItem->getAmount();
if ((int) $amount != $amount) {
$fractionItemsPresent = true;
break;
}
}
return $fractionItemsPresent;
}
/**
* Returns wrapping cost value
*
* @return double
*/
public function getPayPalWrappingCosts()
{
$amount = 0.0;
$wrappingCost = $this->getCosts('oxwrapping');
if ($wrappingCost) {
$amount = $this->isCalculationModeNetto() ? $wrappingCost->getNettoPrice() : $wrappingCost->getBruttoPrice();
}
return $amount;
}
/**
* Returns greeting card cost value
*
* @return double
*/
public function getPayPalGiftCardCosts()
{
$amount = 0.0;
$giftCardCost = $this->getCosts('oxgiftcard');
if ($giftCardCost) {
$amount = $this->isCalculationModeNetto() ? $giftCardCost->getNettoPrice() : $giftCardCost->getBruttoPrice();
}
return $amount;
}
/**
* Returns payment costs netto or brutto value.
*
* @return double
*/
public function getPayPalPaymentCosts()
{
$amount = 0.0;
$paymentCost = $this->getCosts('oxpayment');
if ($paymentCost) {
$amount = $this->isCalculationModeNetto() ? $paymentCost->getNettoPrice() : $paymentCost->getBruttoPrice();
}
return $amount;
}
/**
* Collects all basket discounts (basket, payment and vouchers)
* and returns sum of collected discounts.
*
* @return double
*/
public function getDiscountSumPayPalBasket()
{
// collect discounts
$discount = 0.0;
$totalDiscount = $this->getTotalDiscount();
if ($totalDiscount) {
$discount += $totalDiscount->getBruttoPrice();
}
//if payment costs are negative, adding them to discount
if (($costs = $this->getPaymentCosts()) < 0) {
$discount += ($costs * -1);
}
// vouchers..
$vouchers = (array) $this->getVouchers();
foreach ($vouchers as $voucher) {
$discount += round($voucher->dVoucherdiscount, 2);
}
return $discount;
}
/**
* Calculates basket costs (payment, GiftCard and gift card)
* and returns sum of all costs.
*
* @return double
*/
public function getSumOfCostOfAllItemsPayPalBasket()
{
// basket items sum
$allCosts = $this->getProductsPrice()->getSum($this->isCalculationModeNetto());
//adding to additional costs only if payment is > 0
if (($costs = $this->getPayPalPaymentCosts()) > 0) {
$allCosts += $costs;
}
// wrapping costs
$allCosts += $this->getPayPalWrappingCosts();
// greeting card costs
$allCosts += $this->getPayPalGiftCardCosts();
return $allCosts;
}
/**
* Returns absolute VAT value.
*
* @return float
*/
public function getPayPalBasketVatValue()
{
$basketVatValue = 0;
$basketVatValue += $this->getPayPalProductVat();
$basketVatValue += $this->getPayPalWrappingVat();
$basketVatValue += $this->getPayPalGiftCardVat();
$basketVatValue += $this->getPayPalPayCostVat();
if ($this->getDeliveryCosts() < round($this->getDeliveryCosts(), 2)) {
return floor($basketVatValue * 100) / 100;
}
return $basketVatValue;
}
/**
* Return products VAT.
*
* @return double
*/
public function getPayPalProductVat()
{
$productVatList = $this->getProductVats(false);
$productVatSum = array_sum($productVatList);
return $productVatSum;
}
/**
* Return wrapping VAT.
*
* @return double
*/
public function getPayPalWrappingVat()
{
$wrappingVat = 0.0;
$wrapping = $this->getCosts('oxwrapping');
if ($wrapping && $wrapping->getVatValue()) {
$wrappingVat = $wrapping->getVatValue();
}
return $wrappingVat;
}
/**
* Return gift card VAT.
*
* @return double
*/
public function getPayPalGiftCardVat()
{
$giftCardVat = 0.0;
$giftCard = $this->getCosts('oxgiftcard');
if ($giftCard && $giftCard->getVatValue()) {
$giftCardVat = $giftCard->getVatValue();
}
return $giftCardVat;
}
/**
* Return payment VAT.
*
* @return double
*/
public function getPayPalPayCostVat()
{
$paymentVAT = 0.0;
$paymentCost = $this->getCosts('oxpayment');
if ($paymentCost && $paymentCost->getVatValue()) {
$paymentVAT = $paymentCost->getVatValue();
}
return $paymentVAT;
}
/**
* Check if variants of the given product are already in the basket
*
* @param EshopArticle $product
*
* @return bool
*/
public function hasProductVariantInBasket(EshopArticle $product)
{
$return = false;
$variantIds = $product->getVariantIds();
foreach ($variantIds as $id) {
if ($this->getArtStockInBasket($id)) {
$return = true;
break;
}
}
return $return;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\DbGateways;
/**
* Order payment comment db gateway class.
*/
class OrderPaymentCommentDbGateway extends \OxidEsales\PayPalModule\Core\ModelDbGateway
{
/**
* Save PayPal order payment comment data to database.
*
* @param array $data
*
* @return bool
*/
public function save($data)
{
$db = $this->getDb();
foreach ($data as $field => $value) {
$fields[] = '`' . $field . '` = ' . $db->quote($value);
}
$query = 'INSERT INTO `oepaypal_orderpaymentcomments` SET ';
$query .= implode(', ', $fields);
$query .= ' ON DUPLICATE KEY UPDATE ';
$query .= ' `oepaypal_commentid`=LAST_INSERT_ID(`oepaypal_commentid`), ';
$query .= implode(', ', $fields);
$db->execute($query);
$commentId = $data['oepaypal_commentid'];
if (empty($commentId)) {
$commentId = $db->getOne('SELECT LAST_INSERT_ID()');
}
return $commentId;
}
/**
* Load PayPal order payment comment data from Db.
*
* @param string $paymentId order id
*
* @return array
*/
public function getList($paymentId)
{
$db = $this->getDb();
$data = $db->getAll('SELECT * FROM `oepaypal_orderpaymentcomments` WHERE `oepaypal_paymentid` = ' . $db->quote($paymentId) . ' ORDER BY `oepaypal_date` DESC');
return $data;
}
/**
* Load PayPal order payment comment data from Db.
*
* @param string $commentId Order id.
*
* @return array
*/
public function load($commentId)
{
$db = $this->getDb();
$data = $db->getRow('SELECT * FROM `oepaypal_orderpaymentcomments` WHERE `oepaypal_commentid` = ' . $db->quote($commentId));
return $data;
}
/**
* Delete PayPal order payment comment data from database.
*
* @param string $commentId Order id.
*
* @return bool
*/
public function delete($commentId)
{
$db = $this->getDb();
$db->startTransaction();
$deleteResult = $db->execute('DELETE FROM `oepaypal_orderpaymentcomments` WHERE `oepaypal_commentid` = ' . $db->quote($commentId));
$result = ($deleteResult !== false);
if ($result) {
$db->commitTransaction();
} else {
$db->rollbackTransaction();
}
return $result;
}
}

View File

@@ -0,0 +1,129 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\DbGateways;
/**
* Order payment db gateway class
*/
class OrderPaymentDbGateway extends \OxidEsales\PayPalModule\Core\ModelDbGateway
{
/**
* Save PayPal order payment data to database.
*
* @param array $data
*
* @return int
*/
public function save($data)
{
$db = $this->getDb();
foreach ($data as $field => $value) {
$fields[] = '`' . $field . '` = ' . $db->quote($value);
}
$query = 'INSERT INTO `oepaypal_orderpayments` SET ';
$query .= implode(', ', $fields);
$query .= ' ON DUPLICATE KEY UPDATE ';
$query .= ' `oepaypal_paymentid`=LAST_INSERT_ID(`oepaypal_paymentid`), ';
$query .= implode(', ', $fields);
$db->execute($query);
$id = $data['oepaypal_paymentid'];
if (empty($id)) {
$id = $db->getOne('SELECT LAST_INSERT_ID()');
}
return $id;
}
/**
* Load PayPal order payment data from Db.
*
* @param string $paymentId Order id.
*
* @return array
*/
public function load($paymentId)
{
$db = $this->getDb();
$data = $db->getRow('SELECT * FROM `oepaypal_orderpayments` WHERE `oepaypal_paymentid` = ' . $db->quote($paymentId));
return $data;
}
/**
* Load PayPal order payment data from Db.
*
* @param string $transactionId Order id.
*
* @return array
*/
public function loadByTransactionId($transactionId)
{
$db = $this->getDb();
$data = $db->getRow('SELECT * FROM `oepaypal_orderpayments` WHERE `oepaypal_transactionid` = ' . $db->quote($transactionId));
return $data;
}
/**
* Delete PayPal order payment data from database.
*
* @param string $paymentId Order id.
*
* @return bool
*/
public function delete($paymentId)
{
$db = $this->getDb();
$db->startTransaction();
$deleteResult = $db->execute('DELETE FROM `oepaypal_orderpayments` WHERE `oepaypal_paymentid` = ' . $db->quote($paymentId));
$deleteCommentResult = $db->execute('DELETE FROM `oepaypal_orderpaymentcomments` WHERE `oepaypal_paymentid` = ' . $db->quote($paymentId));
$result = ($deleteResult !== false) || ($deleteCommentResult !== false);
if ($result) {
$db->commitTransaction();
} else {
$db->rollbackTransaction();
}
return $result;
}
/**
* Load PayPal order payment data from Db.
*
* @param string $orderId Order id.
*
* @return array
*/
public function getList($orderId)
{
$db = $this->getDb();
$data = $db->getAll('SELECT * FROM `oepaypal_orderpayments` WHERE `oepaypal_orderid` = ' . $db->quote($orderId) . ' ORDER BY `oepaypal_date` DESC');
return $data;
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\DbGateways;
/**
* Order db gateway class
*/
class PayPalOrderDbGateway extends \OxidEsales\PayPalModule\Core\ModelDbGateway
{
/**
* Save PayPal order data to database.
*
* @param array $data
*
* @return bool
*/
public function save($data)
{
$db = $this->getDb();
$fields = [];
foreach ($data as $field => $value) {
$fields[] = '`' . $field . '` = ' . $db->quote($value);
}
$query = 'INSERT INTO `oepaypal_order` SET ';
$query .= implode(', ', $fields);
$query .= ' ON DUPLICATE KEY UPDATE ';
$query .= ' `oepaypal_orderid`=LAST_INSERT_ID(`oepaypal_orderid`), ';
$query .= implode(', ', $fields);
$db->execute($query);
$id = $data['oepaypal_orderid'];
if (empty($id)) {
$id = $db->getOne('SELECT LAST_INSERT_ID()');
}
return $id;
}
/**
* Load PayPal order data from Db.
*
* @param string $orderId Order id.
*
* @return array
*/
public function load($orderId)
{
$db = $this->getDb();
$data = $db->getRow('SELECT * FROM `oepaypal_order` WHERE `oepaypal_orderid` = ' . $db->quote($orderId));
return $data;
}
/**
* Delete PayPal order data from database.
*
* @param string $orderId Order id.
*
* @return bool
*/
public function delete($orderId)
{
$db = $this->getDb();
$db->startTransaction();
$deleteCommentsResult = $db->execute(
'DELETE
`oepaypal_orderpaymentcomments`
FROM `oepaypal_orderpaymentcomments`
INNER JOIN `oepaypal_orderpayments` ON `oepaypal_orderpayments`.`oepaypal_paymentid` = `oepaypal_orderpaymentcomments`.`oepaypal_paymentid`
WHERE `oepaypal_orderpayments`.`oepaypal_orderid` = ' . $db->quote($orderId)
);
$deleteOrderPaymentResult = $db->execute('DELETE FROM `oepaypal_orderpayments` WHERE `oepaypal_orderid` = ' . $db->quote($orderId));
$deleteOrderResult = $db->execute('DELETE FROM `oepaypal_order` WHERE `oepaypal_orderid` = ' . $db->quote($orderId));
$result = ($deleteOrderResult !== false) || ($deleteOrderPaymentResult !== false) || ($deleteCommentsResult !== false);
if ($result) {
$db->commitTransaction();
} else {
$db->rollbackTransaction();
}
return $result;
}
}

View File

@@ -0,0 +1,270 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN payment builder class.
*/
class IPNPaymentBuilder
{
/** @var \OxidEsales\PayPalModule\Core\Request */
protected $request = null;
/** @var \OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter */
protected $payPalIPNPaymentSetter = null;
/** @var \OxidEsales\PayPalModule\Model\OrderPayment */
protected $orderPayment = null;
/** @var \OxidEsales\PayPalModule\Model\IPNPaymentValidator */
protected $payPalIPNPaymentValidator = null;
/** @var \OxidEsales\PayPalModule\Model\IPNPaymentCreator */
protected $payPalIPNPaymentCreator = null;
/** @var \OxidEsales\Eshop\Core\Language */
protected $lang = null;
/**
* Sets \OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter.
*
* @param \OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter $payPalIPNPaymentSetter
*/
public function setOrderPaymentSetter($payPalIPNPaymentSetter)
{
$this->payPalIPNPaymentSetter = $payPalIPNPaymentSetter;
}
/**
* Creates and sets \OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter object if it was not set.
*
* @return \OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter
*/
public function getOrderPaymentSetter()
{
if (is_null($this->payPalIPNPaymentSetter)) {
$payPalIPNPaymentSetter = oxNew(\OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter::class);
$this->setOrderPaymentSetter($payPalIPNPaymentSetter);
}
return $this->payPalIPNPaymentSetter;
}
/**
* Sets \OxidEsales\PayPalModule\Model\IPNPaymentValidator object.
*
* @param \OxidEsales\PayPalModule\Model\IPNPaymentValidator $payPalIPNPaymentValidator
*/
public function setOrderPaymentValidator($payPalIPNPaymentValidator)
{
$this->payPalIPNPaymentValidator = $payPalIPNPaymentValidator;
}
/**
* Creates and sets \OxidEsales\PayPalModule\Model\IPNPaymentValidator object if it was not set.
*
* @return \OxidEsales\PayPalModule\Model\IPNPaymentValidator
*/
public function getOrderPaymentValidator()
{
if (is_null($this->payPalIPNPaymentValidator)) {
$payPalIPNPaymentValidator = oxNew(\OxidEsales\PayPalModule\Model\IPNPaymentValidator::class);
$this->setOrderPaymentValidator($payPalIPNPaymentValidator);
}
return $this->payPalIPNPaymentValidator;
}
/**
* Sets \OxidEsales\PayPalModule\Model\IPNPaymentCreator.
*
* @param \OxidEsales\PayPalModule\Model\IPNPaymentCreator $oePayPalIPNPaymentCreator
*/
public function setPaymentCreator($oePayPalIPNPaymentCreator)
{
$this->payPalIPNPaymentCreator = $oePayPalIPNPaymentCreator;
}
/**
* Creates and sets \OxidEsales\PayPalModule\Model\IPNPaymentCreator object if it was not set.
*
* @return \OxidEsales\PayPalModule\Model\IPNPaymentCreator
*/
public function getPaymentCreator()
{
if (is_null($this->payPalIPNPaymentCreator)) {
$payPalIPNPaymentCreator = oxNew(\OxidEsales\PayPalModule\Model\IPNPaymentCreator::class);
$payPalIPNPaymentCreator->setRequest($this->getRequest());
$this->setPaymentCreator($payPalIPNPaymentCreator);
}
return $this->payPalIPNPaymentCreator;
}
/**
* Sets request object.
*
* @param \OxidEsales\PayPalModule\Core\Request $request
*/
public function setRequest($request)
{
$this->request = $request;
}
/**
* Returns \OxidEsales\PayPalModule\Core\Request.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Sets oxLang object
*
* @param \OxidEsales\Eshop\Core\Language $lang
*/
public function setLang($lang)
{
$this->lang = $lang;
}
/**
* Returns oxLang object.
*
* @return \OxidEsales\Eshop\Core\Language
*/
public function getLang()
{
return $this->lang;
}
/**
* Create payment from given request.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment|null
*/
public function buildPayment()
{
$return = null;
// Setter forms request payment from request parameters.
$requestOrderPayment = $this->prepareRequestOrderPayment();
// Create order payment from database to check if it match created from request.
$orderPayment = $this->loadOrderPayment($requestOrderPayment->getTransactionId());
// Only need validate if there is order in database.
// If request payment do not have matching payment with order return null.
if ($orderPayment->getOrderId()) {
// Validator change request payment by adding information if it is valid.
$orderPayment = $this->addPaymentValidationInformation($requestOrderPayment, $orderPayment);
$orderPayment = $this->changePaymentStatusInfo($requestOrderPayment, $orderPayment);
$orderPayment->save();
$return = $orderPayment;
} else {
//IPN request might be for a transaction that does not yet exist in the shop database.
$paymentCreator = $this->getPaymentCreator();
$return = $paymentCreator->handleOrderPayment($requestOrderPayment);
}
return $return;
}
/**
* Load order payment from transaction id.
*
* @param string $transactionId transaction id to load object.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment|null
*/
protected function loadOrderPayment($transactionId)
{
$orderPayment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$orderPayment->loadByTransactionId($transactionId);
return $orderPayment;
}
/**
* Wrapper to set parameters to order payment from request.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected function prepareRequestOrderPayment()
{
$requestOrderPayment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$request = $this->getRequest();
$requestPaymentSetter = $this->getOrderPaymentSetter();
$requestPaymentSetter->setRequest($request);
$requestPaymentSetter->setRequestOrderPayment($requestOrderPayment);
$requestOrderPayment = $requestPaymentSetter->getRequestOrderPayment();
return $requestOrderPayment;
}
/**
* Adds payment validation information.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $requestOrderPayment
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected function addPaymentValidationInformation($requestOrderPayment, $orderPayment)
{
$lang = $this->getLang();
$paymentValidator = $this->getOrderPaymentValidator();
$paymentValidator->setRequestOrderPayment($requestOrderPayment);
$paymentValidator->setOrderPayment($orderPayment);
$paymentValidator->setLang($lang);
$paymentIsValid = $paymentValidator->isValid();
if (!$paymentIsValid) {
$orderPayment->setIsValid($paymentIsValid);
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($paymentValidator->getValidationFailureMessage());
$orderPayment->addComment($comment);
}
return $orderPayment;
}
/**
* Add Payment Status information to object from database from object created from from PayPal request.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $requestOrderPayment
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected function changePaymentStatusInfo($requestOrderPayment, $orderPayment)
{
$orderPayment->setStatus($requestOrderPayment->getStatus());
return $orderPayment;
}
}

View File

@@ -0,0 +1,185 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN payment creator class.
* Handles inserting of new IPN data into database including
* updating parent transactions if needed.
*/
class IPNPaymentCreator
{
/** @var string IPN request parameter names. */
const PAYPAL_IPN_AUTH_ID = 'auth_id';
/** @var string IPN request parameter names. */
const PAYPAL_IPN_AUTH_STATUS = 'auth_status';
/** @var string IPN request parameter names. */
const PAYPAL_IPN_PARENT_TRANSACTION_ID = 'parent_txn_id';
/** @var string String PayPal transaction entity. */
const PAYPAL_IPN_TRANSACTION_ENTITY = 'transaction_entity';
/** @var string Class only handles IPN transaction payments. */
const HANDLE_TRANSACTION_ENTITY = 'payment';
/** @var string PayPal payment comment. */
const PAYPAL_IPN_MEMO = 'memo';
/** @var \OxidEsales\PayPalModule\Core\Request */
protected $request = null;
/**
* Sets request object.
*
* @param \OxidEsales\PayPalModule\Core\Request $request
*/
public function setRequest($request)
{
$this->request = $request;
}
/**
* Returns \OxidEsales\PayPalModule\Core\Request.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Handling of IPN data that has not yet a paypal order payment
* entry in shop database.
* Checks if information from IPN is relevant for Shop. That is the case
* if the related PayPal parent transaction can be found in table oepaypal_orderpayments.
*
* If data is relevant, we need to
* - create paypal order payment, store it in database and return it.
* - if it is a refund, update the parent transaction's refunded amount
* - update authorization status (can be Pending, In Progress, Completed)
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $requestOrderPayment
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment|null
*/
public function handleOrderPayment($requestOrderPayment)
{
$return = null;
$authId = $this->getRequest()->getRequestParameter(self::PAYPAL_IPN_AUTH_ID);
$transactionEntity = $this->getRequest()->getRequestParameter(self::PAYPAL_IPN_TRANSACTION_ENTITY);
$parentTransactionId = $this->getRequest()->getRequestParameter(self::PAYPAL_IPN_PARENT_TRANSACTION_ID);
$orderPaymentAuthorization = $this->loadOrderPayment($authId);
$orderPaymentParent = $this->loadOrderPayment($parentTransactionId);
$orderId = $orderPaymentParent->getOrderId();
if ((self::HANDLE_TRANSACTION_ENTITY == $transactionEntity) && $orderId) {
$requestOrderPayment->setOrderId($orderId);
$requestOrderPayment->save();
$requestOrderPayment = $this->addRequestPaymentComment($requestOrderPayment);
if (\OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter::REFUND_ACTION == $requestOrderPayment->getAction()) {
$this->updateParentTransactionRefundAmount($orderPaymentParent, $requestOrderPayment->getAmount());
}
if ((\OxidEsales\PayPalModule\Model\IPNRequestPaymentSetter::AUTHORIZATION_ACTION == $orderPaymentAuthorization->getAction())
&& ($orderId == $orderPaymentAuthorization->getOrderId())
) {
$this->updateOrderPaymentAuthorizationStatus($orderPaymentAuthorization);
}
$return = $requestOrderPayment;
}
return $return;
}
/**
* Update the parent transaction's refund amount.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPaymentParent
* @param float $amount
*/
private function updateParentTransactionRefundAmount($orderPaymentParent, $amount)
{
$orderPaymentParent->addRefundedAmount($amount);
$orderPaymentParent->save();
}
/**
* The status of the related authorization transaction might have changed.
* We need to update that transaction status as well if we got a value in IPN request data.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPaymentAuthorization Authorization PayPal order payment
*/
private function updateOrderPaymentAuthorizationStatus($orderPaymentAuthorization)
{
$authStatus = $this->getRequest()->getRequestParameter(self::PAYPAL_IPN_AUTH_STATUS);
if ($authStatus) {
$orderPaymentAuthorization->setStatus($authStatus);
$orderPaymentAuthorization->save();
}
}
/**
* Load order payment from transaction id.
*
* @param string $transactionId transaction id to load object.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment|null
*/
private function loadOrderPayment($transactionId)
{
$orderPayment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$orderPayment->loadByTransactionId($transactionId);
return $orderPayment;
}
/**
* Add comment for request payment if comment exists.
* Function must only be called when the payment object this
* comment is related to is already stored in the database and has an oxid.
* Comment will be immediately saved to database.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $paypalOrderPayment
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
private function addRequestPaymentComment($paypalOrderPayment)
{
$request = $this->getRequest();
$memo = $request->getRequestParameter(self::PAYPAL_IPN_MEMO);
if ($memo) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setComment($memo);
$paypalOrderPayment->addComment($comment);
if (0 < $paypalOrderPayment->getId()) {
$paypalOrderPayment->save();
}
}
return $paypalOrderPayment;
}
}

View File

@@ -0,0 +1,149 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN Payment validator class.
*/
class IPNPaymentValidator
{
/**
* Language object to get translations from.
*
* @var object
*/
protected $lang = null;
/**
* Payment created from PayPal request.
*
* @var \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected $requestPayment = null;
/**
* Payment created by PayPal request id.
*
* @var \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected $orderPayment = null;
/**
* Sets language object to get translations from.
*
* @param object $lang get translations from.
*/
public function setLang($lang)
{
$this->lang = $lang;
}
/**
* Gets language object to get translations from.
*
* @return object
*/
public function getLang()
{
return $this->lang;
}
/**
* Sets request object.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $requestPayment
*/
public function setRequestOrderPayment($requestPayment)
{
$this->requestPayment = $requestPayment;
}
/**
* Returns request payment object.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function getRequestOrderPayment()
{
return $this->requestPayment;
}
/**
* Sets order payment object.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $payment
*/
public function setOrderPayment($payment)
{
$this->orderPayment = $payment;
}
/**
* Returns order payment object.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function getOrderPayment()
{
return $this->orderPayment;
}
/**
* Returns validation failure message.
*
* @return string
*/
public function getValidationFailureMessage()
{
$requestPayment = $this->getRequestOrderPayment();
$orderPayment = $this->getOrderPayment();
$currencyPayPal = $requestPayment->getCurrency();
$pricePayPal = $requestPayment->getAmount();
$currencyPayment = $orderPayment->getCurrency();
$amountPayment = $orderPayment->getAmount();
$lang = $this->getLang();
$validationMessage = $lang->translateString('OEPAYPAL_PAYMENT_INFORMATION') . ': ' . $amountPayment . ' ' . $currencyPayment . '. ' . $lang->translateString('OEPAYPAL_INFORMATION') . ': ' . $pricePayPal . ' ' . $currencyPayPal . '.';
return $validationMessage;
}
/**
* Check if PayPal response fits payment information.
*
* @return bool
*/
public function isValid()
{
$requestPayment = $this->getRequestOrderPayment();
$orderPayment = $this->getOrderPayment();
$currencyPayPal = $requestPayment->getCurrency();
$pricePayPal = $requestPayment->getAmount();
$currencyPayment = $orderPayment->getCurrency();
$amountPayment = $orderPayment->getAmount();
return ($currencyPayPal == $currencyPayment && $pricePayPal == $amountPayment);
}
}

View File

@@ -0,0 +1,155 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN processor class.
*/
class IPNProcessor
{
/**
* PayPal request handler.
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $request = null;
/**
* @var \OxidEsales\PayPalModule\Model\IPNPaymentBuilder
*/
protected $paymentBuilder = null;
/**
* @var \OxidEsales\PayPalModule\Model\OrderManager
*/
protected $orderManager = null;
/**
* Set object \OxidEsales\PayPalModule\Core\Request.
*
* @param \OxidEsales\PayPalModule\Core\Request $request object to set.
*/
public function setRequest($request)
{
$this->request = $request;
}
/**
* Create object \OxidEsales\PayPalModule\Core\Request to get PayPal request information.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Sets language object.
*
* @param \OxidEsales\Eshop\Core\Language $lang
*/
public function setLang($lang)
{
$this->lang = $lang;
}
/**
* Returns language object.
*
* @return \OxidEsales\Eshop\Core\Language
*/
public function getLang()
{
return $this->lang;
}
/**
* Sets payment builder.
*
* @param \OxidEsales\PayPalModule\Model\IPNPaymentBuilder $paymentBuilder
*/
public function setPaymentBuilder($paymentBuilder)
{
$this->paymentBuilder = $paymentBuilder;
}
/**
* Creates \OxidEsales\PayPalModule\Model\IPNPaymentBuilder, sets if it was not set and than returns it.
*
* @return \OxidEsales\PayPalModule\Model\IPNPaymentBuilder
*/
public function getPaymentBuilder()
{
if (is_null($this->paymentBuilder)) {
$this->paymentBuilder = oxNew(\OxidEsales\PayPalModule\Model\IPNPaymentBuilder::class);
}
return $this->paymentBuilder;
}
/**
* Sets order manager.
*
* @param \OxidEsales\PayPalModule\Model\OrderManager $payPalOrderManager
*/
public function setOrderManager($payPalOrderManager)
{
$this->orderManager = $payPalOrderManager;
}
/**
* Returns order manager.
*
* @return \OxidEsales\PayPalModule\Model\OrderManager
*/
public function getOrderManager()
{
if (is_null($this->orderManager)) {
$this->orderManager = oxNew(\OxidEsales\PayPalModule\Model\OrderManager::class);
}
return $this->orderManager;
}
/**
* Initiate payment status changes according to IPN information.
*
* @return bool
*/
public function process()
{
$lang = $this->getLang();
$request = $this->getRequest();
$paymentBuilder = $this->getPaymentBuilder();
$payPalOrderManager = $this->getOrderManager();
// Create Payment from Request.
$paymentBuilder->setLang($lang);
$paymentBuilder->setRequest($request);
$orderPayment = $paymentBuilder->buildPayment();
$payPalOrderManager->setOrderPayment($orderPayment);
$processSuccess = $payPalOrderManager->updateOrderStatus();
return $processSuccess;
}
}

View File

@@ -0,0 +1,167 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN request payment setter class.
*/
class IPNRequestPaymentSetter
{
/** @var string PayPal action that triggered this transaction. */
const CAPTURE_ACTION = 'capture';
const REFUND_ACTION = 'refund';
const AUTHORIZATION_ACTION = 'authorization';
/** @var string Sandbox mode parameter name. */
const PAYPAL_SANDBOX = 'test_ipn';
/** @var string String PayPal payment status parameter name. */
const PAYPAL_PAYMENT_STATUS = 'payment_status';
/** @var string PayPal transaction id. */
const PAYPAL_TRANSACTION_ID = 'txn_id';
/** @var string PayPal whole price including payment and shipment. */
const MC_GROSS = 'mc_gross';
/** @var string PayPal payment currency. */
const MC_CURRENCY = 'mc_currency';
/** @var string PayPal payment date. */
const PAYMENT_DATE = 'payment_date';
/** @var string PayPal payment correlation id. */
const CORRELATION_ID = 'correlation_id';
/** @var string PayPal payment ipn tracking id, might come instead of correlation id. */
const IPN_TRACK_ID = 'ipn_track_id';
/** @var string PayPal status for successful refund. */
const PAYPAL_STATUS_REFUND_DONE = 'Refunded';
/**
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $request = null;
/**
* @var \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected $requestOrderPayment = null;
/**
* Sets request object to get params for IPN request.
*
* @param \OxidEsales\PayPalModule\Core\Request $request
*/
public function setRequest($request)
{
$this->request = $request;
}
/**
* Gets request object to get params for IPN request.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Sets request order payment object.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment
*/
public function setRequestOrderPayment($orderPayment)
{
$this->requestOrderPayment = $orderPayment;
}
/**
* Returns order payment object.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function getRequestOrderPayment()
{
$this->prepareOrderPayment($this->requestOrderPayment);
return $this->requestOrderPayment;
}
/**
* Prepare PayPal payment. Fill up with request values.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $requestOrderPayment order to set params.
*/
protected function prepareOrderPayment($requestOrderPayment)
{
$request = $this->getRequest();
$requestOrderPayment->setStatus($request->getRequestParameter(self::PAYPAL_PAYMENT_STATUS));
$requestOrderPayment->setTransactionId($request->getRequestParameter(self::PAYPAL_TRANSACTION_ID));
$requestOrderPayment->setCurrency($request->getRequestParameter(self::MC_CURRENCY));
$requestOrderPayment->setAmount($this->getAmount());
$requestOrderPayment->setAction($this->getAction());
$correlationId = $request->getRequestParameter(self::CORRELATION_ID);
if (!$correlationId) {
$correlationId = $request->getRequestParameter(self::IPN_TRACK_ID);
}
$requestOrderPayment->setCorrelationId($correlationId);
$date = 0 < strlen($request->getRequestParameter(self::PAYMENT_DATE)) ?
date('Y-m-d H:i:s', strtotime($request->getRequestParameter(self::PAYMENT_DATE))) : null;
$requestOrderPayment->setDate($date);
}
/**
* Get PayPal action from request, we might have a refund.
*
* @return string
*/
protected function getAction()
{
$action = self::CAPTURE_ACTION;
$request = $this->getRequest();
$rawAmount = $request->getRequestParameter(self::MC_GROSS);
$status = $request->getRequestParameter(self::PAYPAL_PAYMENT_STATUS);
if ((0 > $rawAmount) && (self::PAYPAL_STATUS_REFUND_DONE == $status)) {
$action = self::REFUND_ACTION;
}
return $action;
}
/**
* Get amount from request.
*
* @return number
*/
protected function getAmount()
{
$request = $this->getRequest();
return !is_null($request->getRequestParameter(self::MC_GROSS)) ? abs($request->getRequestParameter(self::MC_GROSS)) : null;
}
}

View File

@@ -0,0 +1,153 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN request validator class.
*/
class IPNRequestValidator
{
/**
* String PayPal receiver email. It should be same as shop owner credential for PayPal.
*
* @var string
*/
const RECEIVER_EMAIL = 'receiver_email';
/**
* Shop owner Email from configuration of PayPal module.
*
* @var string
*/
protected $shopOwnerUserName = null;
/**
* PayPal response if OK.
*
* @var \OxidEsales\PayPalModule\Model\Response\ResponseDoVerifyWithPayPal
*/
protected $payPalResponse = null;
/**
* PayPal request to get email.
*
* @var array
*/
protected $payPalRequest = null;
/**
* Set shop owner user name - payPal ID.
*
* @param string $shopOwnerUserName
*/
public function setShopOwnerUserName($shopOwnerUserName)
{
$this->shopOwnerUserName = $shopOwnerUserName;
}
/**
* get shop owner user name - payPal ID.
*
* @return string
*/
public function getShopOwnerUserName()
{
return $this->shopOwnerUserName;
}
/**
* Set PayPal response object.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseDoVerifyWithPayPal|Response\Response $payPalResponse
*/
public function setPayPalResponse($payPalResponse)
{
$this->payPalResponse = $payPalResponse;
}
/**
* Get PayPal response object.
*
* @return \OxidEsales\PayPalModule\Model\Response\ResponseDoVerifyWithPayPal
*/
public function getPayPalResponse()
{
return $this->payPalResponse;
}
/**
* Set PayPal request array.
*
* @param array $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
/**
* Get PayPal request array.
*
* @return array
*/
public function getPayPalRequest()
{
return $this->payPalRequest;
}
/**
* Returns validation failure messages.
*
* @return array
*/
public function getValidationFailureMessage()
{
$payPalRequest = $this->getPayPalRequest();
$payPalResponse = $this->getPayPalResponse();
$shopOwnerUserName = $this->getShopOwnerUserName();
$receiverEmailPayPal = $payPalRequest[self::RECEIVER_EMAIL];
$validationMessage = array(
'Shop owner' => (string) $shopOwnerUserName,
'PayPal ID' => (string) $receiverEmailPayPal,
'PayPal ACK' => ($payPalResponse->isPayPalAck() ? 'VERIFIED' : 'NOT VERIFIED'),
'PayPal Full Request' => print_r($payPalRequest, true),
'PayPal Full Response' => print_r($payPalResponse->getData(), true),
);
return $validationMessage;
}
/**
* Validate if IPN request from PayPal and to correct shop.
*
* @return bool
*/
public function isValid()
{
$payPalRequest = $this->getPayPalRequest();
$payPalResponse = $this->getPayPalResponse();
$shopOwnerUserName = $this->getShopOwnerUserName();
$receiverEmailPayPal = $payPalRequest[self::RECEIVER_EMAIL];
return ($payPalResponse->isPayPalAck() && $receiverEmailPayPal == $shopOwnerUserName);
}
}

View File

@@ -0,0 +1,241 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal IPN request verifier class.
*/
class IPNRequestVerifier
{
/**
* PayPal \OxidEsales\PayPalModule\Core\Request
*
* @var \OxidEsales\PayPalModule\Core\Request
*/
protected $request = null;
/**
* Shop owner email - PayPal ID.
*
* @var string
*/
protected $shopOwner = null;
/**
* PayPal Service
*
* @var \OxidEsales\PayPalModule\Core\PayPalService
*/
protected $communicationService = null;
/**
* @var \OxidEsales\PayPalModule\Model\IPNRequestValidator
*/
protected $ipnRequestValidator = null;
/**
* @var \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
protected $payPalRequest = null;
/**
* @var array
*/
protected $failureMessage = null;
/**
* Set object \OxidEsales\PayPalModule\Core\Request.
*
* @param \OxidEsales\PayPalModule\Core\Request $request object to set.
*/
public function setRequest($request)
{
$this->request = $request;
}
/**
* Create object \OxidEsales\PayPalModule\Core\Request to get PayPal request information.
*
* @return \OxidEsales\PayPalModule\Core\Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Sets shop owner.
*
* @param string $shopOwner
*/
public function setShopOwner($shopOwner)
{
$this->shopOwner = $shopOwner;
}
/**
* Returns shop owner.
*
* @return string
*/
public function getShopOwner()
{
return $this->shopOwner;
}
/**
* Sets oeIPNCallerService.
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $callerService object to set..
*/
public function setCommunicationService($callerService)
{
$this->communicationService = $callerService;
}
/**
* Getter for the PayPal service
*
* @return \OxidEsales\PayPalModule\Core\PayPalService
*/
public function getCommunicationService()
{
if ($this->communicationService === null) {
$this->communicationService = oxNew(\OxidEsales\PayPalModule\Core\PayPalService::class);
}
return $this->communicationService;
}
/**
* Sets IPN request validator.
*
* @param \OxidEsales\PayPalModule\Model\IPNRequestValidator $ipnRequestValidator
*/
public function setIPNRequestValidator($ipnRequestValidator)
{
$this->ipnRequestValidator = $ipnRequestValidator;
}
/**
* Returns IPN request validator object.
*
* @return \OxidEsales\PayPalModule\Model\IPNRequestValidator
*/
public function getIPNRequestValidator()
{
if ($this->ipnRequestValidator === null) {
$this->ipnRequestValidator = oxNew(\OxidEsales\PayPalModule\Model\IPNRequestValidator::class);
}
return $this->ipnRequestValidator;
}
/**
* Sets request object.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $payPalRequest
*/
public function setPayPalRequest($payPalRequest)
{
$this->payPalRequest = $payPalRequest;
}
/**
* Return, create object to call PayPal with.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if (is_null($this->payPalRequest)) {
$this->payPalRequest = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest::class);
}
return $this->payPalRequest;
}
/**
* Sets failure message.
*
* @param array $failureMessage
*/
public function setFailureMessage($failureMessage)
{
$this->failureMessage = $failureMessage;
}
/**
* Returns failure message.
*
* @return array
*/
public function getFailureMessage()
{
return $this->failureMessage;
}
/**
* IPN handling function.
* - verify with PayPal.
*
* @return bool
*/
public function requestCorrect()
{
$request = $this->getRequest();
$rawRequestData = $request->getPost();
$responseDoVerifyWithPayPal = $this->doVerifyWithPayPal($rawRequestData);
$ipnRequestValidator = $this->getIPNRequestValidator();
$ipnRequestValidator->setPayPalRequest($rawRequestData);
$ipnRequestValidator->setPayPalResponse($responseDoVerifyWithPayPal);
$ipnRequestValidator->setShopOwnerUserName($this->getShopOwner());
$requestCorrect = $ipnRequestValidator->isValid();
if (!$requestCorrect) {
$failureMessage = $ipnRequestValidator->getValidationFailureMessage();
$this->setFailureMessage($failureMessage);
}
return $requestCorrect;
}
/**
* Call PayPal to check if IPN request originally from PayPal.
*
* @param array $requestData data of request.
*
* @return \OxidEsales\PayPalModule\Model\Response\Response
*/
protected function doVerifyWithPayPal($requestData)
{
$callerService = $this->getCommunicationService();
$payPalPayPalRequest = $this->getPayPalRequest();
foreach ($requestData as $requestParameterName => $requestParameterValue) {
$payPalPayPalRequest->setParameter($requestParameterName, $requestParameterValue);
}
$responseDoVerifyWithPayPal = $callerService->doVerifyWithPayPal($payPalPayPalRequest, $requestData['charset']);
return $responseDoVerifyWithPayPal;
}
}

View File

@@ -0,0 +1,332 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal oxOrder class
*
* @mixin \OxidEsales\Eshop\Application\Model\Order
*/
class Order extends Order_parent
{
/** Transaction was finished successfully. */
const OEPAYPAL_TRANSACTION_STATUS_OK = 'OK';
/** Transaction is not finished or failed. */
const OEPAYPAL_TRANSACTION_STATUS_NOT_FINISHED = 'NOT_FINISHED';
/**
* PayPal order information
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $payPalOrder = null;
/**
* Loads order associated with current PayPal order
*
* @return bool
*/
public function loadPayPalOrder()
{
$orderId = \OxidEsales\Eshop\Core\Registry::getSession()->getVariable("sess_challenge");
// if order is not created yet - generating it
if ($orderId === null) {
$orderId = \OxidEsales\Eshop\Core\UtilsObject::getInstance()->generateUID();
$this->setId($orderId);
$this->save();
\OxidEsales\Eshop\Core\Registry::getSession()->setVariable("sess_challenge", $orderId);
}
return $this->load($orderId);
}
/**
* Updates order number.
*
* @return bool
*/
public function oePayPalUpdateOrderNumber()
{
if ($this->oxorder__oxordernr->value) {
$updated = (bool) oxNew(\OxidEsales\Eshop\Core\Counter::class)->update($this->_getCounterIdent(), $this->oxorder__oxordernr->value);
} else {
$updated = $this->_setNumber();
}
return $updated;
}
/**
* Delete order created by current PayPal ordering process
*
* @return bool
*/
public function deletePayPalOrder()
{
$result = false;
if ($this->loadPayPalOrder()) {
$this->getPayPalOrder()->delete();
$result = $this->delete();
}
return $result;
}
/**
* Delete order together with PayPal order data.
*
* @param string $oxId
*
* @return bool
*/
public function delete($oxId = null)
{
$this->getPayPalOrder($oxId)->delete();
return parent::delete($oxId);
}
/**
* Updates order transaction status, ID and date.
*
* @param string $transactionId Order transaction ID
*/
protected function setPaymentInfoPayPalOrder($transactionId)
{
// set transaction ID and payment date to order
$db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$query = 'update oxorder set oxtransid=' . $db->quote($transactionId) . ' where oxid=' . $db->quote($this->getId());
$db->execute($query);
//updating order object
$this->oxorder__oxtransid = new \OxidEsales\Eshop\Core\Field($transactionId);
}
/**
* Finalizes PayPal order.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseDoExpressCheckoutPayment $result PayPal results array.
* @param \OxidEsales\Eshop\Application\Model\Basket $basket Basket object.
* @param string $transactionMode Transaction mode Sale|Authorization.
*/
public function finalizePayPalOrder($result, $basket, $transactionMode)
{
$utilsDate = \OxidEsales\Eshop\Core\Registry::getUtilsDate();
$date = date('Y-m-d H:i:s', $utilsDate->getTime());
// set order status, transaction ID and payment date to order
$this->setPaymentInfoPayPalOrder($result->getTransactionId());
$currency = $result->getCurrencyCode();
if (!$currency) {
$currency = $this->getOrderCurrency()->name;
}
// PayPal order info
$payPalOrder = $this->getPayPalOrder();
$payPalOrder->setOrderId($this->getId());
$payPalOrder->setPaymentStatus('pending');
$payPalOrder->setTransactionMode($transactionMode);
$payPalOrder->setCurrency($currency);
$payPalOrder->setTotalOrderSum($basket->getPrice()->getBruttoPrice());
if ($transactionMode == 'Sale') {
$payPalOrder->setCapturedAmount($basket->getPrice()->getBruttoPrice());
}
$payPalOrder->save();
$orderPayment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$orderPayment->setTransactionId($result->getTransactionId());
$orderPayment->setCorrelationId($result->getCorrelationId());
$orderPayment->setDate($date);
$orderPayment->setAction(($transactionMode == 'Sale') ? 'capture' : 'authorization');
$orderPayment->setStatus($result->getPaymentStatus());
$orderPayment->setAmount($result->getAmount());
$orderPayment->setCurrency($result->getCurrencyCode());
//Adding payment information
$paymentList = $this->getPayPalOrder()->getPaymentList();
$paymentList->addPayment($orderPayment);
//setting order payment status after
$paymentStatusCalculator = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator::class);
$paymentStatusCalculator->setOrder($this->getPayPalOrder());
$this->getPayPalOrder()->setPaymentStatus($paymentStatusCalculator->getStatus(), $this);
$this->getPayPalOrder()->save();
//clear PayPal identification
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$session->deleteVariable('oepaypal');
$session->deleteVariable("oepaypal-payerId");
$session->deleteVariable("oepaypal-userId");
$session->deleteVariable('oepaypal-basketAmount');
}
/**
* Paypal specific status checking.
*
* If status comes as OK, lets check real paypal payment state,
* and if really ok, so lets set it, otherwise dont change status.
*
* @param string $status order transaction status
*/
protected function _setOrderStatus($status)
{
$paymentTypeObject = $this->getPaymentType();
$paymentType = $paymentTypeObject ? $paymentTypeObject->getFieldData('oxpaymentsid') : null;
if ($paymentType != 'oxidpaypal' || $status != self::OEPAYPAL_TRANSACTION_STATUS_OK) {
parent::_setOrderStatus($status);
}
}
/**
* Update order oxpaid to current time.
*/
public function markOrderPaid()
{
parent::_setOrderStatus(self::OEPAYPAL_TRANSACTION_STATUS_OK);
$db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$utilsDate = \OxidEsales\Eshop\Core\Registry::getUtilsDate();
$date = date('Y-m-d H:i:s', $utilsDate->getTime());
$query = 'update oxorder set oxpaid=? where oxid=?';
$db->execute($query, array($date, $this->getId()));
//updating order object
$this->oxorder__oxpaid = new \OxidEsales\Eshop\Core\Field($date);
}
/**
* Checks if delivery set used for current order is available and active.
* Throws exception if not available
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket basket object
*
* @return int
*/
public function validateDelivery($basket)
{
if ($basket->getPaymentId() == 'oxidpaypal') {
$shippingId = $basket->getShippingId();
$basketPrice = $basket->getPrice()->getBruttoPrice();
$user = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
if (!$user->loadUserPayPalUser()) {
$user = $this->getUser();
}
$validState = null;
if (!$this->isPayPalPaymentValid($user, $basketPrice, $shippingId)) {
$validState = self::ORDER_STATE_INVALIDDELIVERY;
}
} else {
$validState = parent::validateDelivery($basket);
}
return $validState;
}
/**
* Returns PayPal order object.
*
* @param string $oxId
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder|null
*/
public function getPayPalOrder($oxId = null)
{
if (is_null($this->payPalOrder)) {
$orderId = is_null($oxId) ? $this->getId() : $oxId;
$order = oxNew(\OxidEsales\PayPalModule\Model\PayPalOrder::class);
$order->load($orderId);
$this->payPalOrder = $order;
}
return $this->payPalOrder;
}
/**
* Get payment status
*
* @return string
*/
public function getPayPalPaymentStatus()
{
return $this->getPayPalOrder()->getPaymentStatus();
}
/**
* Returns PayPal Authorization id.
*
* @return string
*/
public function getAuthorizationId()
{
return $this->oxorder__oxtransid->value;
}
/**
* Checks whether PayPal payment is available.
*
* @param object $user
* @param double $basketPrice
* @param string $shippingId
*
* @return bool
*/
protected function isPayPalPaymentValid($user, $basketPrice, $shippingId)
{
$valid = true;
$payPalPayment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$payPalPayment->load('oxidpaypal');
if (!$payPalPayment->isValidPayment(null, null, $user, $basketPrice, $shippingId)) {
$valid = $this->isEmptyPaymentValid($user, $basketPrice, $shippingId);
}
return $valid;
}
/**
* Checks whether Empty payment is available.
*
* @param object $user
* @param double $basketPrice
* @param string $shippingId
*
* @return bool
*/
protected function isEmptyPaymentValid($user, $basketPrice, $shippingId)
{
$valid = true;
$emptyPayment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$emptyPayment->load('oxempty');
if (!$emptyPayment->isValidPayment(null, null, $user, $basketPrice, $shippingId)) {
$valid = false;
}
return $valid;
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal order action manager class
*/
class OrderActionManager
{
/**
* States related with transaction mode
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $availableActions = array(
'Sale' => array(),
'Authorization' => array('capture', 'reauthorize', 'void'),
);
/**
* Order object
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $order = null;
/**
* Sets order
*
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* Returns order
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder
*/
public function getOrder()
{
return $this->order;
}
/**
* Return state for given transaction mode
*
* @param string $mode transaction mode
*
* @return array
*/
protected function getAvailableAction($mode)
{
$actions = $this->availableActions[$mode];
return $actions ? $actions : array();
}
/**
* Checks whether action is available for given order
*
* @param string $action
*
* @return bool
*/
public function isActionAvailable($action)
{
$order = $this->getOrder();
$availableActions = $this->getAvailableAction($order->getTransactionMode());
$isAvailable = in_array($action, $availableActions);
if ($isAvailable) {
$isAvailable = false;
switch ($action) {
case 'capture':
case 'reauthorize':
case 'void':
if ($order->getRemainingOrderSum() > 0 && $order->getVoidedAmount() < $order->getRemainingOrderSum()) {
$isAvailable = true;
}
break;
}
}
return $isAvailable;
}
}

View File

@@ -0,0 +1,244 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* Class \OxidEsales\PayPalModule\Model\OrderManager.
*/
class OrderManager
{
/**
* @var \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
protected $orderPayment = null;
/**
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $order = null;
/**
* @var \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator
*/
protected $orderPaymentStatusCalculator = null;
/**
* @var \OxidEsales\PayPalModule\Model\OrderPaymentListCalculator
*/
protected $orderPaymentListCalculator = null;
/**
* Sets order payment.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment
*/
public function setOrderPayment($orderPayment)
{
$this->orderPayment = $orderPayment;
}
/**
* Returns order payment.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
public function getOrderPayment()
{
return $this->orderPayment;
}
/**
* Sets order.
*
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* Create object \OxidEsales\PayPalModule\Model\PayPalOrder.
* If Order is not set, create order from Order Payment.
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder
*/
public function getOrder()
{
if ($this->order === null) {
$orderPayment = $this->getOrderPayment();
$order = $this->getOrderFromPayment($orderPayment);
$this->setOrder($order);
}
return $this->order;
}
/**
* Sets \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator.
*
* @param \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator $orderPaymentStatusCalculator
*/
public function setOrderPaymentStatusCalculator($orderPaymentStatusCalculator)
{
$this->orderPaymentStatusCalculator = $orderPaymentStatusCalculator;
}
/**
* Returns \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator.
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator
*/
public function getOrderPaymentStatusCalculator()
{
if (is_null($this->orderPaymentStatusCalculator)) {
$orderPaymentStatusCalculator = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentStatusCalculator::class);
$this->setOrderPaymentStatusCalculator($orderPaymentStatusCalculator);
}
return $this->orderPaymentStatusCalculator;
}
/**
* Sets \OxidEsales\PayPalModule\Model\OrderPaymentListCalculator.
*
* @param \OxidEsales\PayPalModule\Model\OrderPaymentListCalculator $orderPaymentListCalculator
*/
public function setOrderPaymentListCalculator($orderPaymentListCalculator)
{
$this->orderPaymentListCalculator = $orderPaymentListCalculator;
}
/**
* Returns \OxidEsales\PayPalModule\Model\OrderPaymentListCalculator.
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentListCalculator
*/
public function getOrderPaymentListCalculator()
{
if (is_null($this->orderPaymentListCalculator)) {
$orderPaymentListCalculator = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentListCalculator::class);
$this->setOrderPaymentListCalculator($orderPaymentListCalculator);
}
return $this->orderPaymentListCalculator;
}
/**
* Update order manager to status get from order status calculator.
*
* @return bool
*/
public function updateOrderStatus()
{
$orderUpdated = false;
$order = $this->getOrder();
if (!is_null($order)) {
$orderPayment = $this->getOrderPayment();
$order = $this->recalculateAmounts($order);
$newOrderStatus = $this->calculateOrderStatus($orderPayment, $order);
$this->persistNewOrderStatus($order, $newOrderStatus);
$orderUpdated = true;
}
return $orderUpdated;
}
/**
* Recalculate order amounts from connected PayPal payment list.
* This is especially needed if some new PayPal order payment
* entry was created by IPN handler or if we e.g. got a void
* on an existing authorization by IPN.
*
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order
*
* @return mixed
*/
protected function recalculateAmounts($order)
{
$paymentList = $order->getPaymentList();
$orderPaymentListCalculator = $this->getOrderPaymentListCalculator();
$orderPaymentListCalculator->setPaymentList($paymentList);
$orderPaymentListCalculator->calculate();
$order->setCapturedAmount($orderPaymentListCalculator->getCapturedAmount());
$order->setVoidedAmount($orderPaymentListCalculator->getVoidedAmount());
$order->setRefundedAmount($orderPaymentListCalculator->getRefundedAmount());
$order->save();
return $order;
}
/**
* Wrapper for order payment calculator.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment Order payment to set to calculator.
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order Order to be set to validator.
*
* @return null|string
*/
protected function calculateOrderStatus($orderPayment, $order)
{
$orderPaymentStatusCalculator = $this->getOrderPaymentStatusCalculator();
$orderPaymentStatusCalculator->setOrderPayment($orderPayment);
$orderPaymentStatusCalculator->setOrder($order);
$newOrderStatus = $orderPaymentStatusCalculator->getStatus();
return $newOrderStatus;
}
/**
* Update order to given status.
*
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order Order to be updated.
* @param string $newOrderStatus New order status.
*/
protected function persistNewOrderStatus($order, $newOrderStatus)
{
$order->setPaymentStatus($newOrderStatus);
$order->save();
}
/**
* Load order by order id from order payment.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment order payment to get order id.
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder|null
*/
protected function getOrderFromPayment($orderPayment)
{
$orderId = null;
$order = null;
if (!is_null($orderPayment)) {
$orderId = $orderPayment->getOrderId();
}
if (!is_null($orderId)) {
$order = oxNew(\OxidEsales\PayPalModule\Model\PayPalOrder::class);
$order->setOrderId($orderId);
$order->load();
}
return $order;
}
}

View File

@@ -0,0 +1,373 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal order payment class.
*/
class OrderPayment extends \OxidEsales\PayPalModule\Core\Model
{
/**
* Set PayPal order comment Id.
*
* @param string $paymentId
*/
public function setId($paymentId)
{
$this->setPaymentId($paymentId);
}
/**
* Set PayPal comment Id.
*
* @return string
*/
public function getId()
{
return $this->getPaymentId();
}
/**
* If Payment is valid.
*
* @var bool
*/
protected $isValid = true;
/**
* Payment comments
*
* @var array
*/
protected $commentList = null;
/**
* Set PayPal order comment Id.
*
* @param string $paymentId
*/
public function setPaymentId($paymentId)
{
$this->setValue('oepaypal_paymentid', $paymentId);
}
/**
* Set PayPal comment Id.
*
* @return string
*/
public function getPaymentId()
{
return $this->getValue('oepaypal_paymentid');
}
/**
* Sets PayPal payment actions.
*
* @param string $value
*/
public function setAction($value)
{
$this->setValue('oepaypal_action', $value);
}
/**
* Returns PayPal payment action.
*
* @return string
*/
public function getAction()
{
return $this->getValue('oepaypal_action');
}
/**
* Sets PayPal payment OrderId.
*
* @param string $value
*/
public function setOrderId($value)
{
$this->setValue('oepaypal_orderid', $value);
}
/**
* Returns PayPal payment OrderId.
*
* @return string
*/
public function getOrderId()
{
return $this->getValue('oepaypal_orderid');
}
/**
* Sets PayPal payment amount
*
* @param float $value
*/
public function setAmount($value)
{
$this->setValue('oepaypal_amount', $value);
}
/**
* Returns PayPal payment amount.
*
* @return float
*/
public function getAmount()
{
return $this->getValue('oepaypal_amount');
}
/**
* Set PayPal refunded amount.
*
* @param double $amount
*/
public function setRefundedAmount($amount)
{
$this->setValue('oepaypal_refundedamount', $amount);
}
/**
* Adds given amount to PayPal refunded amount.
*
* @param double $amount
*/
public function addRefundedAmount($amount)
{
$this->setRefundedAmount($amount + $this->getRefundedAmount());
}
/**
* Get PayPal refunded amount
*
* @return double
*/
public function getRefundedAmount()
{
return (double) $this->getValue('oepaypal_refundedamount');
}
/**
* Returns not yet captured (remaining) order sum
*
* @return string
*/
public function getRemainingRefundAmount()
{
$amount = $this->getAmount() - $this->getRefundedAmount();
return sprintf("%.2f", round($amount, 2));
}
/**
* Returns PayPal payment status.
*
* @return string
*/
public function getStatus()
{
return $this->getValue('oepaypal_status');
}
/**
* Returns PayPal payment status.
*
* @param string $value status
*/
public function setStatus($value)
{
$this->setValue('oepaypal_status', $value);
}
/**
* Sets PayPal payment date.
*
* @param string $value
*/
public function setDate($value)
{
$this->setValue('oepaypal_date', $value);
}
/**
* Returns PayPal payment date.
*
* @return string
*/
public function getDate()
{
return $this->getValue('oepaypal_date');
}
/**
* Returns PayPal payment currency.
*
* @param string $currency
*/
public function setCurrency($currency)
{
$this->setValue('oepaypal_currency', $currency);
}
/**
* Sets PayPal payment currency
*
* @return string
*/
public function getCurrency()
{
return $this->getValue('oepaypal_currency');
}
/**
* Set PayPal payment transaction id.
*
* @param string $transactionId
*/
public function setTransactionId($transactionId)
{
$this->setValue('oepaypal_transactionid', $transactionId);
}
/**
* Returns PayPal payment transaction id
*
* @return string
*/
public function getTransactionId()
{
return $this->getValue('oepaypal_transactionid');
}
/**
* Set PayPal payment correlation id
*
* @param string $correlationId
*/
public function setCorrelationId($correlationId)
{
$this->setValue('oepaypal_correlationid', $correlationId);
}
/**
* Returns PayPal payment correlation id
*
* @return string
*/
public function getCorrelationId()
{
return $this->getValue('oepaypal_correlationid');
}
/**
* Load payment data by given transaction id
*
* @param string $transactionId transaction id
*
* @return bool
*/
public function loadByTransactionId($transactionId)
{
$result = false;
$data = $this->getDbGateway()->loadByTransactionId($transactionId);
if ($data) {
$this->setData($data);
$result = true;
}
return $result;
}
/**
* Sets if payment is valid.
*
* @param boolean $isValid payment is valid.
*/
public function setIsValid($isValid)
{
$this->isValid = (bool) $isValid;
}
/**
* Gets if payment pass validation.
*
* @return boolean
*/
public function getIsValid()
{
return $this->isValid;
}
/**
* Get comments
*
* @return array
*/
public function getCommentList()
{
if (is_null($this->commentList)) {
$comments = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentCommentList::class);
$comments->load($this->getPaymentId());
$this->setCommentList($comments);
}
return $this->commentList;
}
/**
* Set comments.
*
* @param array $comments
*/
public function setCommentList($comments)
{
$this->commentList = $comments;
}
/**
* Add comment.
*
* @param \oePaypalOrderPaymentComment $comment comment
*/
public function addComment($comment)
{
$this->getCommentList()->addComment($comment);
}
/**
* Return database gateway.
*
* @return \OxidEsales\PayPalModule\Model\DbGateways\OrderPaymentDbGateway|\OxidEsales\PayPalModule\Core\ModelDbGateway
*/
protected function getDbGateway()
{
if (is_null($this->dbGateway)) {
$this->setDbGateway(oxNew(\OxidEsales\PayPalModule\Model\DbGateways\OrderPaymentDbGateway::class));
}
return $this->dbGateway;
}
}

View File

@@ -0,0 +1,114 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal Order payment action manager class
*/
class OrderPaymentActionManager
{
/**
* Array of available actions for payment action.
*
* @var array
*/
protected $availableActions = array(
"capture" => array(
"Completed" => array(
'refund'
)
)
);
/**
* Order object.
*
* @var \OxidEsales\PayPalModule\Model\OrderPayment
*/
protected $payment = null;
/**
* Sets order.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $payment
*/
public function setPayment($payment)
{
$this->payment = $payment;
}
/**
* Returns order.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function getPayment()
{
return $this->payment;
}
/**
* Returns available actions for given payment action
*
* @param string $paymentAction
* @param string $paymentStatus
*
* @return array
*/
protected function getAvailableActions($paymentAction, $paymentStatus)
{
$actions = $this->availableActions[$paymentAction][$paymentStatus];
return $actions ? $actions : array();
}
/**
* Checks whether action is available for given order
*
* @param string $action
* @param \OxidEsales\PayPalModule\Model\OrderPayment $payment
*
* @return bool
*/
public function isActionAvailable($action, $payment = null)
{
if ($payment) {
$this->setPayment($payment);
}
$payment = $this->getPayment();
$isAvailable = in_array($action, $this->getAvailableActions($payment->getAction(), $payment->getStatus()));
if ($isAvailable) {
$isAvailable = false;
switch ($action) {
case 'refund':
$isAvailable = ($payment->getAmount() > $payment->getRefundedAmount());
break;
}
}
return $isAvailable;
}
}

View File

@@ -0,0 +1,151 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal order payment comment class
*/
class OrderPaymentComment extends \OxidEsales\PayPalModule\Core\Model
{
/**
* Sets date value.
*/
public function __construct()
{
$utilsDate = \OxidEsales\Eshop\Core\Registry::getUtilsDate();
$this->setValue('oepaypal_date', date('Y-m-d H:i:s', $utilsDate->getTime()));
}
/**
* Sets comment id.
*
* @param string $commentId
*/
public function setId($commentId)
{
$this->setCommentId($commentId);
}
/**
* Returns comment id.
*
* @return string
*/
public function getId()
{
return $this->getCommentId();
}
/**
* Set PayPal order comment Id
*
* @param string $commentId
*/
public function setCommentId($commentId)
{
$this->setValue('oepaypal_commentid', $commentId);
}
/**
* Set PayPal comment Id
*
* @return string
*/
public function getCommentId()
{
return $this->getValue('oepaypal_commentid');
}
/**
* Set PayPal order payment Id
*
* @param string $paymentId
*/
public function setPaymentId($paymentId)
{
$this->setValue('oepaypal_paymentid', $paymentId);
}
/**
* Set PayPal order payment Id
*
* @return string
*/
public function getPaymentId()
{
return $this->getValue('oepaypal_paymentid');
}
/**
* Set date
*
* @param string $date
*/
public function setDate($date)
{
$this->setValue('oepaypal_date', $date);
}
/**
* Get date
*
* @return string
*/
public function getDate()
{
return $this->getValue('oepaypal_date');
}
/**
* Set comment
*
* @param string $comment
*/
public function setComment($comment)
{
$this->setValue('oepaypal_comment', $comment);
}
/**
* Get comment
*
* @return string
*/
public function getComment()
{
return $this->getValue('oepaypal_comment');
}
/**
* Return database gateway
*
* @return \OxidEsales\PayPalModule\Model\DbGateways\OrderPaymentCommentDbGateway|\OxidEsales\PayPalModule\Core\ModelDbGateway
*/
protected function getDbGateway()
{
if (is_null($this->dbGateway)) {
$this->setDbGateway(oxNew(\OxidEsales\PayPalModule\Model\DbGateways\OrderPaymentCommentDbGateway::class));
}
return $this->dbGateway;
}
}

View File

@@ -0,0 +1,123 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal order payment comment list class
*/
class OrderPaymentCommentList extends \OxidEsales\PayPalModule\Core\PayPalList
{
/**
* Data base gateway
*
* @var oePayPalPayPalDbGateway
*/
protected $dbGateway = null;
/**
* @var string|null
*/
protected $paymentId = null;
/**
* Sets payment id.
*
* @param string $paymentId
*/
public function setPaymentId($paymentId)
{
$this->paymentId = $paymentId;
}
/**
* Returns payment id.
*
* @return null|string
*/
public function getPaymentId()
{
return $this->paymentId;
}
/**
* Returns DB gateway. If it's not set- creates object and sets.
*
* @return oePayPalPayPalDbGateway
*/
protected function getDbGateway()
{
if (is_null($this->dbGateway)) {
$this->setDbGateway(oxNew(\OxidEsales\PayPalModule\Model\DbGateways\OrderPaymentCommentDbGateway::class));
}
return $this->dbGateway;
}
/**
* Set model database gateway.
*
* @param object $dbGateway
*/
protected function setDbGateway($dbGateway)
{
$this->dbGateway = $dbGateway;
}
/**
* Selects and loads order payment history.
*
* @param string $paymentId Order id.
*/
public function load($paymentId)
{
$this->setPaymentId($paymentId);
$comments = array();
$commentsData = $this->getDbGateway()->getList($this->getPaymentId());
if (is_array($commentsData) && count($commentsData)) {
$comments = array();
foreach ($commentsData as $data) {
$comment = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentComment::class);
$comment->setData($data);
$comments[] = $comment;
}
}
$this->setArray($comments);
}
/**
* Add comment.
*
* @param object $comment
*
* @return mixed
*/
public function addComment($comment)
{
$comment->setPaymentId($this->getPaymentId());
$comment->save();
$this->load($this->getPaymentId());
return $comment;
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal order payment list class
*/
class OrderPaymentList extends \OxidEsales\PayPalModule\Core\PayPalList
{
/**
* Data base gateway
*
* @var oePayPalPayPalDbGateway
*/
protected $dbGateway = null;
/**
* @var string|null
*/
protected $orderId = null;
/**
* Sets order id.
*
* @param string $orderId
*/
public function setOrderId($orderId)
{
$this->orderId = $orderId;
}
/**
* Returns order id.
*
* @return null|string
*/
public function getOrderId()
{
return $this->orderId;
}
/**
* Returns oePayPalPayPalDbGateway or creates and sets it if it was not set.
*
* @return oePayPalPayPalDbGateway
*/
protected function getDbGateway()
{
if (is_null($this->dbGateway)) {
$this->setDbGateway(oxNew(\OxidEsales\PayPalModule\Model\DbGateways\OrderPaymentDbGateway::class));
}
return $this->dbGateway;
}
/**
* Set model database gateway.
*
* @param object $dbGateway
*/
protected function setDbGateway($dbGateway)
{
$this->dbGateway = $dbGateway;
}
/**
* Selects and loads order payment history.
*
* @param string $orderId Order id.
*/
public function load($orderId)
{
$this->setOrderId($orderId);
$payments = array();
$paymentsData = $this->getDbGateway()->getList($this->getOrderId());
if (is_array($paymentsData) && count($paymentsData)) {
$payments = array();
foreach ($paymentsData as $data) {
$payment = oxNew(\OxidEsales\PayPalModule\Model\OrderPayment::class);
$payment->setData($data);
$payments[] = $payment;
}
}
$this->setArray($payments);
}
/**
* Check if list has payment with defined status.
*
* @param string $status Payment status.
*
* @return bool
*/
protected function hasPaymentWithStatus($status)
{
$hasStatus = false;
$payments = $this->getArray();
foreach ($payments as $payment) {
if ($status == $payment->getStatus()) {
$hasStatus = true;
break;
}
}
return $hasStatus;
}
/**
* Check if list has pending payment.
*
* @return bool
*/
public function hasPendingPayment()
{
return $this->hasPaymentWithStatus('Pending');
}
/**
* Check if list has failed payment.
*
* @return bool
*/
public function hasFailedPayment()
{
return $this->hasPaymentWithStatus('Failed');
}
/**
* Returns not yet captured (remaining) order sum.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $payment order payment
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment
*/
public function addPayment(\OxidEsales\PayPalModule\Model\OrderPayment $payment)
{
//order payment info
if ($this->getOrderId()) {
$payment->setOrderId($this->getOrderId());
$payment->save();
}
$this->load($this->getOrderId());
return $payment;
}
}

View File

@@ -0,0 +1,164 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* Class \OxidEsales\PayPalModule\Model\OrderPaymentListCalculator
*/
class OrderPaymentListCalculator
{
/** @var \OxidEsales\PayPalModule\Model\OrderPaymentList */
private $paymentList = array();
/** @var float Amount of void action. */
private $voidedAmount = 0.0;
/** @var float Amount of voided authorization action. */
private $voidedAuthAmount = 0.0;
/**@var float Amount of capture action. */
private $capturedAmount = 0.0;
/** @var float Amount of refund action. */
private $refundedAmount = 0.0;
/** @var array Payment and status match. */
private $paymentMatch = array(
'capturedAmount' => array(
'action' => array('capture'),
'status' => array('Completed')
),
'refundedAmount' => array(
'action' => array('refund'),
'status' => array('Refunded')
),
'voidedAuthAmount' => array(
'action' => array('authorization'),
'status' => array('Voided')
),
'voidedAmount' => array(
'action' => array('void'),
'status' => array('Voided')
)
);
/**
* Sets paypal order payment list.
*
* @param \OxidEsales\PayPalModule\Model\OrderPaymentList $paymentList
*/
public function setPaymentList($paymentList)
{
$this->paymentList = $paymentList;
}
/**
* Getter for paypal order payment list.
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentList
*/
public function getPaymentList()
{
return $this->paymentList;
}
/**
* Sum up payment amounts for capture, void, refund.
* Take into account successful transactions only.
*/
public function calculate()
{
$this->init();
foreach ($this->getPaymentList() as $payment) {
$status = $payment->getStatus();
$action = $payment->getAction();
$amount = $payment->getAmount();
$this->aggregateAmounts($action, $status, $amount);
}
}
/**
* Getter for captured amount
*
* @return float
*/
public function getCapturedAmount()
{
return $this->capturedAmount;
}
/**
* Getter for refunded amount
*
* @return float
*/
public function getRefundedAmount()
{
return $this->refundedAmount;
}
/**
* Getter for voided amount.
*
* @return float
*/
public function getVoidedAmount()
{
$return = 0.0;
if (0 < $this->voidedAmount) {
//void action is only logged when executed via shop admin
$return = $this->voidedAmount;
} elseif (0 < $this->voidedAuthAmount) {
//no data from void actions means we might have a voided Authorization
$return = $this->voidedAuthAmount - $this->capturedAmount;
}
return $return;
}
/**
* Initialize results.
* Needs to be done e.g. before calling calculate.
*/
private function init()
{
foreach (array_keys($this->paymentMatch) as $target) {
$this->$target = 0.0;
}
}
/**
* @param string $action PayPal order payment action type (e.g. cpture, refund, void)
* @param string $status PayPal order payment status.
* @param double $amount PayPal order payment amount.
*/
private function aggregateAmounts($action, $status, $amount)
{
foreach ($this->paymentMatch as $target => $check) {
if (in_array($action, $check['action']) && in_array($status, $check['status'])) {
$this->$target += $amount;
}
}
}
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* Class for calculation PayPal order statuses after IPN and order creations.
* Also calculates statuses for suggestion on void, refund, capture operation on PayPal order.
*/
class OrderPaymentStatusCalculator
{
/**
* PayPal Order.
*
* @var \OxidEsales\PayPalModule\Model\PayPalOrder
*/
protected $order = null;
/**
* @var \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
protected $orderPayment = null;
/**
* Set PayPal Order.
*
* @param \OxidEsales\PayPalModule\Model\PayPalOrder $order PayPal order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* Return PayPal Order.
*
* @return \OxidEsales\PayPalModule\Model\PayPalOrder
*/
public function getOrder()
{
return $this->order;
}
/**
* Sets PayPal OrderPayment.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $orderPayment
*/
public function setOrderPayment($orderPayment)
{
$this->orderPayment = $orderPayment;
}
/**
* Return PayPal OrderPayment.
*
* @return \OxidEsales\PayPalModule\Model\OrderPayment::class
*/
public function getOrderPayment()
{
return $this->orderPayment;
}
/**
* Return status for suggestion on void operation.
*
* @return bool
*/
protected function getSuggestStatusOnVoid()
{
$status = 'canceled';
if ($this->getOrder()->getCapturedAmount() > 0) {
$status = 'completed';
}
return $status;
}
/**
* Return true if order statuses can be changed automatically.
*
* @return bool
*/
protected function isOrderPaymentStatusFinal()
{
$orderPaymentStatus = $this->getOrder()->getPaymentStatus();
return $orderPaymentStatus == 'failed' || $orderPaymentStatus == 'canceled';
}
/**
* Returns order payment status which should be set after order creation or IPN.
*
* @return string|null
*/
public function getStatus()
{
if (is_null($this->getOrder())) {
return;
}
$status = $this->getOrderPaymentStatusFinal();
if (is_null($status)) {
$status = $this->getOrderPaymentStatusPaymentValid();
}
if (is_null($status)) {
$status = $this->getOrderPaymentStatusPayments();
}
return $status;
}
/**
* Returns order suggestion for payment status on given action and on given payment.
*
* @param string $action - action with order payment: void, refund, capture, refund_partial, capture_partial
*
* @return string|null
*/
public function getSuggestStatus($action)
{
if (is_null($this->getOrder())) {
return;
}
$status = $this->getOrderPaymentStatusPaymentValid();
if (is_null($status)) {
$status = $this->getStatusByAction($action);
}
return $status;
}
/**
* Returns order payment status if order has final status.
*
* @return string|null
*/
protected function getOrderPaymentStatusFinal()
{
$status = null;
if ($this->isOrderPaymentStatusFinal()) {
$status = $this->getOrder()->getPaymentStatus();
}
return $status;
}
/**
* Returns order payment status by checking if set payment is valid.
*
* @return string|null
*/
protected function getOrderPaymentStatusPaymentValid()
{
$status = null;
$orderPayment = $this->getOrderPayment();
if (isset($orderPayment) && !$orderPayment->getIsValid()) {
$status = 'failed';
}
return $status;
}
/**
* Returns order payment status calculated from existing payments.
*
* @return string|null
*/
protected function getOrderPaymentStatusPayments()
{
$status = 'completed';
$paymentList = $this->getOrder()->getPaymentList();
if ($paymentList->hasPendingPayment()) {
$status = 'pending';
} elseif ($paymentList->hasFailedPayment()) {
$status = 'failed';
}
return $status;
}
/**
* Returns order suggestion for payment status on given action.
*
* @param string $action performed action.
*
* @return string
*/
protected function getStatusByAction($action)
{
$status = null;
switch ($action) {
case 'void':
$status = $this->getSuggestStatusOnVoid();
break;
case 'refund_partial':
case 'reauthorize':
$status = $this->getOrder()->getPaymentStatus();
break;
case 'refund':
case 'capture':
case 'capture_partial':
$status = 'completed';
break;
default:
$status = 'completed';
}
return $status;
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal order payment status list class
*/
class OrderPaymentStatusList extends \OxidEsales\PayPalModule\Core\PayPalList
{
/**
* All available statuses
*
* @return array
*/
protected $array = array(
'completed',
'pending',
'canceled',
'failed'
);
/**
* Available statuses depending on action
*
* @var array
*/
protected $availableStatuses = array(
'capture' => array('completed'),
'capture_partial' => array('completed', 'pending'),
'refund' => array('completed', 'pending', 'canceled'),
'refund_partial' => array('completed', 'pending', 'canceled'),
'void' => array('completed', 'pending', 'canceled'),
);
/**
* Returns the list of available statuses to choose from for admin
*
* @param string $action
*
* @return array
*/
public function getAvailableStatuses($action)
{
$list = $this->availableStatuses[$action];
return $list ? $list : array();
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal out of stock validator class
*/
class OutOfStockValidator
{
/**
* Basket object
*
* @var object
*/
private $basket;
/**
* Level of empty stock level
*
* @var int
*/
private $emptyStockLevel;
/**
* Sets empty stock level.
*
* @param int $emptyStockLevel
*/
public function setEmptyStockLevel($emptyStockLevel)
{
$this->emptyStockLevel = $emptyStockLevel;
}
/**
* Returns empty stock level.
*
* @return int
*/
public function getEmptyStockLevel()
{
return $this->emptyStockLevel;
}
/**
* Sets basket object.
*
* @param object $basket
*/
public function setBasket($basket)
{
$this->basket = $basket;
}
/**
* Returns basket object.
*
* @return object
*/
public function getBasket()
{
return $this->basket;
}
/**
* Checks if basket has Articles that are out of stock.
*
* @return bool
*/
public function hasOutOfStockArticles()
{
$result = false;
$basketContents = $this->getBasket()->getContents();
foreach ($basketContents as $basketItem) {
$article = $basketItem->getArticle();
if (($article->getStockAmount() - $basketItem->getAmount()) < $this->getEmptyStockLevel()) {
$result = true;
break;
}
}
return $result;
}
}

View File

@@ -0,0 +1,324 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* PayPal PayPalOrder class
*/
class PayPalOrder extends \OxidEsales\PayPalModule\Core\Model
{
/** Completion status */
const PAYPAL_ORDER_STATE_COMPLETED = 'completed';
/**
* List of order payments.
*
* @var \OxidEsales\PayPalModule\Model\OrderPaymentList
*/
protected $paymentList = null;
/**
* Sets order id.
*
* @param string $orderId
*/
public function setId($orderId)
{
$this->setOrderId($orderId);
}
/**
* Returns order id.
*
* @return string
*/
public function getId()
{
return $this->getOrderId();
}
/**
* Set PayPal order Id.
*
* @param string $orderId
*/
public function setOrderId($orderId)
{
$this->setValue('oepaypal_orderid', $orderId);
}
/**
* Set PayPal order Id.
*
* @return string
*/
public function getOrderId()
{
return $this->getValue('oepaypal_orderid');
}
/**
* Set PayPal captured amount.
*
* @param double $amount
*/
public function setCapturedAmount($amount)
{
$this->setValue('oepaypal_capturedamount', $amount);
}
/**
* Adds given amount to PayPal captured amount.
*
* @param double $amount
*/
public function addCapturedAmount($amount)
{
$this->setCapturedAmount($amount + $this->getCapturedAmount());
}
/**
* Get PayPal captured amount.
*
* @return double
*/
public function getCapturedAmount()
{
return (double) $this->getValue('oepaypal_capturedamount');
}
/**
* Set PayPal refunded amount.
*
* @param double $amount
*/
public function setRefundedAmount($amount)
{
$this->setValue('oepaypal_refundedamount', $amount);
}
/**
* Adds given amount to PayPal refunded amount.
*
* @param double $amount
*/
public function addRefundedAmount($amount)
{
$this->setRefundedAmount($amount + $this->getRefundedAmount());
}
/**
* Get PayPal refunded amount.
*
* @return double
*/
public function getRefundedAmount()
{
return (double) $this->getValue('oepaypal_refundedamount');
}
/**
* Returns not yet captured (remaining) order sum.
*
* @return double
*/
public function getRemainingRefundAmount()
{
return round($this->getCapturedAmount() - $this->getRefundedAmount(), 2);
}
/**
* Set PayPal refunded amount.
*
* @param double $amount
*/
public function setVoidedAmount($amount)
{
$this->setValue('oepaypal_voidedamount', $amount);
}
/**
* Get PayPal refunded amount.
*
* @return double
*/
public function getVoidedAmount()
{
return (double) $this->getValue('oepaypal_voidedamount');
}
/**
* Set transaction mode.
*
* @param string $mode
*/
public function setTransactionMode($mode)
{
$this->setValue('oepaypal_transactionmode', $mode);
}
/**
* Get transaction mode.
*
* @return string
*/
public function getTransactionMode()
{
return $this->getValue('oepaypal_transactionmode');
}
/**
* Set payment status.
*
* @param string $status
* @param \OxidEsales\Eshop\Application\Model\Order $order Shop order object
*/
public function setPaymentStatus($status, \OxidEsales\Eshop\Application\Model\Order $order = null)
{
$this->setValue('oepaypal_paymentstatus', $status);
// if payment completed, set order paid
if ($status == \OxidEsales\PayPalModule\Model\PayPalOrder::PAYPAL_ORDER_STATE_COMPLETED) {
if (is_null($order)) {
$order = oxNew(\OxidEsales\Eshop\Application\Model\Order::class);
$order->load($this->getOrderId());
}
$order->markOrderPaid();
}
}
/**
* Get payment status.
*
* @return string
*/
public function getPaymentStatus()
{
$state = $this->getValue('oepaypal_paymentstatus');
if (empty($state)) {
$state = self::PAYPAL_ORDER_STATE_COMPLETED;
}
return $state;
}
/**
* Sets total order sum.
*
* @param double $amount
*/
public function setTotalOrderSum($amount)
{
$this->setValue('oepaypal_totalordersum', $amount);
}
/**
* Returns total order sum.
*
* @return string
*/
public function getTotalOrderSum()
{
return $this->getValue('oepaypal_totalordersum');
}
/**
* Returns not yet captured (remaining) order sum.
*
* @return string
*/
public function getRemainingOrderSum()
{
return $this->getTotalOrderSum() - $this->getCapturedAmount();
}
/**
* Set order currency.
*
* @param string $status
*/
public function setCurrency($status)
{
$this->setValue('oepaypal_currency', $status);
}
/**
* Returns order currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getValue('oepaypal_currency');
}
/**
* Adds new payment.
*
* @param \OxidEsales\PayPalModule\Model\OrderPayment $payment order payment
*/
public function addPayment(\OxidEsales\PayPalModule\Model\OrderPayment $payment)
{
$paymentList = $this->getPaymentList();
$paymentList->addPayment($payment);
$this->setPaymentList(null);
}
/**
* Return database gateway.
*
* @return \OxidEsales\PayPalModule\Model\DbGateways\PayPalOrderDbGateway|\OxidEsales\PayPalModule\Core\ModelDbGateway
*/
protected function getDbGateway()
{
if (is_null($this->dbGateway)) {
$this->setDbGateway(oxNew(\OxidEsales\PayPalModule\Model\DbGateways\PayPalOrderDbGateway::class));
}
return $this->dbGateway;
}
/**
* Return order payment list.
*
* @return \OxidEsales\PayPalModule\Model\OrderPaymentList
*/
public function getPaymentList()
{
if (is_null($this->paymentList)) {
$paymentList = oxNew(\OxidEsales\PayPalModule\Model\OrderPaymentList::class);
$paymentList->load($this->getOrderId());
$this->setPaymentList($paymentList);
}
return $this->paymentList;
}
/**
* Return order payment list.
*
* @param oePayPal $paymentList Payment list.
*/
public function setPaymentList($paymentList)
{
$this->paymentList = $paymentList;
}
}

View File

@@ -0,0 +1,374 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\PayPalRequest;
/**
* PayPal request builder class for do express checkout payment
*/
class DoExpressCheckoutPaymentRequestBuilder
{
/**
* @var \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
protected $request = null;
/**
* @var \OxidEsales\PayPalModule\Core\Config
*/
protected $payPalConfig = null;
/**
* @var \OxidEsales\Eshop\Application\Model\Basket
*/
protected $basket = null;
/**
* @var \OxidEsales\Eshop\Application\Model\User
*/
protected $user = null;
/**
* @var \OxidEsales\Eshop\Core\Session
*/
protected $session = null;
/**
* @var sTransactionMode : Sale or Authorization
*/
protected $transactionMode;
/**
* @var \OxidEsales\Eshop\Application\Model\Order
*/
protected $order = null;
/**
* @var \OxidEsales\Eshop\Core\Language
*/
protected $lang = null;
/**
* Sets request object.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*/
public function setRequest($request)
{
$this->request = $request;
}
/**
* Returns request object.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getRequest()
{
if ($this->request === null) {
$this->request = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest::class);
}
return $this->request;
}
/**
* Returns request object
*
* @param \OxidEsales\PayPalModule\Core\Config $config
*/
public function setPayPalConfig($config)
{
$this->payPalConfig = $config;
}
/**
* Returns \OxidEsales\PayPalModule\Core\Config object.
*
* @return \OxidEsales\PayPalModule\Core\Config
*/
public function getPayPalConfig()
{
return $this->payPalConfig;
}
/**
* Sets basket.
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket
*/
public function setBasket($basket)
{
$this->basket = $basket;
}
/**
* Returns basket object.
*
* @return \OxidEsales\Eshop\Application\Model\Basket
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException
*/
public function getBasket()
{
if (is_null($this->basket)) {
/**
* @var \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException $exception
*/
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException::class);
throw $exception;
}
return $this->basket;
}
/**
* Sets order object.
*
* @param \OxidEsales\Eshop\Application\Model\Order $order
*/
public function setOrder($order)
{
$this->order = $order;
}
/**
* Tries to return basket object, but if fails throws exception.
*
* @return \OxidEsales\Eshop\Application\Model\Order
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalResponseException
*/
public function getOrder()
{
if (is_null($this->order)) {
/** @var \OxidEsales\PayPalModule\Core\Exception\PayPalResponseException $exception */
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalResponseException::class, 'OEPAYPAL_ORDER_ERROR');
throw $exception;
}
return $this->order;
}
/**
* Sets session.
*
* @param \OxidEsales\Eshop\Core\Session $session
*/
public function setSession($session)
{
$this->session = $session;
}
/**
* Returns session.
*
* @return \OxidEsales\Eshop\Core\Session
*/
public function getSession()
{
return $this->session;
}
/**
* Returns request object.
*
* @param \OxidEsales\Eshop\Core\Language $lang
*/
public function setLang($lang)
{
$this->lang = $lang;
}
/**
* Returns request object.
*
* @return \OxidEsales\Eshop\Core\Language
*/
public function getLang()
{
if ($this->lang === null) {
$this->lang = $this->getPayPalConfig()->getLang();
}
return $this->lang;
}
/**
* Sets transaction mode.
*
* @param string $transactionMode
*/
public function setTransactionMode($transactionMode)
{
$this->transactionMode = $transactionMode;
}
/**
* Returns transaction mode.
*
* @return string $transactionMode
*/
public function getTransactionMode()
{
return $this->transactionMode;
}
/**
* Sets User object.
*
* @param \OxidEsales\PayPalModule\Model\User $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* Returns User object
*
* @return \OxidEsales\Eshop\Application\Model\User
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException
*/
public function getUser()
{
if (is_null($this->user)) {
/**
* @var \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException $exception
*/
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException::class);
throw $exception;
}
return $this->user;
}
/**
* Sets base parameters to request.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function buildRequest()
{
$this->addBaseParams();
$this->addAddressParams();
return $this->getRequest();
}
/**
* Sets Address parameters to request.
*
* @return null
*/
public function addAddressParams()
{
$user = $this->getUser();
if (!$user) {
return;
}
$request = $this->getRequest();
$addressId = $user->getSelectedAddressId();
if ($addressId) {
$address = oxNew(\OxidEsales\Eshop\Application\Model\Address::class);
$address->load($addressId);
$request->setParameter("PAYMENTREQUEST_0_SHIPTONAME", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($address->oxaddress__oxfname->value . " " . $address->oxaddress__oxlname->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTREET", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($address->oxaddress__oxstreet->value . " " . $address->oxaddress__oxstreetnr->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCITY", $address->oxaddress__oxcity->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOZIP", $address->oxaddress__oxzip->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOPHONENUM", $address->oxaddress__oxfon->value);
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$country->load($address->oxaddress__oxcountryid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE", $country->oxcountry__oxisoalpha2->value);
if ($address->oxaddress__oxstateid->value) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$state->load($address->oxaddress__oxstateid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTATE", $state->oxstates__oxisoalpha2->value);
}
} else {
$request->setParameter("PAYMENTREQUEST_0_SHIPTONAME", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($user->oxuser__oxfname->value . " " . $user->oxuser__oxlname->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTREET", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($user->oxuser__oxstreet->value . " " . $user->oxuser__oxstreetnr->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCITY", $user->oxuser__oxcity->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOZIP", $user->oxuser__oxzip->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOPHONENUM", $user->oxuser__oxfon->value);
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$country->load($user->oxuser__oxcountryid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE", $country->oxcountry__oxisoalpha2->value);
if ($user->oxuser__oxstateid->value) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$state->load($user->oxuser__oxstateid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTATE", $state->oxstates__oxisoalpha2->value);
}
}
}
/**
* Sets basic parameters to request.
*/
public function addBaseParams()
{
$order = $this->getOrder();
$config = $this->getPayPalConfig();
$basket = $this->getBasket();
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$lang = $this->getLang();
$request = $this->getRequest();
$request->setParameter("TOKEN", $session->getVariable("oepaypal-token"));
$request->setParameter("PAYERID", $session->getVariable("oepaypal-payerId"));
$request->setParameter("PAYMENTREQUEST_0_PAYMENTACTION", $this->getTransactionMode());
$request->setParameter("PAYMENTREQUEST_0_AMT", $this->formatFloat($basket->getPrice()->getBruttoPrice()));
$request->setParameter("PAYMENTREQUEST_0_CURRENCYCODE", $basket->getBasketCurrency()->name);
// IPN notify URL for PayPal
if (!$config->suppressIPNCallbackUrl()) {
$request->setParameter("PAYMENTREQUEST_0_NOTIFYURL", $config->getIPNCallbackUrl());
}
// payment description
$subj = sprintf($lang->translateString("OEPAYPAL_ORDER_CONF_SUBJECT"), $order->oxorder__oxordernr->value);
$request->setParameter("PAYMENTREQUEST_0_DESC", $subj);
$request->setParameter("PAYMENTREQUEST_0_CUSTOM", $subj);
// Please do not change this place.
// It is important to guarantee the future development of this O3-Shop extension and to keep it free of charge.
// Thanks!
$request->setParameter("BUTTONSOURCE", $config->getPartnerCode());
}
/**
* Formats given float/int value into PayPal friendly form
*
* @param float $in value to format
*
* @return string
*/
protected function formatFloat($in)
{
return sprintf("%.2f", $in);
}
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\PayPalRequest;
/**
* PayPal request builder class for get express checkout details
*/
class GetExpressCheckoutDetailsRequestBuilder
{
/**
* PayPal Request
*
* @var \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
protected $payPalRequest = null;
/**
* Session object
*
* @var \OxidEsales\Eshop\Core\Session
*
* @deprecated Session property is never used in this class
*/
protected $session = null;
/** @var ?string */
protected $token = null;
/**
* Sets PayPal request object.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*/
public function setPayPalRequest($request)
{
$this->payPalRequest = $request;
}
/**
* Returns PayPal request object.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if ($this->payPalRequest === null) {
$this->payPalRequest = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest::class);
}
return $this->payPalRequest;
}
/**
* Sets Session.
*
* @param \OxidEsales\Eshop\Core\Session $session
* @deprecated Use self::setToken to set token or omit this method if it should be taken from session
*/
public function setSession($session)
{
$this->session = $session;
}
/**
* Returns Session.
*
* @return \OxidEsales\Eshop\Core\Session
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException
*
* @deprecated Session property is never used in this class
*/
public function getSession()
{
if (!$this->session) {
/**
* @var \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException $exception
*/
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException::class);
throw $exception;
}
return $this->session;
}
/**
* @return string|null
*/
public function getToken(): ?string
{
if (!$this->token) {
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$this->token = $session->getVariable('oepaypal-token');
}
return $this->token;
}
/**
* @param string|null $token
*/
public function setToken(?string $token)
{
$this->token = $token;
}
/**
* Builds Request.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function buildRequest()
{
$request = $this->getPayPalRequest();
$request->setParameter('TOKEN', $this->getToken());
return $request;
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\PayPalRequest;
/**
* PayPal request class
*/
class PayPalRequest
{
/**
* PayPal response data
*
* @var array
*/
protected $data = array();
/**
* Sets value to data by given key.
*
* @param string $key Key of data value.
* @param string $value Data value.
*/
public function setParameter($key, $value)
{
$this->data[$key] = $value;
}
/**
* Returns value by given key.
*
* @param string $key Key of data value.
*
* @return string
*/
public function getParameter($key)
{
return $this->data[$key];
}
/**
* Set request data.
*
* @param array $responseData Response data from PayPal.
*/
public function setData($responseData)
{
$this->data = $responseData;
}
/**
* Return request data.
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Return value from data by given key.
*
* @param string $key Key of data value.
* @param string $value Data value.
*/
protected function setValue($key, $value)
{
$this->data[$key] = $value;
}
}

View File

@@ -0,0 +1,124 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\PayPalRequest;
/**
* PayPal request builder class
*/
class PayPalRequestBuilder
{
/**
* Request object
*
* @var \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
protected $request = null;
/**
* Sets Authorization id
*
* @param string $authorizationId
*/
public function setAuthorizationId($authorizationId)
{
$this->getRequest()->setParameter('AUTHORIZATIONID', $authorizationId);
}
/**
* Sets Transaction id
*
* @param string $transactionId
*/
public function setTransactionId($transactionId)
{
$this->getRequest()->setParameter('TRANSACTIONID', $transactionId);
}
/**
* Set amount
*
* @param double $amount
* @param string $currencyCode
*/
public function setAmount($amount, $currencyCode = null)
{
$this->getRequest()->setParameter('AMT', $amount);
if (!$currencyCode) {
$currencyCode = \OxidEsales\Eshop\Core\Registry::getConfig()->getActShopCurrencyObject()->name;
}
$this->getRequest()->setParameter('CURRENCYCODE', $currencyCode);
}
/**
* Set Capture type
*
* @param string $type
*/
public function setCompleteType($type)
{
$this->getRequest()->setParameter('COMPLETETYPE', $type);
}
/**
* Set Refund type
*
* @param string $type
*/
public function setRefundType($type)
{
$this->getRequest()->setParameter('REFUNDTYPE', $type);
}
/**
* Set Refund type
*
* @param string $comment
*/
public function setComment($comment)
{
$this->getRequest()->setParameter('NOTE', $comment);
}
/**
* Return request object.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getRequest()
{
if ($this->request === null) {
$this->request = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest::class);
}
return $this->request;
}
/**
* Sets Request object.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*/
public function setRequest($request)
{
$this->request = $request;
}
}

View File

@@ -0,0 +1,648 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\PayPalRequest;
/**
* PayPal request builder class for set express checkout
*/
class SetExpressCheckoutRequestBuilder
{
/**
* PayPal Request.
*
* @var \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
protected $payPalRequest = null;
/**
* PayPal Config.
*
* @var \OxidEsales\PayPalModule\Core\Config
*/
protected $payPalConfig = null;
/**
* Basket object.
*
* @var \OxidEsales\PayPalModule\Model\Basket
*/
protected $basket = null;
/**
* User object.
*
* @var \OxidEsales\PayPalModule\Model\User
*/
protected $user = null;
/**
* Language object.
*
* @var \OxidEsales\Eshop\Core\Language
*/
protected $lang = null;
/**
* Url to return to after PayPal payment is done.
*
* @var string
*/
protected $returnUrl = null;
/**
* Url to return to if PayPal payment was canceled.
*
* @var string
*/
protected $cancelUrl = null;
/**
* Url for PayPal CallBack.
*
* @var string
*/
protected $callBackUrl = null;
/**
* Show basket items in PayPal.
*
* @var bool
*/
protected $showCartInPayPal = false;
/**
* Transaction mode: Sale|Authorization.
*
* @var string
*/
protected $transactionMode;
/**
* Maximum possible delivery costs value.
*
* @var double
*/
protected $maxDeliveryAmount = 0;
/**
* Sets max delivery amount.
*
* @param double $maxDeliveryAmount
*/
public function setMaxDeliveryAmount($maxDeliveryAmount)
{
$this->maxDeliveryAmount = $maxDeliveryAmount;
}
/**
* Return max delivery amount.
*
* @return double
*/
public function getMaxDeliveryAmount()
{
return $this->maxDeliveryAmount;
}
/**
* Sets PayPal request object.
*
* @param \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest $request
*/
public function setPayPalRequest($request)
{
$this->payPalRequest = $request;
}
/**
* Returns PayPal request object; initiates if not set.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function getPayPalRequest()
{
if ($this->payPalRequest === null) {
$this->payPalRequest = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest::class);
}
return $this->payPalRequest;
}
/**
* Returns config object.
*
* @param \OxidEsales\PayPalModule\Core\Config $config
*/
public function setPayPalConfig($config)
{
$this->payPalConfig = $config;
}
/**
* Returns config object.
*
* @return \OxidEsales\PayPalModule\Core\Config
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException
*/
public function getPayPalConfig()
{
if (!$this->payPalConfig) {
/** @var \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException $exception */
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException::class);
throw $exception;
}
return $this->payPalConfig;
}
/**
* Sets Basket object.
*
* @param \OxidEsales\Eshop\Application\Model\Basket $basket
*/
public function setBasket($basket)
{
$this->basket = $basket;
}
/**
* Returns basket object.
*
* @return \OxidEsales\Eshop\Application\Model\Basket
*
* @throws \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException
*/
public function getBasket()
{
if (is_null($this->basket)) {
/** @var \OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException $exception */
$exception = oxNew(\OxidEsales\PayPalModule\Core\Exception\PayPalMissingParameterException::class);
throw $exception;
}
return $this->basket;
}
/**
* Sets User object
*
* @param \OxidEsales\Eshop\Application\Model\User $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* Returns User object
*
* @return \OxidEsales\PayPalModule\Model\User
*/
public function getUser()
{
return $this->user;
}
/**
* Sets Language object
*
* @param \OxidEsales\Eshop\Core\Language $lang
*/
public function setLang($lang)
{
$this->lang = $lang;
}
/**
* Returns Language object.
*
* @return \OxidEsales\Eshop\Core\Language
*/
public function getLang()
{
if (is_null($this->lang)) {
$this->lang = $this->getPayPalConfig()->getLang();
}
return $this->lang;
}
/**
* Sets CallBack url.
*
* @param string $callBackUrl
*/
public function setCallBackUrl($callBackUrl)
{
$this->callBackUrl = $callBackUrl;
}
/**
* Returns CallBack url.
*
* @return string
*/
public function getCallBackUrl()
{
return $this->callBackUrl;
}
/**
* Sets Cancel Url.
*
* @param string $cancelUrl
*/
public function setCancelUrl($cancelUrl)
{
$this->cancelUrl = $cancelUrl;
}
/**
* Returns Cancel Url.
*
* @return string
*/
public function getCancelUrl()
{
return $this->cancelUrl;
}
/**
* Sets Return Url.
*
* @param string $returnUrl
*/
public function setReturnUrl($returnUrl)
{
$this->returnUrl = $returnUrl;
}
/**
* Returns Return Url.
*
* @return string
*/
public function getReturnUrl()
{
return $this->returnUrl;
}
/**
* Sets whether to show basket in PayPal.
*
* @param string $showCartInPayPal
*/
public function setShowCartInPayPal($showCartInPayPal)
{
$this->showCartInPayPal = $showCartInPayPal;
}
/**
* Returns whether to show basket in PayPal.
*
* @return string
*/
public function getShowCartInPayPal()
{
return $this->showCartInPayPal;
}
/**
* Sets Transaction mode.
*
* @param string $transactionMode
*/
public function setTransactionMode($transactionMode)
{
$this->transactionMode = $transactionMode;
}
/**
* Returns Transaction mode.
*
* @return string $transactionMode
*/
public function getTransactionMode()
{
return $this->transactionMode;
}
/**
* Builds PayPal request for express checkout.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function buildExpressCheckoutRequest()
{
$this->addBaseParams();
$this->addCallBackUrl();
$this->addBasketParams();
$this->addDescriptionParams();
$this->turnOffShippingAddressCollection();
$this->setMaximumOrderAmount();
if ($this->getShowCartInPayPal()) {
$this->addBasketItemParams();
} else {
$this->addBasketGrandTotalParams();
}
$this->addAddressParams();
return $this->getPayPalRequest();
}
/**
* Builds PayPal request for standard checkout.
*
* @return \OxidEsales\PayPalModule\Model\PayPalRequest\PayPalRequest
*/
public function buildStandardCheckoutRequest()
{
$this->addBaseParams();
$this->addBasketParams();
$this->addDescriptionParams();
$this->disableSelectingDifferentAddressInPayPal();
$this->setMaximumOrderAmount();
if ($this->getShowCartInPayPal()) {
$this->addBasketItemParams();
} else {
$this->addBasketGrandTotalParams();
}
$this->addAddressParams();
return $this->getPayPalRequest();
}
/**
* Sets base parameters to request.
*/
public function addBaseParams()
{
$request = $this->getPayPalRequest();
$payPalConfig = $this->getPayPalConfig();
$request->setParameter("CALLBACKVERSION", "84.0");
$request->setParameter("LOCALECODE", $this->getLang()->translateString("OEPAYPAL_LOCALE"));
// enabled guest buy (Buyer does not need to create a PayPal account to check out)
$request->setParameter("SOLUTIONTYPE", ($payPalConfig->isGuestBuyEnabled() ? "Sole" : "Mark"));
$request->setParameter("BRANDNAME", $payPalConfig->getBrandName());
$request->setParameter("CARTBORDERCOLOR", $payPalConfig->getBorderColor());
$request->setParameter("RETURNURL", $this->getReturnUrl());
$request->setParameter("CANCELURL", $this->getCancelUrl());
if ($logoImage = $payPalConfig->getLogoUrl()) {
$request->setParameter("LOGOIMG", $logoImage);
}
$request->setParameter("PAYMENTREQUEST_0_PAYMENTACTION", $this->getTransactionMode());
}
/**
* Adds callback parameters to request.
*/
public function addCallBackUrl()
{
$request = $this->getPayPalRequest();
$request->setParameter("CALLBACK", $this->getCallbackUrl());
$request->setParameter("CALLBACKTIMEOUT", 6);
}
/**
* Turn off shipping address collection.
*/
public function turnOffShippingAddressCollection()
{
$this->getPayPalRequest()->setParameter("NOSHIPPING", "2");
}
/**
* Disables selecting different address in PayPal side.
*/
public function disableSelectingDifferentAddressInPayPal()
{
$this->getPayPalRequest()->setParameter("ADDROVERRIDE", "1");
}
/**
* Calculating maximum order amount
* and adding all used discounts (needed because of bug in PayPal - somehow it substract discount from MAXAMT)
* additionally +1 as PayPal recommends this value a little bit greater than original.
*/
public function setMaximumOrderAmount()
{
$basket = $this->getBasket();
$request = $this->getPayPalRequest();
$request->setParameter("MAXAMT", $this->formatFloat(($basket->getPrice()->getBruttoPrice() + $basket->getDiscountSumPayPalBasket() + $this->getMaxDeliveryAmount() + 1)));
}
/**
* Sets basket parameters to request.
*/
public function addBasketParams()
{
$request = $this->getPayPalRequest();
$basket = $this->getBasket();
$virtualBasket = $basket->isVirtualPayPalBasket();
// only downloadable products? missing getter on oxBasket yet
$request->setParameter("NOSHIPPING", $virtualBasket ? "1" : "0");
if ($virtualBasket) {
$request->setParameter("REQCONFIRMSHIPPING", "0");
}
// passing basket VAT (tax) value. It is required as in Net mode articles are without VAT, but basket is with VAT.
// PayPal need this value to check if all articles sum match basket sum.
if ($basket->isCalculationModeNetto()) {
$request->setParameter("PAYMENTREQUEST_0_TAXAMT", $this->formatFloat($basket->getPayPalBasketVatValue()));
}
$request->setParameter("PAYMENTREQUEST_0_AMT", $this->formatFloat($basket->getPrice()->getBruttoPrice()));
$request->setParameter("PAYMENTREQUEST_0_CURRENCYCODE", $basket->getBasketCurrency()->name);
$request->setParameter("PAYMENTREQUEST_0_ITEMAMT", $this->formatFloat($basket->getSumOfCostOfAllItemsPayPalBasket()));
$request->setParameter("PAYMENTREQUEST_0_SHIPPINGAMT", $this->formatFloat($basket->getDeliveryCosts()));
$request->setParameter("PAYMENTREQUEST_0_SHIPDISCAMT", $this->formatFloat($basket->getDiscountSumPayPalBasket() * -1));
$delivery = oxNew(\OxidEsales\Eshop\Application\Model\DeliverySet::class);
$deliveryName = ($delivery->load($basket->getShippingId())) ? $delivery->oxdeliveryset__oxtitle->value : "#1";
$request->setParameter("L_SHIPPINGOPTIONISDEFAULT0", "true");
$request->setParameter("L_SHIPPINGOPTIONNAME0", $deliveryName);
$request->setParameter("L_SHIPPINGOPTIONAMOUNT0", $this->formatFloat($basket->getDeliveryCosts()));
}
/**
* Sets transaction description parameters.
*/
public function addDescriptionParams()
{
$basket = $this->getBasket();
$config = $this->getPayPalConfig();
$request = $this->getPayPalRequest();
// description
$shopNameFull = $config->getBrandName();
$shopName = substr($shopNameFull, 0, 70);
if ($shopNameFull != $shopName) {
$shopName .= "...";
}
$subj = sprintf($this->getLang()->translateString("OEPAYPAL_ORDER_SUBJECT"), $shopName, $basket->getFPrice(), $basket->getBasketCurrency()->name);
$request->setParameter("PAYMENTREQUEST_0_DESC", $subj);
$request->setParameter("PAYMENTREQUEST_0_CUSTOM", $subj);
}
/**
* Sets basket items parameters to request.
*/
public function addBasketItemParams()
{
$basket = $this->getBasket();
$lang = $this->getLang();
$request = $this->getPayPalRequest();
$pos = 0;
foreach ($basket->getContents() as $basketItem) {
$request->setParameter("L_PAYMENTREQUEST_0_NAME{$pos}", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($basketItem->getTitle()));
$request->setParameter("L_PAYMENTREQUEST_0_AMT{$pos}", $this->formatFloat($basketItem->getUnitPrice()->getPrice()));
$request->setParameter("L_PAYMENTREQUEST_0_QTY{$pos}", (int) $basketItem->getAmount());
$request->setParameter("L_PAYMENTREQUEST_0_ITEMURL{$pos}", $basketItem->getLink());
$basketProduct = $basketItem->getArticle();
$request->setParameter("L_PAYMENTREQUEST_0_NUMBER{$pos}", $basketProduct->oxarticles__oxartnum->value);
$pos++;
}
//adding payment costs as product
if ($basket->getPayPalPaymentCosts() > 0) {
$paymentTitle = $lang->translateString("OEPAYPAL_SURCHARGE") . " " . $lang->translateString("OEPAYPAL_TYPE_OF_PAYMENT");
$request->setParameter("L_PAYMENTREQUEST_0_NAME{$pos}", $paymentTitle);
$request->setParameter("L_PAYMENTREQUEST_0_AMT{$pos}", $this->formatFloat($basket->getPayPalPaymentCosts()));
$request->setParameter("L_PAYMENTREQUEST_0_QTY{$pos}", 1);
$pos++;
}
//adding wrapping as product
if ($basket->getPayPalWrappingCosts() > 0) {
$request->setParameter("L_PAYMENTREQUEST_0_NAME{$pos}", $lang->translateString("OEPAYPAL_GIFTWRAPPER"));
$request->setParameter("L_PAYMENTREQUEST_0_AMT{$pos}", $this->formatFloat($basket->getPayPalWrappingCosts()));
$request->setParameter("L_PAYMENTREQUEST_0_QTY{$pos}", 1);
$pos++;
}
//adding greeting card as product
if ($basket->getPayPalGiftCardCosts() > 0) {
$request->setParameter("L_PAYMENTREQUEST_0_NAME{$pos}", $lang->translateString("OEPAYPAL_GREETING_CARD"));
$request->setParameter("L_PAYMENTREQUEST_0_AMT{$pos}", $this->formatFloat($basket->getPayPalGiftCardCosts()));
$request->setParameter("L_PAYMENTREQUEST_0_QTY{$pos}", 1);
$pos++;
}
}
/**
* Sets basket Grand Total params to request.
*/
public function addBasketGrandTotalParams()
{
$basket = $this->getBasket();
$request = $this->getPayPalRequest();
$request->setParameter("L_PAYMENTREQUEST_0_NAME0", $this->getLang()->translateString("OEPAYPAL_GRAND_TOTAL"));
$request->setParameter("L_PAYMENTREQUEST_0_AMT0", $this->formatFloat($basket->getSumOfCostOfAllItemsPayPalBasket()));
$request->setParameter("L_PAYMENTREQUEST_0_QTY0", 1);
}
/**
* Sets Address parameters to request.
*
* @return null
*/
public function addAddressParams()
{
$user = $this->getUser();
if (!$user) {
return;
}
$request = $this->getPayPalRequest();
$request->setParameter("EMAIL", $user->oxuser__oxusername->value);
$addressId = $user->getSelectedAddressId();
if ($addressId) {
$address = oxNew(\OxidEsales\Eshop\Application\Model\Address::class);
$address->load($addressId);
$request->setParameter("PAYMENTREQUEST_0_SHIPTONAME", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($address->oxaddress__oxfname->value . " " . $address->oxaddress__oxlname->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTREET", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($address->oxaddress__oxstreet->value . " " . $address->oxaddress__oxstreetnr->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCITY", $address->oxaddress__oxcity->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOZIP", $address->oxaddress__oxzip->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOPHONENUM", $address->oxaddress__oxfon->value);
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$country->load($address->oxaddress__oxcountryid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE", $country->oxcountry__oxisoalpha2->value);
if ($address->oxaddress__oxstateid->value) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$state->load($address->oxaddress__oxstateid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTATE", $state->oxstates__oxisoalpha2->value);
}
} else {
$request->setParameter("PAYMENTREQUEST_0_SHIPTONAME", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($user->oxuser__oxfname->value . " " . $user->oxuser__oxlname->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTREET", \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($user->oxuser__oxstreet->value . " " . $user->oxuser__oxstreetnr->value));
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCITY", $user->oxuser__oxcity->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOZIP", $user->oxuser__oxzip->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOPHONENUM", $user->oxuser__oxfon->value);
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$country->load($user->oxuser__oxcountryid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE", $country->oxcountry__oxisoalpha2->value);
if ($user->oxuser__oxstateid->value) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$state->load($user->oxuser__oxstateid->value);
$request->setParameter("PAYMENTREQUEST_0_SHIPTOSTATE", $state->oxstates__oxisoalpha2->value);
}
}
}
/**
* Formats given float/int value into PayPal friendly form
*
* @param float $in value to format
*
* @return string
*/
protected function formatFloat($in)
{
return sprintf("%.2f", $in);
}
}

View File

@@ -0,0 +1,257 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* Payment gateway manager.
* Checks and sets payment method data, executes payment.
*
* @mixin \OxidEsales\Eshop\Application\Model\PaymentGateway
*/
class PaymentGateway extends PaymentGateway_parent
{
/**
* PayPal config.
*
* @var null
*/
protected $payPalConfig = null;
/**
* PayPal config.
*
* @var null
*/
protected $checkoutService = null;
/**
* Order.
*
* @var \OxidEsales\Eshop\Application\Model\Order
*/
protected $payPalOxOrder;
/**
* Sets order.
*
* @param \OxidEsales\Eshop\Application\Model\Order $order
*/
public function setPayPalOxOrder($order)
{
$this->payPalOxOrder = $order;
}
/**
* Gets order.
*
* @return \OxidEsales\Eshop\Application\Model\Order
*/
public function getPayPalOxOrder()
{
if (is_null($this->payPalOxOrder)) {
$order = oxNew(\OxidEsales\Eshop\Application\Model\Order::class);
$order->loadPayPalOrder();
$this->setPayPalOxOrder($order);
}
return $this->payPalOxOrder;
}
/**
* Executes payment, returns true on success.
*
* @param double $amount Goods amount
* @param \OxidEsales\PayPalModule\Model\Order $order User ordering object
*
* @return bool
*/
public function executePayment($amount, &$order)
{
$success = parent::executePayment($amount, $order);
$session = \OxidEsales\Eshop\Core\Registry::getSession();
if ( ($session->getVariable('paymentid') == 'oxidpaypal')
|| ($session->getBasket()->getPaymentId() == 'oxidpaypal')
) {
$this->setPayPalOxOrder($order);
$success = $this->doExpressCheckoutPayment();
}
return $success;
}
/**
* Executes "DoExpressCheckoutPayment" to PayPal
*
* @return bool
*/
public function doExpressCheckoutPayment()
{
$success = false;
$order = $this->getPayPalOrder();
try {
// updating order state
if ($order) {
$order->oePayPalUpdateOrderNumber();
$session = \OxidEsales\Eshop\Core\Registry::getSession();
$basket = $session->getBasket();
$transactionMode = $this->getTransactionMode($basket);
$builder = oxNew(\OxidEsales\PayPalModule\Model\PayPalRequest\DoExpressCheckoutPaymentRequestBuilder::class);
$builder->setPayPalConfig($this->getPayPalConfig());
$builder->setSession($session);
$builder->setBasket($basket);
$builder->setTransactionMode($transactionMode);
$builder->setUser($this->getPayPalUser());
$builder->setOrder($order);
$request = $builder->buildRequest();
$payPalService = $this->getPayPalCheckoutService();
$result = $payPalService->doExpressCheckoutPayment($request);
$order->finalizePayPalOrder(
$result,
$session->getBasket(),
$transactionMode
);
$success = true;
} else {
/**
* @var $exception \OxidEsales\Eshop\Core\Exception\StandardException
*/
$exception = oxNew(\OxidEsales\Eshop\Core\Exception\StandardException::class, 'OEPAYPAL_ORDER_ERROR');
throw $exception;
}
} catch (\OxidEsales\Eshop\Core\Exception\StandardException $exception) {
// deleting order on error
if ($order) {
$order->deletePayPalOrder();
}
$this->_iLastErrorNo = \OxidEsales\Eshop\Application\Model\Order::ORDER_STATE_PAYMENTERROR;
$utilsView = \OxidEsales\Eshop\Core\Registry::getUtilsView();
$utilsView->addErrorToDisplay($exception);
}
return $success;
}
/**
* Returns transaction mode.
*
* @param object $basket
*
* @return string
*/
protected function getTransactionMode($basket)
{
$transactionMode = $this->getPayPalConfig()->getTransactionMode();
if ($transactionMode == "Automatic") {
$outOfStockValidator = new \OxidEsales\PayPalModule\Model\OutOfStockValidator();
$outOfStockValidator->setBasket($basket);
$outOfStockValidator->setEmptyStockLevel($this->getPayPalConfig()->getEmptyStockLevel());
$transactionMode = ($outOfStockValidator->hasOutOfStockArticles()) ? "Authorization" : "Sale";
return $transactionMode;
}
return $transactionMode;
}
/**
* Return PayPal config
*
* @return \OxidEsales\PayPalModule\Core\Config
*/
public function getPayPalConfig()
{
if (is_null($this->payPalConfig)) {
$this->setPayPalConfig(oxNew(\OxidEsales\PayPalModule\Core\Config::class));
}
return $this->payPalConfig;
}
/**
* Set PayPal config
*
* @param \OxidEsales\PayPalModule\Core\Config $payPalConfig config
*/
public function setPayPalConfig($payPalConfig)
{
$this->payPalConfig = $payPalConfig;
}
/**
* Sets PayPal service
*
* @param \OxidEsales\PayPalModule\Core\PayPalService $checkoutService
*/
public function setPayPalCheckoutService($checkoutService)
{
$this->checkoutService = $checkoutService;
}
/**
* Returns PayPal service
*
* @return \OxidEsales\PayPalModule\Core\PayPalService
*/
public function getPayPalCheckoutService()
{
if (is_null($this->checkoutService)) {
$this->setPayPalCheckoutService(oxNew(\OxidEsales\PayPalModule\Core\PayPalService::class));
}
return $this->checkoutService;
}
/**
* Returns PayPal order object
*
* @return \OxidEsales\Eshop\Application\Model\Order
*/
protected function getPayPalOrder()
{
return $this->getPayPalOxOrder();
}
/**
* Returns PayPal user
*
* @return \OxidEsales\Eshop\Application\Model\User
*/
protected function getPayPalUser()
{
$user = oxNew(\OxidEsales\Eshop\Application\Model\User::class);
if (!$user->loadUserPayPalUser()) {
$user = $this->getUser();
}
return $user;
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
use OxidEsales\Eshop\Core\Registry as EshopRegistry;
use OxidEsales\PayPalModule\Core\Config as PayPalConfig;
/**
* PayPal PaymentList class
*
* @mixin \OxidEsales\Eshop\Application\Model\PaymentList
*/
class PaymentList extends PaymentList_parent
{
public function getPaymentList($sShipSetId, $dPrice, $oUser = null)
{
$paymentList = parent::getPaymentList($sShipSetId, $dPrice, $oUser);
$payPalConfig = oxNew(PayPalConfig::class);
$serviceType = EshopRegistry::getSession()->getVariable(PayPalConfig::OEPAYPAL_TRIGGER_NAME);
foreach ($paymentList as $key => $paymentModel) {
if ($paymentModel->getId() !== "oxidpaypal") {
continue;
}
if (
(
!$payPalConfig->isExpressCheckoutEnabled() &&
$serviceType === PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS
) || (
!$payPalConfig->isStandardCheckoutEnabled() &&
$serviceType !== PaymentManager::PAYPAL_SERVICE_TYPE_EXPRESS
)
) {
unset($paymentList[$key]);
}
}
return $paymentList;
}
}

View File

@@ -0,0 +1,365 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
use OxidEsales\Eshop\Application\Model\Basket;
use OxidEsales\Eshop\Application\Model\User;
use OxidEsales\Eshop\Application\Model\User as EshopUserModel;
use OxidEsales\Eshop\Application\Model\UserBasket as EshopUserBasketModel;
use OxidEsales\Eshop\Application\Model\DeliverySetList as EshopDeliverySetListModel;
use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\Exception\ArticleException as EshopArticleException;
use OxidEsales\Eshop\Core\Exception\StandardException as EshopStandardException;
use OxidEsales\PayPalModule\Core\Config as PayPalConfig;
use OxidEsales\PayPalModule\Core\Exception\PayPalException;
use OxidEsales\PayPalModule\Core\PayPalService;
use OxidEsales\PayPalModule\Model\PayPalRequest\GetExpressCheckoutDetailsRequestBuilder;
use OxidEsales\PayPalModule\Model\PayPalRequest\SetExpressCheckoutRequestBuilder;
use OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails;
use OxidEsales\PayPalModule\Model\Response\ResponseSetExpressCheckout;
use OxidEsales\PayPalModule\Core\PayPalCheckValidator;
/**
* Class \OxidEsales\PayPalModule\Model\PaymentManager.
*/
class PaymentManager
{
public const PAYPAL_SERVICE_TYPE_STANDARD = 1;
public const PAYPAL_SERVICE_TYPE_EXPRESS = 2;
/** @var PayPalService */
private $payPalService;
/** @var PayPalConfig */
private $payPalConfig;
public function __construct(PayPalService $payPalService)
{
$this->payPalService = $payPalService;
$this->payPalConfig = oxNew(PayPalConfig::class);
}
public function setStandardCheckout(
Basket $basket,
?User $user,
string $returnUrl,
string $cancelUrl,
bool $showCartInPayPal,
string $deliveryAddressId
): ResponseSetExpressCheckout {
$builder = oxNew(SetExpressCheckoutRequestBuilder::class);
if ($deliveryAddressId && $user) {
$user->setSelectedAddressId($deliveryAddressId);
$basket->setUser($user);
}
$basket->setPayment("oxidpaypal");
$basket->onUpdate();
$basket->calculateBasket(true);
$this->validatePayment($user, $basket);
$builder->setPayPalConfig($this->payPalConfig);
$builder->setBasket($basket);
$builder->setUser($user);
$builder->setReturnUrl($returnUrl);
$builder->setCancelUrl($cancelUrl);
$showCartInPayPal = $showCartInPayPal && !$basket->isFractionQuantityItemsPresent();
$builder->setShowCartInPayPal($showCartInPayPal);
$builder->setTransactionMode($this->getTransactionMode($basket, $this->payPalConfig));
$request = $builder->buildStandardCheckoutRequest();
return $this->payPalService->setExpressCheckout($request);
}
public function setExpressCheckout(
Basket $basket,
?User $user,
string $returnUrl,
string $cancelUrl,
string $callbackUrl,
bool $showCartInPayPal,
string $shippingId = ''
): ResponseSetExpressCheckout
{
$builder = oxNew(SetExpressCheckoutRequestBuilder::class);
$basket->setPayment('oxidpaypal');
$basket->setShipping($shippingId);
//calculate basket
$mobileDefaultShippingId = $this->payPalConfig->getMobileECDefaultShippingId();
$prevOptionValue = Registry::getConfig()->getConfigParam('blCalculateDelCostIfNotLoggedIn');
Registry::getConfig()->setConfigParam('blCalculateDelCostIfNotLoggedIn', false);
if (!$this->payPalConfig->isDeviceMobile()) {
$builder->setCallBackUrl($callbackUrl);
$builder->setMaxDeliveryAmount($this->payPalConfig->getMaxPayPalDeliveryAmount());
} elseif (!empty($mobileDefaultShippingId) && ($shippingId === $mobileDefaultShippingId)) {
Registry::getConfig()->setConfigParam('blCalculateDelCostIfNotLoggedIn', true);
}
$basket->onUpdate();
$basket->calculateBasket(true);
Registry::getConfig()->setConfigParam('blCalculateDelCostIfNotLoggedIn', $prevOptionValue);
$this->validatePayment($user, $basket, true);
$builder->setPayPalConfig($this->payPalConfig);
$builder->setBasket($basket);
$builder->setUser($user);
$builder->setReturnUrl($returnUrl);
$builder->setCancelUrl($cancelUrl);
$showCartInPayPal = $showCartInPayPal && !$basket->isFractionQuantityItemsPresent();
$builder->setShowCartInPayPal($showCartInPayPal);
$builder->setTransactionMode($this->getTransactionMode($basket, $this->payPalConfig));
$request = $builder->buildExpressCheckoutRequest();
return $this->payPalService->setExpressCheckout($request);
}
public function getExpressCheckoutDetails(?string $token = null): ResponseGetExpressCheckoutDetails
{
$builder = oxNew(GetExpressCheckoutDetailsRequestBuilder::class);
if ($token) {
$builder->setToken($token);
}
$request = $builder->buildRequest();
return $this->payPalService->getExpressCheckoutDetails($request);
}
public function validatePayment(?User $user, Basket $basket, bool $isExpressCheckout = false): void
{
$validator = oxNew(PaymentValidator::class);
$validator->setUser($user);
$validator->setConfig(Registry::getConfig());
$validator->setPrice($basket->getPrice()->getPrice());
if ($isExpressCheckout) {
$validator->setCheckCountry(false);
}
if (!$validator->isPaymentValid()) {
$message = Registry::getLang()->translateString("OEPAYPAL_PAYMENT_NOT_VALID");
throw oxNew(PayPalException::class, $message);
}
}
public function getTransactionMode(Basket $basket, PayPalConfig $payPalConfig): string
{
$transactionMode = $payPalConfig->getTransactionMode();
if ($transactionMode == "Automatic") {
$outOfStockValidator = new OutOfStockValidator();
$outOfStockValidator->setBasket($basket);
$outOfStockValidator->setEmptyStockLevel($payPalConfig->getEmptyStockLevel());
$transactionMode = ($outOfStockValidator->hasOutOfStockArticles()) ? "Authorization" : "Sale";
return $transactionMode;
}
return $transactionMode;
}
public function validateApprovedBasketAmount(float $currentAmount, float $approvedAmount): bool
{
$payPalCheckValidator = oxNew(PayPalCheckValidator::class);
$payPalCheckValidator->setNewBasketAmount($currentAmount);
$payPalCheckValidator->setOldBasketAmount($approvedAmount);
return $payPalCheckValidator->isPayPalCheckValid();
}
public function initializeUserData(ResponseGetExpressCheckoutDetails $details, string $authenticatedUserId): EshopUserModel
{
$userEmail = $details->getEmail();
/** @var EshopUserModel $user */
$authenticatedUser = oxNew(EshopUserModel::class);
$authenticatedUserExists = false;
if ($authenticatedUser->load($authenticatedUserId)) {
$userEmail = $authenticatedUser->getFieldData('oxusername');
$authenticatedUserExists = true;
}
$user = oxNew(EshopUserModel::class);
if ($userId = $user->isRealPayPalUser($userEmail)) {
// if user exist
$user->load($userId);
if (!$authenticatedUserExists) {
if ($user->hasNoInvoiceAddress()) {
//this can only happen when user was registered via graphql, is anonymous and did not yet set invoice data
$user->setInvoiceDataFromPayPalResult($details);
} elseif (!$user->isSamePayPalUser($details)) {
$exception = new EshopStandardException();
$exception->setMessage('OEPAYPAL_ERROR_USER_ADDRESS');
throw $exception;
}
} elseif ($user->hasNoInvoiceAddress()) {
//this can only happen when user was registered via graphql, is logged in and did not yet set invoice data
$user->setInvoiceDataFromPayPalResult($details);
} elseif (!$user->isSameAddressUserPayPalUser($details) || !$user->isSameAddressPayPalUser($details)) {
// user has selected different address in PayPal (not equal with usr shop address)
// so adding PayPal address as new user address to shop user account
$address = oxNew(\OxidEsales\Eshop\Application\Model\Address::class);
$address->createPayPalAddress($details, $userId);
$user->setSelectedAddressId($address->getId());
} else {
// user uses billing address for shipping
$user->setSelectedAddressId(null);
}
} else {
$user->setId($authenticatedUserId);
$user->createPayPalUser($details);
$user->load($authenticatedUserId);
}
$user->setAnonymousUserId($authenticatedUserId);
return $user;
}
public function extractShippingId(
string $shippingOptionName,
?EshopUserModel $user = null,
array $deliverySetList = null
): ?string
{
$result = null;
$shippingOptionName = $this->reencodeHtmlEntities($shippingOptionName);
$name = trim(str_replace(Registry::getLang()->translateString("OEPAYPAL_PRICE"), "", $shippingOptionName));
if (!$deliverySetList) {
$delSetList = $this->getDeliverySetList($user);
$deliverySetList = $this->makeUniqueNames($delSetList);
}
if (is_array($deliverySetList)) {
$flipped = array_flip($deliverySetList);
$result = $flipped[$name];
}
return $result;
}
public function getDeliverySetList(EshopUserModel $user): array
{
$delSetList = oxNew(EshopDeliverySetListModel::class);
return $delSetList->getDeliverySetList($user, $this->getUserShippingCountryId($user));
}
public function getUserShippingCountryId(EshopUserModel $user): string
{
if ($user->getSelectedAddressId() && $user->getSelectedAddress()) {
$countryId = $user->getSelectedAddress()->getFieldData('oxcountryid');
} else {
$countryId = (string) $user->getFieldData('oxcountryid');
}
return $countryId;
}
public function reencodeHtmlEntities(string $input): string
{
$charset = $this->payPalConfig->getCharset();
return htmlentities(html_entity_decode($input, ENT_QUOTES, $charset), ENT_QUOTES, $charset);
}
/**
* @var EshopDeliverySetListModel[] $deliverySetList
*/
public function makeUniqueNames(array $deliverySetList): array
{
$result = [];
$nameCounts = [];
foreach ($deliverySetList as $deliverySet) {
$deliverySetName = trim($deliverySet->oxdeliveryset__oxtitle->value);
if (isset($nameCounts[$deliverySetName])) {
$nameCounts[$deliverySetName] += 1;
} else {
$nameCounts[$deliverySetName] = 1;
}
$suffix = ($nameCounts[$deliverySetName] > 1) ? " (" . $nameCounts[$deliverySetName] . ")" : '';
$result[$deliverySet->oxdeliveryset__oxid->value] = $this->reencodeHtmlEntities($deliverySetName . $suffix);
}
return $result;
}
public function prepareCallback(string $basketId): Basket
{
$sessionBasket = oxNew(Basket::class);
$userBasket = oxNew(EshopUserBasketModel::class);
if (!$userBasket->load($basketId)) {
return $sessionBasket;
}
foreach ($userBasket->getItems() as $basketItem) {
try {
$selectList = $basketItem->getSelList();
$sessionBasket->addToBasket(
$basketItem->getFieldData('oxartid'),
$basketItem->getFieldData('oxamount'),
$selectList,
$basketItem->getPersParams(),
true
);
} catch (EshopArticleException $exception) {
// caught and ignored
}
}
//calculate the basket
Registry::getConfig()->setConfigParam('blCalculateDelCostIfNotLoggedIn', true);
if ($userBasket->getFieldData('OEGQL_DELIVERYMETHODID')) {
$sessionBasket->setShipping($userBasket->getFieldData('OEGQL_DELIVERYMETHODID'));
}
$sessionBasket->calculateBasket(true);
return $sessionBasket;
}
/**
* We do not have the session stored when using the graphql API.
* Callback needs to use the basket id instead.
*/
public function getGraphQLCallBackUrl(string $basketId): string
{
return Registry::getConfig()->getSslShopUrl() . "index.php?lang=" . Registry::getLang()->getBaseLanguage() .
"&basketid=" . $basketId .
"&shp=" . Registry::getConfig()->getShopId() .
"&cl=oepaypalexpresscheckoutdispatcher&fnc=processGraphQLCallBack";
}
}

View File

@@ -0,0 +1,336 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
/**
* This class is for checking validation of PayPal payment for user and basket amount
*/
class PaymentValidator
{
/**
* Basket price
*
* @var double $_dPrice
*/
protected $price;
/**
* Config object
*
* @var \OxidEsales\Eshop\Core\Config $_oConfig
*/
protected $config = null;
/**
* User object
*
* @var \OxidEsales\Eshop\Application\Model\User $_oUser
*/
protected $user = null;
/**
* Payment object
*
* @var \OxidEsales\Eshop\Application\Model\Payment $_oPayment
*/
protected $payment = null;
/**
* Check country in validator.
*
* @var bool
*/
protected $checkCountry = true;
/**
* Basket price setter
*
* @param double $price
*/
public function setPrice($price)
{
$this->price = $price;
}
/**
* Basket price getter
*
* @return double
*/
public function getPrice()
{
return $this->price;
}
/**
* Config object setter
*
* @param \OxidEsales\Eshop\Core\Config $config
*/
public function setConfig($config)
{
$this->config = $config;
}
/**
* Config object getter
*
* @return \OxidEsales\Eshop\Core\Config
*/
public function getConfig()
{
return $this->config;
}
/**
* User object setter
*
* @param \OxidEsales\Eshop\Application\Model\User $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* User object getter
*
* @return \OxidEsales\Eshop\Application\Model\User
*/
public function getUser()
{
return $this->user;
}
/**
* Payment object setter
*
* @param \OxidEsales\Eshop\Application\Model\Payment $payment
*/
public function setPayment($payment)
{
$this->payment = $payment;
}
/**
* Check country setter.
*
* @param boolean $checkCountry
*/
public function setCheckCountry($checkCountry)
{
$this->checkCountry = $checkCountry;
}
/**
* Returns if country should be checked.
*
* @return boolean
*/
public function getCheckCountry()
{
return $this->checkCountry;
}
/**
* Payment object getter
*
* @return \OxidEsales\Eshop\Application\Model\Payment
*/
public function getPayment()
{
if (is_null($this->payment)) {
$payPalPayment = oxNew(\OxidEsales\Eshop\Application\Model\Payment::class);
$payPalPayment->load('oxidpaypal');
$this->setPayment($payPalPayment);
}
return $this->payment;
}
/**
* Checks if PayPal payment is active
*
* @return boolean
*/
public function isPaymentActive()
{
$result = false;
if ($payPalPayment = $this->getPayment()) {
$result = $payPalPayment->oxpayments__oxactive->value ? true : false;
}
return $result;
}
/**
* Checks if payment is valid according to config, user and basket amount.
*
* @return boolean
*/
public function isPaymentValid()
{
$isValid = $this->isPaymentActive();
if ($isValid && !is_null($this->getPrice())) {
$isValid = $this->checkPriceRange() && $this->checkMinOrderPrice();
}
$user = $this->getUser();
if ($isValid && $user && $user->hasAccount()) {
$isValid = $this->checkUserGroup();
}
if ($isValid && $user && $this->getCheckCountry()) {
$isValid = $this->checkUserCountry();
}
return $isValid;
}
/**
* Checks if basket price is inside payment price range
* If range is not set check returns true
*
* @return bool
*/
protected function checkPriceRange()
{
$isValid = true;
$payPalPayment = $this->getPayment();
if ($payPalPayment->oxpayments__oxfromamount->value != 0 ||
$payPalPayment->oxpayments__oxtoamount->value != 0
) {
$cur = \OxidEsales\Eshop\Core\Registry::getConfig()->getActShopCurrencyObject();
$price = $this->getPrice() / $cur->rate;
$isValid = (($price >= $payPalPayment->oxpayments__oxfromamount->value) &&
($price <= $payPalPayment->oxpayments__oxtoamount->value));
}
return $isValid;
}
/**
* Checks if basket price is higher than minimum order price
* If min price is not set check returns true
*
* @return bool
*/
protected function checkMinOrderPrice()
{
$isValid = true;
if ($minOrderPrice = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('iMinOrderPrice')) {
$isValid = $this->getPrice() > $minOrderPrice;
}
return $isValid;
}
/**
* Checks if user country is among payment countries
* If payment countries are not set returns true
*
* @return bool
*/
protected function checkUserCountry()
{
$isValid = true;
$payPalPayment = $this->getPayment();
$countries = $payPalPayment->getCountries();
if ($countries) {
$isValid = false;
foreach ($countries as $countryId) {
if ($countryId === $this->getShippingCountryId()) {
$isValid = true;
break;
}
}
}
return $isValid;
}
/**
* Checks if user belongs group that is assigned to payment
* If payment does not have any groups assigned returns true
*
* @return bool
*/
protected function checkUserGroup()
{
$isValid = true;
$payPalPayment = $this->getPayment();
$groups = $payPalPayment->getGroups();
if ($groups && $groups->count() > 0) {
$isValid = $this->isUserAssignedToGroup($groups);
}
return $isValid;
}
/**
* Checks whether user is assigned to given groups array.
*
* @param \OxidEsales\Eshop\Core\Model\ListModel $groups
*
* @return bool
*/
protected function isUserAssignedToGroup($groups)
{
$isValid = false;
$user = $this->getUser();
foreach ($groups as $group) {
if ($user->inGroup($group->getId())) {
$isValid = true;
break;
}
}
return $isValid;
}
/**
* Returns shipping country ID.
*
* @return string
*/
protected function getShippingCountryId()
{
$user = $this->getUser();
if ($user->getSelectedAddressId()) {
$countryId = $user->getSelectedAddress()->oxaddress__oxcountryid->value;
} else {
$countryId = $user->oxuser__oxcountryid->value;
}
return $countryId;
}
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* Abstract PayPal Response class
*/
abstract class Response
{
/**
* PayPal response data
*
* @var array
*/
protected $data = null;
/**
* Set response data
*
* @param array $responseData Response data from PayPal
*/
public function setData($responseData)
{
$this->data = $responseData;
}
/**
* Return response data
*
* @return array
*/
public function getData()
{
return $this->data;
}
/**
* Return value from data by given key
*
* @param string $key key of data value
*
* @return string
*/
protected function getValue($key)
{
$data = $this->getData();
return $data[$key];
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for do capture
*/
class ResponseDoCapture extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return transaction id
*
* @return string
*/
public function getTransactionId()
{
return $this->getValue('TRANSACTIONID');
}
/**
* Return transaction id
*
* @return string
*/
public function getCorrelationId()
{
return $this->getValue('CORRELATIONID');
}
/**
* Return payment status
*
* @return string
*/
public function getPaymentStatus()
{
return $this->getValue('PAYMENTSTATUS');
}
/**
* Return payment status
*
* @return string
*/
public function getCapturedAmount()
{
return $this->getValue('AMT');
}
/**
* Return currency
*
* @return string
*/
public function getCurrency()
{
return $this->getValue('CURRENCYCODE');
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for do express checkout payment
*/
class ResponseDoExpressCheckoutPayment extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return transaction id.
*
* @return string
*/
public function getTransactionId()
{
return $this->getValue('PAYMENTINFO_0_TRANSACTIONID');
}
/**
* Return transaction id.
*
* @return string
*/
public function getCorrelationId()
{
return $this->getValue('CORRELATIONID');
}
/**
* Return payment status.
*
* @return string
*/
public function getPaymentStatus()
{
return $this->getValue('PAYMENTINFO_0_PAYMENTSTATUS');
}
/**
* Return price amount.
*
* @return string
*/
public function getAmount()
{
return ( float ) $this->getValue('PAYMENTINFO_0_AMT');
}
/**
* Return currency code.
*
* @return string
*/
public function getCurrencyCode()
{
return $this->getValue('PAYMENTINFO_0_CURRENCYCODE');
}
}

View File

@@ -0,0 +1,57 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for do reauthorize
*/
class ResponseDoReAuthorize extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return authorization id.
*
* @return string
*/
public function getAuthorizationId()
{
return $this->getValue('AUTHORIZATIONID');
}
/**
* Return payment status.
*
* @return string
*/
public function getPaymentStatus()
{
return $this->getValue('PAYMENTSTATUS');
}
/**
* Return transaction id.
*
* @return string
*/
public function getCorrelationId()
{
return $this->getValue('CORRELATIONID');
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for do refund
*/
class ResponseDoRefund extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return transaction id.
*
* @return string
*/
public function getTransactionId()
{
return $this->getValue('REFUNDTRANSACTIONID');
}
/**
* Return transaction id.
*
* @return string
*/
public function getCorrelationId()
{
return $this->getValue('CORRELATIONID');
}
/**
* Return payment status.
*
* @return string
*/
public function getPaymentStatus()
{
return $this->getValue('REFUNDSTATUS');
}
/**
* Return payment status.
*
* @return string
*/
public function getRefundAmount()
{
return $this->getValue('GROSSREFUNDAMT');
}
/**
* Return currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getValue('CURRENCYCODE');
}
}

View File

@@ -0,0 +1,138 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for do verify with PayPal
*/
class ResponseDoVerifyWithPayPal extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* String PayPal sends if all is ok.
*
* @var string
*/
const PAYPAL_ACK = 'VERIFIED';
/**
* String PayPal receiver email. It should be same as shop owner credential for PayPal.
*
* @var string
*/
const RECEIVER_EMAIL = 'receiver_email';
/**
* Sandbox mode parameter name.
*
* @var string
*/
const PAYPAL_SANDBOX = 'test_ipn';
/**
* String PayPal payment status parameter name.
*
* @var string
*/
const PAYPAL_PAYMENT_STATUS = 'payment_status';
/**
* String PayPal transaction id.
*
* @var string
*/
const PAYPAL_TRANSACTION_ID = 'txn_id';
/**
* String PayPal whole price including payment and shipment.
*
* @var string
*/
const MC_GROSS = 'mc_gross';
/**
* String PayPal payment currency.
*
* @var string
*/
const MC_CURRENCY = 'mc_currency';
/**
* Return if response verified as ACK from PayPal.
*
* @return boolean
*/
public function isPayPalAck()
{
$response = $this->getData();
return isset($response[self::PAYPAL_ACK]);
}
/**
* Return if response verified as ACK from PayPal.
*
* @return string
*/
public function getReceiverEmail()
{
return $this->getValue(self::RECEIVER_EMAIL);
}
/**
* Return payment status.
*
* @return string
*/
public function getPaymentStatus()
{
return $this->getValue(self::PAYPAL_PAYMENT_STATUS);
}
/**
* Return payment transaction id.
*
* @return string
*/
public function getTransactionId()
{
return $this->getValue(self::PAYPAL_TRANSACTION_ID);
}
/**
* Return payment currency.
*
* @return string
*/
public function getCurrency()
{
return $this->getValue(self::MC_CURRENCY);
}
/**
* Return payment amount.
*
* @return string
*/
public function getAmount()
{
return $this->getValue(self::MC_GROSS);
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for do valid
*/
class ResponseDoVoid extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return authorization id.
*
* @return string
*/
public function getAuthorizationId()
{
return $this->getValue('AUTHORIZATIONID');
}
/**
* Return transaction id.
*
* @return string
*/
public function getCorrelationId()
{
return $this->getValue('CORRELATIONID');
}
}

View File

@@ -0,0 +1,196 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for get express checkout details
*/
class ResponseGetExpressCheckoutDetails extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return internal/system name of a shipping option.
*
* @return string
*/
public function getShippingOptionName()
{
return $this->getValue('SHIPPINGOPTIONNAME');
}
/**
* Return price amount.
*
* @return string
*/
public function getAmount()
{
return ( float ) $this->getValue('PAYMENTREQUEST_0_AMT');
}
/**
* Return payer id.
*
* @return string
*/
public function getPayerId()
{
return (string) $this->getValue('PAYERID');
}
/**
* Return email.
*
* @return string
*/
public function getEmail()
{
return $this->getValue('EMAIL');
}
/**
* Return first name.
*
* @return string
*/
public function getFirstName()
{
return $this->getValue('FIRSTNAME');
}
/**
* Return last name.
*
* @return string
*/
public function getLastName()
{
return $this->getValue('LASTNAME');
}
/**
* Return shipping street.
*
* @return string
*/
public function getShipToStreet()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTOSTREET');
}
/**
* Return shipping city.
*
* @return string
*/
public function getShipToCity()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTOCITY');
}
/**
* Return name.
*
* @return string
*/
public function getShipToName()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTONAME');
}
/**
* Return shipping country.
*
* @return string
*/
public function getShipToCountryCode()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE');
}
/**
* Return shipping state.
*
* @return string
*/
public function getShipToState()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTOSTATE');
}
/**
* Return shipping zip code.
*
* @return string
*/
public function getShipToZip()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTOZIP');
}
/**
* Return phone number.
* Note: PayPal returns a contact phone number only if your
* Merchant Account Profile settings require that the buyer enter one.
*
* @return string
*/
public function getShipToPhoneNumber()
{
$value = $this->getValue('PAYMENTREQUEST_0_SHIPTOPHONENUM');
$requiredAddressFields = oxNew(\OxidEsales\Eshop\Application\Model\RequiredAddressFields::class);
if (in_array('oxuser__oxfon', $requiredAddressFields->getRequiredFields())) {
$phone = $this->getValue('PHONENUM');
$value = !empty($phone) ? $phone : $value;
}
return $value;
}
/**
* Return second shipping street.
*
* @return string
*/
public function getShipToStreet2()
{
return $this->getValue('PAYMENTREQUEST_0_SHIPTOSTREET2');
}
/**
* Return salutation.
*
* @return string
*/
public function getSalutation()
{
return $this->getValue('SALUTATION');
}
/**
* Returns company.
*
* @return string
*/
public function getBusiness()
{
return $this->getValue('BUSINESS');
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model\Response;
/**
* PayPal response class for set express checkout
*/
class ResponseSetExpressCheckout extends \OxidEsales\PayPalModule\Model\Response\Response
{
/**
* Return token.
*
* @return string
*/
public function getToken()
{
return $this->getValue('TOKEN');
}
}

View File

@@ -0,0 +1,416 @@
<?php
/**
* This file is part of O3-Shop Paypal module.
*
* O3-Shop is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* O3-Shop is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with O3-Shop. If not, see <http://www.gnu.org/licenses/>
*
* @copyright Copyright (c) 2022 OXID eSales AG (https://www.oxid-esales.com)
* @copyright Copyright (c) 2022 O3-Shop (https://www.o3-shop.com)
* @license https://www.gnu.org/licenses/gpl-3.0 GNU General Public License 3 (GPLv3)
*/
namespace OxidEsales\PayPalModule\Model;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\Driver\Result;
use OxidEsales\Eshop\Core\Exception\StandardException as EshopStandardException;
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
use OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails;
/**
* PayPal oxUser class.
*
* @mixin \OxidEsales\Eshop\Application\Model\User
*/
class User extends User_parent
{
/**
* CallBack user mode
*
* @var bool
*/
protected $callBackUser = false;
/**
* Check if exist real user (with password) for passed email
*
* @param string $userEmail - email
*
* @return bool
*/
public function isRealPayPalUser($userEmail)
{
$db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
$query = "SELECT `oxid` FROM `oxuser` WHERE `oxusername` = " . $db->quote($userEmail) . " AND `oxpassword` != ''";
if (!\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('blMallUsers')) {
$query .= $this->getShopIdQueryPart();
}
if ($userId = $db->getOne($query)) {
return $userId;
}
return false;
}
/**
* Check if the shop user is the same as PayPal user.
* Fields: first name, last name, street, street nr, city - must be equal.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details - data returned from PayPal
*
* @return bool
*/
public function isSamePayPalUser($details)
{
$userData = array();
$userData[] = \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxfname->value);
$userData[] = \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxlname->value);
$compareData = array();
$compareData[] = $details->getFirstName();
$compareData[] = $details->getLastName();
return (($userData == $compareData) && $this->isSameAddressPayPalUser($details));
}
/**
* Check if the shop user address is the same in PayPal.
* Fields: street, street nr, city - must be equal.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details - data returned from PayPal
*
* @return bool
*/
public function isSameAddressPayPalUser($details)
{
$userData = array();
$userData[] = \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxstreet->value);
$userData[] = \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxstreetnr->value);
$userData[] = \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxcity->value);
$street = $this->splitShipToStreetPayPalUser($details->getShipToStreet());
$compareData = array();
$compareData[] = $street['street'];
$compareData[] = $street['streetnr'];
$compareData[] = $details->getShipToCity();
return $userData == $compareData;
}
/**
* Check if the shop user address user name is the same in PayPal.
* Fields: name, lname.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $details - data returned from PayPal
*
* @return bool
*/
public function isSameAddressUserPayPalUser($details)
{
$fullUserName = \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxfname->value) . ' ' . \OxidEsales\Eshop\Core\Str::getStr()->html_entity_decode($this->oxuser__oxlname->value);
return $fullUserName == $details->getShipToName();
}
/**
* Returns user from session associated with current PayPal order.
*
* @return bool
*/
public function loadUserPayPalUser()
{
$result = false;
if (($userId = \OxidEsales\Eshop\Core\Registry::getSession()->getVariable("oepaypal-userId"))) {
$result = $this->load($userId);
}
return $result;
}
/**
* Creates user from PayPal data.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $payPalData Data returned from PayPal.
*/
public function createPayPalUser($payPalData)
{
$userData = $this->prepareDataPayPalUser($payPalData);
$userId = $this->getIdByUserName($payPalData->getEmail());
if ($userId) {
$this->load($userId);
}
$this->oxuser__oxactive = new \OxidEsales\Eshop\Core\Field(1);
$this->oxuser__oxusername = new \OxidEsales\Eshop\Core\Field($payPalData->getEmail());
$this->oxuser__oxfname = new \OxidEsales\Eshop\Core\Field($userData['oxfname']);
$this->oxuser__oxlname = new \OxidEsales\Eshop\Core\Field($userData['oxlname']);
$this->oxuser__oxfon = new \OxidEsales\Eshop\Core\Field($userData['oxfon']);
$this->oxuser__oxsal = new \OxidEsales\Eshop\Core\Field($userData['oxsal']);
$this->oxuser__oxcompany = new \OxidEsales\Eshop\Core\Field($userData['oxcompany']);
$this->oxuser__oxstreet = new \OxidEsales\Eshop\Core\Field($userData['oxstreet']);
$this->oxuser__oxstreetnr = new \OxidEsales\Eshop\Core\Field($userData['oxstreetnr']);
$this->oxuser__oxcity = new \OxidEsales\Eshop\Core\Field($userData['oxcity']);
$this->oxuser__oxzip = new \OxidEsales\Eshop\Core\Field($userData['oxzip']);
$this->oxuser__oxcountryid = new \OxidEsales\Eshop\Core\Field($userData['oxcountryid']);
$this->oxuser__oxstateid = new \OxidEsales\Eshop\Core\Field($userData['oxstateid']);
$this->oxuser__oxaddinfo = new \OxidEsales\Eshop\Core\Field($userData['oxaddinfo']);
$this->oxuser__oxpassword = new \OxidEsales\Eshop\Core\Field('');
$this->oxuser__oxbirthdate = new \OxidEsales\Eshop\Core\Field('');
if ($this->save()) {
$this->_setAutoGroups($this->oxuser__oxcountryid->value);
// and adding to group "oxidnotyetordered"
$this->addToGroup("oxidnotyetordered");
}
}
/**
* Prepare address data array from PayPal response data.
*
* @param \OxidEsales\PayPalModule\Model\Response\ResponseGetExpressCheckoutDetails $payPalData PayPal data.
*
* @return array
*/
protected function prepareDataPayPalUser($payPalData)
{
$userData = array();
$fullName = oxNew(\OxidEsales\PayPalModule\Core\FullName::class, $payPalData->getShipToName());
$userData['oxfname'] = $fullName->getFirstName();
$userData['oxlname'] = $fullName->getLastName();
$street = $this->splitShipToStreetPayPalUser($payPalData->getShipToStreet());
$userData['oxstreet'] = $street['street'];
$userData['oxstreetnr'] = $street['streetnr'];
$userData['oxcity'] = $payPalData->getShipToCity();
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$countryId = $country->getIdByCode($payPalData->getShipToCountryCode());
$userData['oxcountryid'] = $countryId;
$stateId = '';
if ($payPalData->getShipToState()) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$stateId = $state->getIdByCode($payPalData->getShipToState(), $countryId);
}
$userData['oxstateid'] = $stateId;
$userData['oxzip'] = $payPalData->getShipToZip();
$userData['oxfon'] = $payPalData->getShipToPhoneNumber();
$userData['oxaddinfo'] = $payPalData->getShipToStreet2();
$userData['oxsal'] = $payPalData->getSalutation();
$userData['oxcompany'] = $payPalData->getBusiness();
return $userData;
}
/**
* Check required fields.
*
* @param array $addressData PayPal data.
*
* @return bool
*/
protected function checkRequiredFieldsPayPalUser($addressData)
{
$reqFields = \OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('aMustFillFields');
$result = true;
foreach ($reqFields as $field) {
if (strpos($field, 'oxuser__') === 0 && empty($addressData[str_replace('oxuser__', '', $field)])) {
return false;
}
}
return $result;
}
/**
* Split street nr from address.
*
* @param string $shipToStreet Address string.
*
* @return array
*/
protected function splitShipToStreetPayPalUser($shipToStreet)
{
$address = oxNew(\OxidEsales\Eshop\Application\Model\Address::class);
return $address->splitShipToStreetPayPalAddress($shipToStreet);
}
/**
* Returns true if user has callback state.
*
* @return bool
*/
public function isCallBackUserPayPalUser()
{
return $this->callBackUser;
}
/**
* Returns user group list.
*
* @param string $oxId oxId identifier.
*
* @return \OxidEsales\Eshop\Core\Model\ListModel
*/
public function getUserGroups($oxId = null)
{
if (!$this->isCallBackUserPayPalUser()) {
return parent::getUserGroups();
}
if (!$this->_oGroups) {
/** @var \OxidEsales\Eshop\Core\TableViewNameGenerator $viewNameGenerator */
$viewNameGenerator = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\TableViewNameGenerator::class);
$viewName = $viewNameGenerator->getViewName("oxgroups");
$select = "select {$viewName}.* from {$viewName} where ({$viewName}.oxid = 'oxidnotyetordered' OR {$viewName}.oxid = 'oxidnewcustomer')";
$this->_oGroups = oxNew(\OxidEsales\Eshop\Core\Model\ListModel::class, \OxidEsales\Eshop\Application\Model\Groups::class);
$this->_oGroups->selectString($select);
}
return $this->_oGroups;
}
/**
* Initializes call back user.
*
* @param array $payPalData Callback user data.
*/
public function initializeUserForCallBackPayPalUser($payPalData)
{
// setting mode..
$this->callBackUser = true;
// setting data..
$street = $this->splitShipToStreetPayPalUser($payPalData['SHIPTOSTREET']);
// setting object id as it is requested later while processing user object
$this->setId(\OxidEsales\Eshop\Core\UtilsObject::getInstance()->generateUID());
$this->oxuser__oxstreet = new \OxidEsales\Eshop\Core\Field($street['street']);
$this->oxuser__oxstreetnr = new \OxidEsales\Eshop\Core\Field($street['streetnr']);
$this->oxuser__oxcity = new \OxidEsales\Eshop\Core\Field($payPalData['SHIPTOCITY']);
$this->oxuser__oxzip = new \OxidEsales\Eshop\Core\Field($payPalData['SHIPTOZIP']);
$country = oxNew(\OxidEsales\Eshop\Application\Model\Country::class);
$countryId = $country->getIdByCode($payPalData["SHIPTOCOUNTRY"]);
$this->oxuser__oxcountryid = new \OxidEsales\Eshop\Core\Field($countryId);
$stateId = '';
if (isset($payPalData["SHIPTOSTATE"])) {
$state = oxNew(\OxidEsales\Eshop\Application\Model\State::class);
$stateId = $state->getIdByCode($payPalData["SHIPTOSTATE"], $countryId);
}
$this->oxuser__oxstateid = new \OxidEsales\Eshop\Core\Field($stateId);
}
public function setAnonymousUserId(string $userId): bool
{
$this->assign(
[
'OEPAYPAL_ANON_USERID' => $userId,
]
);
return (bool) $this->save();
}
public function getAnonymousId(string $userId): string
{
if (empty($userId)) {
return '';
}
$queryBuilder = ContainerFactory::getInstance()
->getContainer()
->get(QueryBuilderFactoryInterface::class)
->create();
$queryBuilder->select('oxuser.oxid')
->from('oxuser')
->where('(oxshopid = :shopid)')
->andWhere('(oxuser.OEPAYPAL_ANON_USERID = :userid)')
->setParameters([
':userid' => $userId,
':shopid' => \OxidEsales\Eshop\Core\Registry::getConfig()->getShopId()
]);
$result = $queryBuilder->execute()->fetch(FetchMode::COLUMN);
$id = $result ?: $userId;
return $id;
}
/**
* @param string $id
*
* @return bool
*/
public function load($id)
{
$result = true;
if (!parent::load($id)) {
$result = !empty($id) ? parent::load($this->getAnonymousId($id)) : false;
$this->setId($id);
$this->_isLoaded = false;
}
return $result;
}
public function hasNoInvoiceAddress(): bool
{
return $this->getFieldData('oxusername') === $this->_getMergedAddressFields();
}
public function setGroupsAfterUserCreation(): void
{
$this->_setAutoGroups($this->oxuser__oxcountryid->value);
// and adding to group "oxidnotyetordered"
$this->addToGroup("oxidnotyetordered");
}
public function setInvoiceDataFromPayPalResult(ResponseGetExpressCheckoutDetails $payPalData): void
{
//doublecheck
if (!$this->hasNoInvoiceAddress()) {
$exception = new EshopStandardException();
$exception->setMessage('OEPAYPAL_ERROR_USER_ADDRESS');
throw $exception;
}
$this->assign($this->prepareDataPayPalUser($payPalData));
$this->save();
$this->setGroupsAfterUserCreation();
}
/**
* Create query part for selecting by shopid.
*
* @return string
*/
protected function getShopIdQueryPart()
{
$db = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
return " AND `oxshopid` = " . $db->quote(\OxidEsales\Eshop\Core\Registry::getConfig()->getShopId());
}
}