Skip to content

Commit

Permalink
Merge pull request #184 from Invertus/release-1.2.3
Browse files Browse the repository at this point in the history
Release 1.2.3
  • Loading branch information
GytisZum authored Sep 17, 2024
2 parents 51bc5de + 9dfbcf2 commit e185635
Show file tree
Hide file tree
Showing 33 changed files with 680 additions and 342 deletions.
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,16 @@ e2e-1786-prepare:
# Run e2e tests in headless way.
e2eh1786: test-e2e-headless-1786
test-e2e-headless-1786:
make e2e1786p
make e2e1786p

prepare-zip:
rm -rf vendor && \
composer install --no-dev --optimize-autoloader && \
cp .github/.htaccess vendor/.htaccess && \
rm -rf .git .github tests cypress .docker && \
mkdir saferpayofficial && \
rsync -Rr ./ ./saferpayofficial && \
find . -maxdepth 1 ! -name saferpayofficial -exec mv {} saferpayofficial/ \; && \
find . -maxdepth 1 -type f -exec rm "{}" \; && \
cd saferpayofficial && rm -rf saferpayofficial && \
cd ../ && zip -r saferpayofficial.zip saferpayofficial/
7 changes: 7 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,10 @@
- FO : Confirmation email after order authorization fix
- BO : Order confirmation email setting removed
- BO : Security improvements

- ## [1.2.3] - *
- FO : Increased API version to 1.40
- FO : WeChat Pay payment method added
- FO : AccountToAccount Pay payment method added
- BO : Security improvements
- BO : Bug fixes and improvements
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@
},
"author": "PrestaShop",
"license": "AFL-3.0"
}
}
75 changes: 75 additions & 0 deletions controllers/front/ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Invertus\SaferPay\Controller\Front\CheckoutController;
use Invertus\SaferPay\Core\Payment\DTO\CheckoutData;
use Invertus\SaferPay\Enum\ControllerName;
use Invertus\SaferPay\Repository\SaferPayOrderRepository;

if (!defined('_PS_VERSION_')) {
exit;
Expand All @@ -43,7 +44,81 @@ public function postProcess()
case 'submitHostedFields':
$this->submitHostedFields();
break;
case 'getStatus':
$this->processGetStatus();
break;
}
}

/**
* @throws PrestaShopDatabaseException
* @throws PrestaShopException
*/
protected function processGetStatus()
{
header('Content-Type: application/json;charset=UTF-8');
/** @var SaferPayOrderRepository $saferPayOrderRepository */
$saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class);
$cartId = Tools::getValue('cartId');
$secureKey = Tools::getValue('secureKey');
$isBusinessLicence = (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE);
$fieldToken = Tools::getValue('fieldToken');
$moduleId = $this->module->id;
$selectedCard = Tools::getValue('selectedCard');
$saferPayOrderId = $saferPayOrderRepository->getIdByCartId($cartId);
$saferPayOrder = new SaferPayOrder($saferPayOrderId);

if (!$saferPayOrder->id || $saferPayOrder->canceled) {
$this->ajaxDie(json_encode([
'isFinished' => true,
'href' => $this->getFailControllerLink($cartId, $secureKey, $moduleId)
]));
}

$this->ajaxDie(json_encode([
'saferpayOrder' => json_encode($saferPayOrder),
'isFinished' => $saferPayOrder->authorized || $saferPayOrder->captured || $saferPayOrder->pending,
'href' => $this->context->link->getModuleLink(
$this->module->name,
$this->getSuccessControllerName($isBusinessLicence, $fieldToken),
[
'cartId' => $cartId,
'orderId' => $saferPayOrder->id_order,
'moduleId' => $moduleId,
'secureKey' => $secureKey,
'selectedCard' => $selectedCard,
]
)
]));
}

private function getFailControllerLink($cartId, $secureKey, $moduleId)
{
return $this->context->link->getModuleLink(
$this->module->name,
ControllerName::FAIL,
[
'cartId' => $cartId,
'secureKey' => $secureKey,
'moduleId' => $moduleId,
],
true
);
}

private function getSuccessControllerName($isBusinessLicence, $fieldToken)
{
$successController = ControllerName::SUCCESS;

if ($isBusinessLicence) {
$successController = ControllerName::SUCCESS_IFRAME;
}

if ($fieldToken) {
$successController = ControllerName::SUCCESS_HOSTED;
}

return $successController;
}

