From c03b4ec8be6060f69137c5a03b75b24ca3fc493d Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Thu, 26 Oct 2023 12:05:01 +0200 Subject: [PATCH 01/12] Bugfix: Set a default for the issuer list type #710 --- .github/workflows/end-2-end-test.yml | 2 + Config.php | 16 + Helper/General.php | 4 +- Model/MollieConfigProvider.php | 2 +- Service/Mollie/GetIssuers.php | 12 +- .../e2e/magento/graphql/place-order.cy.js | 50 ++ .../cypress/fixtures/mollie-pwa.html | 834 ++++++++++++++++++ .../support/pages/backend/OrdersPage.js | 13 + 8 files changed, 925 insertions(+), 8 deletions(-) create mode 100644 Test/End-2-end/cypress/e2e/magento/graphql/place-order.cy.js create mode 100644 Test/End-2-end/cypress/fixtures/mollie-pwa.html diff --git a/.github/workflows/end-2-end-test.yml b/.github/workflows/end-2-end-test.yml index 43455ac0f36..14ff4a960e1 100644 --- a/.github/workflows/end-2-end-test.yml +++ b/.github/workflows/end-2-end-test.yml @@ -76,10 +76,12 @@ jobs: 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 + # Note the `mollie-pwa.html` file, as it is copied to the pub folder. This is so that it can be accessed by Cypress. - name: Upload the code into the docker container run: | sed -i '/version/d' ./composer.json && \ docker cp $(pwd) magento-project-community-edition:/data/extensions/ && \ + docker cp $(pwd)/Test/End-2-end/cypress/fixtures/mollie-pwa.html magento-project-community-edition:/data/pub/opt/ && \ docker exec magento-project-community-edition ./install-composer-package mollie/magento2:@dev - name: Activate the extension diff --git a/Config.php b/Config.php index 9fcb87b2724..0a2bf109633 100644 --- a/Config.php +++ b/Config.php @@ -58,6 +58,7 @@ class Config const PAYMENT_CREDITCARD_USE_COMPONENTS = 'payment/mollie_methods_creditcard/use_components'; const PAYMENT_CREDITCARD_ENABLE_CUSTOMERS_API = 'payment/mollie_methods_creditcard/enable_customers_api'; const PAYMENT_BANKTRANSFER_STATUS_PENDING = 'payment/mollie_methods_banktransfer/order_status_pending'; + const PAYMENT_METHOD_ISSUER_LIST_TYPE = 'payment/mollie_methods_%s/issuer_list_type'; const PAYMENT_METHOD_PAYMENT_ACTIVE = 'payment/mollie_methods_%s/active'; const PAYMENT_METHOD_PAYMENT_DESCRIPTION = 'payment/mollie_methods_%s/payment_description'; const PAYMENT_METHOD_PAYMENT_SURCHARGE_FIXED_AMOUNT = 'payment/mollie_methods_%s/payment_surcharge_fixed_amount'; @@ -73,6 +74,7 @@ class Config const PAYMENT_VOUCHER_CUSTOM_ATTRIBUTE = 'payment/mollie_methods_voucher/custom_attribute'; const CURRENCY_OPTIONS_DEFAULT = 'currency/options/default'; + /** * @var ScopeConfigInterface */ @@ -726,6 +728,20 @@ public function encryptPaymentDetails($storeId = null): bool return $this->isSetFlag(static::GENERAL_ENCRYPT_PAYMENT_DETAILS, $storeId); } + /** + * @param string $method + * @param null|int|string $storeId + * + * @return string + */ + public function getIssuerListType(string $method, $storeId = null): string + { + return $this->getPath( + $this->addMethodToPath(static::PAYMENT_METHOD_ISSUER_LIST_TYPE, $method), + $storeId + ) ?? 'none'; + } + /** * @param $method * @return string diff --git a/Helper/General.php b/Helper/General.php index 06945c89d3b..36683d2556e 100755 --- a/Helper/General.php +++ b/Helper/General.php @@ -380,6 +380,8 @@ public function useImage($storeId = null) } /** + * @deprecated See \Mollie\Payment\Config::getIssuerListType instead + * * @param string $method * * @return mixed @@ -387,7 +389,7 @@ public function useImage($storeId = null) public function getIssuerListType(string $method): string { $methodXpath = str_replace('%method%', $method, self::XPATH_ISSUER_LIST_TYPE); - return $this->getStoreConfig($methodXpath); + return $this->getStoreConfig($methodXpath) ?? 'none'; } /** diff --git a/Model/MollieConfigProvider.php b/Model/MollieConfigProvider.php index bb9797195e6..3efe02cc6ad 100644 --- a/Model/MollieConfigProvider.php +++ b/Model/MollieConfigProvider.php @@ -263,7 +263,7 @@ public function getActiveMethods(MollieApiClient $mollieApi, CartInterface $cart */ private function getIssuers(MollieApiClient $mollieApi, string $code, array $config): array { - $issuerListType = $this->mollieHelper->getIssuerListType($code); + $issuerListType = $this->config->getIssuerListType($code, $this->storeManager->getStore()->getId()); $config['payment']['issuersListType'][$code] = $issuerListType; $config['payment']['issuers'][$code] = $this->getIssuers->execute($mollieApi, $code, $issuerListType); diff --git a/Service/Mollie/GetIssuers.php b/Service/Mollie/GetIssuers.php index 25a3f0986dc..d9259c5ff71 100644 --- a/Service/Mollie/GetIssuers.php +++ b/Service/Mollie/GetIssuers.php @@ -10,6 +10,7 @@ use Magento\Framework\Serialize\SerializerInterface; use Magento\Framework\Locale\Resolver; use Mollie\Api\MollieApiClient; +use Mollie\Payment\Config; use Mollie\Payment\Helper\General; use Mollie\Payment\Model\Mollie as MollieModel; @@ -36,24 +37,23 @@ class GetIssuers * @var Resolver */ private $resolver; - /** - * @var General + * @var Config */ - private $general; + private $config; public function __construct( CacheInterface $cache, SerializerInterface $serializer, MollieModel $mollieModel, Resolver $resolver, - General $general + Config $config ) { $this->cache = $cache; $this->serializer = $serializer; $this->mollieModel = $mollieModel; $this->resolver = $resolver; - $this->general = $general; + $this->config = $config; } /** @@ -106,7 +106,7 @@ public function getForGraphql($storeId, string $method): ?array $issuers = $this->execute( $mollieApi, $method, - $this->general->getIssuerListType($method) + $this->config->getIssuerListType($method) ); if (!$issuers) { diff --git a/Test/End-2-end/cypress/e2e/magento/graphql/place-order.cy.js b/Test/End-2-end/cypress/e2e/magento/graphql/place-order.cy.js new file mode 100644 index 00000000000..b4251d1c255 --- /dev/null +++ b/Test/End-2-end/cypress/e2e/magento/graphql/place-order.cy.js @@ -0,0 +1,50 @@ +/* + * Copyright Magmodules.eu. All rights reserved. + * See COPYING.txt for license details. + */ + +import Cookies from "Services/Cookies"; +import MollieHostedPaymentPage from "Pages/mollie/MollieHostedPaymentPage"; +import CheckoutSuccessPage from "Pages/frontend/CheckoutSuccessPage"; +import OrdersPage from "Pages/backend/OrdersPage"; + +const cookies = new Cookies(); +const mollieHostedPaymentPage = new MollieHostedPaymentPage(); +const checkoutSuccessPage = new CheckoutSuccessPage(); +const ordersPage = new OrdersPage(); + +describe('Check that the headless endpoints work as expected', () => { + it('C1835263: Validate that an order can be placed through GraphQL ', () => { + cy.visit('opt/mollie-pwa.html'); + + cy.get('[data-key="start-checkout-process"]').click(); + + cy.get('[data-key="mollie_methods_ideal"]').click(); + + cy.get('[data-key="mollie_methods_ideal-issuer"]').first().click(); + + cy.get('[data-key="place-order-action"]').click(); + + cy.get('[data-key="increment-id"]').then((element) => { + cy.wrap(element.text()).as('increment-id'); + }); + + cookies.disableSameSiteCookieRestrictions(); + + cy.get('[data-key="redirect-url"]').then((element) => { + cy.visit(element.attr('href')); + }); + + mollieHostedPaymentPage.selectStatus('paid'); + + checkoutSuccessPage.assertThatOrderSuccessPageIsShown(); + + cy.backendLogin(false); + + cy.get('@increment-id').then((incrementId) => { + ordersPage.openByIncrementId(incrementId); + }); + + ordersPage.assertOrderStatusIs('Processing'); + }); +}) diff --git a/Test/End-2-end/cypress/fixtures/mollie-pwa.html b/Test/End-2-end/cypress/fixtures/mollie-pwa.html new file mode 100644 index 00000000000..fcea4e2c5e7 --- /dev/null +++ b/Test/End-2-end/cypress/fixtures/mollie-pwa.html @@ -0,0 +1,834 @@ + + + + +
+
+ + +
+
+
+
Profile ID (optional)
+
+
+ +
+
+ Mode + (Must match payment/mollie_general/type) +
+
+
+ +
+
+ +
+
CurrentStep
+
{{ currentStep }}
+
+ +
+
CartId
+
{{ cartId }}
+
+ +
+ +
+
+
+
    +
  • + + + Create cart + + (from storage) + +
  • +
  • + + + Add product to cart +
  • +
  • + + + Add shipping & billing address +
  • +
  • + + + Get shippings methods ({{ shippingMethod }}) +
  • +
  • + + + Set shipping method +
  • +
  • + + + Get payment methods +
  • +
  • + + + Set the payment method +
  • +
  • + + + Place order +
  • +
  • + + + Check transaction +
  • +
