Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #801

Merged
merged 16 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
21e5d6f
Bugfix: Use payment link expiry date when no method for expiry is fou…
michielgerritsen Jul 16, 2024
d5ab67f
Improvement: Prevent multiple captured amount notification when compl…
michielgerritsen Jul 22, 2024
e3c7f9c
Bugfix: Render script in secure tag #797
michielgerritsen Jul 22, 2024
8ee118a
Bugfix: Do not set shipping method for Apple Pay when ordering digita…
michielgerritsen Jul 29, 2024
d317f69
Bugfix: Only check if the order can be re-ordered when the payment li…
michielgerritsen Jul 16, 2024
0152fdc
Merge branch 'bugfix/use-paymentlink-method-when-no-method-found' int…
michielgerritsen Aug 7, 2024
d5b7e36
Merge branch 'bugfix/only-check-if-order-can-be-reordered-when-the-li…
michielgerritsen Aug 7, 2024
d39572f
Merge branch 'bugfix/render-script-in-securetag' into release-week-31
michielgerritsen Aug 7, 2024
dc93269
Merge branch 'improvement/prevent-multiple-captured-amount-notificati…
michielgerritsen Aug 7, 2024
ae94d16
Merge branch 'bugfix/applepay-with-digital-orders' into release-week-31
michielgerritsen Aug 7, 2024
5cfabb4
Bugfix: Redirect customer to success page when the Mollie order is 's…
michielgerritsen Aug 7, 2024
ba5a27e
Merge branch 'bugfix/redirect-customer-to-success-when-order-is-shipp…
michielgerritsen Aug 7, 2024
999a4a7
docker-compose -> docker compose
michielgerritsen Aug 7, 2024
37007ff
2.3.7 fix
michielgerritsen Aug 7, 2024
cb445f2
Disabled ALMA CSS class checking
michielgerritsen Aug 7, 2024
f289083
Fix: Don't rely on SecureRenderer (@hostep feedback)
michielgerritsen Aug 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/end-2-end-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ jobs:
- name: Start the Magento container
run: |
openssl req -x509 -newkey rsa:4096 -keyout .github/workflows/templates/nginx-proxy/magento.test.key -out .github/workflows/templates/nginx-proxy/magento.test.crt -days 365 -nodes -subj "/CN=magento.test" && \
docker-compose -f .github/workflows/templates/docker-compose.yml up -d
docker compose -f .github/workflows/templates/docker-compose.yml up -d
# Get the URL from ngrok
docker-compose -f .github/workflows/templates/docker-compose.yml logs ngrok
docker compose -f .github/workflows/templates/docker-compose.yml logs ngrok
MAGENTO_URL=$(docker exec magento-project-community-edition /bin/bash -c "curl -s ngrok:4040/api/tunnels |jq -r \".tunnels[0].public_url\"")
echo "magento_url=$MAGENTO_URL" >> $GITHUB_ENV

Expand Down Expand Up @@ -118,9 +118,9 @@ jobs:
- name: Dump docker-compose logs
if: always()
run: |
docker-compose -f .github/workflows/templates/docker-compose.yml logs magento > magento.log && \
docker-compose -f .github/workflows/templates/docker-compose.yml logs ngrok > ngrok.log && \
docker-compose -f .github/workflows/templates/docker-compose.yml logs e2e > e2e.log
docker compose -f .github/workflows/templates/docker-compose.yml logs magento > magento.log && \
docker compose -f .github/workflows/templates/docker-compose.yml logs ngrok > ngrok.log && \
docker compose -f .github/workflows/templates/docker-compose.yml logs e2e > e2e.log

- name: Upload artifacts
uses: actions/upload-artifact@v3
Expand Down
17 changes: 10 additions & 7 deletions Controller/ApplePay/PlaceOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,16 @@ public function execute()

$cart->setCustomerEmail($this->getRequest()->getParam('shippingAddress')['emailAddress']);

$shippingAddress->setShippingMethod(
str_replace(
'__SPLIT__',
'_',
$this->getRequest()->getParam('shippingMethod')['identifier']
)
);
// Orders with digital products can't have a shipping method
if ($this->getRequest()->getParam('shippingMethod')) {
$shippingAddress->setShippingMethod(
str_replace(
'__SPLIT__',
'_',
$this->getRequest()->getParam('shippingMethod')['identifier']
)
);
}