private function submitHostedFields()
Expand Down
156 changes: 96 additions & 60 deletions controllers/front/notify.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
use Invertus\SaferPay\Api\Enum\TransactionStatus;
use Invertus\SaferPay\Config\SaferPayConfig;
use Invertus\SaferPay\Controller\AbstractSaferPayController;
use Invertus\SaferPay\Core\Order\Action\UpdateOrderStatusAction;
use Invertus\SaferPay\Core\Order\Action\UpdateSaferPayOrderAction;
use Invertus\SaferPay\Core\Payment\DTO\CheckoutData;
use Invertus\SaferPay\Processor\CheckoutProcessor;
use Invertus\SaferPay\Repository\SaferPayOrderRepository;
Expand All @@ -39,7 +37,6 @@
class SaferPayOfficialNotifyModuleFrontController extends AbstractSaferPayController
{
const FILENAME = 'notify';
const SAFERPAY_ORDER_AUTHORIZE_ACTION = 'AUTHORIZE';

/**
* This code is being called by SaferPay by using NotifyUrl in InitializeRequest.
Expand All @@ -50,7 +47,6 @@ public function postProcess()
{
$cartId = Tools::getValue('cartId');
$secureKey = Tools::getValue('secureKey');

$cart = new Cart($cartId);

if (!Validate::isLoadedObject($cart)) {
Expand All @@ -70,76 +66,49 @@ public function postProcess()
$secureKey
));

if (!$lockResult->isSuccessful()) {
die($this->module->l('Lock already exist', self::FILENAME));
if (!SaferPayConfig::isVersion17()) {
if ($lockResult > 200) {
die($this->module->l('Lock already exists', self::FILENAME));
}
} else {
if (!$lockResult->isSuccessful()) {
die($this->module->l('Lock already exists', self::FILENAME));
}
}

if ($cart->orderExists()) {
if (method_exists('Order', 'getIdByCartId')) {
$orderId = Order::getIdByCartId($cartId);
} else {
// For PrestaShop 1.6 use the alternative method
$orderId = Order::getOrderByCartId($cartId);
}

$order = new Order($orderId);
$order = new Order($this->getOrderId($cartId));
$completed = (int) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_COMPLETED);

$saferPayAuthorizedStatus = (int) Configuration::get(\Invertus\SaferPay\Config\SaferPayConfig::SAFERPAY_PAYMENT_AUTHORIZED);
$saferPayCapturedStatus = (int) Configuration::get(\Invertus\SaferPay\Config\SaferPayConfig::SAFERPAY_PAYMENT_COMPLETED);

if ((int) $order->current_state === $saferPayAuthorizedStatus || (int) $order->current_state === $saferPayCapturedStatus) {
die($this->module->l('Order already created', self::FILENAME));
if ((int) $order->current_state === $completed) {
die($this->module->l('Order already complete', self::FILENAME));
}
}

/** @var SaferPayOrderRepository $saferPayOrderRepository */
$saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class);

try {
$assertResponseBody = $this->assertTransaction($cartId);
$transactionStatus = $assertResponseBody->getTransaction()->getStatus();

/** @var CheckoutProcessor $checkoutProcessor **/
$checkoutProcessor = $this->module->getService(CheckoutProcessor::class);
$checkoutData = CheckoutData::create(
(int) $cart->id,
$assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(),
(int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE)
);

/** @var SaferPayOrderRepository $saferPayOrderRepository */
$saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class);
$saferPayOrderId = $saferPayOrderRepository->getIdByCartId($cartId);
$checkoutData->setOrderStatus($transactionStatus);
$checkoutProcessor->run($checkoutData);

/** @var UpdateSaferPayOrderAction $updateSaferPayOrderAction */
$updateSaferPayOrderAction = $this->module->getService(UpdateSaferPayOrderAction::class);
$updateSaferPayOrderAction->run(new SaferPayOrder($saferPayOrderId), self::SAFERPAY_ORDER_AUTHORIZE_ACTION);

// If order does not exist but assertion is valid that means order authorized or captured.
if (method_exists('Order', 'getIdByCartId')) {
$orderId = Order::getIdByCartId($cartId);
} else {
// For PrestaShop 1.6 use the alternative method
$orderId = Order::getOrderByCartId($cartId);
}
if (!$orderId) {
/** @var CheckoutProcessor $checkoutProcessor **/
$checkoutProcessor = $this->module->getService(CheckoutProcessor::class);
$checkoutData = CheckoutData::create(
(int) $cart->id,
$assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(),
(int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE)
);

$checkoutData->setIsAuthorizedOrder(true);
$checkoutData->setOrderStatus($assertResponseBody->getTransaction()->getStatus());

$checkoutProcessor->run($checkoutData);

if (method_exists('Order', 'getIdByCartId')) {
$orderId = Order::getIdByCartId($cartId);
} else {
// For PrestaShop 1.6 or lower, use the alternative method
$orderId = Order::getOrderByCartId($cartId);
}
}
$orderId = $this->getOrderId($cartId);

//TODO look into pipeline design pattern to use when object is modified in multiple places to avoid this issue.
//NOTE must be left below assert action to get newest information.
$order = new Order($orderId);

/** @var UpdateOrderStatusAction $updateOrderStatusAction **/
$updateOrderStatusAction = $this->module->getService(UpdateOrderStatusAction::class);
$updateOrderStatusAction->run((int) $orderId, (int) Configuration::get('SAFERPAY_PAYMENT_AUTHORIZED'));

if (!$assertResponseBody->getLiability()->getLiabilityShift() &&
in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) &&
(int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D) === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL
Expand All @@ -153,15 +122,65 @@ public function postProcess()

