Skip to content

Commit d5eb964

Browse files
authored
Merge pull request #1267 from BearGroup/release/5.18.2
Release/5.18.2
2 parents 8673cf8 + d0a3f11 commit d5eb964

22 files changed

+225
-28
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Change Log
22

3+
## 5.18.2
4+
* Added security enhancements around Express Checkout
5+
* Changed when Magento order ID is sent to Amazon to improve traceability
6+
* Changed how promo banner is rendered for configurable/bundle products
7+
* Clarified usage of "Reset configuration" button in admin for new merchants
8+
* Fixed bug in email plugin if no payment is set
9+
* Restored PHP 7 compatibility
10+
311
## 5.18.1
412
* Add new logos/acceptance marks at checkout
513
* Improved clarity of order comments on cancelled orders

Cron/CleanUpIncompleteSessions.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ protected function processTransaction(array $transactionData)
117117

118118
try {
119119
// Check current state of Amazon checkout session
120-
$amazonSession = $this->amazonPayAdapter->getCheckoutSession($transactionData['store_id'], $checkoutSessionId);
120+
$amazonSession = $this->amazonPayAdapter->getCheckoutSession(
121+
$transactionData['store_id'],
122+
$checkoutSessionId
123+
);
121124
$state = $amazonSession['statusDetails']['state'] ?? false;
122125
switch ($state) {
123126
case self::SESSION_STATUS_STATE_CANCELED:
@@ -150,6 +153,7 @@ protected function processTransaction(array $transactionData)
150153
* Cancel the order
151154
*
152155
* @param int $orderId
156+
* @param string $reasonMessage
153157
* @return void
154158
*/
155159
protected function cancelOrder($orderId, $reasonMessage = '')

Gateway/Request/SettlementRequestBuilder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ protected function getHeaders($payment)
110110
* @param \Magento\Payment\Model\InfoInterface $payment
111111
* @return string
112112
*/
113-
protected function getChargeId($payment) {
113+
protected function getChargeId($payment)
114+
{
114115
$chargeId = '';
115116

116117
if ($parentTransactionId = $payment->getParentTransactionId()) {

Helper/Address.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,31 @@ public function convertToArray(AddressInterface $address)
216216

217217
return $data;
218218
}
219+
220+
/**
221+
* Ensure shipping address associated with checkout session is one coming from Amazon
222+
*
223+
* @param mixed $amazonAddress
224+
* @param \Magento\Quote\Model\Quote\Address $magentoAddress
225+
*/
226+
public function validateShippingIsSame($amazonAddress, $magentoAddress)
227+
{
228+
return $this->fuzzyCompare($amazonAddress['firstname'], $magentoAddress->getFirstname()) &&
229+
$this->fuzzyCompare($amazonAddress['lastname'], $magentoAddress->getLastname()) &&
230+
$this->fuzzyCompare($amazonAddress['city'], $magentoAddress->getCity()) &&
231+
$this->fuzzyCompare($amazonAddress['postcode'], $magentoAddress->getPostcode()) &&
232+
$this->fuzzyCompare($amazonAddress['street'][0], $magentoAddress->getStreet()[0]);
233+
}
234+
235+
/**
236+
* Compare two strings after stripping punctuation and lowercasing
237+
*
238+
* @param string $a
239+
* @param string $b
240+
* @return bool
241+
*/
242+
protected function fuzzyCompare($a, $b)
243+
{
244+
return strtolower(preg_replace("#[[:punct:]]#", "", $a)) == strtolower(preg_replace("#[[:punct:]]#", "", $b));
245+
}
219246
}

Helper/SubscriptionHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ function ($subscription) use ($publicHash) {
194194
* @param mixed $value
195195
* @return Filter
196196
*/
197-
private function buildFilter(string $field, mixed $value)
197+
private function buildFilter(string $field, $value)
198198
{
199199
return $this->filterBuilder
200200
->setField($field)

Helper/Transaction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public function getIncomplete()
131131
* @param mixed $transactionId
132132
* @return void
133133
*/
134-
public function closeTransaction(mixed $transactionId)
134+
public function closeTransaction($transactionId)
135135
{
136136
$transaction = $this->transactionRepository->get($transactionId);
137137
$transaction->setIsClosed(true);

Model/Adapter/AmazonPayAdapter.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,18 @@ public function updateCheckoutSession($quote, $checkoutSessionId, $paymentIntent
197197
'chargeAmount' => $this->createPrice($quote->getGrandTotal(), $quote->getQuoteCurrencyCode()),
198198
],
199199
'merchantMetadata' => [
200-
'merchantStoreName' => $this->amazonConfig->getStoreName()
200+
'merchantStoreName' => $this->amazonConfig->getStoreName(),
201+
'merchantReferenceId' => $quote->getReservedOrderId()
201202
],
202203
'platformId' => $this->amazonConfig->getPlatformId(),
203204
];
204205

205206
$headers = $this->getPlatformHeaders();
206-
$response = $this->clientFactory->create($storeId)->updateCheckoutSession($checkoutSessionId, $payload, $headers);
207+
$response = $this->clientFactory->create($storeId)->updateCheckoutSession(
208+
$checkoutSessionId,
209+
$payload,
210+
$headers
211+
);
207212

208213
return $this->processResponse($response, __FUNCTION__);
209214
}
@@ -361,7 +366,11 @@ public function updateChargePermission(int $storeId, string $chargePermissionId,
361366
}
362367

363368
$headers = $this->getPlatformHeaders();
364-
$response = $this->clientFactory->create($storeId)->updateChargePermission($chargePermissionId, $payload, $headers);
369+
$response = $this->clientFactory->create($storeId)->updateChargePermission(
370+
$chargePermissionId,
371+
$payload,
372+
$headers
373+
);
365374

366375
return $this->processResponse($response, __FUNCTION__);
367376
}
@@ -402,7 +411,11 @@ public function closeChargePermission($storeId, $chargePermissionId, $reason, $c
402411
];
403412

404413
$headers = $this->getPlatformHeaders();
405-
$response = $this->clientFactory->create($storeId)->closeChargePermission($chargePermissionId, $payload, $headers);
414+
$response = $this->clientFactory->create($storeId)->closeChargePermission(
415+
$chargePermissionId,
416+
$payload,
417+
$headers
418+
);
406419

407420
return $this->processResponse($response, __FUNCTION__);
408421
}

Model/AmazonConfig.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,10 +1020,10 @@ public function isGuestCheckoutEnabled($scope = ScopeInterface::SCOPE_STORE, $sc
10201020
}
10211021

10221022
/**
1023-
* get configured payment method logo / acceptance mark
1023+
* Get configured payment method logo / acceptance mark
10241024
*
1025-
* @param $scope
1026-
* @param $scopeCode
1025+
* @param string $scope
1026+
* @param int|string $scopeCode
10271027
* @return string
10281028
*/
10291029
public function getAcceptanceMark($scope = ScopeInterface::SCOPE_STORE, $scopeCode = null)

Model/CheckoutSessionManagement.php

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
class CheckoutSessionManagement implements \Amazon\Pay\Api\CheckoutSessionManagementInterface
4646
{
4747
protected const GENERIC_COMPLETE_CHECKOUT_ERROR_MESSAGE = 'Unable to complete Amazon Pay checkout.';
48+
protected const ADDRESS_CHANGED_CHECKOUT_ERROR_MESSAGE = 'Shipping address mismatch.';
4849

4950
/**
5051
* @var \Magento\Store\Model\StoreManagerInterface
@@ -731,9 +732,12 @@ public function cancelOrder($order, $quote = null, $reasonMessage = '')
731732
protected function handleCompleteCheckoutSessionError($message, $logEntryDetails = '')
732733
{
733734
$this->logger->error($message . ' ' . $logEntryDetails);
735+
if ($message == $this::ADDRESS_CHANGED_CHECKOUT_ERROR_MESSAGE) {
736+
$message = $this::GENERIC_COMPLETE_CHECKOUT_ERROR_MESSAGE;
737+
}
734738
$result = [
735739
'success' => false,
736-
'message' => $this->getTranslationString($message),
740+
'message' => $this->getTranslationString($message)
737741
];
738742
return $result;
739743
}
@@ -811,6 +815,20 @@ public function completeCheckoutSession($amazonSessionId, $cartId = null, $order
811815
*/
812816
public function placeOrder($amazonSessionId, $quoteId = null)
813817
{
818+
819+
// verify the shipping address has not been modified in Magento, it must match
820+
// the one selected in the Amazon checkout session (express checkout only)
821+
if ($amznShippingAddress = $this->getShippingAddress($amazonSessionId)) {
822+
$amazonAddress = $amznShippingAddress[0];
823+
$magentoAddress = $this->session->getQuoteFromIdOrSession($quoteId)->getShippingAddress();
824+
if (!$this->addressHelper->validateShippingIsSame($amazonAddress, $magentoAddress)) {
825+
return $this->handleCompleteCheckoutSessionError(
826+
self::ADDRESS_CHANGED_CHECKOUT_ERROR_MESSAGE,
827+
$this->getAddressMismatchDetails($amazonAddress, $magentoAddress)
828+
);
829+
}
830+
}
831+
814832
if (!$quote = $this->session->getQuoteFromIdOrSession($quoteId)) {
815833
$errorMsg = "Unable to complete Amazon Pay checkout. Quote not found.";
816834
if ($quoteId) {
@@ -881,7 +899,7 @@ public function placeOrder($amazonSessionId, $quoteId = null)
881899
$this->logger->error($errorMsg . $quote->getId());
882900
return [
883901
'success' => false,
884-
'message' => $this->getTranslationString(self::GENERIC_COMPLETE_CHECKOUT_ERROR_MESSAGE),
902+
'message' => $this->getTranslationString(self::GENERIC_COMPLETE_CHECKOUT_ERROR_MESSAGE)
885903
];
886904
}
887905

@@ -910,6 +928,31 @@ protected function getCanceledMessage($amazonSession)
910928
return $amazonSession['statusDetails']['reasonDescription'];
911929
}
912930

931+
/**
932+
* Get log-friendly details of disagreeing checkout session addresses
933+
*
934+
* @param mixed $amazonAddress
935+
* @param \Magento\Quote\Model\Quote\Address $magentoAddress
936+
* @return string
937+
*/
938+
protected function getAddressMismatchDetails($amazonAddress, $magentoAddress)
939+
{
940+
return 'Address from Amazon account: ' . json_encode($amazonAddress) . '; Address entered in Magento: ' .
941+
json_encode([
942+
'city' => $magentoAddress->getCity(),
943+
'firstname' => $magentoAddress->getFirstName(),
944+
'lastname' => $magentoAddress->getLastname(),
945+
'country_id' => $magentoAddress->getCountryId(),
946+
'street' => $magentoAddress->getStreet(),
947+
'postcode' => $magentoAddress->getPostcode(),
948+
'telephone' => $magentoAddress->getTelephone(),
949+
'region' => $magentoAddress->getRegion(),
950+
'region_id' => $magentoAddress->getRegionId(),
951+
'region_code' => $magentoAddress->getRegionCode(),
952+
'email' => $magentoAddress->getEmail()
953+
]);
954+
}
955+
913956
/**
914957
* Update vault token
915958
*
@@ -1365,7 +1408,7 @@ private function closeChargePermission($amazonSessionId, OrderInterface $order,
13651408
* @param mixed $orderId
13661409
* @return void
13671410
*/
1368-
public function setOrderPendingPaymentReview(mixed $orderId)
1411+
public function setOrderPendingPaymentReview($orderId)
13691412
{
13701413
try {
13711414
if (!$orderId) {

Model/Config/Source/AcceptanceMark.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct($logos = [])
4141
public function toOptionArray()
4242
{
4343
$result = [];
44-
foreach($this->logos as $logo){
44+
foreach ($this->logos as $logo) {
4545
$result[] = [
4646
'label' => __($logo['label']),
4747
'value' => $logo['value']

0 commit comments

Comments
 (0)