$cart->setPaymentMethod('mollie_methods_applepay');
$cart->setCustomerIsGuest(true);
Expand Down
10 changes: 6 additions & 4 deletions Model/Client/Orders/Processors/SuccessfulPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ public function __construct(
}

/**
* @param OrderInterface|\Magento\Sales\Model\Order $order
* @param OrderInterface|MagentoOrder $order
* @param MollieOrder $mollieOrder
* @param string $type
* @param ProcessTransactionResponse $response
* @throws \Magento\Framework\Exception\LocalizedException
* @return ProcessTransactionResponse|null
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function process(OrderInterface $order, Order $mollieOrder, string $type, ProcessTransactionResponse $response): ?ProcessTransactionResponse
{
Expand Down Expand Up @@ -173,7 +173,9 @@ private function handleWebhookCall(OrderInterface $order, MollieOrder $mollieOrd
$payment->setTransactionId($paymentId);
$payment->setCurrencyCode($order->getBaseCurrencyCode());

if ($order->getState() != \Magento\Sales\Model\Order::STATE_PROCESSING && $mollieOrder->isPaid()) {
if (!in_array($order->getState(), [MagentoOrder::STATE_PROCESSING, MagentoOrder::STATE_COMPLETE]) &&
$mollieOrder->isPaid()
) {
$payment->setIsTransactionClosed(true);
$payment->registerCaptureNotification($order->getBaseGrandTotal(), true);
}
Expand Down Expand Up @@ -230,7 +232,7 @@ public function checkCheckoutSession(
}

/**
* @param OrderInterface|\Magento\Sales\Model\Order $order
* @param OrderInterface|MagentoOrder $order
*/
protected function sendOrderEmails(OrderInterface $order): void
{
Expand Down
4 changes: 3 additions & 1 deletion Model/Client/Payments.php
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,9 @@ public function processTransaction(Order $order, $mollieApi, $type = 'webhook',
);
}

$payment->registerCaptureNotification($order->getBaseGrandTotal(), true);
if (!in_array($order->getState(), [Order::STATE_PROCESSING, Order::STATE_COMPLETE])) {
$payment->registerCaptureNotification($order->getBaseGrandTotal(), true);
}
}

$order->setState(Order::STATE_PROCESSING);
Expand Down
2 changes: 1 addition & 1 deletion Service/Magento/PaymentLinkRedirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function execute(string $orderId): PaymentLinkRedirectResult
]);
}

if ($this->isPaymentLinkExpired->execute($order) || !$order->canReorder()) {
if ($this->isPaymentLinkExpired->execute($order)) {
return $this->paymentLinkRedirectResultFactory->create([
'redirectUrl' => null,
'isExpired' => true,
Expand Down
1 change: 1 addition & 0 deletions Service/Mollie/GetMollieStatusResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function shouldRedirectToSuccessPage(): bool
'pending',
'paid',
'authorized',
'shipping', // When having free or virtual products orders might go into shipping status real quick
'completed', // Completed is mainly to support digital products
]);
}
Expand Down
14 changes: 9 additions & 5 deletions Service/Mollie/Order/IsPaymentLinkExpired.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public function __construct(

public function execute(OrderInterface $order): bool
{
$methodCode = $this->methodCode->execute($order);
$this->methodCode->getExpiresAtMethod();
$this->methodCode->execute($order);
$methodCode = $this->methodCode->getExpiresAtMethod();
if (!$this->expires->availableForMethod($methodCode, $order->getStoreId())) {
return $this->checkWithDefaultDate($order);
}
Expand All @@ -51,11 +51,15 @@ public function execute(OrderInterface $order): bool
return $expiresAt < $order->getCreatedAt();
}

/**
* Default for when no expiry date is set on the chosen method.
*/
private function checkWithDefaultDate(OrderInterface $order): bool
{
$date = $this->timezone->scopeDate($order->getStoreId());
$date = $date->add(new \DateInterval('P28D'));
$now = $this->timezone->scopeDate($order->getStoreId());
$orderDate = $this->timezone->scopeDate($order->getStoreId(), new \DateTime($order->getCreatedAt()));
$diff = $now->diff($orderDate);

return $date->format('Y-m-d H:i:s') < $order->getCreatedAt();
return $diff->days >= 28;
}
}
1 change: 1 addition & 0 deletions Service/Order/MethodCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ private function paymentLinkMethod(OrderInterface $order): string
}

