Skip to content

Commit a7f3656

Browse files
Release version 5.4.4
1 parent 3e05c63 commit a7f3656

55 files changed

Lines changed: 755 additions & 116 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Afterpay\Afterpay\Gateway\Http\Client;
4+
5+
class CaptureClient extends Client
6+
{
7+
public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject): array
8+
{
9+
try {
10+
$response = parent::placeRequest($transferObject);
11+
if (empty($response)) {
12+
$response = $this->getPaymentByToken($transferObject);
13+
}
14+
} catch (\Throwable $e) {
15+
$response = $this->getPaymentByToken($transferObject);
16+
}
17+
return $response;
18+
}
19+
20+
private function getPaymentByToken(\Magento\Payment\Gateway\Http\TransferInterface $transferObject): array
21+
{
22+
$this->logger->warning(
23+
'Something went wrong during the execution of the capture transaction. getPaymentByToken() is called'
24+
);
25+
try {
26+
if (empty($this->client->getBody()) || strpos($transferObject->getUri(), 'capture') === false) {
27+
return [];
28+
}
29+
30+
$token = $transferObject->getBody()['token'] ?? null;
31+
if (!$token) {
32+
return [];
33+
}
34+
35+
$this->client->setHeaders($transferObject->getHeaders());
36+
$this->client->addHeader(
37+
'Authorization',
38+
'Basic ' . base64_encode($transferObject->getAuthUsername() . ':' . $transferObject->getAuthPassword())
39+
);
40+
41+
$uri = str_replace('capture', 'token:', $transferObject->getUri());
42+
$this->client->get($uri . $token);
43+
$unserializedBody = $this->serializer->unserialize($this->client->getBody());
44+
45+
$this->debugLogger->debug([
46+
'merchant_id' => $transferObject->getAuthUsername(),
47+
'merchant_action' => $this->request instanceof \Magento\Framework\App\Request\Http
48+
? $this->request->getServer('REQUEST_URI') : '',
49+
'target_uri' => $uri,
50+
'request_body' => [],
51+
'response' => $unserializedBody
52+
]);
53+
54+
return is_array($unserializedBody) ? $unserializedBody : [];
55+
} catch (\Throwable $e) {
56+
$message = $e->getMessage() ?: 'Please, try again';
57+
$this->logger->critical($message, $e->getTrace());
58+
throw new \Magento\Payment\Gateway\Http\ClientException(__($message));
59+
}
60+
}
61+
}

