Skip to content

Commit

Permalink
Merge pull request #205 from Invertus/SL-219/just-saving
Browse files Browse the repository at this point in the history
SL-219 Fixed credit card saving
  • Loading branch information
MarijusCoding authored Oct 8, 2024
2 parents dc2ea31 + 2a2b76d commit 4567d34
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 82 deletions.
125 changes: 71 additions & 54 deletions controllers/front/return.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public function postProcess()
$cartId = (int) Tools::getValue('cartId');
$order = new Order($this->getOrderId($cartId));
$secureKey = Tools::getValue('secureKey');
$selectedCard = Tools::getValue('selectedCard');

$cart = new Cart($cartId);

if (!Validate::isLoadedObject($cart)) {
Expand All @@ -69,7 +71,12 @@ public function postProcess()
$transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class);

try {
$assertResponseBody = $transactionAssert->assert($cartId);
$assertResponseBody = $transactionAssert->assert(
$cartId,
(int) $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE,
$selectedCard,
(int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE)
);
$transactionStatus = $assertResponseBody->getTransaction()->getStatus();
} catch (Exception $e) {
\PrestaShopLogger::addLog($e->getMessage());
Expand All @@ -80,57 +87,12 @@ public function postProcess()
/**
* NOTE: This flow is for hosted iframe payment method
*/
if (Tools::getValue('isBusinessLicence')) {
if (
Configuration::get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::getConfigSuffix())
|| Configuration::get(SaferPayConfig::FIELDS_ACCESS_TOKEN . SaferPayConfig::getConfigSuffix())
) {
try {
/** @var CheckoutProcessor $checkoutProcessor * */
$checkoutProcessor = $this->module->getService(CheckoutProcessor::class);

$checkoutData = CheckoutData::create(
(int) $cartId,
$assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(),
(int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE)
);
$checkoutData->setOrderStatus($transactionStatus);

$checkoutProcessor->run($checkoutData);

$orderId = $this->getOrderId($cartId);

$order = new Order($orderId);
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
) {
/** @var SaferPayOrderStatusService $orderStatusService */
$orderStatusService = $this->module->getService(SaferPayOrderStatusService::class);
$orderStatusService->cancel($order);
}

//NOTE to get latest information possible and not override new information.

$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);

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);

return;
}
$this->createAndValidateOrder($assertResponseBody, $transactionStatus, $cartId);
} catch (Exception $e) {
\PrestaShopLogger::addLog($e->getMessage());
$this->warning[] = $this->module->l('An error occurred. Please contact support', self::FILENAME);
Expand Down Expand Up @@ -208,10 +170,12 @@ public function initContent()
$saferPayAuthorizedStatus = (int) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_AUTHORIZED);
$saferPayCapturedStatus = (int) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_COMPLETED);

$usingSavedCard = $selectedCard > 0;

if ((int) $order->current_state === $saferPayAuthorizedStatus || (int) $order->current_state === $saferPayCapturedStatus) {
Tools::redirect($this->context->link->getModuleLink(
$this->module->name,
$this->getSuccessControllerName($isBusinessLicence, $fieldToken),
$this->getSuccessControllerName($isBusinessLicence, $fieldToken, $usingSavedCard),
[
'cartId' => $cartId,
'orderId' => $orderId,
Expand Down Expand Up @@ -246,15 +210,15 @@ public function initContent()
$this->setTemplate('saferpay_wait_16.tpl');
}

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

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

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

Expand Down Expand Up @@ -312,4 +276,57 @@ private function getRedirectionToControllerUrl($controllerName)
]
);
}

private function createAndValidateOrder($assertResponseBody, $transactionStatus, $cartId)
{
/** @var CheckoutProcessor $checkoutProcessor * */
$checkoutProcessor = $this->module->getService(CheckoutProcessor::class);

$checkoutData = CheckoutData::create(
(int) $cartId,
$assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(),
(int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE)
);
$checkoutData->setOrderStatus($transactionStatus);

$checkoutProcessor->run($checkoutData);

$orderId = $this->getOrderId($cartId);

$order = new Order($orderId);
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
) {
/** @var SaferPayOrderStatusService $orderStatusService */
$orderStatusService = $this->module->getService(SaferPayOrderStatusService::class);
$orderStatusService->cancel($order);
}

