Skip to content

Commit fd7c82c

Browse files
Afterpay Release v4.2.1
1 parent aa76a3a commit fd7c82c

File tree

24 files changed

+454
-128
lines changed

24 files changed

+454
-128
lines changed

Api/Data/TokenInterface.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
namespace Afterpay\Afterpay\Api\Data;
3+
4+
interface TokenInterface
5+
{
6+
public const LOG_ID_FIELD = 'log_id';
7+
public const ORDER_ID_FIELD = 'order_id';
8+
public const TOKEN_FIELD = 'token';
9+
public const EXPIRATION_DATE_FIELD = 'expiration_date';
10+
}

Controller/Express/PlaceOrder.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,24 @@ class PlaceOrder implements HttpPostActionInterface
2121
private $placeOrderProcessor;
2222
private $syncCheckoutDataCommand;
2323
private $storeManager;
24+
private $messageManager;
2425

2526
public function __construct(
2627
RequestInterface $request,
2728
Session $checkoutSession,
2829
JsonFactory $jsonFactory,
2930
PlaceOrderProcessor $placeOrderProcessor,
3031
CommandInterface $syncCheckoutDataCommand,
31-
StoreManagerInterface $storeManager
32+
StoreManagerInterface $storeManager,
33+
ManagerInterface $messageManager
3234
) {
3335
$this->request = $request;
3436
$this->checkoutSession = $checkoutSession;
3537
$this->jsonFactory = $jsonFactory;
3638
$this->placeOrderProcessor = $placeOrderProcessor;
3739
$this->syncCheckoutDataCommand = $syncCheckoutDataCommand;
3840
$this->storeManager = $storeManager;
41+
$this->messageManager = $messageManager;
3942
}
4043

4144
public function execute()
@@ -74,6 +77,8 @@ public function execute()
7477
]);
7578
}
7679

80+
$this->messageManager->addSuccessMessage((string)__('Afterpay Transaction Completed.'));
81+
7782
return $jsonResult->setData(['redirectUrl' => $this->storeManager->getStore()->getUrl('checkout/onepage/success')]);
7883
}
7984
}

Controller/Payment/Capture.php

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,20 @@
22

33
namespace Afterpay\Afterpay\Controller\Payment;
44

5-
class Capture implements \Magento\Framework\App\Action\HttpGetActionInterface
5+
use Afterpay\Afterpay\Model\Payment\Capture\PlaceOrderProcessor;
6+
use Magento\Checkout\Model\Session;
7+
use Magento\Framework\App\Action\HttpGetActionInterface;
8+
use Magento\Framework\App\RequestInterface;
9+
use Magento\Framework\Controller\Result\RedirectFactory;
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\Message\ManagerInterface;
12+
use Magento\Payment\Gateway\CommandInterface;
13+
use Magento\Store\Model\StoreManagerInterface;
14+
15+
class Capture implements HttpGetActionInterface
616
{
717
const CHECKOUT_STATUS_CANCELLED = 'CANCELLED';
818
const CHECKOUT_STATUS_SUCCESS = 'SUCCESS';
9-
1019
private $request;
1120
private $session;
1221
private $redirectFactory;
@@ -16,13 +25,13 @@ class Capture implements \Magento\Framework\App\Action\HttpGetActionInterface
1625
private $storeManager;
1726

1827
public function __construct(
19-
\Magento\Framework\App\RequestInterface $request,
20-
\Magento\Checkout\Model\Session $session,
21-
\Magento\Framework\Controller\Result\RedirectFactory $redirectFactory,
22-
\Magento\Framework\Message\ManagerInterface $messageManager,
23-
\Afterpay\Afterpay\Model\Payment\Capture\PlaceOrderProcessor $placeOrderProcessor,
24-
\Magento\Payment\Gateway\CommandInterface $validateCheckoutDataCommand,
25-
\Magento\Store\Model\StoreManagerInterface $storeManager
28+
RequestInterface $request,
29+
Session $session,
30+
RedirectFactory $redirectFactory,
31+
ManagerInterface $messageManager,
32+
PlaceOrderProcessor $placeOrderProcessor,
33+
CommandInterface $validateCheckoutDataCommand,
34+
StoreManagerInterface $storeManager
2635
) {
2736
$this->request = $request;
2837
$this->session = $session;
@@ -39,6 +48,7 @@ public function execute()
3948
$this->messageManager->addErrorMessage(
4049
(string)__('You have cancelled your Afterpay payment. Please select an alternative payment method.')
4150
);
51+
4252
return $this->redirectFactory->create()->setPath('checkout/cart', [
4353
'_scope' => $this->storeManager->getStore()
4454
]);
@@ -47,6 +57,7 @@ public function execute()
4757
$this->messageManager->addErrorMessage(
4858
(string)__('Afterpay payment is declined. Please select an alternative payment method.')
4959
);
60+
5061
return $this->redirectFactory->create()->setPath('checkout/cart', [
5162
'_scope' => $this->storeManager->getStore()
5263
]);
@@ -57,16 +68,18 @@ public function execute()
5768
$afterpayOrderToken = $this->request->getParam('orderToken');
5869
$this->placeOrderProcessor->execute($quote, $this->validateCheckoutDataCommand, $afterpayOrderToken);
5970
} catch (\Throwable $e) {
60-
$errorMessage = $e instanceof \Magento\Framework\Exception\LocalizedException
71+
$errorMessage = $e instanceof LocalizedException
6172
? $e->getMessage()
6273
: (string)__('Afterpay payment is declined. Please select an alternative payment method.');
6374
$this->messageManager->addErrorMessage($errorMessage);
75+
6476
return $this->redirectFactory->create()->setPath('checkout/cart', [
6577
'_scope' => $this->storeManager->getStore()
6678
]);
6779
}
6880

69-
$this->messageManager->addSuccessMessage((string)__('Afterpay Transaction Completed'));
81+
$this->messageManager->addSuccessMessage((string)__('Afterpay Transaction Completed.'));
82+
7083
return $this->redirectFactory->create()->setPath('checkout/onepage/success');
7184
}
7285
}