if (!is_array($additionalInformation['limited_methods']) || count($additionalInformation['limited_methods']) !== 1) {
$this->expiresAtMethod = 'paymentlink';
return '';
}

Expand Down
2 changes: 1 addition & 1 deletion Test/End-2-end/cypress/e2e/magento/checkout.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('Checkout usage', () => {

const availableMethods = Cypress.env('mollie_available_methods');
[
'alma',
// 'alma', Disabled, not available in NL
'bancomatpay',
'bancontact',
'banktransfer',
Expand Down
76 changes: 76 additions & 0 deletions Test/Integration/Service/Magento/PaymentLinkRedirectTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/*
* Copyright Magmodules.eu. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Mollie\Payment\Test\Integration\Service\Magento;

use Magento\Framework\Encryption\EncryptorInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;
use Mollie\Payment\Model\Mollie;
use Mollie\Payment\Service\Magento\PaymentLinkRedirect;
use Mollie\Payment\Test\Integration\IntegrationTestCase;

class PaymentLinkRedirectTest extends IntegrationTestCase
{
public function testThrowsExceptionWhenOrderDoesNotExists(): void
{
$this->expectException(\Magento\Framework\Exception\NotFoundException::class);

$encryptor = $this->objectManager->get(EncryptorInterface::class);
$orderId = base64_encode($encryptor->encrypt('random string'));

/** @var PaymentLinkRedirect $instance */
$instance = $this->objectManager->create(PaymentLinkRedirect::class);

$instance->execute($orderId);
}

/**
* @magentoDataFixture Magento/Sales/_files/order.php
*
* @return void
*/
public function testDoesNotRedirectWhenOrderAlreadyPaid(): void
{
$order = $this->loadOrder('100000001');
$order->setState(Order::STATE_PROCESSING);

$encryptor = $this->objectManager->get(EncryptorInterface::class);
$orderId = base64_encode($encryptor->encrypt($order->getEntityId()));

/** @var PaymentLinkRedirect $instance */
$instance = $this->objectManager->create(PaymentLinkRedirect::class);
$result = $instance->execute($orderId);

$this->assertTrue($result->isAlreadyPaid());
}

/**
* @magentoDataFixture Magento/Sales/_files/order.php
*
* @return void
*/
public function testDoesNotRedirectWhenExpired(): void
{
$orderRepository = $this->objectManager->get(OrderRepositoryInterface::class);

$order = $this->loadOrder('100000001');
$order->setState(Order::STATE_PENDING_PAYMENT);
$order->setCreatedAt(date('Y-m-d H:i:s', strtotime('-31 days')));
$orderRepository->save($order);

$encryptor = $this->objectManager->get(EncryptorInterface::class);
$orderId = base64_encode($encryptor->encrypt($order->getEntityId()));

/** @var PaymentLinkRedirect $instance */
$instance = $this->objectManager->create(PaymentLinkRedirect::class);
$result = $instance->execute($orderId);

$this->assertTrue($result->isExpired());
}
}
33 changes: 29 additions & 4 deletions Test/Integration/Service/Mollie/Order/IsPaymentLinkExpiredTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function testIsValidTheDayBeforeTheDefaultExpire(): void

$date = new \DateTimeImmutable();
$date = $date->add(new \DateInterval('P28D'))->setTime(0, 0, 0);
$order->setcreatedAt($date->format('Y-m-d H:i:s'));
$order->setCreatedAt($date->format('Y-m-d H:i:s'));

$instance = $this->objectManager->create(IsPaymentLinkExpired::class);

Expand All @@ -42,7 +42,7 @@ public function testIsInvalidTheDayAfterTheDefaultExpire(): void

$date = new \DateTimeImmutable();
$date = $date->add(new \DateInterval('P29D'))->setTime(23, 59, 59);
$order->setcreatedAt($date->format('Y-m-d H:i:s'));
$order->setCreatedAt($date->format('Y-m-d H:i:s'));

$instance = $this->objectManager->create(IsPaymentLinkExpired::class);

Expand All @@ -61,7 +61,7 @@ public function testIsValidWhenAvailableForMethodIsSetTheDayBefore(): void

$date = new \DateTimeImmutable();
$date = $date->add(new \DateInterval('P9D'))->setTime(0, 0, 0);
$order->setcreatedAt($date->format('Y-m-d H:i:s'));
$order->setCreatedAt($date->format('Y-m-d H:i:s'));

$order->getPayment()->setAdditionalInformation(['limited_methods' => ['ideal']]);

Expand All @@ -82,12 +82,37 @@ public function testIsValidWhenAvailableForMethodIsSetTheDayAfter(): void

$date = new \DateTimeImmutable();
$date = $date->add(new \DateInterval('P11D'))->setTime(23, 59, 59);
$order->setcreatedAt($date->format('Y-m-d H:i:s'));
$order->setCreatedAt($date->format('Y-m-d H:i:s'));

$order->getPayment()->setAdditionalInformation(['limited_methods' => ['ideal']]);

$instance = $this->objectManager->create(IsPaymentLinkExpired::class);

$this->assertTrue($instance->execute($order));
}