//NOTE to get latest information possible and not override new information.

$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);

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);

return;
}
}
}
5 changes: 5 additions & 0 deletions controllers/front/successIFrame.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public function postProcess() // todo refactor this by the logic provided
$this->redirectWithNotifications($this->getOrderLink());
}

/** Purchase is made with card that needs to be saved */
if (Tools::getValue('selectedCard') <= 0) {
return;
}

try {
$logger->debug(sprintf('%s - Controller action ended', self::FILE_NAME));

Expand Down
28 changes: 18 additions & 10 deletions src/Api/Request/AssertService.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
namespace Invertus\SaferPay\Api\Request;

use Exception;
use Invertus\SaferPay\Adapter\Configuration;
use Invertus\SaferPay\Api\ApiRequest;
use Invertus\SaferPay\Config\SaferPayConfig;
use Invertus\SaferPay\Core\Payment\DTO\CheckoutData;
use Invertus\SaferPay\DTO\Request\Assert\AssertRequest;
use Invertus\SaferPay\DTO\Response\Assert\AssertBody;
use Invertus\SaferPay\EntityBuilder\SaferPayAssertBuilder;
use Invertus\SaferPay\EntityBuilder\SaferPayCardAliasBuilder;
use Invertus\SaferPay\Exception\Api\SaferPayApiException;
use Invertus\SaferPay\Service\Response\AssertResponseObjectCreator;
use SaferPayOrder;
Expand All @@ -54,15 +58,18 @@ class AssertService
* @var SaferPayAssertBuilder
*/
private $assertBuilder;
private $aliasBuilder;

public function __construct(
ApiRequest $apiRequest,
AssertResponseObjectCreator $assertResponseObjectCreator,
SaferPayAssertBuilder $assertBuilder
SaferPayAssertBuilder $assertBuilder,
SaferPayCardAliasBuilder $aliasBuilder
) {
$this->apiRequest = $apiRequest;
$this->assertResponseObjectCreator = $assertResponseObjectCreator;
$this->assertBuilder = $assertBuilder;
$this->aliasBuilder = $aliasBuilder;
}

/**
Expand All @@ -72,17 +79,13 @@ public function __construct(
* @return object|null
* @throws \Exception
*/
public function assert(AssertRequest $assertRequest, $saferPayOrderId)
public function assert(AssertRequest $assertRequest, $isBusiness)
{
$saferPayOrder = new SaferPayOrder($saferPayOrderId);

$assertApi = self::ASSERT_API_PAYMENT;

//TODO: refactor this to use authorize request.
// naming is weird. With transaction, we do a request to an authorize endpoint but name it assert ?
// also we call authorize method in some of the success controllers, so if we leave the logic here,
// we get an error with TRANSACTION_IN_WRONG_STATE
if ($saferPayOrder->is_transaction) {
$isBusinessLicense = \Configuration::get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::getConfigSuffix());

if ($isBusiness) {
$assertApi = self::ASSERT_API_TRANSACTION;
}

Expand All @@ -103,10 +106,15 @@ public function assert(AssertRequest $assertRequest, $saferPayOrderId)
* @return AssertBody
* @throws Exception
*/
public function createObjectsFromAssertResponse($responseBody, $saferPayOrderId)
public function createObjectsFromAssertResponse($responseBody, $saferPayOrderId, $customerId, $selectedCardOption)
{
$assertBody = $this->assertResponseObjectCreator->createAssertObject($responseBody);
$this->assertBuilder->createAssert($assertBody, $saferPayOrderId);
$isPaymentSafe = $assertBody->getLiability()->getLiabilityShift();

if ((int) $selectedCardOption === SaferPayConfig::CREDIT_CARD_OPTION_SAVE && $isPaymentSafe) {
$this->aliasBuilder->createCardAlias($assertBody, $customerId);
}

return $assertBody;
}
Expand Down
9 changes: 8 additions & 1 deletion src/DTO/Request/Assert/AssertRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,16 @@ class AssertRequest
* @var string
*/
private $token;
private $saveCard;

public function __construct(
RequestHeader $requestHeader,
$token
$token,
$saveCard
) {
$this->requestHeader = $requestHeader;
$this->token = $token;
$this->saveCard = $saveCard;
}

public function getAsArray()
Expand All @@ -65,6 +68,10 @@ public function getAsArray()
'Token' => $this->token,
];

if ($this->saveCard) {
$return['RegisterAlias'] = [ 'IdGenerator' => 'RANDOM_UNIQUE'];
}

return $return;
}
}
4 changes: 2 additions & 2 deletions src/Service/Request/AssertRequestObjectCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public function __construct(
*
* @return AssertRequest
*/
public function create($token)
public function create($token, $saveCard)
{
$requestHeader = $this->requestObjectCreator->createRequestHeader();

return new AssertRequest($requestHeader, $token);
return new AssertRequest($requestHeader, $token, $saveCard);
}
}
13 changes: 9 additions & 4 deletions src/Service/TransactionFlow/SaferPayTransactionAssertion.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
namespace Invertus\SaferPay\Service\TransactionFlow;

