diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83ab875..117d2e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.
+## [2.0.8]
+### Fixed
+- Payment status was shown as Failed even though the order was placed successfully.
+- Add a new configuration option to enable or disable Known IP Protection for callbacks.
## [2.0.7]
### Fixed
diff --git a/Docs/Configuration/shopware_setup_altapay_credentials.png b/Docs/Configuration/shopware_setup_altapay_credentials.png
index 4730faf..d6211ee 100644
Binary files a/Docs/Configuration/shopware_setup_altapay_credentials.png and b/Docs/Configuration/shopware_setup_altapay_credentials.png differ
diff --git a/composer.json b/composer.json
index bf83c4e..1adda35 100644
--- a/composer.json
+++ b/composer.json
@@ -3,7 +3,7 @@
"description": "AltaPay plugin for Shopware 6",
"type": "shopware-platform-plugin",
"license": "MIT",
- "version": "2.0.7",
+ "version": "2.0.8",
"authors": [
{
"name": "AltaPay A/S",
diff --git a/src/Controller/CallbackController.php b/src/Controller/CallbackController.php
index d9efca8..eaf7f31 100644
--- a/src/Controller/CallbackController.php
+++ b/src/Controller/CallbackController.php
@@ -165,8 +165,12 @@ public function getError(Request $request): Response
)]
public function notification(Request $request, SalesChannelContext $salesChannelContext)
{
- if (!IpUtils::checkIp($request->getClientIp(), PaymentService::ALTAPAY_IP_ADDRESS_SET)) {
- return new Response('Invalid request', 400);
+ $enableKnownIpProtection = $this->systemConfigService->getBool(
+ 'WexoAltaPay.config.enableKnownIpProtection',
+ $salesChannelContext->getSalesChannelId()
+ );
+ if ($enableKnownIpProtection && !IpUtils::checkIp($request->getClientIp(), PaymentService::ALTAPAY_IP_ADDRESS_SET)) {
+ return new Response('Invalid callback request', 400);
}
try {
$result = new SimpleXMLElement($request->get('xml'));
diff --git a/src/Resources/config/config.xml b/src/Resources/config/config.xml
index 533da7a..01064a6 100644
--- a/src/Resources/config/config.xml
+++ b/src/Resources/config/config.xml
@@ -54,6 +54,18 @@
false
+
+ Known IP Protection
+
+ enableKnownIpProtection
+
+ true
+
+ Restricts callbacks to known gateway IP addresses.
+ Disable this option if the store is using a firewall or proxy service (such as Cloudflare).
+
+
+ Checkout Settings
diff --git a/src/Service/PaymentService.php b/src/Service/PaymentService.php
index ff389ec..c465129 100644
--- a/src/Service/PaymentService.php
+++ b/src/Service/PaymentService.php
@@ -56,7 +56,8 @@ class PaymentService extends AbstractPaymentHandler
public const ALTAPAY_TRANSACTION_ID_CUSTOM_FIELD = "wexoAltaPayTransactionId";
public const ALTAPAY_TRANSACTION_PAYMENT_SCHEME_NAME_CUSTOM_FIELD = "wexoAltapayTransactionPaymentSchemeName";
public const ALTAPAY_TRANSACTION_PAYMENT_NATURE_CUSTOM_FIELD = "wexoAltapayTransactionPaymentNature";
- public const ALTAPAY_IP_ADDRESS_SET = ["185.206.120.0/24", "2a10:a200::/29"];
+ public const ALTAPAY_IP_ADDRESS_SET = ["185.206.120.0/24", "2a10:a200::/29", '185.203.232.129', '185.203.233.129']; //NOSONAR
+ public const ALTAPAY_ORDER_STATUS = "altaPayOrderStatus";
public function __construct(
protected readonly SystemConfigService $systemConfigService,
@@ -268,6 +269,12 @@ public function transactionCallback(
case "Open":
break;
case "Success":
+ $customFields = $order->getCustomFields() ?? [];
+ $orderStatus = $customFields[self::ALTAPAY_ORDER_STATUS] ?? null;
+
+ if ($orderStatus === 'processed') {
+ break;
+ }
// Delete cart when either customer or AltaPay reaches this page.
$cartToken = $order->getCustomFieldsValue(field: WexoAltaPay::ALTAPAY_CART_TOKEN);
if (!empty($cartToken)) {
@@ -280,41 +287,47 @@ public function transactionCallback(
$stateMachineState = $transaction->getStateMachineState();
// Handle case when state machine state is null - force status update
if (!$stateMachineState) {
- // Force the transaction to open state first, then process
- $this->orderTransactionStateHandler->reopen(
- $transaction->getId(),
- $salesChannelContext->getContext()
- );
-
- // Now process to in_progress
- $this->orderTransactionStateHandler->process(
- $transaction->getId(),
- $salesChannelContext->getContext()
- );
-
- // Handle payment status
- if ($result->Body->Transactions->Transaction->CapturedAmount > 0) {
- $this->orderTransactionStateHandler->paid(
+ try {
+ // Force the transaction to open state first, then process
+ $this->orderTransactionStateHandler->reopen(
$transaction->getId(),
$salesChannelContext->getContext()
);
- if ($updateOrderStateAfterPayment) {
- // Update order state to "in progress"
- $this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
- }
- } elseif ($result->Body->Transactions->Transaction->ReservedAmount > 0) {
- $this->orderTransactionStateHandler->authorize(
+ // Now process to in_progress
+ $this->orderTransactionStateHandler->process(
$transaction->getId(),
$salesChannelContext->getContext()
);
- if ($updateOrderStateAfterPayment) {
- // Update order state to "in progress"
- $this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
+ // Handle payment status
+ if ($result->Body->Transactions->Transaction->CapturedAmount > 0) {
+ $this->orderTransactionStateHandler->paid(
+ $transaction->getId(),
+ $salesChannelContext->getContext()
+ );
+
+ if ($updateOrderStateAfterPayment) {
+ // Update order state to "in progress"
+ $this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
+ }
+ } elseif ($result->Body->Transactions->Transaction->ReservedAmount > 0) {
+ $this->orderTransactionStateHandler->authorize(
+ $transaction->getId(),
+ $salesChannelContext->getContext()
+ );
+
+ if ($updateOrderStateAfterPayment) {
+ // Update order state to "in progress"
+ $this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
+ }
}
+ $order->changeCustomFields([
+ self::ALTAPAY_ORDER_STATUS => 'processed'
+ ]);
+ } catch (\Exception $e) {
+ $this->logger->error("order transaction state error:". $e->getMessage());
}
-
break;
}
diff --git a/src/WexoAltaPay.php b/src/WexoAltaPay.php
index c90e13d..51615b6 100644
--- a/src/WexoAltaPay.php
+++ b/src/WexoAltaPay.php
@@ -21,7 +21,7 @@ class WexoAltaPay extends Plugin
public const ALTAPAY_FIELD_SET_NAME = "wexoAltaPay";
public const ALTAPAY_PAYMENT_METHOD_FIELD_SET_NAME = "wexoAltaPayPaymentMethod";
public const ALTAPAY_CART_TOKEN = "wexoAltaPayCartToken";
- public const ALTAPAY_PLUGIN_VERSION = '2.0.7';
+ public const ALTAPAY_PLUGIN_VERSION = '2.0.8';
public const ALTAPAY_PLUGIN_NAME = 'WexoAltaPay';
public function update(UpdateContext $updateContext): void
diff --git a/wiki.md b/wiki.md
index c30e7d0..e5f11e9 100644
--- a/wiki.md
+++ b/wiki.md
@@ -63,9 +63,11 @@ be provided by AltaPay.
3. Enable the **Change the order status to In-Progress after a successful payment** setting if you want to update the order status to **In Progress** automatically after a successful payment.
-3. Select the payment form logo to be displayed in the header of the payment form.
+4. Enable **Known IP Protection** option to restrict callbacks to known gateway IP addresses. Disable this option if the store is using a firewall or proxy service (such as Cloudflare).
-4. From the Checkout Form Style dropdown, choose the preferred checkout form style.
+5. Select the payment form logo to be displayed in the header of the payment form.
+
+6. From the Checkout Form Style dropdown, choose the preferred checkout form style.
`Legacy`