/**
* @magentoDataFixture Magento/Sales/_files/order.php
* @magentoConfigFixture default_store payment/mollie_methods_paymentlink/days_before_expire 10
*/
public function testUsesPaymentlinkForExpiryWhenNoLimitedMethodsAreSet(): void
{
$order = $this->loadOrder('100000001');
$order->getPayment()->setMethod(Paymentlink::CODE);
$order->getPayment()->setAdditionalInformation(['limited_methods' => null]);

$instance = $this->objectManager->create(IsPaymentLinkExpired::class);

$date = new \DateTimeImmutable();
$date = $date->add(new \DateInterval('P9D'))->setTime(23, 59, 59);
$order->setCreatedAt($date->format('Y-m-d H:i:s'));

$this->assertFalse($instance->execute($order));

$date = new \DateTimeImmutable();
$date = $date->add(new \DateInterval('P11D'))->setTime(23, 59, 59);
$order->setCreatedAt($date->format('Y-m-d H:i:s'));

$this->assertTrue($instance->execute($order));
}
}
32 changes: 22 additions & 10 deletions view/adminhtml/templates/form/mollie_paymentlink_javascript.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,34 @@
* Copyright Magmodules.eu. All rights reserved.
* See COPYING.txt for license details.
*/
?>
<script>
document.addEventListener('DOMContentLoaded', function () {

use Magento\Framework\View\Helper\SecureHtmlRenderer;

/** @var SecureHtmlRenderer $secureRenderer */

$scriptString = '
document.addEventListener(\'DOMContentLoaded\', function () {
const saveSelectedMethods = () => {
// Save the selected payment methods to local storage
var paymentMethods = document.getElementById('mollie_methods_paymentlink_methods');
var paymentMethods = document.getElementById(\'mollie_methods_paymentlink_methods\');
if (!paymentMethods) {
return;
}

paymentMethods.addEventListener('change', function () {
paymentMethods.addEventListener(\'change\', function () {
var selected = [];
for (var i = 0; i < paymentMethods.options.length; i++) {
if (paymentMethods.options[i].selected) {
selected.push(paymentMethods.options[i].value);
}
}
localStorage.setItem('mollie_paymentlink_methods', JSON.stringify(selected));
localStorage.setItem(\'mollie_paymentlink_methods\', JSON.stringify(selected));
});
};

const setSelectedMethods = () => {
var paymentMethods = document.getElementById('mollie_methods_paymentlink_methods');
const selectedMethods = JSON.parse(localStorage.getItem('mollie_paymentlink_methods'));
var paymentMethods = document.getElementById(\'mollie_methods_paymentlink_methods\');
const selectedMethods = JSON.parse(localStorage.getItem(\'mollie_paymentlink_methods\'));
if (!selectedMethods || !paymentMethods) {
return;
}
Expand All @@ -41,9 +45,17 @@
saveSelectedMethods();
setSelectedMethods();

document.getElementById('order-billing_method').addEventListener('DOMSubtreeModified', () => {
document.getElementById(\'order-billing_method\').addEventListener(\'DOMSubtreeModified\', () => {
saveSelectedMethods();
setSelectedMethods();
})
});
</script>
';

// @phpstan-ignore-next-line
if (isset($secureRenderer)) {
echo $secureRenderer->renderTag('script', [], $scriptString, false);
return;
}

echo '<script>' . $scriptString . '</script>';
Loading
Loading