use Invertus\SaferPay\Api\Request\AssertService;
use Invertus\SaferPay\Config\SaferPayConfig;
use Invertus\SaferPay\DTO\Response\Assert\AssertBody;
use Invertus\SaferPay\Logger\LoggerInterface;
use Invertus\SaferPay\Repository\SaferPayOrderRepository;
Expand Down Expand Up @@ -74,8 +75,10 @@ public function __construct(
* @return AssertBody
* @throws \Exception
*/
public function assert($cartId, $update = true)
public function assert($cartId, $saveCard = null, $selectedCard = null, $isBusiness = 0, $update = true)
{
$cart = new \Cart($cartId);

$saferPayOrder = new SaferPayOrder($this->orderRepository->getIdByCartId($cartId));

$this->logger->debug(sprintf('%s - assert service called',self::FILE_NAME), [
Expand All @@ -85,16 +88,18 @@ public function assert($cartId, $update = true)
],
]);

$assertRequest = $this->assertRequestCreator->create($saferPayOrder->token);
$assertResponse = $this->assertionService->assert($assertRequest, $saferPayOrder->id);
$assertRequest = $this->assertRequestCreator->create($saferPayOrder->token, $saveCard);
$assertResponse = $this->assertionService->assert($assertRequest, $isBusiness);

if (empty($assertResponse)) {
return null;
}

$assertBody = $this->assertionService->createObjectsFromAssertResponse(
$assertResponse,
$saferPayOrder->id
$saferPayOrder->id,
$cart->id_customer,
$selectedCard
);

// assertion shouldn't update, this is quickfix for what seems to be a general flaw in structure
Expand Down
1 change: 1 addition & 0 deletions src/ServiceProvider/BaseServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use Invertus\SaferPay\Logger\Logger;
use Invertus\SaferPay\Logger\LoggerInterface;
use Invertus\SaferPay\Provider\BasicIdempotencyProvider;
use Invertus\SaferPay\Provider\CurrentPaymentTypeProvider;
use Invertus\SaferPay\Provider\IdempotencyProviderInterface;
use Invertus\SaferPay\Repository\OrderRepository;
use Invertus\SaferPay\Repository\OrderRepositoryInterface;
Expand Down
9 changes: 0 additions & 9 deletions views/js/front/hosted-templates/hosted_fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ $(document).ready(function () {
$('[id="payment-form"]').on('submit', function (event) {
event.preventDefault();

var paymentType = $(this).find("[name=saferpayPaymentType]").val();

//NOTE: if it's not a hosted iframe then we don't need to submitHostedFields.
if (paymentType !== saferpay_payment_types.hosted_iframe) {
event.target.submit();

return;
}

var selectedCardMethod = $(this).find("[name=saved_card_method]").val();

var selectedCard = $(this).find("[name=selectedCreditCard_" + selectedCardMethod + "]").val();
Expand Down
2 changes: 1 addition & 1 deletion views/templates/front/credit_cards.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</tr>
</thead>
{foreach $rows as $row}
{$row|escape:'htmlall':'UTF-8'|nofilter}
{$row|cleanHtml nofilter}
{/foreach}
</table>
</div>
Expand Down
2 changes: 1 addition & 1 deletion views/templates/front/credit_cards_16.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</tr>
</thead>
{foreach $rows as $row}
{$row|escape:'htmlall':'UTF-8'|nofilter}
{$row|cleanHtml nofilter}
{/foreach}
</table>
</div>

0 comments on commit 4567d34

Please sign in to comment.