Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Binary file modified Docs/Configuration/shopware_setup_altapay_credentials.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 6 additions & 2 deletions src/Controller/CallbackController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
Expand Down
12 changes: 12 additions & 0 deletions src/Resources/config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@
<default>false</default>
</input-field>
</card>
<card>
<title>Known IP Protection</title>
<input-field type="bool">
<name>enableKnownIpProtection</name>
<label>Known IP Protection</label>
<default>true</default>
<helpText>
Restricts callbacks to known gateway IP addresses.
Disable this option if the store is using a firewall or proxy service (such as Cloudflare).
</helpText>
</input-field>
</card>
<card>
<title>Checkout Settings</title>
<component name="sw-media-field">
Expand Down
65 changes: 39 additions & 26 deletions src/Service/PaymentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)) {
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/WexoAltaPay.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions wiki.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down