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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.

## [2.0.6]
### Added
- Provide a new configuration option to enable or disable changing the order status to `In Progress` after successful payment.
- Improve error handling for capture and refund operations, ensuring clear and accurate error messages in all cases.

## [2.0.5]
### Added
- Add option to change the `Checkout Form Style`.
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.5",
"version": "2.0.6",
"authors": [
{
"name": "AltaPay A/S",
Expand Down
1 change: 1 addition & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sonar.projectKey=AltaPay_plugin-shopware_6ff55bfb-f13e-4cba-a54c-9f0804511bbf
sonar.projectBaseDir=src
sonar.coverage.exclusions=**
sonar.cpd.exclusions=**
13 changes: 6 additions & 7 deletions src/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,23 @@ public function capture(Request $request): JsonApiResponse|Response
->addSorting(new FieldSorting('transactions.createdAt', FieldSorting::DESCENDING));
$order = $this->orderRepository->search($criteria, $context)->first();
if (!$order) {
return new Response(status: 400);
return new JsonApiResponse(['success' => false, 'message' => 'Order not found.'], 400);
}

$transactionResponse = $this->paymentService->getTransaction($order, $order->getSalesChannelId());
$transactionResponseAsXml = new \SimpleXMLElement($transactionResponse->getBody()->getContents());
$altaPayTransaction = $transactionResponseAsXml->Body?->Transactions?->Transaction;

if (!$altaPayTransaction) {
return new Response(status: 400);
return new JsonApiResponse(['success' => false, 'message' => 'Transaction does not exist.'], 400);
}

$orderTotal = (float)$order->getAmountTotal();
$capturedAmount = (float)$altaPayTransaction->CapturedAmount;

$remainingAmount = $orderTotal - $capturedAmount;
if ($captureAmount > $remainingAmount) {
return new Response(status: 400);
return new JsonApiResponse(['success' => false, 'message' => 'The capture amount exceeds the remaining amount.'], 400);
}

/** @var $order OrderEntity */
Expand Down Expand Up @@ -101,24 +101,23 @@ public function refund(Request $request): JsonApiResponse|Response
->addSorting(new FieldSorting('transactions.createdAt', FieldSorting::DESCENDING));
$order = $this->orderRepository->search($criteria, $context)->first();
if (!$order) {
return new Response(status: 400);
return new JsonApiResponse(['success' => false, 'message' => 'Order not found.'], 400);
}

$transactionResponse = $this->paymentService->getTransaction($order, $order->getSalesChannelId());
$transactionResponseAsXml = new \SimpleXMLElement($transactionResponse->getBody()->getContents());
$altaPayTransaction = $transactionResponseAsXml->Body?->Transactions?->Transaction;

if (!$altaPayTransaction) {
return new Response(status: 400);
return new JsonApiResponse(['success' => false, 'message' => 'Transaction does not exist.'], 400);
}

$orderTotal = (float)$order->getAmountTotal();
$refundedAmount = (float)$altaPayTransaction->RefundedAmount;
$capturedAmount = (float)$altaPayTransaction->CapturedAmount;

$remainingAmount = $refundedAmount - $capturedAmount;
if ($remainingAmount == 0) {
return new Response(status: 400);
return new JsonApiResponse(['success' => false, 'message' => 'The order has already been fully refunded.'], 400);
}

/** @var $order OrderEntity */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ Shopware.Component.register('sw-order-detail-altapay', {
}
this.transaction = response.Body.Transactions.Transaction;
this.$emit('save-edits');
}).catch(error => {
const message = error.response?.data?.message;
this.errorMessage = message || 'Something went wrong.';
}).finally(() => {
setTimeout(() => {
this.isLoadingCapture = false;
Expand All @@ -91,6 +94,9 @@ Shopware.Component.register('sw-order-detail-altapay', {
}
this.transaction = response.Body.Transactions.Transaction;
this.$emit('save-edits');
}).catch(error => {
const message = error.response?.data?.message;
this.errorMessage = message || 'Something went wrong.';
}).finally(() => {
setTimeout(() => {
this.isLoadingRefund = false;
Expand Down
9 changes: 8 additions & 1 deletion src/Resources/config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@
<label>AltaPay Password</label>
</input-field>
</card>

<card>
<title>Order Status</title>
<input-field type="bool">
<name>updateOrderStateAfterPayment</name>
<label>Change the order status to In-Progress after a successful payment.</label>
<default>false</default>
</input-field>
</card>
<card>
<title>Checkout Settings</title>
<component name="sw-media-field">
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Resources/public/administration/js/wexo-alta-pay.js

Large diffs are not rendered by default.

31 changes: 19 additions & 12 deletions src/Service/PaymentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,8 @@ public function transactionCallback(
$salesChannelContext
);
}

$updateOrderStateAfterPayment = $this->systemConfigService->getBool('WexoAltaPay.config.updateOrderStateAfterPayment', $salesChannelContext->getSalesChannelId());
$stateMachineState = $transaction->getStateMachineState();
$currentState = $stateMachineState ? $stateMachineState->getTechnicalName() : null;
// Handle case when state machine state is null - force status update
if (!$stateMachineState) {
// Force the transaction to open state first, then process
Expand All @@ -299,17 +298,21 @@ public function transactionCallback(
$transaction->getId(),
$salesChannelContext->getContext()
);

// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $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()
);

// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());

if ($updateOrderStateAfterPayment) {
// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
}
}

break;
Expand All @@ -328,8 +331,10 @@ public function transactionCallback(
$transaction->getId(),
$salesChannelContext->getContext()
);
// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
if ($updateOrderStateAfterPayment) {
// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
}
} elseif (!$is_notification and $allRequestParams['type'] == 'paymentAndCapture' and $allRequestParams['require_capture'] == 'true') {
$captureResponse = $this->captureReservation($order, $salesChannelContext->getSalesChannelId(), (string)$result->Body->Transactions->Transaction->TransactionId);
$captureResponseAsXml = new SimpleXMLElement($captureResponse->getBody()->getContents());
Expand All @@ -344,8 +349,10 @@ public function transactionCallback(
$transaction->getId(),
$salesChannelContext->getContext()
);
// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
if ($updateOrderStateAfterPayment) {
// Update order state to "in progress"
$this->updateOrderStateToInProgress($order, $salesChannelContext->getContext());
}
}
break;
case "Cancel":
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.5';
public const ALTAPAY_PLUGIN_VERSION = '2.0.6';
public const ALTAPAY_PLUGIN_NAME = 'WexoAltaPay';

public function update(UpdateContext $updateContext): void
Expand Down
2 changes: 2 additions & 0 deletions wiki.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ be provided by AltaPay.

> **Note:** The **AltaPay ShopName** should match the subdomain at the beginning of your AltaPay URL. For example, if your payment URL is `https://demoshop.altapaysecure.com`, then the AltaPay ShopName is `demoshop`.

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. From the Checkout Form Style dropdown, choose the preferred checkout form style.
Expand Down