//NOTE to get latest information possible and not override new information.
$order = new Order($orderId);
$paymentMethod = $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod();

// if payment does not support order capture, it means it always auto-captures it (at least with accountToAccount payment),
// so in this case if status comes back "captured" we just update the order state accordingly
if (!SaferPayConfig::supportsOrderCapture($paymentMethod) &&
$transactionStatus === TransactionStatus::CAPTURED
) {
/** @var SaferPayOrderStatusService $orderStatusService */
$orderStatusService = $this->module->getService(SaferPayOrderStatusService::class);
$orderStatusService->setComplete($order);

if ((int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE &&
$assertResponseBody->getTransaction()->getStatus() !== TransactionStatus::CAPTURED
return;
}

if (SaferPayConfig::supportsOrderCapture($paymentMethod) &&
(int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE &&
$transactionStatus !== TransactionStatus::CAPTURED
) {
/** @var SaferPayOrderStatusService $orderStatusService */
$orderStatusService = $this->module->getService(SaferPayOrderStatusService::class);
$orderStatusService->capture($order);
}
} catch (Exception $e) {
// this might be executed after pending transaction is declined (e.g. with accountToAccount payment)
if (!isset($order)) {
$order = new Order($this->getOrderId($cartId));
}

$orderId = (int) $order->id;

if ($orderId) {
$saferPayCapturedStatus = (int) Configuration::get(\Invertus\SaferPay\Config\SaferPayConfig::SAFERPAY_PAYMENT_COMPLETED);

if ((int) $order->current_state === $saferPayCapturedStatus) {
die($this->module->l('Order already created', self::FILENAME));
}

// assuming order transaction was declined
$order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZATION_FAILED_);
}

// using cartId, because ps order might not be assigned yet
$saferPayOrder = new SaferPayOrder($saferPayOrderRepository->getIdByCartId($cartId));

if ($saferPayOrder->id) {
$saferPayOrder->authorized = false;
$saferPayOrder->pending = false;
$saferPayOrder->canceled = true;

if ($orderId) {
// assign ps order to saferpay order id in case it was not assigned previously
$saferPayOrder->id_order = $orderId;
}

$saferPayOrder->update();
$this->releaseLock();
die('canceled');
}

PrestaShopLogger::addLog(
sprintf(
'%s has caught an error: %s',
Expand All @@ -174,6 +193,8 @@ public function postProcess()
null,
true
);
$this->releaseLock();

die($this->module->l($e->getMessage(), self::FILENAME));
}

Expand All @@ -187,6 +208,21 @@ private function assertTransaction($cartId) {
return $transactionAssert->assert($cartId);
}

/**
* @param int $cartId
*
* @return bool|int
*/
private function getOrderId($cartId)
{
if (method_exists('Order', 'getIdByCartId')) {
return Order::getIdByCartId($cartId);
} else {
// For PrestaShop 1.6 use the alternative method
return Order::getOrderByCartId($cartId);
}
}

protected function displayMaintenancePage()
{
return true;
Expand Down
8 changes: 4 additions & 4 deletions controllers/front/pendingNotify.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*@license SIX Payment Services
*/

use Invertus\SaferPay\Config\SaferPayConfig;
use Invertus\SaferPay\Api\Enum\TransactionStatus;
use Invertus\SaferPay\Controller\AbstractSaferPayController;
use Invertus\SaferPay\DTO\Response\AssertRefund\AssertRefundBody;
use Invertus\SaferPay\Repository\SaferPayOrderRepository;
Expand Down Expand Up @@ -57,12 +57,12 @@ public function postProcess()

$orderRefunds = $saferPayOrderRepository->getOrderRefunds($saferPayOrderId);
foreach ($orderRefunds as $orderRefund) {
if ($orderRefund['status'] === SaferPayConfig::TRANSACTION_STATUS_CAPTURED) {
if ($orderRefund['status'] === TransactionStatus::CAPTURED) {
continue;
}

$assertRefundResponse = $this->assertRefundTransaction($orderRefund['transaction_id']);
if ($assertRefundResponse->getStatus() === SaferPayConfig::TRANSACTION_STATUS_CAPTURED) {
if ($assertRefundResponse->getStatus() === TransactionStatus::CAPTURED) {
$this->handleCapturedRefund($orderRefund['id_saferpay_order_refund']);
}
}
Expand Down Expand Up @@ -90,7 +90,7 @@ private function handleCapturedRefund($orderRefundId)
$saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class);

$orderRefund = new SaferPayOrderRefund($orderRefundId);
$orderRefund->status = SaferPayConfig::TRANSACTION_STATUS_CAPTURED;
$orderRefund->status = TransactionStatus::CAPTURED;
$orderRefund->update();

$orderAssertId = $saferPayOrderRepository->getAssertIdBySaferPayOrderId($orderRefund->id_saferpay_order);
Expand Down
Loading

0 comments on commit e185635

Please sign in to comment.