Skip to content

Commit

Permalink
Afterpay Release v5.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
afterpayplugins committed Oct 18, 2023
1 parent 22b7e14 commit e836929
Show file tree
Hide file tree
Showing 26 changed files with 453 additions and 130 deletions.
10 changes: 10 additions & 0 deletions Api/Data/TokenInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace Afterpay\Afterpay\Api\Data;

interface TokenInterface
{
public const LOG_ID_FIELD = 'log_id';
public const ORDER_ID_FIELD = 'order_id';
public const TOKEN_FIELD = 'token';
public const EXPIRATION_DATE_FIELD = 'expiration_date';
}
7 changes: 6 additions & 1 deletion Controller/Express/PlaceOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,24 @@ class PlaceOrder implements HttpPostActionInterface
private PlaceOrderProcessor $placeOrderProcessor;
private CommandInterface $syncCheckoutDataCommand;
private StoreManagerInterface $storeManager;
private ManagerInterface $messageManager;

public function __construct(
RequestInterface $request,
Session $checkoutSession,
JsonFactory $jsonFactory,
PlaceOrderProcessor $placeOrderProcessor,
CommandInterface $syncCheckoutDataCommand,
StoreManagerInterface $storeManager
StoreManagerInterface $storeManager,
ManagerInterface $messageManager
) {
$this->request = $request;
$this->checkoutSession = $checkoutSession;
$this->jsonFactory = $jsonFactory;
$this->placeOrderProcessor = $placeOrderProcessor;
$this->syncCheckoutDataCommand = $syncCheckoutDataCommand;
$this->storeManager = $storeManager;
$this->messageManager = $messageManager;
}

public function execute()
Expand Down Expand Up @@ -74,6 +77,8 @@ public function execute()
]);
}

$this->messageManager->addSuccessMessage((string)__('Afterpay Transaction Completed.'));

return $jsonResult->setData(['redirectUrl' => $this->storeManager->getStore()->getUrl('checkout/onepage/success')]);
}
}
44 changes: 28 additions & 16 deletions Controller/Payment/Capture.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@

namespace Afterpay\Afterpay\Controller\Payment;

class Capture implements \Magento\Framework\App\Action\HttpGetActionInterface
use Afterpay\Afterpay\Model\Payment\Capture\PlaceOrderProcessor;
use Magento\Checkout\Model\Session;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\Result\RedirectFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Message\ManagerInterface;
use Magento\Payment\Gateway\CommandInterface;

class Capture implements HttpGetActionInterface
{
const CHECKOUT_STATUS_CANCELLED = 'CANCELLED';
const CHECKOUT_STATUS_SUCCESS = 'SUCCESS';

private \Magento\Framework\App\RequestInterface $request;
private \Magento\Checkout\Model\Session $session;
private \Magento\Framework\Controller\Result\RedirectFactory $redirectFactory;
private \Magento\Framework\Message\ManagerInterface $messageManager;
private \Afterpay\Afterpay\Model\Payment\Capture\PlaceOrderProcessor $placeOrderProcessor;
private \Magento\Payment\Gateway\CommandInterface $validateCheckoutDataCommand;
private RequestInterface $request;
private Session $session;
private RedirectFactory $redirectFactory;
private ManagerInterface $messageManager;
private PlaceOrderProcessor $placeOrderProcessor;
private CommandInterface $validateCheckoutDataCommand;

public function __construct(
\Magento\Framework\App\RequestInterface $request,
\Magento\Checkout\Model\Session $session,
\Magento\Framework\Controller\Result\RedirectFactory $redirectFactory,
\Magento\Framework\Message\ManagerInterface $messageManager,
\Afterpay\Afterpay\Model\Payment\Capture\PlaceOrderProcessor $placeOrderProcessor,
\Magento\Payment\Gateway\CommandInterface $validateCheckoutDataCommand
RequestInterface $request,
Session $session,
RedirectFactory $redirectFactory,
ManagerInterface $messageManager,
PlaceOrderProcessor $placeOrderProcessor,
CommandInterface $validateCheckoutDataCommand
) {
$this->request = $request;
$this->session = $session;
Expand All @@ -36,12 +44,14 @@ public function execute()
$this->messageManager->addErrorMessage(
(string)__('You have cancelled your Afterpay payment. Please select an alternative payment method.')
);

return $this->redirectFactory->create()->setPath('checkout/cart');
}
if ($this->request->getParam('status') != self::CHECKOUT_STATUS_SUCCESS) {
$this->messageManager->addErrorMessage(
(string)__('Afterpay payment is declined. Please select an alternative payment method.')
);

return $this->redirectFactory->create()->setPath('checkout/cart');
}

Expand All @@ -50,14 +60,16 @@ public function execute()
$afterpayOrderToken = $this->request->getParam('orderToken');
$this->placeOrderProcessor->execute($quote, $this->validateCheckoutDataCommand, $afterpayOrderToken);
} catch (\Throwable $e) {
$errorMessage = $e instanceof \Magento\Framework\Exception\LocalizedException
$errorMessage = $e instanceof LocalizedException
? $e->getMessage()
: (string)__('Afterpay payment is declined. Please select an alternative payment method.');
$this->messageManager->addErrorMessage($errorMessage);

return $this->redirectFactory->create()->setPath('checkout/cart');
}