Model/Checks/PaymentMethod.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
class PaymentMethod implements PaymentMethodInterface
66
{
7-
public function isAfterPayMethod(\Magento\Sales\Model\Order\Payment $payment): bool
7+
public function isAfterPayMethod($payment): bool
88
{
99
return $payment->getMethod() == \Afterpay\Afterpay\Gateway\Config\Config::CODE;
1010
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
<?php
2-
32
namespace Afterpay\Afterpay\Model\Checks;
43

54
interface PaymentMethodInterface
65
{
7-
public function isAfterPayMethod(\Magento\Sales\Model\Order\Payment $payment): bool;
6+
/**
7+
* @param \Magento\Sales\Api\Data\OrderPaymentInterface|\Magento\Quote\Api\Data\PaymentInterface $payment
8+
*
9+
* @return bool
10+
*/
11+
public function isAfterPayMethod($payment): bool;
812
}

Model/Config.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ public function websiteHasOwnConfig(int $websiteId): bool
407407
return true;
408408
}
409409
$connection = $this->resourceConnection->getConnection();
410-
$coreConfigData = $connection->getTableName('core_config_data');
410+
$coreConfigData = $this->resourceConnection->getTableName('core_config_data');
411411
$configsExistToCheck = array_merge(
412412
\Afterpay\Afterpay\Observer\Adminhtml\ConfigSaveAfter::AFTERPAY_CONFIGS,
413413
\Afterpay\Afterpay\Observer\Adminhtml\ConfigSaveAfter::CONFIGS_PATHS_TO_TRACK
@@ -556,9 +556,9 @@ public function setConsumerLendingMinAmount(string $value, int $scopeId = 0): se
556556
return $this;
557557
}
558558

559-
public function getConsumerLendingMinAmount(?int $scopeCode = null): bool
559+
public function getConsumerLendingMinAmount(?int $scopeCode = null): float
560560
{
561-
return (bool)$this->scopeConfig->getValue(
561+
return (float)$this->scopeConfig->getValue(
562562
self::XML_PATH_CONSUMER_LENDING_MIN_AMOUNT,
563563
ScopeInterface::SCOPE_WEBSITE,
564564
$scopeCode

Model/Order/CreditMemo/OrdersRetriever.php

Lines changed: 43 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,100 +2,76 @@
22

33
namespace Afterpay\Afterpay\Model\Order\CreditMemo;
44

5-
use Afterpay\Afterpay\Model\Payment\AdditionalInformationInterface;
5+
use Afterpay\Afterpay\Api\Data\TokenInterface;
6+
use Afterpay\Afterpay\Model\ResourceModel\Token\CollectionFactory;
7+
use Magento\Framework\App\ResourceConnection;
8+
use Magento\Framework\Stdlib\DateTime\DateTime;
9+
use Magento\Sales\Api\Data\OrderInterface;
10+
use Magento\Sales\Api\Data\OrderPaymentInterface;
11+
use Magento\Sales\Model\Order;
12+
use Magento\Sales\Model\ResourceModel\Order\Collection;
13+
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollectionFactory;
614

715
class OrdersRetriever
816
{
917
private $orderCollectionFactory;
1018
private $resourceConnection;
11-
private $serializer;
12-
private $logger;
19+
private $tokensCollectionFactory;
20+
private $dateTime;
1321

1422
public function __construct(
15-
\Magento\Framework\Serialize\SerializerInterface $serializer,
16-
\Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory,
17-
\Magento\Framework\App\ResourceConnection $resourceConnection,
18-
\Psr\Log\LoggerInterface $logger
23+
OrderCollectionFactory $orderCollectionFactory,
24+
ResourceConnection $resourceConnection,
25+
CollectionFactory $tokensCollectionFactory,
26+
DateTime $dateTime
1927
) {
20-
$this->serializer = $serializer;
2128
$this->orderCollectionFactory = $orderCollectionFactory;
2229
$this->resourceConnection = $resourceConnection;
23-
$this->logger = $logger;
30+
$this->tokensCollectionFactory = $tokensCollectionFactory;
31+
$this->dateTime = $dateTime;
2432
}
2533

2634
/**
27-
* @return \Magento\Sales\Model\Order[]
35+
* @return Order[]
2836
*/
2937
public function getAfterpayOrders(): array
3038
{
31-
$orderCollection = $this->orderCollectionFactory->create();
32-
$orderCollection
39+
$tokensCollection = $this->tokensCollectionFactory->create()
40+
->addFieldToSelect(TokenInterface::ORDER_ID_FIELD)
41+
->addFieldToFilter(TokenInterface::EXPIRATION_DATE_FIELD, ['notnull' => true])
3342
->addFieldToFilter(
34-
'state',
35-
['eq' => \Magento\Sales\Model\Order::STATE_PROCESSING]
43+
TokenInterface::EXPIRATION_DATE_FIELD,
44+
[
45+
'date' => true,
46+
'from' => $this->dateTime->date('Y-m-d H:i:s', '-90 days'),
47+
'to' => $this->dateTime->date('Y-m-d H:i:s')
48+
]
3649
);
50+
$ids = $tokensCollection->getColumnValues(TokenInterface::ORDER_ID_FIELD);
51+
52+
$orderCollection = $this->orderCollectionFactory->create();
53+
$orderCollection->addFieldToFilter(
54+
OrderInterface::ENTITY_ID,
55+
['in' => $ids]
56+
)->addFieldToFilter(
57+
OrderInterface::STATE,
58+
['eq' => Order::STATE_PROCESSING]
59+
);
3760
$orderCollection = $this->joinAfterpayPaymentAdditionalInfo($orderCollection);
38-
/** @var \Magento\Sales\Model\Order[] $items */
39-
$items = $orderCollection->getItems();
40-
$items = $this->getItemsWithAdditionalInfo($items);
41-
return $items;
42-
}
4361

44-
/**
45-
* @var \Magento\Sales\Model\Order[] $items
46-
* @return \Magento\Sales\Model\Order[]
47-
*/
48-
private function getItemsWithAdditionalInfo(array $items): array
49-
{
50-
$itemsWithJsonAdditionalInfo = [];
51-
foreach ($items as $item) {
52-
$additionalInformation = $item->getData(
53-
\Magento\Sales\Api\Data\OrderPaymentInterface::ADDITIONAL_INFORMATION
54-
);
55-
try {
56-
$unserializedInfo = $this->serializer->unserialize($additionalInformation);
57-
if (!is_array($unserializedInfo)) {
58-
continue;
59-
}
60-
/** @var array $unserializedInfo */
61-
$item->setData(
62-
\Magento\Sales\Api\Data\OrderPaymentInterface::ADDITIONAL_INFORMATION,
63-
$unserializedInfo
64-
);
65-
$isAdditionalInfoFull =
66-
isset($unserializedInfo[AdditionalInformationInterface::AFTERPAY_PAYMENT_STATE]) &&
67-
isset($unserializedInfo[AdditionalInformationInterface::AFTERPAY_OPEN_TO_CAPTURE_AMOUNT]) &&
68-
isset($unserializedInfo[AdditionalInformationInterface::AFTERPAY_AUTH_EXPIRY_DATE]);
69-
if ($isAdditionalInfoFull) {
70-
$itemsWithJsonAdditionalInfo[] = $item;
71-
}
72-
} catch (\InvalidArgumentException $e) {
73-
$this->logger->warning($e->getMessage());
74-
}
75-
}
76-
return $itemsWithJsonAdditionalInfo;
62+
return $orderCollection->getItems();
7763
}
7864

7965
private function joinAfterpayPaymentAdditionalInfo(
80-
\Magento\Sales\Model\ResourceModel\Order\Collection $orderCollection
81-
): \Magento\Sales\Model\ResourceModel\Order\Collection {
82-
$salesOrderPaymentTable = $this->resourceConnection->getConnection()->getTableName('sales_order_payment');
66+
Collection $orderCollection
67+
): Collection {
68+
$salesOrderPaymentTable = $this->resourceConnection->getTableName('sales_order_payment');
8369
$orderCollection->join(
8470
['sop' => $salesOrderPaymentTable],
8571
'sop.parent_id = main_table.entity_id',
86-
\Magento\Sales\Api\Data\OrderPaymentInterface::ADDITIONAL_INFORMATION
72+
OrderPaymentInterface::ADDITIONAL_INFORMATION
8773
);
88-
$selectSql = $orderCollection->getSelectSql();
89-
/** @var \Magento\Framework\DB\Select $selectSql */
90-
$selectSql
91-
->where(
92-
'sop.method = ?',
93-
\Afterpay\Afterpay\Gateway\Config\Config::CODE
94-
)
95-
->where(
96-
'sop.additional_information like ?',
97-
'%' . AdditionalInformationInterface::AFTERPAY_AUTH_EXPIRY_DATE . '%'
98-
);
74+
9975
return $orderCollection;
10076
}
10177
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Afterpay\Afterpay\Model\Order\Payment\Auth;
4+
5+
use Afterpay\Afterpay\Model\ResourceModel\Token;
6+
use Magento\Framework\Stdlib\DateTime;
7+
8+
class TokenSaver
9+
{
10+
private $tokensResource;
11+
private $dateTime;
12+
13+
public function __construct(
14+
Token $tokensResource,
15+
DateTime $dateTime
16+
) {
17+
$this->tokensResource = $tokensResource;
18+
$this->dateTime = $dateTime;
19+
}
20+
21+
public function execute(int $orderId, string $token, ?string $expiryDate): bool
22+
{
23+
return (bool)$this->tokensResource->insertNewToken($orderId, $token, $this->dateTime->formatDate($expiryDate));
24+
}
25+
}

Model/Order/Payment/Auth/TokenValidator.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,24 @@
22

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

5-
use Afterpay\Afterpay\Api\Data\CheckoutInterface;
6-
use Afterpay\Afterpay\Gateway\Config\Config;
7-
use Magento\Framework\App\ResourceConnection;
5+
use Afterpay\Afterpay\Model\ResourceModel\Token;
86

97
class TokenValidator
108
{
11-
private $resourceConnection;
9+
private $results = [];
10+
private $tokensResource;
1211

13-
public function __construct(ResourceConnection $resourceConnection)
12+
public function __construct(Token $tokensResource)
1413
{
15-
$this->resourceConnection = $resourceConnection;
14+
$this->tokensResource = $tokensResource;
1615
}
1716

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

28-
return (bool)$this->resourceConnection->getConnection()->fetchOne($checkSelect);
23+
return $this->results[$token];
2924
}
3025
}

0 commit comments

Comments
 (0)