Gateway/Http/Client/Client.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ class Client implements \Magento\Payment\Gateway\Http\ClientInterface
66
{
77
protected \Magento\Framework\HTTP\ClientInterface $client;
88
protected \Magento\Framework\Serialize\SerializerInterface $serializer;
9-
private \Psr\Log\LoggerInterface $logger;
10-
private \Magento\Payment\Model\Method\Logger $debugLogger;
11-
private \Magento\Framework\App\RequestInterface $request;
9+
protected \Psr\Log\LoggerInterface $logger;
10+
protected \Magento\Payment\Model\Method\Logger $debugLogger;
11+
protected \Magento\Framework\App\RequestInterface $request;
1212

1313
public function __construct(
1414
\Magento\Framework\HTTP\ClientInterface $client,

Gateway/Response/CaptureVirtualProductsHandler.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ class CaptureVirtualProductsHandler implements \Magento\Payment\Gateway\Response
66
{
77
private \Magento\Payment\Gateway\CommandInterface $authCaptureCommand;
88
private \Magento\Payment\Gateway\Data\PaymentDataObjectFactoryInterface $paymentDataObjectFactory;
9-
private \Afterpay\Afterpay\Model\Payment\AmountProcessor\Order $orderAmountProcessor;
9+
private \Afterpay\Afterpay\Model\Payment\AmountProcessor\VirtualProducts $virtualProductsAmountProcessor;
1010
private \Magento\Payment\Gateway\CommandInterface $voidCommand;
1111

1212
public function __construct(
13-
\Magento\Payment\Gateway\CommandInterface $authCaptureCommand,
14-
\Magento\Payment\Gateway\Data\PaymentDataObjectFactoryInterface $paymentDataObjectFactory,
15-
\Afterpay\Afterpay\Model\Payment\AmountProcessor\Order $orderAmountProcessor,
16-
\Magento\Payment\Gateway\CommandInterface $voidCommand
13+
\Magento\Payment\Gateway\CommandInterface $authCaptureCommand,
14+
\Magento\Payment\Gateway\Data\PaymentDataObjectFactoryInterface $paymentDataObjectFactory,
15+
\Afterpay\Afterpay\Model\Payment\AmountProcessor\VirtualProducts $virtualProductsAmountProcessor,
16+
\Magento\Payment\Gateway\CommandInterface $voidCommand
1717
) {
1818
$this->authCaptureCommand = $authCaptureCommand;
1919
$this->paymentDataObjectFactory = $paymentDataObjectFactory;
20-
$this->orderAmountProcessor = $orderAmountProcessor;
20+
$this->virtualProductsAmountProcessor = $virtualProductsAmountProcessor;
2121
$this->voidCommand = $voidCommand;
2222
}
2323

@@ -38,7 +38,7 @@ public function handle(array $handlingSubject, array $response)
3838
);
3939

4040
if (count($itemsToCapture)) {
41-
$amountToCapture = $this->orderAmountProcessor->process($itemsToCapture, $payment);
41+
$amountToCapture = $this->virtualProductsAmountProcessor->process($itemsToCapture, $payment);
4242
if ($amountToCapture > 0) {
4343
try {
4444
$this->authCaptureCommand->execute([

Gateway/Response/Checkout/CheckoutDataToQuoteHandler.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@ class CheckoutDataToQuoteHandler implements \Magento\Payment\Gateway\Response\Ha
77
private \Magento\Checkout\Api\ShippingInformationManagementInterface $shippingInformationManagement;
88
private \Magento\Checkout\Api\Data\ShippingInformationInterfaceFactory $shippingInformationFactory;
99
private \Magento\Quote\Api\Data\AddressInterfaceFactory $addressInterfaceFactory;
10+
private \Magento\Directory\Model\Region $region;
1011

1112
public function __construct(
1213
\Magento\Checkout\Api\ShippingInformationManagementInterface $shippingInformationManagement,
1314
\Magento\Checkout\Api\Data\ShippingInformationInterfaceFactory $shippingInformationFactory,
14-
\Magento\Quote\Api\Data\AddressInterfaceFactory $addressInterfaceFactory
15+
\Magento\Quote\Api\Data\AddressInterfaceFactory $addressInterfaceFactory,
16+
\Magento\Directory\Model\Region $region
1517
) {
1618
$this->shippingInformationManagement = $shippingInformationManagement;
1719
$this->shippingInformationFactory = $shippingInformationFactory;
1820
$this->addressInterfaceFactory = $addressInterfaceFactory;
21+
$this->region = $region;
1922
}
2023

2124
public function handle(array $handlingSubject, array $response): void
@@ -60,7 +63,11 @@ public function handle(array $handlingSubject, array $response): void
6063
->setCountryId($response['shipping']['countryCode'])
6164
->setStreet([$response['shipping']['line1']])
6265
->setPostcode($response['shipping']['postcode'])
63-
->setRegion($response['shipping']['region'] ?? '');
66+
->setRegion($response['shipping']['region'] ?? '')
67+
->setRegionId(
68+
$this->region->loadByCode($address->getRegion(), $address->getCountryId())->getId()
69+
?? $this->region->loadByName($address->getRegion(), $address->getCountryId())->getId()
70+
);
6471
if (isset($response['shipping']['line2']) && $streetLine2 = $response['shipping']['line2']) {
6572
/** @var string[] $street */
6673
$street = array_merge($address->getStreet(), [$streetLine2]);

Gateway/Response/PaymentDetailsHandler.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ class PaymentDetailsHandler implements \Magento\Payment\Gateway\Response\Handler
66
{
77
private \Afterpay\Afterpay\Model\Order\Payment\Auth\ExpiryDate $authExpiryDate;
88

9-
private \Afterpay\Afterpay\Model\Order\CreditMemo\PaymentUpdater\Proxy $paymentUpdater;
9+
private \Afterpay\Afterpay\Model\Order\CreditMemo\PaymentUpdater $paymentUpdater;
1010

1111
public function __construct(
1212
\Afterpay\Afterpay\Model\Order\Payment\Auth\ExpiryDate $authExpiryDate,
13-
\Afterpay\Afterpay\Model\Order\CreditMemo\PaymentUpdater\Proxy $paymentUpdater
13+
\Afterpay\Afterpay\Model\Order\CreditMemo\PaymentUpdater $paymentUpdater
1414
) {
1515
$this->authExpiryDate = $authExpiryDate;
1616
$this->paymentUpdater = $paymentUpdater;

Model/CBT/CheckCBTCurrencyAvailabilityInterface.php

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

55
interface CheckCBTCurrencyAvailabilityInterface
66
{
7-
public function check(string $currencyCode, float $amount = null): bool;
7+
public function check(string $currencyCode, ?float $amount = null): bool;
88

99
public function checkByQuote(\Magento\Quote\Model\Quote $quote): bool;
1010
}

Model/Checks/IsCBTAvailable.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public function __construct(\Afterpay\Afterpay\Model\Config $config)
1313
$this->config = $config;
1414
}
1515

16-
public function check(string $currencyCode, float $amount = null): bool
16+
public function check(string $currencyCode, ?float $amount = null): bool
1717
{
1818
$cbtCurrencies = $this->config->getCbtCurrencyLimits();
1919

Model/Config.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Afterpay\Afterpay\Model;
44

5+
use Afterpay\Afterpay\Model\FeatureFlag\Service\GetCreditMemoOnGrandTotalEnabled;
56
use Magento\Framework\App\Config\ScopeConfigInterface;
67
use Magento\Framework\App\Config\Storage\WriterInterface;
78
use Magento\Framework\App\ResourceConnection;
@@ -10,7 +11,6 @@
1011

1112
class Config
1213
{
13-
1414
public const XML_PATH_PAYMENT_ACTIVE = 'payment/afterpay/active';
1515
public const XML_PATH_API_MODE = 'payment/afterpay/api_mode';
1616
public const XML_PATH_DEBUG = 'payment/afterpay/debug';
@@ -28,11 +28,9 @@ class Config
2828
public const XML_PATH_MAX_LIMIT = 'payment/afterpay/max_order_total';
2929
public const XML_PATH_CBT_CURRENCY_LIMITS = 'payment/afterpay/cbt_currency_limits';
3030
public const XML_PATH_EXCLUDE_CATEGORIES = 'payment/afterpay/exclude_categories';
31-
public const XML_PATH_ALLOW_SPECIFIC_COUNTRIES = 'payment/afterpay/allowspecific';
3231
public const XML_PATH_SPECIFIC_COUNTRIES = 'payment/afterpay/specificcountry';
3332
public const XML_PATH_ALLOWED_MERCHANT_COUNTRIES = 'payment/afterpay/allowed_merchant_countries';
3433
public const XML_PATH_ALLOWED_MERCHANT_CURRENCIES = 'payment/afterpay/allowed_merchant_currencies';
35-
public const XML_PATH_PAYPAL_MERCHANT_COUNTRY = 'paypal/general/merchant_country';
3634
public const XML_PATH_ENABLE_REVERSAL = 'payment/afterpay/enable_reversal';
3735
public const XML_PATH_MPID = 'payment/afterpay/public_id';
3836
public const XML_PATH_CASHAPP_PAY_AVAILABLE = 'payment/afterpay/cash_app_pay_available';
@@ -53,22 +51,24 @@ class Config
5351
public const XML_PATH_CART_PAGE_PLACEMENT_AFTER_SELECTOR = 'payment/afterpay/cart_page_placement_after_selector';
5452
public const XML_PATH_CART_PAGE_PLACEMENT_PRICE_SELECTOR = 'payment/afterpay/cart_page_placement_price_selector';
5553

56-
5754
private ScopeConfigInterface $scopeConfig;
5855
private WriterInterface $writer;
5956
private ResourceConnection $resourceConnection;
6057
private SerializerInterface $serializer;
58+
private GetCreditMemoOnGrandTotalEnabled $getCreditMemoOnGrandTotalEnabledService;
6159

6260
public function __construct(
63-
ScopeConfigInterface $scopeConfig,
64-
WriterInterface $writer,
65-
ResourceConnection $resourceConnection,
66-
SerializerInterface $serializer
61+
ScopeConfigInterface $scopeConfig,
62+
WriterInterface $writer,
63+
ResourceConnection $resourceConnection,
64+
SerializerInterface $serializer,
65+
GetCreditMemoOnGrandTotalEnabled $getCreditMemoOnGrandTotalEnabledService
6766
) {
6867
$this->scopeConfig = $scopeConfig;
6968
$this->writer = $writer;
7069
$this->resourceConnection = $resourceConnection;
7170
$this->serializer = $serializer;
71+
$this->getCreditMemoOnGrandTotalEnabledService = $getCreditMemoOnGrandTotalEnabledService;
7272
}
7373

7474
public function getIsPaymentActive(?int $scopeCode = null): bool
@@ -586,7 +586,10 @@ public function getAddLastSelectedShipRate(?int $scopeCode = null): bool
586586
public function getIsCreditMemoGrandTotalOnlyEnabled(?int $websiteId = null, bool $fromApi = false): bool
587587
{
588588
if ($fromApi) {
589-
$flagValue = false; // TODO: replace it with a flag pull
589+
$flagValue = $this->getCreditMemoOnGrandTotalEnabledService->execute(
590+
$this->getPublicId($websiteId),
591+
$this->getMerchantCountry(ScopeInterface::SCOPE_WEBSITES, $websiteId)
592+
);
590593
$this->setIsCreditMemoGrandTotalOnlyEnabled((int)$flagValue, $websiteId);
591594

592595
return $flagValue;

Model/Config/Source/Category.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ private function renderSubCategory(array $categoryData, array &$optionsResult):
3737
$this->renderSubCategory($subCatData, $optionsResult);
3838
}
3939
}
40+
41+
if (!isset($categoryData['level']) || !is_numeric($categoryData['level']) || $categoryData['level'] < 2) {
42+
return;
43+
}
44+
4045
$optionsResult[] = [
4146
'label' => str_repeat('', $categoryData['level'] - 2) . $categoryData['label'],
4247
'value' => $categoryData['id']
@@ -49,15 +54,15 @@ private function getCategoriesTree(): array
4954

5055
$this->storeManager->setCurrentStore($this->getStoreIdByRequest() ?? $currentStoreId);
5156
$this->categorySourceRegistry->setShowAllCategories(true);
52-
/** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $categories */
57+
/** @var \Magento\Framework\Data\Collection $categories */
5358
$categories = $this->categoryHelper->getStoreCategories(false, true);
5459
$this->categorySourceRegistry->setShowAllCategories(false);
5560
$this->storeManager->setCurrentStore($currentStoreId);
5661

5762
return $this->convertToTree($categories);
5863
}
5964

60-
private function convertToTree(\Magento\Catalog\Model\ResourceModel\Category\Collection $categories): array
65+
private function convertToTree(\Magento\Framework\Data\Collection $categories): array
6166
{
6267
$categoryById = [];
6368
foreach ($categories as $category) {

Model/FeatureFlag/Client.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Afterpay\Afterpay\Model\FeatureFlag;
4+
5+
use Afterpay\Afterpay\Model\Url\UrlBuilder;
6+
use Magento\Framework\Exception\LocalizedException;
7+
use Magento\Framework\HTTP\ClientInterface;
8+
use Magento\Framework\Serialize\SerializerInterface;
9+
use Magento\Payment\Model\Method\Logger;
10+
use Psr\Log\LoggerInterface;
11+
12+
class Client
13+
{
14+
private ClientInterface $client;
15+
private SerializerInterface $serializer;
16+
private LoggerInterface $logger;
17+
private Logger $debugLogger;
18+
private UrlBuilder $urlBuilder;
19+
20+
public function __construct(
21+
ClientInterface $client,
22+
SerializerInterface $serializer,
23+
LoggerInterface $logger,
24+
Logger $debugLogger,
25+
UrlBuilder $urlBuilder
26+
) {
27+
$this->client = $client;
28+
$this->serializer = $serializer;
29+
$this->logger = $logger;
30+
$this->debugLogger = $debugLogger;
31+
$this->urlBuilder = $urlBuilder;
32+
}
33+
34+
/**
35+
* Pulls the feature flag data from the internal API.
36+
*
37+
* @param string $flag Feature flag name
38+
* @param string $mpid Merchant Public ID - Afterpay\Afterpay\Model\Config::getPublicId
39+
* @param string $countryCode Merchant Country ID - Afterpay\Afterpay\Model\Config::getMerchantCountry
40+
*
41+
* @return array
42+
* @throws LocalizedException
43+
*/
44+
public function execute(string $flag, string $mpid, string $countryCode): array
45+
{
46+
$response = [];
47+
$actionUrl = $this->urlBuilder->build(UrlBuilder::TYPE_FEATURE_FLAG_API, $flag);
48+
try {
49+
$this->client->addHeader('x-mpid', $mpid);
50+
$this->client->addHeader('x-country', $countryCode);
51+
$this->client->get($actionUrl);
52+
53+
if (empty($this->client->getBody())) {
54+
return [];
55+
}
56+
57+
if (is_string($this->client->getBody()) && strpos($this->client->getBody(), 'error code') !== false ) {
58+
$this->logger->critical("Afterpay: Error fetching feature flag: {$flag}");
59+
return [];
60+
}
61+
62+
$unserializedBody = $this->serializer->unserialize($this->client->getBody());
63+
$response = is_array($unserializedBody) ? $unserializedBody : [];
64+
} catch (\Throwable $e) {
65+
$message = $e->getMessage() ?: 'Please, try again';
66+
$this->logger->critical("Afterpay: Error fetching feature flag: {$flag}" . $message, $e->getTrace());
67+
} finally {
68+
$this->debugLogger->debug([
69+
'merchant_public_id' => $mpid,
70+
'action_url' => $actionUrl,
71+
'request_flag' => $flag,
72+
'response' => $response
73+
]);
74+
}
75+
return $response;
76+
}
77+
}

0 commit comments

Comments
 (0)