$this->messageManager->addSuccessMessage((string)__('Afterpay Transaction Completed'));
$this->messageManager->addSuccessMessage((string)__('Afterpay Transaction Completed.'));

return $this->redirectFactory->create()->setPath('checkout/onepage/success');
}
}
2 changes: 1 addition & 1 deletion Model/Checks/PaymentMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class PaymentMethod implements PaymentMethodInterface
{
public function isAfterPayMethod(\Magento\Sales\Model\Order\Payment $payment): bool
public function isAfterPayMethod($payment): bool
{
return $payment->getMethod() == \Afterpay\Afterpay\Gateway\Config\Config::CODE;
}
Expand Down
8 changes: 6 additions & 2 deletions Model/Checks/PaymentMethodInterface.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<?php

namespace Afterpay\Afterpay\Model\Checks;

interface PaymentMethodInterface
{
public function isAfterPayMethod(\Magento\Sales\Model\Order\Payment $payment): bool;
/**
* @param \Magento\Sales\Api\Data\OrderPaymentInterface|\Magento\Quote\Api\Data\PaymentInterface $payment
*
* @return bool
*/
public function isAfterPayMethod($payment): bool;
}
6 changes: 3 additions & 3 deletions Model/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ public function websiteHasOwnConfig(int $websiteId): bool
return true;
}
$connection = $this->resourceConnection->getConnection();
$coreConfigData = $connection->getTableName('core_config_data');
$coreConfigData = $this->resourceConnection->getTableName('core_config_data');
$configsExistToCheck = array_merge(
\Afterpay\Afterpay\Observer\Adminhtml\ConfigSaveAfter::AFTERPAY_CONFIGS,
\Afterpay\Afterpay\Observer\Adminhtml\ConfigSaveAfter::CONFIGS_PATHS_TO_TRACK
Expand Down Expand Up @@ -555,9 +555,9 @@ public function setConsumerLendingMinAmount(string $value, int $scopeId = 0): se
return $this;
}