+ +
+
+
+
+ + +
+
+

Order done!

+
+

Order ID: {{ orderId }}

+

1. Please open this url and select a payment status (or not):

+ {{ redirectUrl }}
+ +

2. When you have opened the url, click here to get the payment status:

+ + +
+ PaymentStatus: {{ paymentStatus }}
+ redirect_to_cart: {{ redirectToCart ? 'true' : 'false' }}
+ redirect_to_success_page: {{ redirectToSuccessPage ? 'true' : 'false' }}
+
+
+
+
+
+
+ +
+
+ + {{ method.title }} + + +
    +
  • + +
  • +
+
+ +
+
+
Card Number
+
+
+
+ +
+
Card Holder
+
+
+
+ +
+
Expiry Date
+
+
+
+ +
+
CVV
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+ + Continue!? +
+
+
+ + + diff --git a/Test/End-2-end/cypress/support/pages/backend/OrdersPage.js b/Test/End-2-end/cypress/support/pages/backend/OrdersPage.js index 56b3b537b33..41f445ff7c6 100644 --- a/Test/End-2-end/cypress/support/pages/backend/OrdersPage.js +++ b/Test/End-2-end/cypress/support/pages/backend/OrdersPage.js @@ -15,6 +15,19 @@ export default class OrdersPage { cy.visit('/admin/sales/order/view/order_id/' + id); } + openByIncrementId(incrementId) { + cy.visit('/admin/sales/order/'); + + cy.get('.data-grid-cell-content') + .contains(incrementId) + .parents('tr') + .find('a.action-menu-item') + .contains('View') + .then((element) => { + cy.visit(element.attr('href')); + }); + } + callFetchStatus() { cy.get('.fetch-mollie-payment-status').click(); From 916893d01cfd9bc28b37d6306d6763442aff17bc Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Thu, 26 Oct 2023 14:55:48 +0200 Subject: [PATCH 02/12] Improvement: Added E2E test for refunds --- .../cypress/e2e/magento/backend/refunds.cy.js | 28 +++++++++++ .../actions/composite/PlaceOrderComposite.js | 28 +++++++++++ .../support/pages/backend/CreditMemoPage.js | 16 +++++++ .../pages/backend/InvoiceOverviewPage.js | 47 +++++++++++++++++++ .../support/pages/backend/InvoicePage.js | 11 +++++ 5 files changed, 130 insertions(+) create mode 100644 Test/End-2-end/cypress/e2e/magento/backend/refunds.cy.js create mode 100644 Test/End-2-end/cypress/support/actions/composite/PlaceOrderComposite.js create mode 100644 Test/End-2-end/cypress/support/pages/backend/CreditMemoPage.js create mode 100644 Test/End-2-end/cypress/support/pages/backend/InvoiceOverviewPage.js diff --git a/Test/End-2-end/cypress/e2e/magento/backend/refunds.cy.js b/Test/End-2-end/cypress/e2e/magento/backend/refunds.cy.js new file mode 100644 index 00000000000..a44b2e4c6bb --- /dev/null +++ b/Test/End-2-end/cypress/e2e/magento/backend/refunds.cy.js @@ -0,0 +1,28 @@ +/* + * Copyright Magmodules.eu. All rights reserved. + * See COPYING.txt for license details. + */ + +import InvoiceOverviewPage from "Pages/backend/InvoiceOverviewPage"; +import InvoicePage from "Pages/backend/InvoicePage"; +import CreditMemoPage from "Pages/backend/CreditMemoPage"; +import PlaceOrderComposite from "CompositeActions/PlaceOrderComposite"; + +const invoiceOverviewPage = new InvoiceOverviewPage(); +const invoicePage = new InvoicePage(); +const creditMemoPage = new CreditMemoPage(); +const placeOrderComposite = new PlaceOrderComposite(); + +describe('Check that refunds behave as excepted', () => { + it('Can do a refund on an iDeal order', () => { + placeOrderComposite.placeOrder(); + + cy.get('@order-id').then(orderId => { + invoiceOverviewPage.openByOrderId(orderId); + }); + + invoicePage.creditMemo(); + + creditMemoPage.refund(); + }); +}); diff --git a/Test/End-2-end/cypress/support/actions/composite/PlaceOrderComposite.js b/Test/End-2-end/cypress/support/actions/composite/PlaceOrderComposite.js new file mode 100644 index 00000000000..70cea2577e4 --- /dev/null +++ b/Test/End-2-end/cypress/support/actions/composite/PlaceOrderComposite.js @@ -0,0 +1,28 @@ +/* + * Copyright Magmodules.eu. All rights reserved. + * See COPYING.txt for license details. + */ + +import VisitCheckoutPaymentCompositeAction from "CompositeActions/VisitCheckoutPaymentCompositeAction"; +import CheckoutPaymentPage from "Pages/frontend/CheckoutPaymentPage"; +import MollieHostedPaymentPage from "Pages/mollie/MollieHostedPaymentPage"; +import CheckoutSuccessPage from "Pages/frontend/CheckoutSuccessPage"; + +const visitCheckoutPaymentCompositeAction = new VisitCheckoutPaymentCompositeAction(); +const checkoutPaymentsPage = new CheckoutPaymentPage(); +const mollieHostedPaymentPage = new MollieHostedPaymentPage(); +const checkoutSuccessPage = new CheckoutSuccessPage(); + +export default class PlaceOrderComposite { + placeOrder() { + visitCheckoutPaymentCompositeAction.visit(); + + checkoutPaymentsPage.selectPaymentMethod('iDeal'); + checkoutPaymentsPage.selectFirstAvailableIssuer(); + checkoutPaymentsPage.placeOrder(); + + mollieHostedPaymentPage.selectStatus('paid'); + + checkoutSuccessPage.assertThatOrderSuccessPageIsShown(); + } +} diff --git a/Test/End-2-end/cypress/support/pages/backend/CreditMemoPage.js b/Test/End-2-end/cypress/support/pages/backend/CreditMemoPage.js new file mode 100644 index 00000000000..329345f664c --- /dev/null +++ b/Test/End-2-end/cypress/support/pages/backend/CreditMemoPage.js @@ -0,0 +1,16 @@ +/* + * Copyright Magmodules.eu. All rights reserved. + * See COPYING.txt for license details. + */ + +export default class CreditMemoPage { + refund() { + cy.get('.primary.refund').click(); + + cy.url().should('include', 'admin/sales/order/view/order_id/'); + + cy.contains('You created the credit memo.'); + + cy.get('.note-list-comment').contains('We refunded').contains('Transaction ID:'); + } +} diff --git a/Test/End-2-end/cypress/support/pages/backend/InvoiceOverviewPage.js b/Test/End-2-end/cypress/support/pages/backend/InvoiceOverviewPage.js new file mode 100644 index 00000000000..a62a676bc4c --- /dev/null +++ b/Test/End-2-end/cypress/support/pages/backend/InvoiceOverviewPage.js @@ -0,0 +1,47 @@ +/* + * Copyright Magmodules.eu. All rights reserved. + * See COPYING.txt for license details. + */ + +import MagentoRestApi from "Services/MagentoRestApi"; + +const magentoRestApi = new MagentoRestApi(); + +export default class InvoiceOverviewPage { + openByOrderId(orderId) { + const invoices = magentoRestApi.getInvoicesByOrderId(orderId).then(response => { + const entityId = response.items[0].entity_id; + cy.wrap(entityId).as('invoiceId'); + const incrementId = response.items[0].increment_id; + cy.wrap(incrementId).as('invoiceIncrementId'); + }); + + cy.backendLogin(); + + cy.get('[data-ui-id="menu-magento-sales-sales-invoice"] a').click({force: true}); + + cy.url().should('include', 'admin/sales/invoice/index'); + + cy.get('[data-action="grid-filter-expand"]').click(); + + cy.get('.action-clear').click({force: true}); + + cy.get('@invoiceIncrementId').then(invoiceIncrementId => { + cy.get('.admin__form-field-label') + .contains('Invoice') + .parents('.admin__form-field') + .find('input') + .clear() + .type(invoiceIncrementId); + + cy.get('.admin__data-grid-filters-wrap .action-secondary').click(); + + cy.get('.data-grid-cell-content') + .contains(invoiceIncrementId) + .first() + .parents('tr') + .find('a') + .click(); + }); + } +} diff --git a/Test/End-2-end/cypress/support/pages/backend/InvoicePage.js b/Test/End-2-end/cypress/support/pages/backend/InvoicePage.js index fd7e1ac8f81..154836b389a 100644 --- a/Test/End-2-end/cypress/support/pages/backend/InvoicePage.js +++ b/Test/End-2-end/cypress/support/pages/backend/InvoicePage.js @@ -17,4 +17,15 @@ export default class InvoicePage { cy.url().should('include', '/admin/sales/order/view/order_id/'); } + + creditMemo() { + // Last element on the page so javascript has time to load + cy.get('.magento-version').should('be.visible'); + cy.wait(500); + + cy.get('.credit-memo') + .should('be.visible') + .should('not.be.disabled') + .click(); + } } From 26257fb6ecbec28506f861cb83d1cae032820a49 Mon Sep 17 00:00:00 2001 From: Florian Bender Date: Thu, 2 Nov 2023 12:07:29 +0100 Subject: [PATCH 03/12] PIMAG-503: Fix CC locales --- i18n/de_DE.csv | 2 +- i18n/en_US.csv | 2 +- i18n/es_ES.csv | 2 +- i18n/fr_FR.csv | 2 +- i18n/nl_NL.csv | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/i18n/de_DE.csv b/i18n/de_DE.csv index 33c354f4b48..ffc04215f39 100644 --- a/i18n/de_DE.csv +++ b/i18n/de_DE.csv @@ -198,7 +198,7 @@ "We recommend using another 'pending' status as the default Magento pending status can automatically cancel the order before the payment expiry time is reached.
By default the status ""Pending Payment"" is not visible for customers, therefore we advise you to create a new status for this, which should also be visible to the customer, informing them they still have to complete their payment.","Wir empfehlen, einen anderen als den standardmäßigen ausstehenden Status von Magento zu verwenden, da die Zahlung bei diesem vor Ablauf der Zahlungsfrist automatisch storniert werden kann.
Standardmäßig ist der Status „Ausstehende Zahlung“ für den Kunden nicht sichtbar. Wir empfehlen Ihnen daher, einen neuen Status zu erstellen, der auch für den Kunden sichtbar ist und ihm mitteilt, dass er die Zahlung noch vervollständigen muss." "Due Days","Zahlungstermine" "Belfius","Belfius" -"Credit Card","Kreditkarte" +"Credit Card","Kredit-/Debitkarte" "Use Mollie Components","Mollie-Komponenten verwenden" "Enable Single Click Payments","Ein-Klick-Zahlungen aktivieren" "SEPA Direct Debit","SEPA-Lastschrift" diff --git a/i18n/en_US.csv b/i18n/en_US.csv index 9423b35c7bc..bf91ace9770 100644 --- a/i18n/en_US.csv +++ b/i18n/en_US.csv @@ -198,7 +198,7 @@ "We recommend using another 'pending' status as the default Magento pending status can automatically cancel the order before the payment expiry time is reached.
By default the status ""Pending Payment"" is not visible for customers, therefore we advise you to create a new status for this, which should also be visible to the customer, informing them they still have to complete their payment.","We recommend using another 'pending' status as the default Magento pending status can automatically cancel the order before the payment expiry time is reached.
By default the status ""Pending Payment"" is not visible for customers, therefore we advise you to create a new status for this, which should also be visible to the customer, informing them they still have to complete their payment." "Due Days","Due Days" "Belfius","Belfius" -"Credit Card","Credit Card" +"Credit Card","Credit/Debit Card" "Use Mollie Components","Use Mollie Components" "Enable Single Click Payments","Enable Single Click Payments" "SEPA Direct Debit","SEPA Direct Debit" diff --git a/i18n/es_ES.csv b/i18n/es_ES.csv index b23eb98c316..b47786c5312 100644 --- a/i18n/es_ES.csv +++ b/i18n/es_ES.csv @@ -198,7 +198,7 @@ "We recommend using another 'pending' status as the default Magento pending status can automatically cancel the order before the payment expiry time is reached.
By default the status ""Pending Payment"" is not visible for customers, therefore we advise you to create a new status for this, which should also be visible to the customer, informing them they still have to complete their payment.","Recomendamos utilizar otro estado 'pendiente', ya que el estado pendiente por defecto de Magento puede cancelar automáticamente el pedido antes de que se llegue a la fecha de vencimiento del pago.
Por defecto, el estado «Pago pendiente» no es visible para los clientes, por lo que le aconsejamos que cree un nuevo estado para esto, que también debería ser visible para el cliente, que le informe de que todavía tiene que completar su pago." "Due Days","Días de vencimiento" "Belfius","Belfius" -"Credit Card","Tarjeta de crédito" +"Credit Card","Tarjeta de crédito/débito" "Use Mollie Components","Usar componentes de Mollie" "Enable Single Click Payments","Habilitar pagos con un solo clic" "SEPA Direct Debit","Adeudo directo SEPA" diff --git a/i18n/fr_FR.csv b/i18n/fr_FR.csv index 72501816b60..4a68eba30eb 100644 --- a/i18n/fr_FR.csv +++ b/i18n/fr_FR.csv @@ -198,7 +198,7 @@ "We recommend using another 'pending' status as the default Magento pending status can automatically cancel the order before the payment expiry time is reached.
By default the status ""Pending Payment"" is not visible for customers, therefore we advise you to create a new status for this, which should also be visible to the customer, informing them they still have to complete their payment.","Nous vous recommandons d'utiliser un autre statut «en attente», car le statut en attente Magento par défaut peut annuler automatiquement la commande avant même l'expiration du délai de paiement.
Comme le statut «Paiement en attente» n'est pas visible par défaut par les clients, nous vous recommandons de créer un nouveau statut qui sera visible par la clientèle et l'informera qu'elle doit finaliser son paiement." "Due Days","Jours d'échéance" "Belfius","Belfius" -"Credit Card","Carte de crédit" +"Credit Card","Carte de crédit/débit" "Use Mollie Components","Utilisez les composants Mollie" "Enable Single Click Payments","Activer les paiements Single Click" "SEPA Direct Debit","SEPA débit direct" diff --git a/i18n/nl_NL.csv b/i18n/nl_NL.csv index 80607968e49..81ccf595230 100644 --- a/i18n/nl_NL.csv +++ b/i18n/nl_NL.csv @@ -198,7 +198,7 @@ "We recommend using another 'pending' status as the default Magento pending status can automatically cancel the order before the payment expiry time is reached.
By default the status ""Pending Payment"" is not visible for customers, therefore we advise you to create a new status for this, which should also be visible to the customer, informing them they still have to complete their payment.","Wij raden u aan om een andere status voor 'openstaand' te gebruiken, omdat de standaard Magento-status 'openstaand' de bestelling automatisch kan annuleren, voordat de vervaltermijn is afgelopen.
Standaard is de status 'openstaande betaling' niet zichtbaar voor klanten, daarom adviseren wij u om hiervoor een nieuwe status aan te maken, die ook zichtbaar is voor de klant, om hem te laten weten dat hij zijn betaling nog dient te voltooien." "Due Days","Dagen achterstallig" "Belfius","Belfius" -"Credit Card","Creditcard" +"Credit Card","Krediet-/Debetkaart" "Use Mollie Components","Gebruik Mollie Components" "Enable Single Click Payments","Schakel betaling met één klik in" "SEPA Direct Debit","SEPA Direct Debit" From 04fd5da3a7f83917b36b95303e09a485d12fe61a Mon Sep 17 00:00:00 2001 From: James Allen-Lewis Date: Fri, 3 Nov 2023 17:01:01 +0000 Subject: [PATCH 04/12] Resolve issue where changing shipping method in ApplePay does not correctly update the quote, resulting in orders failing. Simplify entire code to remove unrequired saves/collects that are adding to the problem. Don't set a default shipping method - by the nature of this method a shipping method is always being passed in. --- Controller/ApplePay/ShippingMethods.php | 100 +++--------------------- 1 file changed, 13 insertions(+), 87 deletions(-) diff --git a/Controller/ApplePay/ShippingMethods.php b/Controller/ApplePay/ShippingMethods.php index 6d4377f3dfe..5a864e1470d 100644 --- a/Controller/ApplePay/ShippingMethods.php +++ b/Controller/ApplePay/ShippingMethods.php @@ -6,18 +6,13 @@ namespace Mollie\Payment\Controller\ApplePay; -use Magento\Checkout\Model\Session as CheckoutSession; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\Controller\ResultFactory; use Magento\Quote\Api\CartRepositoryInterface; -use Magento\Quote\Api\Data\AddressInterfaceFactory; use Magento\Quote\Api\Data\CartInterface; -use Magento\Quote\Api\Data\PaymentInterface; -use Magento\Quote\Api\Data\PaymentInterfaceFactory; use Magento\Quote\Api\GuestCartRepositoryInterface; -use Magento\Quote\Api\PaymentMethodManagementInterface; -use Magento\Quote\Api\ShippingMethodManagementInterface; +use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\Quote\Address\Total as AddressTotal; class ShippingMethods extends Action @@ -32,78 +27,39 @@ class ShippingMethods extends Action */ private $guestCartRepository; - /** - * @var AddressInterfaceFactory - */ - private $addressFactory; - - /** - * @var PaymentMethodManagementInterface - */ - private $paymentMethodManagement; - - /** - * @var PaymentInterfaceFactory - */ - private $paymentInterfaceFactory; - - /** - * @var CheckoutSession - */ - private $checkoutSession; - - /** - * @var ShippingMethodManagementInterface - */ - private $shippingMethodManagement; - public function __construct( Context $context, CartRepositoryInterface $cartRepository, GuestCartRepositoryInterface $guestCartRepository, - ShippingMethodManagementInterface $shippingMethodManagement, - AddressInterfaceFactory $addressFactory, - PaymentMethodManagementInterface $paymentMethodManagement, - PaymentInterfaceFactory $paymentInterfaceFactory, - CheckoutSession $checkoutSession ) { parent::__construct($context); - $this->guestCartRepository = $guestCartRepository; - $this->shippingMethodManagement = $shippingMethodManagement; - $this->addressFactory = $addressFactory; - $this->paymentMethodManagement = $paymentMethodManagement; - $this->paymentInterfaceFactory = $paymentInterfaceFactory; $this->cartRepository = $cartRepository; - $this->checkoutSession = $checkoutSession; } public function execute() { $cart = $this->getCart(); - $address = $this->addressFactory->create(); + /** + * @var Address $address + */ + $address = $cart->getShippingAddress(); + $address->setData(null); $address->setCountryId($this->getRequest()->getParam('countryCode')); $address->setPostcode($this->getRequest()->getParam('postalCode')); - $cart->setShippingAddress($address); - - $cart->collectTotals(); - $this->cartRepository->save($cart); - if ($this->getRequest()->getParam('shippingMethod')) { - $this->addShippingMethod($cart, $this->getRequest()->getParam('shippingMethod')['identifier']); + $address->setCollectShippingRates(true); + $address->setShippingMethod($this->getRequest()->getParam('shippingMethod')['identifier']); } - $methods = $this->shippingMethodManagement->getList($cart->getId()); - $this->setDefaultShippingMethod($cart, $methods); - - /** @var PaymentInterface $payment */ - $payment = $this->paymentInterfaceFactory->create(); - $payment->setMethod('mollie_methods_applepay'); - $this->paymentMethodManagement->set($cart->getId(), $payment); - $cart = $this->cartRepository->get($cart->getId()); + $cart->setPaymentMethod('mollie_methods_applepay'); + $cart->getPayment()->importData(['method' => 'mollie_methods_applepay']); + $this->cartRepository->save($cart); + $cart->collectTotals(); + $methods = $this->shippingMethodManagement->getList($cart->getId()); $response = $this->resultFactory->create(ResultFactory::TYPE_JSON); return $response->setData([ @@ -125,36 +81,6 @@ public function execute() ]); } - /** - * @param CartInterface $cart - * @param \Magento\Quote\Api\Data\ShippingMethodInterface[] $methods - */ - private function setDefaultShippingMethod(CartInterface $cart, array $methods) - { - if ($cart->getShippingAddress()->getShippingMethod()) { - return; - } - - $method = array_shift($methods); - if (!$method) { - return; - } - - $this->addShippingMethod($cart, $method->getCarrierCode() . '_' . $method->getMethodCode()); - $this->cartRepository->save($cart); - } - - private function addShippingMethod(CartInterface $cart, string $identifier) - { - $address = $cart->getShippingAddress(); - - $address->setShippingMethod($identifier); - $address->setCollectShippingRates(true); - $address->save(); - - $address->collectShippingRates(); - } - /** * @throws \Magento\Framework\Exception\NoSuchEntityException * @return CartInterface From e703b459f8a55ee66217d7a0fb228b0d88eb59f2 Mon Sep 17 00:00:00 2001 From: Florian Bender Date: Mon, 6 Nov 2023 09:56:17 +0100 Subject: [PATCH 05/12] Fix typo --- Controller/ApplePay/ShippingMethods.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Controller/ApplePay/ShippingMethods.php b/Controller/ApplePay/ShippingMethods.php index 5a864e1470d..84d80a02e06 100644 --- a/Controller/ApplePay/ShippingMethods.php +++ b/Controller/ApplePay/ShippingMethods.php @@ -30,7 +30,7 @@ class ShippingMethods extends Action public function __construct( Context $context, CartRepositoryInterface $cartRepository, - GuestCartRepositoryInterface $guestCartRepository, + GuestCartRepositoryInterface $guestCartRepository ) { parent::__construct($context); $this->guestCartRepository = $guestCartRepository; From d04fe1fef9a944f3c5768d3c112274d25b1d2be1 Mon Sep 17 00:00:00 2001 From: Florian Bender Date: Mon, 6 Nov 2023 10:08:19 +0100 Subject: [PATCH 06/12] Re-add Shipping Method Management --- Controller/ApplePay/ShippingMethods.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Controller/ApplePay/ShippingMethods.php b/Controller/ApplePay/ShippingMethods.php index 84d80a02e06..533722a39ad 100644 --- a/Controller/ApplePay/ShippingMethods.php +++ b/Controller/ApplePay/ShippingMethods.php @@ -12,6 +12,7 @@ use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Api\GuestCartRepositoryInterface; +use Magento\Quote\Api\ShippingMethodManagementInterface; use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\Quote\Address\Total as AddressTotal; @@ -27,12 +28,19 @@ class ShippingMethods extends Action */ private $guestCartRepository; + /** + * @var ShippingMethodManagementInterface + */ + private $shippingMethodManagement; + public function __construct( Context $context, CartRepositoryInterface $cartRepository, + ShippingMethodManagementInterface $shippingMethodManagement, GuestCartRepositoryInterface $guestCartRepository ) { parent::__construct($context); + $this->shippingMethodManagement = $shippingMethodManagement; $this->guestCartRepository = $guestCartRepository; $this->cartRepository = $cartRepository; } From 99e6343a1afbcadadd8f20199e7ad0d17cf190d0 Mon Sep 17 00:00:00 2001 From: Florian Bender Date: Mon, 6 Nov 2023 10:13:58 +0100 Subject: [PATCH 07/12] Re-add checkout session --- Controller/ApplePay/ShippingMethods.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Controller/ApplePay/ShippingMethods.php b/Controller/ApplePay/ShippingMethods.php index 533722a39ad..b6928076875 100644 --- a/Controller/ApplePay/ShippingMethods.php +++ b/Controller/ApplePay/ShippingMethods.php @@ -6,6 +6,7 @@ namespace Mollie\Payment\Controller\ApplePay; +use Magento\Checkout\Model\Session as CheckoutSession; use Magento\Framework\App\Action\Action; use Magento\Framework\App\Action\Context; use Magento\Framework\Controller\ResultFactory; @@ -33,16 +34,23 @@ class ShippingMethods extends Action */ private $shippingMethodManagement; + /** + * @var CheckoutSession + */ + private $checkoutSession; + public function __construct( Context $context, CartRepositoryInterface $cartRepository, ShippingMethodManagementInterface $shippingMethodManagement, + CheckoutSession $checkoutSession, GuestCartRepositoryInterface $guestCartRepository ) { parent::__construct($context); $this->shippingMethodManagement = $shippingMethodManagement; $this->guestCartRepository = $guestCartRepository; $this->cartRepository = $cartRepository; + $this->checkoutSession = $checkoutSession; } public function execute() From cf5e5b8012ca6da0d7a4a70c128ba36cecb85e36 Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Mon, 6 Nov 2023 13:15:38 +0100 Subject: [PATCH 08/12] Bugfix: Show the payment fee tax when the product has a different tax rate --- .../Quote/Address/Total/PaymentFeeTax.php | 88 ++++++++++++--- Plugin/Tax/Helper/DataPlugin.php | 104 ++++++++++++++++++ .../Quote/Address/Total/PaymentFeeTaxTest.php | 1 + etc/adminhtml/di.xml | 4 + 4 files changed, 184 insertions(+), 13 deletions(-) create mode 100644 Plugin/Tax/Helper/DataPlugin.php diff --git a/Model/PaymentFee/Quote/Address/Total/PaymentFeeTax.php b/Model/PaymentFee/Quote/Address/Total/PaymentFeeTax.php index 1e6f0d8afcb..b4772d7947c 100644 --- a/Model/PaymentFee/Quote/Address/Total/PaymentFeeTax.php +++ b/Model/PaymentFee/Quote/Address/Total/PaymentFeeTax.php @@ -6,25 +6,30 @@ namespace Mollie\Payment\Model\PaymentFee\Quote\Address\Total; +use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement; +use Magento\Customer\Api\Data\AddressInterfaceFactory as CustomerAddressFactory; +use Magento\Customer\Api\Data\RegionInterfaceFactory as CustomerAddressRegionFactory; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Quote\Api\Data\ShippingAssignmentInterface; use Magento\Quote\Model\Quote; use Magento\Quote\Model\Quote\Address\Total; use Magento\Quote\Model\Quote\Address\Total\AbstractTotal; +use Magento\Tax\Api\Data\QuoteDetailsInterfaceFactory; +use Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterfaceFactory; +use Magento\Tax\Api\Data\QuoteDetailsItemInterfaceFactory; +use Magento\Tax\Api\Data\TaxClassKeyInterface; +use Magento\Tax\Api\Data\TaxClassKeyInterfaceFactory; +use Magento\Tax\Api\TaxCalculationInterface; +use Magento\Tax\Helper\Data as TaxHelper; +use Magento\Tax\Model\Config as TaxConfig; use Magento\Tax\Model\Sales\Total\Quote\CommonTaxCollector; use Mollie\Payment\Config; use Mollie\Payment\Exceptions\UnknownPaymentFeeType; -use Mollie\Payment\Service\Config\PaymentFee as PaymentFeeConfig; use Mollie\Payment\Service\PaymentFee\Calculate; use Mollie\Payment\Service\PaymentFee\Result; -class PaymentFeeTax extends AbstractTotal +class PaymentFeeTax extends CommonTaxCollector { - /** - * @var PaymentFeeConfig - */ - private $paymentFeeConfig; - /** * @var PriceCurrencyInterface */ @@ -41,14 +46,55 @@ class PaymentFeeTax extends AbstractTotal private $config; public function __construct( - PaymentFeeConfig $paymentFeeConfig, - PriceCurrencyInterface $priceCurrency, + TaxConfig $taxConfig, + TaxCalculationInterface $taxCalculationService, + QuoteDetailsInterfaceFactory $quoteDetailsDataObjectFactory, + QuoteDetailsItemInterfaceFactory $quoteDetailsItemDataObjectFactory, + TaxClassKeyInterfaceFactory $taxClassKeyDataObjectFactory, + CustomerAddressFactory $customerAddressFactory, + CustomerAddressRegionFactory $customerAddressRegionFactory, Calculate $calculate, - Config $config + PriceCurrencyInterface $priceCurrency, + Config $config, + TaxHelper $taxHelper = null, + QuoteDetailsItemExtensionInterfaceFactory $quoteDetailsItemExtensionInterfaceFactory = null, + ?CustomerAccountManagement $customerAccountManagement = null ) { - $this->paymentFeeConfig = $paymentFeeConfig; - $this->priceCurrency = $priceCurrency; + $parent = new \ReflectionClass(parent::class); + $parentConstructor = $parent->getConstructor(); + + // The parent call fails when running setup:di:compile in 2.4.3 and lower due to an extra parameter. + if ($parentConstructor->getNumberOfParameters() == 9) { + // @phpstan-ignore-next-line + parent::__construct( + $taxConfig, + $taxCalculationService, + $quoteDetailsDataObjectFactory, + $quoteDetailsItemDataObjectFactory, + $taxClassKeyDataObjectFactory, + $customerAddressFactory, + $customerAddressRegionFactory, + $taxHelper, + $quoteDetailsItemExtensionInterfaceFactory + ); + } else { + // @phpstan-ignore-next-line + parent::__construct( + $taxConfig, + $taxCalculationService, + $quoteDetailsDataObjectFactory, + $quoteDetailsItemDataObjectFactory, + $taxClassKeyDataObjectFactory, + $customerAddressFactory, + $customerAddressRegionFactory, + $taxHelper, + $quoteDetailsItemExtensionInterfaceFactory, + $customerAccountManagement + ); + } + $this->calculate = $calculate; + $this->priceCurrency = $priceCurrency; $this->config = $config; } @@ -74,10 +120,26 @@ public function collect(Quote $quote, ShippingAssignmentInterface $shippingAssig $this->addAssociatedTaxable($shippingAssignment, $result, $quote); + $feeDataObject = $this->quoteDetailsItemDataObjectFactory->create() + ->setType('mollie_payment_fee') + ->setCode('mollie_payment_fee') + ->setQuantity(1); + + $feeDataObject->setUnitPrice($result->getRoundedAmount()); + $feeDataObject->setTaxClassKey( + $this->taxClassKeyDataObjectFactory->create() + ->setType(TaxClassKeyInterface::TYPE_ID) + ->setValue(4) + ); + $feeDataObject->setIsTaxIncluded(true); + + $quoteDetails = $this->prepareQuoteDetails($shippingAssignment, [$feeDataObject]); + + $this->taxCalculationService->calculateTax($quoteDetails, $quote->getStoreId()); + parent::collect($quote, $shippingAssignment, $total); $extensionAttributes = $quote->getExtensionAttributes(); - if (!$extensionAttributes) { return $this; } diff --git a/Plugin/Tax/Helper/DataPlugin.php b/Plugin/Tax/Helper/DataPlugin.php new file mode 100644 index 00000000000..58b90e589d1 --- /dev/null +++ b/Plugin/Tax/Helper/DataPlugin.php @@ -0,0 +1,104 @@ +orderTaxManagement = $orderTaxManagement; + } + + public function afterGetCalculatedTaxes(object $callable, array $result, $source): array + { + if (!$source instanceof InvoiceInterface && + !$source instanceof CreditmemoInterface + ) { + return $result; + } + + $order = $source->getOrder(); + $orderTaxDetails = $this->orderTaxManagement->getOrderTaxDetails($order->getId()); + + $items = array_filter($orderTaxDetails->getItems(), function (Item $item) { + return $item->getType() == 'mollie_payment_fee_tax'; + }); + + if (count($items) === 0) { + return $result; + } + + foreach ($items as $item) { + $result = $this->aggregateTaxes($result, $item, 1); + } + + return $result; + } + + /** + * Copied from \Magento\Tax\Helper\Data::_aggregateTaxes + * + * @param $taxClassAmount + * @param OrderTaxDetailsItemInterface $itemTaxDetail + * @param $ratio + * @return array + */ + private function aggregateTaxes($taxClassAmount, OrderTaxDetailsItemInterface $itemTaxDetail, $ratio) + { + $itemAppliedTaxes = $itemTaxDetail->getAppliedTaxes(); + foreach ($itemAppliedTaxes as $itemAppliedTax) { + $taxAmount = $itemAppliedTax->getAmount() * $ratio; + $baseTaxAmount = $itemAppliedTax->getBaseAmount() * $ratio; + + if (0 == $taxAmount && 0 == $baseTaxAmount) { + continue; + } + $taxCode = $this->getKeyByName($taxClassAmount, $itemAppliedTax->getCode()); + if (!isset($taxClassAmount[$taxCode])) { + $taxClassAmount[$taxCode]['title'] = $itemAppliedTax->getTitle(); + $taxClassAmount[$taxCode]['percent'] = $itemAppliedTax->getPercent(); + $taxClassAmount[$taxCode]['tax_amount'] = $taxAmount; + $taxClassAmount[$taxCode]['base_tax_amount'] = $baseTaxAmount; + } else { + $taxClassAmount[$taxCode]['tax_amount'] += $taxAmount; + $taxClassAmount[$taxCode]['base_tax_amount'] += $baseTaxAmount; + } + } + + return $taxClassAmount; + } + + /** + * @param array $taxClassAmount + * @param string $name + * @return string|int + */ + private function getKeyByName(array $taxClassAmount, string $name) + { + foreach ($taxClassAmount as $key => $tax) { + if ($tax['title'] === $name) { + return $key; + } + } + + return $name; + } +} diff --git a/Test/Integration/Model/PaymentFee/Quote/Address/Total/PaymentFeeTaxTest.php b/Test/Integration/Model/PaymentFee/Quote/Address/Total/PaymentFeeTaxTest.php index 57bf27b752b..116ec18d9ad 100644 --- a/Test/Integration/Model/PaymentFee/Quote/Address/Total/PaymentFeeTaxTest.php +++ b/Test/Integration/Model/PaymentFee/Quote/Address/Total/PaymentFeeTaxTest.php @@ -103,6 +103,7 @@ private function getShippingAssignment() { /** @var AddressInterface $address */ $address = $this->objectManager->create(AddressInterface::class); + $address->setQuote($this->getQuote()); /** @var ShippingInterface $shipping */ $shipping = $this->objectManager->create(ShippingInterface::class); diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml index 6bb0a891f96..43c49dd54e7 100644 --- a/etc/adminhtml/di.xml +++ b/etc/adminhtml/di.xml @@ -49,4 +49,8 @@ + + + + From d577ade12a8a352ec1178dfddab2405d79f97c27 Mon Sep 17 00:00:00 2001 From: Sam Butler Thompson Date: Mon, 6 Nov 2023 14:36:59 +0000 Subject: [PATCH 09/12] BUGFIX - Fix issue where this.applePayPaymentToken may not be defined when initially loaded --- .../web/js/view/payment/method-renderer/applepay-direct.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/view/frontend/web/js/view/payment/method-renderer/applepay-direct.js b/view/frontend/web/js/view/payment/method-renderer/applepay-direct.js index eb920e76e24..05f29cf8713 100644 --- a/view/frontend/web/js/view/payment/method-renderer/applepay-direct.js +++ b/view/frontend/web/js/view/payment/method-renderer/applepay-direct.js @@ -2,6 +2,7 @@ define( [ 'jquery', 'uiRegistry', + 'ko', 'Mollie_Payment/js/view/payment/method-renderer/default', 'Magento_Checkout/js/model/totals', 'mage/url', @@ -11,6 +12,7 @@ define( function ( $, uiRegistry, + ko, Component, totals, url, @@ -28,6 +30,7 @@ define( defaults: { template: 'Mollie_Payment/payment/applepay-direct', isIosc: uiRegistry.has("checkout.iosc.ajax"), + applePayPaymentToken: ko.observable('') }, initObservable: function () { From 7ec19ce0b7089bfde82ba42869edd59811a14d6b Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Thu, 9 Nov 2023 10:55:54 +0100 Subject: [PATCH 10/12] Bugfix: Get the grand total by code --- .github/workflows/templates/e2e/Dockerfile | 1 + Controller/ApplePay/ShippingMethods.php | 1 + view/frontend/web/js/view/product/apple-pay-button.js | 6 ++++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/templates/e2e/Dockerfile b/.github/workflows/templates/e2e/Dockerfile index 2136acaf2c3..b9bf86b6530 100644 --- a/.github/workflows/templates/e2e/Dockerfile +++ b/.github/workflows/templates/e2e/Dockerfile @@ -2,6 +2,7 @@ FROM cypress/included:12.1.0 WORKDIR /e2e +RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* RUN npm i @cypress/webpack-preprocessor cypress-mollie cypress-testrail --save-dev CMD tail -f /dev/null diff --git a/Controller/ApplePay/ShippingMethods.php b/Controller/ApplePay/ShippingMethods.php index 6d4377f3dfe..39fb40cbb26 100644 --- a/Controller/ApplePay/ShippingMethods.php +++ b/Controller/ApplePay/ShippingMethods.php @@ -118,6 +118,7 @@ public function execute() 'totals' => array_map(function (AddressTotal $total) { return [ 'type' => 'final', + 'code' => $total->getCode(), 'label' => $total->getData('title'), 'amount' => number_format($total->getData('value'), 2, '.', ''), ]; diff --git a/view/frontend/web/js/view/product/apple-pay-button.js b/view/frontend/web/js/view/product/apple-pay-button.js index f965801e7e1..1ae2ac23045 100644 --- a/view/frontend/web/js/view/product/apple-pay-button.js +++ b/view/frontend/web/js/view/product/apple-pay-button.js @@ -223,7 +223,9 @@ define([ getLineItems: function () { let totals = [...this.quoteTotals]; - totals.pop(); + + // Delete the item that has code == grand_total + totals.splice(totals.findIndex(total => total.code === 'grand_total'), 1); return totals; }, @@ -231,7 +233,7 @@ define([ getTotal: function () { let totals = [...this.quoteTotals]; - var total = totals.pop(); + const total = totals.find(total => total.code === 'grand_total'); total.label = this.storeName; From ed0bd924c3b0fa35a6768e1b843105b835987a0b Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Mon, 13 Nov 2023 15:36:30 +0100 Subject: [PATCH 11/12] Bugfix: Link all Mollie urls to the backend mollie/magento2-scandipwa#20 --- etc/di.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/di.xml b/etc/di.xml index cbaa6870e46..4db948de342 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -338,7 +338,7 @@ - ^/mollie/checkout/webhook.* + ^/mollie/.* From 7d2cdb804574e3fecb31dac27cb4d1606a7e814e Mon Sep 17 00:00:00 2001 From: Marvin Besselsen Date: Tue, 14 Nov 2023 11:10:57 +0100 Subject: [PATCH 12/12] Version bump --- composer.json | 2 +- etc/config.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 086128c0ee2..057388c2ca7 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "mollie/magento2", "description": "Mollie Payment Module for Magento 2", - "version": "2.32.2", + "version": "2.32.3", "keywords": [ "mollie", "payment", diff --git a/etc/config.xml b/etc/config.xml index 753a4a59a11..80db50cddd7 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -3,7 +3,7 @@ - v2.32.2 + v2.32.3 0 0 test