public function getConsumerLendingMinAmount(?int $scopeCode = null): bool
public function getConsumerLendingMinAmount(?int $scopeCode = null): float
{
return (bool)$this->scopeConfig->getValue(
return (float)$this->scopeConfig->getValue(
self::XML_PATH_CONSUMER_LENDING_MIN_AMOUNT,
ScopeInterface::SCOPE_WEBSITE,
$scopeCode
Expand Down
2 changes: 2 additions & 0 deletions Model/GraphQl/Resolver/AfterpayConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public function resolve(
$isEnabledCtaMinicart = $this->config->getIsEnableCtaMiniCart((int)$websiteId);
$isEnabledCtaCheckout = $this->config->getIsEnableCtaCartPage((int)$websiteId);
$publicId = $this->config->getPublicId((int)$websiteId);
$apiMode = $this->config->getApiMode((int)$websiteId);

return [
'max_amount' => $maxAmount,
Expand All @@ -48,6 +49,7 @@ public function resolve(
'is_enabled_cta_pdp' => $isEnabledCtaProductPage,
'is_enabled_cta_minicart' => $isEnabledCtaMinicart,
'is_enabled_cta_checkout' => $isEnabledCtaCheckout,
'api_mode' => $apiMode,
'mpid' => $publicId,
];
}
Expand Down
114 changes: 45 additions & 69 deletions Model/Order/CreditMemo/OrdersRetriever.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,76 @@

namespace Afterpay\Afterpay\Model\Order\CreditMemo;

use Afterpay\Afterpay\Model\Payment\AdditionalInformationInterface;
use Afterpay\Afterpay\Api\Data\TokenInterface;
use Afterpay\Afterpay\Model\ResourceModel\Token\CollectionFactory;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\Data\OrderPaymentInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\ResourceModel\Order\Collection;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollectionFactory;

class OrdersRetriever
{
private \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory;
private \Magento\Framework\App\ResourceConnection $resourceConnection;
private \Magento\Framework\Serialize\SerializerInterface $serializer;
private \Psr\Log\LoggerInterface $logger;
private OrderCollectionFactory $orderCollectionFactory;
private ResourceConnection $resourceConnection;
private CollectionFactory $tokensCollectionFactory;
private DateTime $dateTime;

public function __construct(
\Magento\Framework\Serialize\SerializerInterface $serializer,
\Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
\Magento\Framework\App\ResourceConnection $resourceConnection,
\Psr\Log\LoggerInterface $logger
OrderCollectionFactory $orderCollectionFactory,
ResourceConnection $resourceConnection,
CollectionFactory $tokensCollectionFactory,
DateTime $dateTime
) {
$this->serializer = $serializer;
$this->orderCollectionFactory = $orderCollectionFactory;
$this->resourceConnection = $resourceConnection;
$this->logger = $logger;
$this->tokensCollectionFactory = $tokensCollectionFactory;
$this->dateTime = $dateTime;
}

/**
* @return \Magento\Sales\Model\Order[]
* @return Order[]
*/
public function getAfterpayOrders(): array
{
$orderCollection = $this->orderCollectionFactory->create();
$orderCollection
$tokensCollection = $this->tokensCollectionFactory->create()
->addFieldToSelect(TokenInterface::ORDER_ID_FIELD)
->addFieldToFilter(TokenInterface::EXPIRATION_DATE_FIELD, ['notnull' => true])
->addFieldToFilter(
'state',
['eq' => \Magento\Sales\Model\Order::STATE_PROCESSING]
TokenInterface::EXPIRATION_DATE_FIELD,
[
'date' => true,
'from' => $this->dateTime->date('Y-m-d H:i:s', '-90 days'),
'to' => $this->dateTime->date('Y-m-d H:i:s')
]
);
$ids = $tokensCollection->getColumnValues(TokenInterface::ORDER_ID_FIELD);

$orderCollection = $this->orderCollectionFactory->create();
$orderCollection->addFieldToFilter(
OrderInterface::ENTITY_ID,
['in' => $ids]
)->addFieldToFilter(
OrderInterface::STATE,
['eq' => Order::STATE_PROCESSING]
);
$orderCollection = $this->joinAfterpayPaymentAdditionalInfo($orderCollection);
/** @var \Magento\Sales\Model\Order[] $items */
$items = $orderCollection->getItems();
$items = $this->getItemsWithAdditionalInfo($items);
return $items;
}

/**
* @var \Magento\Sales\Model\Order[] $items
* @return \Magento\Sales\Model\Order[]
*/
private function getItemsWithAdditionalInfo(array $items): array
{
$itemsWithJsonAdditionalInfo = [];
foreach ($items as $item) {
$additionalInformation = $item->getData(
\Magento\Sales\Api\Data\OrderPaymentInterface::ADDITIONAL_INFORMATION
);
try {
$unserializedInfo = $this->serializer->unserialize($additionalInformation);
if (!is_array($unserializedInfo)) {
continue;
}
/** @var array $unserializedInfo */
$item->setData(
\Magento\Sales\Api\Data\OrderPaymentInterface::ADDITIONAL_INFORMATION,
$unserializedInfo
);
$isAdditionalInfoFull =
isset($unserializedInfo[AdditionalInformationInterface::AFTERPAY_PAYMENT_STATE]) &&
isset($unserializedInfo[AdditionalInformationInterface::AFTERPAY_OPEN_TO_CAPTURE_AMOUNT]) &&
isset($unserializedInfo[AdditionalInformationInterface::AFTERPAY_AUTH_EXPIRY_DATE]);
if ($isAdditionalInfoFull) {
$itemsWithJsonAdditionalInfo[] = $item;
}
} catch (\InvalidArgumentException $e) {
$this->logger->warning($e->getMessage());
}
}
return $itemsWithJsonAdditionalInfo;
return $orderCollection->getItems();
}

private function joinAfterpayPaymentAdditionalInfo(
\Magento\Sales\Model\ResourceModel\Order\Collection $orderCollection
): \Magento\Sales\Model\ResourceModel\Order\Collection {
$salesOrderPaymentTable = $this->resourceConnection->getConnection()->getTableName('sales_order_payment');
Collection $orderCollection
): Collection {
$salesOrderPaymentTable = $this->resourceConnection->getTableName('sales_order_payment');
$orderCollection->join(
['sop' => $salesOrderPaymentTable],
'sop.parent_id = main_table.entity_id',
\Magento\Sales\Api\Data\OrderPaymentInterface::ADDITIONAL_INFORMATION
OrderPaymentInterface::ADDITIONAL_INFORMATION
);
$selectSql = $orderCollection->getSelectSql();
/** @var \Magento\Framework\DB\Select $selectSql */
$selectSql
->where(
'sop.method = ?',
\Afterpay\Afterpay\Gateway\Config\Config::CODE
)
->where(
'sop.additional_information like ?',
'%' . AdditionalInformationInterface::AFTERPAY_AUTH_EXPIRY_DATE . '%'
);

return $orderCollection;
}
}
25 changes: 25 additions & 0 deletions Model/Order/Payment/Auth/TokenSaver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php declare(strict_types=1);

namespace Afterpay\Afterpay\Model\Order\Payment\Auth;

use Afterpay\Afterpay\Model\ResourceModel\Token;
use Magento\Framework\Stdlib\DateTime;

class TokenSaver
{
private Token $tokensResource;
private DateTime $dateTime;

public function __construct(
Token $tokensResource,
DateTime $dateTime
) {
$this->tokensResource = $tokensResource;
$this->dateTime = $dateTime;
}

public function execute(int $orderId, string $token, ?string $expiryDate): bool
{
return (bool)$this->tokensResource->insertNewToken($orderId, $token, $this->dateTime->formatDate($expiryDate));
}
}
23 changes: 9 additions & 14 deletions Model/Order/Payment/Auth/TokenValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,24 @@

namespace Afterpay\Afterpay\Model\Order\Payment\Auth;

use Afterpay\Afterpay\Api\Data\CheckoutInterface;
use Afterpay\Afterpay\Gateway\Config\Config;
use Magento\Framework\App\ResourceConnection;
use Afterpay\Afterpay\Model\ResourceModel\Token;

class TokenValidator
{
private ResourceConnection $resourceConnection;
private array $results = [];
private Token $tokensResource;

public function __construct(ResourceConnection $resourceConnection)
public function __construct(Token $tokensResource)
{
$this->resourceConnection = $resourceConnection;
$this->tokensResource = $tokensResource;
}

public function checkIsUsed(string $token): bool
{
$salesOrderPaymentTable = $this->resourceConnection->getConnection()->getTableName('sales_order_payment');
$checkSelect = $this->resourceConnection->getConnection()->select()
->from($salesOrderPaymentTable)
->where('method = ?', Config::CODE)
->where('base_amount_paid_online IS NOT NULL')
->where('last_trans_id IS NOT NULL')
->where('additional_information like ?', '%"' . CheckoutInterface::AFTERPAY_TOKEN . '":"' . $token . '%');
if (!isset($this->results[$token])) {
$this->results[$token] = (bool)$this->tokensResource->selectByToken($token);
}

return (bool)$this->resourceConnection->getConnection()->fetchOne($checkSelect);
return $this->results[$token];
}
}
Loading

0 comments on commit e836929

Please sign in to comment.