Compare commits

..

1 Commits

Author SHA1 Message Date
andrewrowanwallee 2f5789aea8 Release 7.0.0 2025-06-24 11:48:03 +02:00
45 changed files with 577 additions and 427 deletions
+2 -5
View File
@@ -1,8 +1,5 @@
# 6.1.16 # 7.0.0
- Fixed issue with pending orders remaining open - Compatibility with Shopware 6.7.0
# 6.1.15
- Fixed issue with shipping costs not being processed correctly
# 6.1.14 # 6.1.14
- Disable Recreate Cart for Headless Storefront Order - Disable Recreate Cart for Headless Storefront Order
+2 -5
View File
@@ -1,8 +1,5 @@
# 6.1.16 # 7.0.0
- Problem behoben, bei dem die Versandkosten nicht korrekt verarbeitet wurden - Kompatibilität mit Shopware 6.7.0
# 6.1.15
- Problem behoben, bei dem ausstehende Bestellungen offen blieben
# 6.1.14 # 6.1.14
Warenkorb neu erstellen für Headless Storefront Order deaktivieren Warenkorb neu erstellen für Headless Storefront Order deaktivieren
+10 -10
View File
@@ -3,21 +3,20 @@
VR Payment Integration for Shopware 6 VR Payment Integration for Shopware 6
============================= =============================
## **Overview** The VR Payment plugin wraps around the VR Payment API. This library facilitates your interaction with various services such as transactions.
The VR Payment Payment Plugin integrates modern payment processing into Shopware 6, offering features like iFrame-based payments, refunds, captures, and PCI compliance. It supports seamless integration with the [VR Payment Portal](https://gateway.vr-payment.de/) for managing transactions and payment methods. Please note that this plugin is for versions 6.5, 6.6 or 6.7. For the 6.4 plugin please visit [our Shopware 6.4 plugin](https://github.com/vr-payment/shopware-6-4).
## Requirements ## Requirements
- **Shopware Version:** 6.5.x or 6.6.x (see [compatibility table](#compatibility)). - Shopware 6.7.x, 6.6.x or 6.5.x. See table below.
- **PHP:** Minimum version as required by your Shopware installation (e.g., 7.4+). - PHP minimum version supported by the each shop version.
- **VR Payment Account:** Obtain `Space ID`, `User ID`, and `API Key` from the [VR Payment Dashboard](https://gateway.vr-payment.de/).
## Documentation ## Documentation
- For English documentation click [here](@WalleeDocPath(/docs/en/documentation.html)) - For English documentation click [here](https://plugin-documentation.vr-payment.de/vr-payment/shopware-6/7.0.0/docs/en/documentation.html)
- Für die deutsche Dokumentation klicken Sie [hier](@WalleeDocPath(/docs/de/documentation.html)) - Für die deutsche Dokumentation klicken Sie [hier](https://plugin-documentation.vr-payment.de/vr-payment/shopware-6/7.0.0/docs/de/documentation.html)
- Pour la documentation Française, cliquez [ici](@WalleeDocPath(/docs/fr/documentation.html)) - Pour la documentation Française, cliquez [ici](https://plugin-documentation.vr-payment.de/vr-payment/shopware-6/7.0.0/docs/fr/documentation.html)
- Per la documentazione in tedesco, clicca [qui](@WalleeDocPath(/docs/it/documentation.html)) - Per la documentazione in tedesco, clicca [qui](https://plugin-documentation.vr-payment.de/vr-payment/shopware-6/7.0.0/docs/it/documentation.html)
## Installation ## Installation
@@ -67,7 +66,8 @@ Configure supported methods (e.g., credit cards, Apple Pay) via the [VR Payment
___________________________________________________________________________________ ___________________________________________________________________________________
| Shopware 6 version | Plugin major version | Supported until | | Shopware 6 version | Plugin major version | Supported until |
|-------------------------------|------------------------|------------------------| |-------------------------------|------------------------|------------------------|
| Shopware 6.6.x | 6.x | Further notice | | Shopware 6.7.x | 7.x | Further notice |
| Shopware 6.6.x | 6.x | December 2025 |
| Shopware 6.5.x | 5.x | October 2024 | | Shopware 6.5.x | 5.x | October 2024 |
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
+4 -4
View File
@@ -53,11 +53,11 @@
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"php": ">=8.2", "php": ">=8.2",
"shopware/core": "~6.6.0", "shopware/core": "~6.7.0",
"shopware/administration": "~6.6.0", "shopware/administration": "~6.7.0",
"shopware/storefront":"~6.6.0", "shopware/storefront":"~6.7.0",
"vrpayment/sdk": "^4.0.0" "vrpayment/sdk": "^4.0.0"
}, },
"type": "shopware-platform-plugin", "type": "shopware-platform-plugin",
"version": "6.1.16" "version": "7.0.0"
} }
+3 -3
View File
@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment."> <meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment.">
<link rel="canonical" href="@WalleeCanonicalPath(https://plugin-documentation.wallee.com/wallee-payment, VRPaymentPayment/docs/de/documentation.html)" /> <link rel="canonical" href="https://plugin-documentation.wallee.com/wallee-payment/shopware-6/master/VRPaymentPayment/docs/de/documentation.html" />
<title>VR Payment Zahlungs-Plugin für Shopware 6</title> <title>VR Payment Zahlungs-Plugin für Shopware 6</title>
<link href="assets/monokai-sublime.css" rel="stylesheet" /> <link href="assets/monokai-sublime.css" rel="stylesheet" />
<link href="assets/base.css" rel="stylesheet" /> <link href="assets/base.css" rel="stylesheet" />
@@ -23,7 +23,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="@WalleeReleasePath()"> <a href="https://github.com/vr-payment/shopware-6/releases/tag/7.0.0/">
Source Source
</a> </a>
</li> </li>
@@ -185,7 +185,7 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
<p>Gehen Sie zu <a href="https://gateway.vr-payment.de/user/login">VR Payment</a> und erstellen Sie ein Konto, falls Sie noch keines haben.</p> <p>Gehen Sie zu <a href="https://gateway.vr-payment.de/user/login/user/login">VR Payment</a> und erstellen Sie ein Konto, falls Sie noch keines haben.</p>
</div><div class="admonitionblock tip"> </div><div class="admonitionblock tip">
<table> <table>
<tr> <tr>
+3 -3
View File
@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment."> <meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment.">
<link rel="canonical" href="@WalleeCanonicalPath(https://plugin-documentation.wallee.com/wallee-payment, VRPaymentPayment/docs/en/documentation.html)" /> <link rel="canonical" href="https://plugin-documentation.wallee.com/wallee-payment/shopware-6/master/VRPaymentPayment/docs/en/documentation.html" />
<title>VR Payment Shopware 6 Documentation</title> <title>VR Payment Shopware 6 Documentation</title>
<link href="assets/monokai-sublime.css" rel="stylesheet" /> <link href="assets/monokai-sublime.css" rel="stylesheet" />
<link href="assets/base.css" rel="stylesheet" /> <link href="assets/base.css" rel="stylesheet" />
@@ -23,7 +23,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="@WalleeReleasePath()"> <a href="https://github.com/vr-payment/shopware-6/releases/tag/7.0.0/">
Source Source
</a> </a>
</li> </li>
@@ -179,7 +179,7 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
<p>Go to <a href="https://gateway.vr-payment.de/user/login">VR Payment</a> and create an Account if you do not already have one.</p> <p>Go to <a href="https://gateway.vr-payment.de/user/login/user/login">VR Payment</a> and create an Account if you do not already have one.</p>
</div><div class="admonitionblock tip"> </div><div class="admonitionblock tip">
<table> <table>
<tr> <tr>
+3 -3
View File
@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment."> <meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment.">
<link rel="canonical" href="@WalleeCanonicalPath(https://plugin-documentation.wallee.com/wallee-payment, VRPaymentPayment/docs/fr/documentation.html)" /> <link rel="canonical" href="https://plugin-documentation.wallee.com/wallee-payment/shopware-6/master/VRPaymentPayment/docs/fr/documentation.html" />
<title>Wallee Payment Plugin pour Shopware 6</title> <title>Wallee Payment Plugin pour Shopware 6</title>
<link href="assets/monokai-sublime.css" rel="stylesheet" /> <link href="assets/monokai-sublime.css" rel="stylesheet" />
<link href="assets/base.css" rel="stylesheet" /> <link href="assets/base.css" rel="stylesheet" />
@@ -23,7 +23,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="@WalleeReleasePath()"> <a href="https://github.com/vr-payment/shopware-6/releases/tag/7.0.0/">
Source Source
</a> </a>
</li> </li>
@@ -172,7 +172,7 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
<p>Allez sur hhttps://gateway.vr-payment.de/user/login[VR Payment] et créez un Compte si vous nen avez pas déjà un</p> <p>Allez sur <a href="https://gateway.vr-payment.de/user/login/user/login">VR Payment</a> et créez un Compte si vous nen avez pas déjà un</p>
</div><div class="admonitionblock tip"> </div><div class="admonitionblock tip">
<table> <table>
<tr> <tr>
+3 -3
View File
@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment."> <meta name="keywords" value="VR Payment, Shopware, Shopware Plugin, Payment, Payment Integration, Documentation"><meta name="description" value="The documentation for the Shopware 6 plugin that enables processing payments with VR Payment.">
<link rel="canonical" href="@WalleeCanonicalPath(https://plugin-documentation.wallee.com/wallee-payment, VRPaymentPayment/docs/it/documentation.html)" /> <link rel="canonical" href="https://plugin-documentation.wallee.com/wallee-payment/shopware-6/master/VRPaymentPayment/docs/it/documentation.html" />
<title>VR Payment Shopware 6 Documentation</title> <title>VR Payment Shopware 6 Documentation</title>
<link href="assets/monokai-sublime.css" rel="stylesheet" /> <link href="assets/monokai-sublime.css" rel="stylesheet" />
<link href="assets/base.css" rel="stylesheet" /> <link href="assets/base.css" rel="stylesheet" />
@@ -23,7 +23,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="@WalleeReleasePath()"> <a href="https://github.com/vr-payment/shopware-6/releases/tag/7.0.0/">
Source Source
</a> </a>
</li> </li>
@@ -179,7 +179,7 @@ php bin/console plugin:install --activate --clearCache VRPaymentPayment</code></
</div> </div>
<div class="chapter-body"> <div class="chapter-body">
<div class="paragraph"> <div class="paragraph">
<p>Andate su <a href="https://gateway.vr-payment.de/user/login">VR Payment</a> e create un account se non ne avete già uno.</p> <p>Andate su <a href="https://gateway.vr-payment.de/user/login/user/login">VR Payment</a> e create un account se non ne avete già uno.</p>
</div><div class="admonitionblock tip"> </div><div class="admonitionblock tip">
<table> <table>
<tr> <tr>
@@ -499,6 +499,7 @@ class PaymentMethodConfigurationService {
'afterOrderEnabled' => true, 'afterOrderEnabled' => true,
'active' => true, 'active' => true,
'translations' => $this->getPaymentMethodConfigurationTranslation($paymentMethodConfiguration, $context), 'translations' => $this->getPaymentMethodConfigurationTranslation($paymentMethodConfiguration, $context),
'technicalName' => $paymentMethodConfiguration->getName(),
]; ];
$data['mediaId'] = $this->upsertMedia($id, $paymentMethodConfiguration, $context); $data['mediaId'] = $this->upsertMedia($id, $paymentMethodConfiguration, $context);
@@ -8,7 +8,7 @@ use Shopware\Core\{
Checkout\Cart\CartException, Checkout\Cart\CartException,
Checkout\Cart\LineItem\LineItem, Checkout\Cart\LineItem\LineItem,
Checkout\Order\OrderEntity, Checkout\Order\OrderEntity,
Checkout\Payment\Cart\AsyncPaymentTransactionStruct, Checkout\Payment\Cart\PaymentTransactionStruct,
Framework\Context, Framework\Context,
Framework\DataAbstractionLayer\Search\Criteria, Framework\DataAbstractionLayer\Search\Criteria,
Framework\DataAbstractionLayer\Search\Filter\EqualsFilter, Framework\DataAbstractionLayer\Search\Filter\EqualsFilter,
@@ -115,7 +115,7 @@ class TransactionService
* *
* A redirect to the url will be performed * A redirect to the url will be performed
* *
* @param \Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct $transaction * @param \Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct $transaction
* @param \Shopware\Core\System\SalesChannel\SalesChannelContext $salesChannelContext * @param \Shopware\Core\System\SalesChannel\SalesChannelContext $salesChannelContext
* *
* @return string * @return string
@@ -124,10 +124,14 @@ class TransactionService
* @throws \VRPayment\Sdk\VersioningException * @throws \VRPayment\Sdk\VersioningException
*/ */
public function create( public function create(
AsyncPaymentTransactionStruct $transaction, PaymentTransactionStruct $transaction,
SalesChannelContext $salesChannelContext SalesChannelContext $salesChannelContext
): string ): string
{ {
$criteria = new Criteria([$transaction->getOrderTransactionId()]);
$criteria->addAssociation('order');
$orderTransaction = $this->container->get('order_transaction.repository')->search($criteria, $salesChannelContext->getContext())->first();
$salesChannelId = $salesChannelContext->getSalesChannel()->getId(); $salesChannelId = $salesChannelContext->getSalesChannel()->getId();
$settings = $this->settingsService->getSettings($salesChannelId); $settings = $this->settingsService->getSettings($salesChannelId);
$apiClient = $settings->getApiClient(); $apiClient = $settings->getApiClient();
@@ -165,7 +169,7 @@ class TransactionService
$redirectUrl = $this->container->get('router')->generate( $redirectUrl = $this->container->get('router')->generate(
'frontend.vrpayment.checkout.pay', 'frontend.vrpayment.checkout.pay',
['orderId' => $transaction->getOrder()->getId(),], ['orderId' => $orderTransaction->getOrder()->getId(),],
UrlGeneratorInterface::ABSOLUTE_URL UrlGeneratorInterface::ABSOLUTE_URL
); );
@@ -177,8 +181,8 @@ class TransactionService
$this->upsert( $this->upsert(
$createdTransaction, $createdTransaction,
$salesChannelContext->getContext(), $salesChannelContext->getContext(),
$transaction->getOrderTransaction()->getPaymentMethodId(), $orderTransaction->getPaymentMethodId(),
$transaction->getOrder()->getSalesChannelId() $orderTransaction->getOrder()->getSalesChannelId()
); );
$_SESSION['transactionId'] = null; $_SESSION['transactionId'] = null;
$_SESSION['arrayOfPossibleMethods'] = null; $_SESSION['arrayOfPossibleMethods'] = null;
@@ -186,26 +190,26 @@ class TransactionService
$_SESSION['currencyCheck'] = null; $_SESSION['currencyCheck'] = null;
$this->holdDelivery($transaction->getOrder()->getId(), $salesChannelContext->getContext()); $this->holdDelivery($orderTransaction->getOrder()->getId(), $salesChannelContext->getContext());
return $redirectUrl; return $redirectUrl;
} }
/** /**
* @param \Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct $transaction * @param \Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct $transaction
* @param \Shopware\Core\Framework\Context $context * @param \Shopware\Core\Framework\Context $context
* @param int $vrpaymentTransactionId * @param int $vrpaymentTransactionId
* @param int $spaceId * @param int $spaceId
*/ */
protected function addVRPaymentTransactionId( protected function addVRPaymentTransactionId(
AsyncPaymentTransactionStruct $transaction, PaymentTransactionStruct $transaction,
Context $context, Context $context,
int $vrpaymentTransactionId, int $vrpaymentTransactionId,
int $spaceId int $spaceId
): void ): void
{ {
$data = [ $data = [
'id' => $transaction->getOrderTransaction()->getId(), 'id' => $transaction->getOrderTransactionId(),
'customFields' => [ 'customFields' => [
TransactionPayload::ORDER_TRANSACTION_CUSTOM_FIELDS_VRPAYMENT_TRANSACTION_ID => $vrpaymentTransactionId, TransactionPayload::ORDER_TRANSACTION_CUSTOM_FIELDS_VRPAYMENT_TRANSACTION_ID => $vrpaymentTransactionId,
TransactionPayload::ORDER_TRANSACTION_CUSTOM_FIELDS_VRPAYMENT_SPACE_ID => $spaceId, TransactionPayload::ORDER_TRANSACTION_CUSTOM_FIELDS_VRPAYMENT_SPACE_ID => $spaceId,
@@ -343,7 +347,7 @@ class TransactionService
* *
* @return \Shopware\Core\Checkout\Order\OrderEntity * @return \Shopware\Core\Checkout\Order\OrderEntity
*/ */
private function getOrderEntity(string $orderId, Context $context): OrderEntity protected function getOrderEntity(string $orderId, Context $context): OrderEntity
{ {
try { try {
$criteria = (new Criteria([$orderId]))->addAssociations(['deliveries']); $criteria = (new Criteria([$orderId]))->addAssociations(['deliveries']);
@@ -0,0 +1,59 @@
<?php declare(strict_types=1);
namespace VRPaymentPayment\Core\Checkout\Cart;
use Shopware\Core\Checkout\Cart\AbstractCartPersister;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use VRPaymentPayment\Core\Checkout\PaymentHandler\VRPaymentPaymentHandler;
class CustomCartPersister extends AbstractCartPersister
{
private AbstractCartPersister $inner;
public function __construct(AbstractCartPersister $inner)
{
$this->inner = $inner;
}
public function delete(string $token, SalesChannelContext $context): void
{
if (!$context->getContext()->hasState('do-cart-delete') && $this->isWhiteLabelPayment($context)) {
return;
}
$this->inner->delete($token, $context);
}
public function load(string $token, SalesChannelContext $context): Cart
{
return $this->inner->load($token, $context);
}
public function save(Cart $cart, SalesChannelContext $context): void
{
$this->inner->save($cart, $context);
}
public function replace(string $oldToken, string $newToken, SalesChannelContext $context): void
{
$this->inner->replace($oldToken, $newToken, $context);
}
public function getDecorated(): AbstractCartPersister
{
return $this->inner;
}
private function isWhiteLabelPayment(SalesChannelContext $context): bool
{
$paymentMethod = $context->getPaymentMethod();
if (!$paymentMethod instanceof PaymentMethodEntity) {
return false;
}
return $paymentMethod->getHandlerIdentifier() === VRPaymentPaymentHandler::class;
}
}
@@ -4,16 +4,30 @@ namespace VRPaymentPayment\Core\Checkout\PaymentHandler;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shopware\Core\{ use Shopware\Core\{
Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity,
Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler, Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler,
Checkout\Payment\Cart\AsyncPaymentTransactionStruct, Checkout\Payment\Cart\PaymentTransactionStruct,
Checkout\Payment\Cart\PaymentHandler\AsynchronousPaymentHandlerInterface, Checkout\Payment\Cart\PaymentHandler\AbstractPaymentHandler,
Checkout\Payment\Exception\AsyncPaymentFinalizeException, Checkout\Payment\Cart\PaymentHandler\PaymentHandlerType,
Checkout\Payment\Exception\AsyncPaymentProcessException,
Checkout\Payment\PaymentException, Checkout\Payment\PaymentException,
Checkout\Payment\Exception\CustomerCanceledAsyncPaymentException, Checkout\Payment\Exception\CustomerCanceledAsyncPaymentException,
Framework\App\AppException,
Framework\Api\Context\SalesChannelApiSource,
Framework\Context,
Framework\DataAbstractionLayer\EntityRepository,
Framework\DataAbstractionLayer\Search\Criteria,
Framework\DataAbstractionLayer\Search\Sorting\FieldSorting,
Framework\Struct\Struct,
Framework\Validation\DataBag\RequestDataBag, Framework\Validation\DataBag\RequestDataBag,
System\SalesChannel\SalesChannelContext System\SalesChannel\Context\SalesChannelContextService,
System\SalesChannel\Context\SalesChannelContextServiceParameters
}; };
use Shopware\Core\Framework\Util\Random;
use VRPaymentPayment\Core\Checkout\Cart\CustomCartPersister;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\CartPersister;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\{ use Symfony\Component\{
HttpFoundation\RedirectResponse, HttpFoundation\RedirectResponse,
HttpFoundation\Request HttpFoundation\Request
@@ -27,9 +41,14 @@ use VRPaymentPayment\Core\Api\Transaction\Service\TransactionService;
* *
* @package VRPaymentPayment\Core\Checkout\PaymentHandler * @package VRPaymentPayment\Core\Checkout\PaymentHandler
*/ */
class VRPaymentPaymentHandler implements AsynchronousPaymentHandlerInterface class VRPaymentPaymentHandler extends AbstractPaymentHandler
{ {
/**
* @var CustomCartPersister
*/
private CustomCartPersister $cartPersister;
/** /**
* @var \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService * @var \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService
*/ */
@@ -44,22 +63,34 @@ class VRPaymentPaymentHandler implements AsynchronousPaymentHandlerInterface
*/ */
private $orderTransactionStateHandler; private $orderTransactionStateHandler;
protected SalesChannelContextService $salesChannelContextService;
protected EntityRepository $orderTransactionRepository;
/** /**
* VRPaymentPaymentHandler constructor. * VRPaymentPaymentHandler constructor.
* *
* @param \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService $transactionService * @param \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService $transactionService
* @param \Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler $orderTransactionStateHandler * @param \Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler $orderTransactionStateHandler
* @param SalesChannelContextService $salesChannelContextService
* @param EntityRepository $orderTransactionRepository
*/ */
public function __construct(TransactionService $transactionService, OrderTransactionStateHandler $orderTransactionStateHandler) public function __construct(
{ CustomCartPersister $cartPersister,
TransactionService $transactionService,
OrderTransactionStateHandler $orderTransactionStateHandler,
SalesChannelContextService $salesChannelContextService,
EntityRepository $orderTransactionRepository
) {
$this->cartPersister = $cartPersister;
$this->transactionService = $transactionService; $this->transactionService = $transactionService;
$this->orderTransactionStateHandler = $orderTransactionStateHandler; $this->orderTransactionStateHandler = $orderTransactionStateHandler;
$this->salesChannelContextService = $salesChannelContextService;
$this->orderTransactionRepository = $orderTransactionRepository;
} }
/** /**
* @param \Psr\Log\LoggerInterface $logger * @param \Psr\Log\LoggerInterface $logger
* @internal
* @required
* *
*/ */
public function setLogger(LoggerInterface $logger): void public function setLogger(LoggerInterface $logger): void
@@ -73,78 +104,123 @@ class VRPaymentPaymentHandler implements AsynchronousPaymentHandlerInterface
* *
* A redirect to the url will be performed * A redirect to the url will be performed
* *
* @param \Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct $transaction * @param \Symfony\Component\HttpFoundation\Request
* @param \Shopware\Core\Framework\Validation\DataBag\RequestDataBag $dataBag * @param \Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct $transaction
* @param \Shopware\Core\System\SalesChannel\SalesChannelContext $salesChannelContext * @param \Shopware\Core\Framework\Context $context
* @param \Shopware\Core\Framework\Struct\Struct $validateStruct
* @return \Symfony\Component\HttpFoundation\RedirectResponse * @return \Symfony\Component\HttpFoundation\RedirectResponse
*/ */
public function pay( public function pay(
AsyncPaymentTransactionStruct $transaction, Request $request,
RequestDataBag $dataBag, PaymentTransactionStruct $transaction,
SalesChannelContext $salesChannelContext Context $context,
?Struct $validateStruct
): RedirectResponse ): RedirectResponse
{ {
try { try {
$orderTransactionId = $transaction->getOrderTransactionId();
$orderTransaction = $this->orderTransactionRepository->search(
(new Criteria([$orderTransactionId]))
->addAssociation('order'), $context
)->getEntities()->first();
$contextSource = $context->getSource();
if ($contextSource instanceof SalesChannelApiSource) {
$salesChannelContextId = $contextSource->getSalesChannelId();
}
$parameters = new SalesChannelContextServiceParameters($salesChannelContextId, $request->getSession()->get("sw-context-token", Random::getAlphanumericString(32)), originalContext: $context);
$salesChannelContext = $this->salesChannelContextService->get($parameters);
$redirectUrl = $transaction->getReturnUrl(); $redirectUrl = $transaction->getReturnUrl();
if ($transaction->getOrder()->getAmountTotal() > 0) {
if ($orderTransaction->getOrder()->getAmountTotal() > 0) {
$transactionId = $_SESSION['transactionId'] ?? null; $transactionId = $_SESSION['transactionId'] ?? null;
if ($transactionId === null) { if ($transactionId === null) {
$this->transactionService->createPendingTransaction($salesChannelContext); $this->transactionService->createPendingTransaction($transaction, $salesChannelContext);
} }
$redirectUrl = $this->transactionService->create($transaction, $salesChannelContext); $redirectUrl = $this->transactionService->create($transaction, $salesChannelContext);
} }
return new RedirectResponse($redirectUrl); return new RedirectResponse($redirectUrl);
} catch (\Exception $e) { } catch (\Throwable $e) {
unset($_SESSION['transactionId']); unset($_SESSION['transactionId']);
$errorMessage = 'An error occurred during the communication with external payment gateway : ' . $e->getMessage(); $errorMessage = 'An error occurred during the communication with external payment gateway : ' . $e->getMessage();
$this->logger->critical($errorMessage); $this->logger->critical($errorMessage);
throw new \Exception($transaction->getOrderTransaction()->getId() . ': ' . $errorMessage); throw PaymentException::customerCanceled($transaction->getOrderTransaction()->getId(), $errorMessage);
} }
} }
/** /**
* The finalize function will be called when the user is redirected back to shop from the payment gateway. * The finalize function will be called when the user is redirected back to shop from the payment gateway.
* *
* Throw a @param \Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct $transaction
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Symfony\Component\HttpFoundation\Request $request
* @param \Shopware\Core\System\SalesChannel\SalesChannelContext $salesChannelContext * @param \Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct $transaction
* @param \Shopware\Core\Framework\Context $context
* @throws \VRPayment\Sdk\ApiException * @throws \VRPayment\Sdk\ApiException
* @throws \VRPayment\Sdk\Http\ConnectionException * @throws \VRPayment\Sdk\Http\ConnectionException
* @throws \VRPayment\Sdk\VersioningException * @throws \VRPayment\Sdk\VersioningException
* @see AsyncPaymentFinalizeException exception if an error ocurres while calling an external payment API * @throws \Exception when the payment was canceled by the customer
* Throw a @see CustomerCanceledAsyncPaymentException exception if the customer canceled the payment process on
* payment provider page
*
*/ */
public function finalize( public function finalize(
AsyncPaymentTransactionStruct $transaction, Request $request,
Request $request, PaymentTransactionStruct $transaction,
SalesChannelContext $salesChannelContext Context $context
): void ): void
{ {
if ($transaction->getOrder()->getAmountTotal() > 0) { $orderTransactionId = $transaction->getOrderTransactionId();
$orderTransaction = $this->orderTransactionRepository->search(
(new Criteria([$orderTransactionId]))
->addAssociation('order'), $context
)->getEntities()->first();
if ($orderTransaction->getOrder()->getAmountTotal() > 0) {
$transactionEntity = $this->transactionService->getByOrderId( $transactionEntity = $this->transactionService->getByOrderId(
$transaction->getOrder()->getId(), $orderTransaction->getOrder()->getId(),
$salesChannelContext->getContext() $context
); );
$vRPaymentTransaction = $this->transactionService->read( $vRPaymentTransaction = $this->transactionService->read(
$transactionEntity->getTransactionId(), $transactionEntity->getTransactionId(),
$salesChannelContext->getSalesChannel()->getId() $transactionEntity->getSalesChannelId()
); );
if (in_array($vRPaymentTransaction->getState(), [TransactionState::FAILED])) { if (in_array($vRPaymentTransaction->getState(), [TransactionState::FAILED])) {
$errorMessage = strtr('Customer canceled payment for :orderId on SalesChannel :salesChannelName', [ $errorMessage = strtr('Customer canceled payment for :orderId on SalesChannel :salesChannelName', [
':orderId' => $transaction->getOrder()->getId(), ':orderId' => $orderTransaction->getOrder()->getId(),
':salesChannelName' => $salesChannelContext->getSalesChannel()->getName(), ':salesChannelName' => $transactionEntity->getSalesChannelId(),
]); ]);
unset($_SESSION['transactionId']); unset($_SESSION['transactionId']);
$this->logger->info($errorMessage); $this->logger->info($errorMessage);
throw PaymentException::customerCanceled($transaction->getOrderTransaction()->getId(), $errorMessage); throw PaymentException::customerCanceled($transaction->getOrderTransaction()->getId(), $errorMessage);
} }
} else { } else {
$this->orderTransactionStateHandler->paid($transaction->getOrderTransaction()->getId(), $salesChannelContext->getContext()); $this->orderTransactionStateHandler->paid($orderTransaction->getId(), $context);
}
$token = $request->getSession()->get('sw-context-token');
if ($token) {
$salesChannelId = $transactionEntity->getSalesChannelId();
$parameters = new SalesChannelContextServiceParameters($salesChannelId, $token, originalContext: $context);
$salesChannelContext = $this->salesChannelContextService->get($parameters);
$salesChannelContext->getContext()->addState('do-cart-delete');
$this->logger->info('Clearing cart with token: ' . $token);
$this->cartPersister->delete($salesChannelContext->getToken(), $salesChannelContext);
} }
} }
/**
* {@inheritDoc}
*/
public function supports(
PaymentHandlerType $type,
string $paymentMethodId,
Context $context
): bool {
if ($type === PaymentHandlerType::RECURRING) {
return false;
}
return true;
}
} }
+1 -32
View File
@@ -29,31 +29,6 @@ class SettingsService {
public const CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED = 'storefrontWebhooksUpdateEnabled'; public const CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED = 'storefrontWebhooksUpdateEnabled';
public const CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED = 'storefrontPaymentsUpdateEnabled'; public const CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED = 'storefrontPaymentsUpdateEnabled';
/**
* List of config properties whose values allowed to be empty without triggering a warning in logger.
*
* This list is derived from testing of all config properties. The plugin fails only when either spaceId, userId, applicationKey and/or integration is empty.
* On top of that, spaceId, userId, applicationKey are marked as "required" input fields in admin interface.
*
* It is worth considering updating this list whenever a new config is introduced in settings.
* If new config is optional, left empty by design and not required for transactions to work, this list should be updated to avoid false-positive warnings.
*
* @var array
*/
private const ALLOWED_EMPTY_CONFIGS = [
// Options
self::CONFIG_SPACE_VIEW_ID,
self::CONFIG_LINE_ITEM_CONSISTENCY_ENABLED,
self::CONFIG_EMAIL_ENABLED,
// Storefront Options
self::CONFIG_STOREFRONT_INVOICE_DOWNLOAD_ENABLED,
// Advanced Options
self::CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED,
self::CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED
];
/** /**
* @var \Shopware\Core\System\SystemConfig\SystemConfigService * @var \Shopware\Core\System\SystemConfig\SystemConfigService
*/ */
@@ -157,13 +132,7 @@ class SettingsService {
if ($property === '') { if ($property === '') {
continue; continue;
} }
// Space view id is only numeric setting which can be 0. If it is, rest of the loop is skipped. if (!is_numeric($value) && empty($value)) {
if ($property === self::CONFIG_SPACE_VIEW_ID && $value === 0) {
$propertyValuePairs[$property] = $value;
continue;
}
// Check if $value is empty and is not in the list of configs which are allowed to be empty
if (empty($value) && !in_array($property, self::ALLOWED_EMPTY_CONFIGS, true)) {
$this->logger->warning(strtr('Empty value :value for settings :property.', [':property' => $property, ':value' => $value])); $this->logger->warning(strtr('Empty value :value for settings :property.', [':property' => $property, ':value' => $value]));
} }
$propertyValuePairs[$property] = $value; $propertyValuePairs[$property] = $value;
@@ -10,9 +10,7 @@ use Shopware\Core\{
Checkout\Cart\SalesChannel\CartService, Checkout\Cart\SalesChannel\CartService,
Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection, Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection,
Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity, Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity,
Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler,
Checkout\Order\OrderEntity, Checkout\Order\OrderEntity,
Checkout\Order\OrderDefinition,
Checkout\Order\SalesChannel\AbstractOrderRoute, Checkout\Order\SalesChannel\AbstractOrderRoute,
Framework\Context, Framework\Context,
Framework\DataAbstractionLayer\Search\Criteria, Framework\DataAbstractionLayer\Search\Criteria,
@@ -23,9 +21,7 @@ use Shopware\Core\{
Framework\Uuid\Uuid, Framework\Uuid\Uuid,
Framework\Uuid\Exception\InvalidUuidException, Framework\Uuid\Exception\InvalidUuidException,
Framework\Validation\DataBag\RequestDataBag, Framework\Validation\DataBag\RequestDataBag,
System\SalesChannel\SalesChannelContext, System\SalesChannel\SalesChannelContext
System\StateMachine\StateMachineRegistry,
System\StateMachine\Transition,
}; };
use Shopware\Storefront\{ use Shopware\Storefront\{
Controller\StorefrontController, Controller\StorefrontController,
@@ -47,8 +43,7 @@ use VRPaymentPayment\Core\{
Settings\Options\Integration, Settings\Options\Integration,
Settings\Service\SettingsService, Settings\Service\SettingsService,
Storefront\Checkout\Struct\CheckoutPageData, Storefront\Checkout\Struct\CheckoutPageData,
Util\Payload\CustomProducts\CustomProductsLineItemTypes, Util\Payload\CustomProducts\CustomProductsLineItemTypes
Util\Payload\TransactionPayload
}; };
@@ -62,18 +57,6 @@ use VRPaymentPayment\Core\{
#[Route(defaults: ['_routeScope' => ['storefront']])] #[Route(defaults: ['_routeScope' => ['storefront']])]
class CheckoutController extends StorefrontController { class CheckoutController extends StorefrontController {
public const ORDER_STATE_CANCEL = 'cancel';
/**
* @var \Shopware\Core\System\StateMachine\StateMachineRegistry
*/
private $stateMachineRegistry;
/**
* @var \Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler
*/
protected $orderTransactionStateHandler;
/** /**
* @var \Shopware\Storefront\Page\GenericPageLoader * @var \Shopware\Storefront\Page\GenericPageLoader
*/ */
@@ -123,8 +106,6 @@ class CheckoutController extends StorefrontController {
* @param \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService $transactionService * @param \VRPaymentPayment\Core\Api\Transaction\Service\TransactionService $transactionService
* @param \Shopware\Storefront\Page\GenericPageLoaderInterface $genericLoader * @param \Shopware\Storefront\Page\GenericPageLoaderInterface $genericLoader
* @param \Shopware\Core\Checkout\Order\SalesChannel\AbstractOrderRoute $orderRoute * @param \Shopware\Core\Checkout\Order\SalesChannel\AbstractOrderRoute $orderRoute
* @param \Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler $orderTransactionStateHandler
* @param \Shopware\Core\System\StateMachine\StateMachineRegistry $stateMachineRegistry
*/ */
public function __construct( public function __construct(
LineItemFactoryRegistry $lineItemFactoryRegistry, LineItemFactoryRegistry $lineItemFactoryRegistry,
@@ -132,9 +113,7 @@ class CheckoutController extends StorefrontController {
SettingsService $settingsService, SettingsService $settingsService,
TransactionService $transactionService, TransactionService $transactionService,
GenericPageLoaderInterface $genericLoader, GenericPageLoaderInterface $genericLoader,
AbstractOrderRoute $orderRoute, AbstractOrderRoute $orderRoute
OrderTransactionStateHandler $orderTransactionStateHandler,
StateMachineRegistry $stateMachineRegistry
) )
{ {
$this->cartService = $cartService; $this->cartService = $cartService;
@@ -143,8 +122,6 @@ class CheckoutController extends StorefrontController {
$this->transactionService = $transactionService; $this->transactionService = $transactionService;
$this->lineItemFactoryRegistry = $lineItemFactoryRegistry; $this->lineItemFactoryRegistry = $lineItemFactoryRegistry;
$this->orderRoute = $orderRoute; $this->orderRoute = $orderRoute;
$this->orderTransactionStateHandler = $orderTransactionStateHandler;
$this->stateMachineRegistry = $stateMachineRegistry;
} }
/** /**
@@ -403,7 +380,6 @@ class CheckoutController extends StorefrontController {
} }
$transaction = $this->getTransaction($orderId, $salesChannelContext->getContext()); $transaction = $this->getTransaction($orderId, $salesChannelContext->getContext());
$orderTransactionId = $transaction->getMetaData()[TransactionPayload::VRPAYMENT_METADATA_ORDER_TRANSACTION_ID];
if (!empty($transaction->getUserFailureMessage())) { if (!empty($transaction->getUserFailureMessage())) {
$this->addFlash('danger', $transaction->getUserFailureMessage()); $this->addFlash('danger', $transaction->getUserFailureMessage());
} }
@@ -438,18 +414,6 @@ class CheckoutController extends StorefrontController {
} }
// Close the old, existing order to prevent confusion for the customer
$this->orderTransactionStateHandler->cancel($orderTransactionId, $salesChannelContext->getContext());
$this->stateMachineRegistry->transition(
new Transition(
OrderDefinition::ENTITY_NAME,
$orderId,
self::ORDER_STATE_CANCEL,
'stateId'
),
$salesChannelContext->getContext()
);
} catch (\Exception $exception) { } catch (\Exception $exception) {
$this->addFlash('danger', $this->trans('error.addToCartError')); $this->addFlash('danger', $this->trans('error.addToCartError'));
$this->logger->critical($exception->getMessage()); $this->logger->critical($exception->getMessage());
-2
View File
@@ -14,7 +14,6 @@ class Analytics {
public const SHOP_SYSTEM = 'x-meta-shop-system'; public const SHOP_SYSTEM = 'x-meta-shop-system';
public const SHOP_SYSTEM_VERSION = 'x-meta-shop-system-version'; public const SHOP_SYSTEM_VERSION = 'x-meta-shop-system-version';
public const SHOP_SYSTEM_AND_VERSION = 'x-meta-shop-system-and-version'; public const SHOP_SYSTEM_AND_VERSION = 'x-meta-shop-system-and-version';
public const PLUGIN_SYSTEM_VERSION = 'x-meta-plugin-version';
/** /**
* @return array * @return array
@@ -25,7 +24,6 @@ class Analytics {
self::SHOP_SYSTEM => 'shopware', self::SHOP_SYSTEM => 'shopware',
self::SHOP_SYSTEM_VERSION => '6', self::SHOP_SYSTEM_VERSION => '6',
self::SHOP_SYSTEM_AND_VERSION => 'shopware-6', self::SHOP_SYSTEM_AND_VERSION => 'shopware-6',
self::PLUGIN_SYSTEM_VERSION => '6.1.16',
]; ];
} }
+163 -66
View File
@@ -8,10 +8,14 @@ use Shopware\Core\{Checkout\Cart\Tax\Struct\CalculatedTaxCollection,
Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity, Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity,
Checkout\Customer\CustomerEntity, Checkout\Customer\CustomerEntity,
Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity, Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity,
Checkout\Payment\Cart\AsyncPaymentTransactionStruct, Checkout\Order\OrderEntity,
Checkout\Payment\Cart\PaymentTransactionStruct,
Framework\DataAbstractionLayer\Search\Criteria, Framework\DataAbstractionLayer\Search\Criteria,
System\SalesChannel\SalesChannelContext System\SalesChannel\SalesChannelContext
}; };
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use VRPayment\Sdk\{Model\AddressCreate, use VRPayment\Sdk\{Model\AddressCreate,
@@ -36,6 +40,10 @@ use VRPaymentPayment\Core\{Api\PaymentMethodConfiguration\Entity\PaymentMethodCo
Util\Payload\CustomProducts\CustomProductsLineItemTypes Util\Payload\CustomProducts\CustomProductsLineItemTypes
}; };
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Core\Framework\Context;
use Shopware\Core\System\Tax\TaxEntity;
/** /**
* Class TransactionPayload * Class TransactionPayload
* *
@@ -61,7 +69,7 @@ class TransactionPayload extends AbstractPayload
protected $salesChannelContext; protected $salesChannelContext;
/** /**
* @var \Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct * @var \Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct
*/ */
protected $transaction; protected $transaction;
@@ -85,6 +93,10 @@ class TransactionPayload extends AbstractPayload
*/ */
protected $translator; protected $translator;
protected EntityRepository $orderTransactionRepository;
protected OrderEntity $order;
/** /**
* TransactionPayload constructor. * TransactionPayload constructor.
* *
@@ -92,14 +104,14 @@ class TransactionPayload extends AbstractPayload
* @param \VRPaymentPayment\Core\Util\LocaleCodeProvider $localeCodeProvider * @param \VRPaymentPayment\Core\Util\LocaleCodeProvider $localeCodeProvider
* @param \Shopware\Core\System\SalesChannel\SalesChannelContext $salesChannelContext * @param \Shopware\Core\System\SalesChannel\SalesChannelContext $salesChannelContext
* @param \VRPaymentPayment\Core\Settings\Struct\Settings $settings * @param \VRPaymentPayment\Core\Settings\Struct\Settings $settings
* @param \Shopware\Core\Checkout\Payment\Cart\AsyncPaymentTransactionStruct $transaction * @param \Shopware\Core\Checkout\Payment\Cart\PaymentTransactionStruct $transaction
*/ */
public function __construct( public function __construct(
ContainerInterface $container, ContainerInterface $container,
LocaleCodeProvider $localeCodeProvider, LocaleCodeProvider $localeCodeProvider,
SalesChannelContext $salesChannelContext, SalesChannelContext $salesChannelContext,
Settings $settings, Settings $settings,
AsyncPaymentTransactionStruct $transaction PaymentTransactionStruct $transaction
) )
{ {
$this->localeCodeProvider = $localeCodeProvider; $this->localeCodeProvider = $localeCodeProvider;
@@ -108,6 +120,23 @@ class TransactionPayload extends AbstractPayload
$this->transaction = $transaction; $this->transaction = $transaction;
$this->container = $container; $this->container = $container;
$this->translator = $this->container->get('translator'); $this->translator = $this->container->get('translator');
$this->orderTransactionRepository = $this->container->get('order_transaction.repository');
$criteria = (new Criteria());
$criteria->addFilter(new EqualsFilter('id', $this->transaction->getOrderTransactionId()));
$orders = $this->orderTransactionRepository->search($criteria, $this->salesChannelContext->getContext())->getEntities();
$orderId = $orders->first()->getOrderId();
$criteria = new Criteria([$orderId]);
$criteria
->addAssociation('lineItems')
->addAssociation('orderCustomer')
->addAssociation('transactions')
->addAssociation('currency')
;
$this->order = $this->container->get('order.repository')->search($criteria, $this->salesChannelContext->getContext())->getEntities()->first();
} }
/** /**
@@ -118,13 +147,21 @@ class TransactionPayload extends AbstractPayload
*/ */
public function get(int $version): TransactionPending public function get(int $version): TransactionPending
{ {
$customer = $this->salesChannelContext->getCustomer(); $customerId = $this->order->getOrderCustomer()->getCustomerId();
$criteria = new Criteria([$customerId]);
$criteria->addAssociation('activeBillingAddress')
->addAssociation('activeShippingAddress')
->addAssociation('activeShippingAddress')
->addAssociation('defaultBillingAddress')
->addAssociation('defaultShippingAddress')
->addAssociation('salutation');
$customer = $this->container->get('customer.repository')->search($criteria, $this->salesChannelContext->getContext())->getEntities()->first();
$lineItems = $this->getLineItems(); $lineItems = $this->getLineItems();
$billingAddress = $this->getAddressPayload($customer, $customer->getActiveBillingAddress()); $billingAddress = $this->getAddressPayload($customer, $customer->getActiveBillingAddress());
$shippingAddress = $this->getAddressPayload($customer, $customer->getActiveShippingAddress(), false); $shippingAddress = $this->getAddressPayload($customer, $customer->getActiveShippingAddress(), false);
$customerId = null; $customerId = null;
$customerName = null; $customerName = null;
if ($customer->getGuest() === false) { if ($customer->getGuest() === false) {
@@ -137,14 +174,14 @@ class TransactionPayload extends AbstractPayload
} }
$transactionData = [ $transactionData = [
'currency' => $this->salesChannelContext->getCurrency()->getIsoCode(), 'currency' => $this->order->getCurrency()->getIsoCode(),
'customer_email_address' => $billingAddress->getEmailAddress(), 'customer_email_address' => $customer->getEmail(),
'customer_id' => $customerId, 'customer_id' => $customerId,
'language' => $this->localeCodeProvider->getLocaleCodeFromContext($this->salesChannelContext->getContext()) ?? null, 'language' => $this->localeCodeProvider->getLocaleCodeFromContext($this->salesChannelContext->getContext()) ?? null,
'merchant_reference' => $this->fixLength($this->transaction->getOrder()->getOrderNumber(), 100), 'merchant_reference' => $this->fixLength($this->order->getOrderNumber(), 100),
'meta_data' => [ 'meta_data' => [
self::VRPAYMENT_METADATA_ORDER_ID => $this->transaction->getOrder()->getId(), self::VRPAYMENT_METADATA_ORDER_ID => $this->order->getId(),
self::VRPAYMENT_METADATA_ORDER_TRANSACTION_ID => $this->transaction->getOrderTransaction()->getId(), self::VRPAYMENT_METADATA_ORDER_TRANSACTION_ID => $this->order->getTransactions()->first()->getId(),
self::VRPAYMENT_METADATA_SALES_CHANNEL_ID => $this->salesChannelContext->getSalesChannel()->getId(), self::VRPAYMENT_METADATA_SALES_CHANNEL_ID => $this->salesChannelContext->getSalesChannel()->getId(),
self::VRPAYMENT_METADATA_CUSTOMER_NAME => $customerName, self::VRPAYMENT_METADATA_CUSTOMER_NAME => $customerName,
], ],
@@ -161,8 +198,8 @@ class TransactionPayload extends AbstractPayload
$transactionData['meta_data']['additionalAddress2'] = $additionalAddress2; $transactionData['meta_data']['additionalAddress2'] = $additionalAddress2;
} }
if (!empty($this->transaction->getOrder()->getCustomerComment())) { if (!empty($this->order->getCustomerComment())) {
$transactionData['meta_data']['customer_comment'] = $this->transaction->getOrder()->getCustomerComment(); $transactionData['meta_data']['customer_comment'] = $this->order->getCustomerComment();
} }
$vatIds = $customer->getVatIds(); $vatIds = $customer->getVatIds();
@@ -198,7 +235,7 @@ class TransactionPayload extends AbstractPayload
$transactionPayload->setAllowedPaymentMethodConfigurations([$paymentConfiguration->getPaymentMethodConfigurationId()]); $transactionPayload->setAllowedPaymentMethodConfigurations([$paymentConfiguration->getPaymentMethodConfigurationId()]);
$successUrl = $this->transaction->getReturnUrl() . '&status=paid'; $successUrl = $this->transaction->getReturnUrl() . '&status=paid';
$failedUrl = $this->getFailUrl($this->transaction->getOrder()->getId()) . '&status=fail'; $failedUrl = $this->getFailUrl($this->order->getId()) . '&status=fail';
$transactionPayload->setSuccessUrl($successUrl) $transactionPayload->setSuccessUrl($successUrl)
->setFailedUrl($failedUrl); ->setFailedUrl($failedUrl);
@@ -219,7 +256,7 @@ class TransactionPayload extends AbstractPayload
protected function getLineItems(): array protected function getLineItems(): array
{ {
$lineItems = []; $lineItems = [];
$items = $this->transaction->getOrder()->getLineItems(); $items = $this->order->getLineItems() ?? [];
foreach ($items as $shopLineItem) { foreach ($items as $shopLineItem) {
if ($this->shouldSkipLineItem($shopLineItem)) { if ($this->shouldSkipLineItem($shopLineItem)) {
@@ -307,36 +344,99 @@ class TransactionPayload extends AbstractPayload
protected function addDiscountLineItem($discount, array &$lineItems): void protected function addDiscountLineItem($discount, array &$lineItems): void
{ {
$calculatedPrice = $discount->getPrice(); $calculatedPrice = $discount->getPrice();
$calculatedTaxesCollection = $calculatedPrice->getCalculatedTaxes(); $discountName = $discount->getLabel() ?? 'Unnamed';
$definition = $discount->getPriceDefinition();
foreach ($calculatedTaxesCollection as $calculatedTax) { if ($this->order->getTaxStatus() === 'net' || $definition instanceof \Shopware\Core\Checkout\Cart\Price\Struct\AbsolutePriceDefinition) {
$rate = $calculatedTax->getTaxRate(); $calculatedTaxesCollection = $calculatedPrice->getCalculatedTaxes();
$lineItem = new LineItemCreate(); foreach ($calculatedTaxesCollection as $calculatedTax) {
$amount = $this->calculateDiscountAmount($calculatedTax); $rate = $calculatedTax->getTaxRate();
$amount = $this->calculateDiscountAmount($calculatedTax);
$discountName = $discount->getLabel(); $lineItems[] = $this->createDiscountLineItem($discountName, $amount, $rate);
$lineItem->setAmountIncludingTax($amount) }
->setName(sprintf('DISCOUNT: %s (%s%% tax)', $discount->getLabel(), $rate)) } else {
->setQuantity(1) $taxRules = $calculatedPrice->getTaxRules();
->setShippingRequired(false)
->setSku('sku-discount-' . $rate . '-' . $discountName, 200)
->setType(LineItemType::DISCOUNT)
->setUniqueId('coupon-sku-discount-' . $rate . '-' . $rate . '-' . $discountName);
$taxRate = new TaxCreate(['title' => 'Discount Tax: ' . $rate, 'rate' => $rate]); if ($taxRules && $taxRules->count() > 0) {
$lineItem->setTaxes([$taxRate]); foreach ($taxRules as $taxRule) {
$rate = $taxRule->getTaxRate();
$lineItems[] = $lineItem; $amount = $calculatedPrice->getTotalPrice();
$lineItems[] = $this->createDiscountLineItem($discountName, $amount, $rate);
}
} else {
$rate = $this->getDefaultTaxRate();
$amount = $calculatedPrice->getTotalPrice();
$lineItems[] = $this->createDiscountLineItem($discountName, $amount, $rate);
}
} }
} }
/**
* @param string $discountName
* @param float $amount
* @param float $rate
* @return LineItemCreate
*/
private function createDiscountLineItem(string $discountName, float $amount, float $rate): LineItemCreate
{
$lineItem = new LineItemCreate();
$discountSkuName = 'sku-discount-' . $rate . '-' . $discountName;
$discountTitle = sprintf('DISCOUNT: %s (%s%% tax)', $discountName, $rate);
if ($this->order->getTaxStatus() === 'tax-free') {
$discountSkuName = 'sku-discount-' . $discountName;
$discountTitle = sprintf('DISCOUNT: %s', $discountName);
}
$lineItem->setAmountIncludingTax($amount)
->setName($discountTitle)
->setQuantity(1)
->setShippingRequired(false)
->setSku($discountSkuName, 200)
->setType(LineItemType::DISCOUNT)
->setUniqueId('coupon-' . $discountSkuName);
$taxRate = new TaxCreate([
'title' => 'Discount Tax: ' . $rate,
'rate' => $rate,
]);
if ($this->order->getTaxStatus() !== 'tax-free') {
$lineItem->setTaxes([$taxRate]);
}
return $lineItem;
}
/**
* @return float
*/
private function getDefaultTaxRate(): float
{
/** @var SystemConfigService $systemConfigService */
$systemConfigService = $this->container->get(SystemConfigService::class);
$taxId = $systemConfigService->get('core.tax.defaultTaxRate');
if (!$taxId || !is_string($taxId)) {
return 21.0;
}
$criteria = new Criteria([$taxId]);
/** @var TaxRepository $taxRepository */
$taxRepository = $this->container->get('tax.repository');
$tax = $taxRepository->search($criteria, Context::createDefaultContext())->get($taxId);
return $tax instanceof TaxEntity ? $tax->getTaxRate() : 21.0;
}
/** /**
* Calculate discount amount including tax if necessary. * Calculate discount amount including tax if necessary.
*/ */
protected function calculateDiscountAmount($calculatedTax): float protected function calculateDiscountAmount($calculatedTax): float
{ {
$amount = self::round($calculatedTax->getPrice()); $amount = self::round($calculatedTax->getPrice());
if ($this->transaction->getOrder()->getTaxStatus() === 'net') { if ($this->order->getTaxStatus() === 'net') {
$amount = self::round($amount + $calculatedTax->getTax()); $amount = self::round($amount + $calculatedTax->getTax());
} }
return $amount; return $amount;
@@ -357,9 +457,7 @@ class TransactionPayload extends AbstractPayload
*/ */
protected function addOptionalLineItems(array &$lineItems): void protected function addOptionalLineItems(array &$lineItems): void
{ {
$shippingCosts = $this->transaction->getOrder()->getShippingCosts(); if (count($this->order->getShippingCosts()->getCalculatedTaxes()) === 1) {
if ($shippingCosts && $this->transaction->getOrder()->getShippingTotal() > 0) {
if ($shippingLineItem = $this->getShippingLineItem()) { if ($shippingLineItem = $this->getShippingLineItem()) {
$lineItems[] = $shippingLineItem; $lineItems[] = $shippingLineItem;
} }
@@ -381,7 +479,7 @@ class TransactionPayload extends AbstractPayload
protected function getCustomProductOptionLabel(string $lineItemParentId): string protected function getCustomProductOptionLabel(string $lineItemParentId): string
{ {
$label = ''; $label = '';
foreach ($this->transaction->getOrder()->getLineItems() as $shopLineItem) { foreach ($this->order->getLineItems() as $shopLineItem) {
if ($shopLineItem->getParentId() === $lineItemParentId && $shopLineItem->getType() === CustomProductsLineItemTypes::LINE_ITEM_TYPE_PRODUCT) { if ($shopLineItem->getParentId() === $lineItemParentId && $shopLineItem->getType() === CustomProductsLineItemTypes::LINE_ITEM_TYPE_PRODUCT) {
$label = $shopLineItem->getLabel(); $label = $shopLineItem->getLabel();
break; break;
@@ -406,10 +504,11 @@ class TransactionPayload extends AbstractPayload
$sku = $payLoad['productNumber']; $sku = $payLoad['productNumber'];
} }
$sku = $this->fixLength($sku, 200); $sku = $this->fixLength($sku, 200);
$amount = $shopLineItem->getTotalPrice() ? self::round($shopLineItem->getTotalPrice()) : 0; $amount = $shopLineItem->getTotalPrice() ? self::round($shopLineItem->getTotalPrice()) : 0;
//include Tax Excluded for Net Tax display customer group //include Tax Excluded for Net Tax display customer group
if ($this->transaction->getOrder()->getTaxStatus() === 'net') { if ($this->order->getTaxStatus() === 'net') {
$amount = self::round($amount + $shopLineItem->getPrice()->getCalculatedTaxes()->getAmount()); $amount = self::round($amount + $shopLineItem->getPrice()->getCalculatedTaxes()->getAmount());
} }
@@ -445,7 +544,9 @@ class TransactionPayload extends AbstractPayload
} }
if (!empty($taxes)) { if (!empty($taxes)) {
$lineItem->setTaxes($taxes); if ($this->order->getTaxStatus() !== 'tax-free') {
$lineItem->setTaxes($taxes);
}
} }
if ($shopLineItem->getTotalPrice() >= 0) { if ($shopLineItem->getTotalPrice() >= 0) {
@@ -521,31 +622,34 @@ class TransactionPayload extends AbstractPayload
{ {
try { try {
$amount = $this->transaction->getOrder()->getShippingTotal(); $amount = $this->order->getShippingTotal();
$amount = self::round($amount); $amount = self::round($amount);
if ($amount > 0) { if ($amount > 0) {
$shippingName = $this->salesChannelContext->getShippingMethod()->getName() ?? $this->translator->trans('vrpayment.payload.shipping.name'); $shippingName = $this->salesChannelContext->getShippingMethod()->getName() ?? $this->translator->trans('vrpayment.payload.shipping.name');
$taxes = $this->getTaxes( $taxes = $this->getTaxes(
$this->transaction->getOrder()->getShippingCosts()->getCalculatedTaxes(), $this->order->getShippingCosts()->getCalculatedTaxes(),
$shippingName $shippingName
); );
if ($this->transaction->getOrder()->getTaxStatus() === 'net') { if ($this->order->getTaxStatus() === 'net') {
$amount = self::round($amount + $this->transaction->getOrder()->getShippingCosts()->getCalculatedTaxes()->getAmount()); $amount = self::round($amount + $this->order->getShippingCosts()->getCalculatedTaxes()->getAmount());
} }
$lineItem = (new LineItemCreate()) $lineItem = (new LineItemCreate())
->setAmountIncludingTax($amount) ->setAmountIncludingTax($amount)
->setName($this->fixLength($shippingName . ' ' . $this->translator->trans('vrpayment.payload.shipping.lineItem'), 150)) ->setName($this->fixLength($shippingName . ' ' . $this->translator->trans('vrpayment.payload.shipping.lineItem'), 150))
->setQuantity($this->transaction->getOrder()->getShippingCosts()->getQuantity() ?? 1) ->setQuantity($this->order->getShippingCosts()->getQuantity() ?? 1)
->setTaxes($taxes)
->setSku($this->fixLength($shippingName . '-Shipping', 200)) ->setSku($this->fixLength($shippingName . '-Shipping', 200))
/** @noinspection PhpParamsInspection */ /** @noinspection PhpParamsInspection */
->setType(LineItemType::SHIPPING) ->setType(LineItemType::SHIPPING)
->setUniqueId($this->fixLength($shippingName . '-Shipping', 200)); ->setUniqueId($this->fixLength($shippingName . '-Shipping', 200));
if ($this->order->getTaxStatus() !== 'tax-free') {
$lineItem->setTaxes($taxes);
}
if (!$lineItem->valid()) { if (!$lineItem->valid()) {
$this->logger->critical('Shipping LineItem payload invalid:', $lineItem->listInvalidProperties()); $this->logger->critical('Shipping LineItem payload invalid:', $lineItem->listInvalidProperties());
throw new InvalidPayloadException('Shipping LineItem payload invalid:' . json_encode($lineItem->listInvalidProperties())); throw new InvalidPayloadException('Shipping LineItem payload invalid:' . json_encode($lineItem->listInvalidProperties()));
@@ -566,15 +670,15 @@ class TransactionPayload extends AbstractPayload
protected function getMultipleShippingLineItems(): array protected function getMultipleShippingLineItems(): array
{ {
try { try {
if ($this->transaction->getOrder()->getShippingTotal() > 0) { if ($this->order->getShippingTotal() > 0) {
$lineItems = []; $lineItems = [];
$shippingName = $this->salesChannelContext->getShippingMethod()->getName() ?? $this->translator->trans('vrpayment.payload.shipping.name'); $shippingName = $this->salesChannelContext->getShippingMethod()->getName() ?? $this->translator->trans('vrpayment.payload.shipping.name');
$isFirst = true; $isFirst = true;
foreach ($this->transaction->getOrder()->getShippingCosts()->getCalculatedTaxes() as $taxItem) { foreach ($this->order->getShippingCosts()->getCalculatedTaxes() as $taxItem) {
$amount = self::round($taxItem->getPrice()); $amount = self::round($taxItem->getPrice());
if ($this->transaction->getOrder()->getTaxStatus() === 'net') { if ($this->order->getTaxStatus() === 'net') {
$amount = self::round($amount + $taxItem->getTax()); $amount = self::round($amount + $taxItem->getTax());
} }
$taxRate = $taxItem->getTaxRate(); $taxRate = $taxItem->getTaxRate();
@@ -586,12 +690,15 @@ class TransactionPayload extends AbstractPayload
$lineItem = (new LineItemCreate()) $lineItem = (new LineItemCreate())
->setAmountIncludingTax($amount) ->setAmountIncludingTax($amount)
->setName($this->fixLength($name . ' ' . $this->translator->trans('vrpayment.payload.shipping.lineItem'), 150)) ->setName($this->fixLength($name . ' ' . $this->translator->trans('vrpayment.payload.shipping.lineItem'), 150))
->setQuantity($this->transaction->getOrder()->getShippingCosts()->getQuantity() ?? 1) ->setQuantity($this->order->getShippingCosts()->getQuantity() ?? 1)
->setTaxes([$tax])
->setSku($this->fixLength($name . '-Shipping', 200)) ->setSku($this->fixLength($name . '-Shipping', 200))
->setType($isFirst ? LineItemType::SHIPPING : LineItemType::FEE) // First item as SHIPPING, rest as FEE ->setType($isFirst ? LineItemType::SHIPPING : LineItemType::FEE) // First item as SHIPPING, rest as FEE
->setUniqueId($this->fixLength($name . '-Shipping', 200)); ->setUniqueId($this->fixLength($name . '-Shipping', 200));
if ($this->order->getTaxStatus() !== 'tax-free') {
$lineItem->setTaxes([$tax]);
}
if (!$lineItem->valid()) { if (!$lineItem->valid()) {
$this->logger->critical('Shipping LineItem payload invalid:', $lineItem->listInvalidProperties()); $this->logger->critical('Shipping LineItem payload invalid:', $lineItem->listInvalidProperties());
throw new InvalidPayloadException('Shipping LineItem payload invalid:' . json_encode($lineItem->listInvalidProperties())); throw new InvalidPayloadException('Shipping LineItem payload invalid:' . json_encode($lineItem->listInvalidProperties()));
@@ -621,28 +728,18 @@ class TransactionPayload extends AbstractPayload
{ {
$lineItem = null; $lineItem = null;
// Calculate total of all current line items $lineItemPriceTotal = array_sum(array_map(static function (LineItemCreate $lineItem) {
$lineItemPriceTotal = array_sum(array_map(static fn(LineItemCreate $li) => $li->getAmountIncludingTax(), $lineItems)); return $lineItem->getAmountIncludingTax();
}, $lineItems));
$this->logger->debug("LineItem price total before adjustment: $lineItemPriceTotal"); $adjustmentPrice = $this->order->getAmountTotal() - $lineItemPriceTotal;
$adjustmentPrice = self::round($adjustmentPrice);
// Get shipping total including taxes from the order
$shippingCosts = $this->transaction->getOrder()->getShippingCosts();
$shippingTotal = $shippingCosts ? self::round($shippingCosts->getTotalPrice()) : 0.0;
// Add shipping to the line items total if it's not already included
$hasShippingLineItem = array_filter($lineItems, static fn(LineItemCreate $li) => $li->getType() === LineItemType::SHIPPING);
if (!$hasShippingLineItem && $shippingTotal > 0) {
$lineItemPriceTotal += $shippingTotal;
}
$adjustmentPrice = self::round($this->transaction->getOrder()->getAmountTotal() - $lineItemPriceTotal);
if (abs($adjustmentPrice) != 0) { if (abs($adjustmentPrice) != 0) {
if ($this->settings->isLineItemConsistencyEnabled()) { if ($this->settings->isLineItemConsistencyEnabled()) {
$error = strtr('LineItems total :lineItemTotal does not add up to order total :orderTotal', [ $error = strtr('LineItems total :lineItemTotal does not add up to order total :orderTotal', [
':lineItemTotal' => $lineItemPriceTotal, ':lineItemTotal' => $lineItemPriceTotal,
':orderTotal' => $this->transaction->getOrder()->getAmountTotal(), ':orderTotal' => $this->order->getAmountTotal(),
]); ]);
$this->logger->critical($error); $this->logger->critical($error);
throw new \Exception($error); throw new \Exception($error);
@@ -4,21 +4,21 @@
@modal-close="$emit('modal-close')"> @modal-close="$emit('modal-close')">
{% block vrpayment_order_action_completion_amount %} {% block vrpayment_order_action_completion_amount %}
<sw-checkbox-field <mt-checkbox
:label="$tc('vrpayment-order.captureAction.button.text')" :label="$tc('vrpayment-order.captureAction.button.text')"
v-model:value="isCompletion"> v-model:checked="isCompletion">
</sw-checkbox-field> </mt-checkbox>
{% endblock %} {% endblock %}
{% block vrpayment_order_action_completion_confirm_button %} {% block vrpayment_order_action_completion_confirm_button %}
<template #modal-footer> <template #modal-footer>
<sw-button variant="primary" <mt-button variant="primary"
@click="completion"> @click="completion">
{{ $tc('vrpayment-order.refundAction.confirmButton.text') }} {{ $tc('vrpayment-order.refundAction.confirmButton.text') }}
</sw-button> </mt-button>
</template> </template>
{% endblock %} {% endblock %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</sw-modal> </sw-modal>
{% endblock %} {% endblock %}
@@ -4,23 +4,23 @@
@modal-close="$emit('modal-close')"> @modal-close="$emit('modal-close')">
{% block vrpayment_order_action_refund_amount_by_amount %} {% block vrpayment_order_action_refund_amount_by_amount %}
<sw-number-field <mt-number-field
:max="refundableAmount" :max="refundableAmount"
:min="0" :min="0"
v-model:value="refundAmount" v-model="refundAmount"
:label="$tc('vrpayment-order.refund.refundAmount.label')" :label="$tc('vrpayment-order.refund.refundAmount.label')"
:suffix="currency"> :suffix="currency">
</sw-number-field> </mt-number-field>
{% endblock %} {% endblock %}
{% block vrpayment_order_action_refund_confirm_button_by_amount %} {% block vrpayment_order_action_refund_confirm_button_by_amount %}
<template #modal-footer> <template #modal-footer>
<sw-button variant="primary" @click="refundByAmount()"> <mt-button variant="primary" @click="refundByAmount()">
{{ $tc('vrpayment-order.refundAction.confirmButton.text') }} {{ $tc('vrpayment-order.refundAction.confirmButton.text') }}
</sw-button> </mt-button>
</template> </template>
{% endblock %} {% endblock %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</sw-modal> </sw-modal>
{% endblock %} {% endblock %}
@@ -4,13 +4,13 @@
@modal-close="$emit('modal-close')"> @modal-close="$emit('modal-close')">
{% block vrpayment_order_action_refund_amount_partial %} {% block vrpayment_order_action_refund_amount_partial %}
<sw-number-field <mt-number-field
:max="this.$parent.$parent.itemRefundableAmount" :max="this.$parent.$parent.itemRefundableAmount"
:min="0.00" :min="0.00"
v-model:value="refundAmount" v-model="refundAmount"
:label="$tc('vrpayment-order.refund.refundAmount.label')" :label="$tc('vrpayment-order.refund.refundAmount.label')"
:suffix="currency"> :suffix="currency">
</sw-number-field> </mt-number-field>
<div> <div>
{{ $tc('vrpayment-order.refundAction.maxAvailableAmountToRefund') }}: {{ $tc('vrpayment-order.refundAction.maxAvailableAmountToRefund') }}:
@@ -20,12 +20,12 @@
{% block vrpayment_order_action_refund_confirm_button_partial %} {% block vrpayment_order_action_refund_confirm_button_partial %}
<template #modal-footer> <template #modal-footer>
<sw-button variant="primary" @click="createPartialRefund(this.$parent.$parent.currentLineItem)"> <mt-button variant="primary" @click="createPartialRefund(this.$parent.$parent.currentLineItem)">
{{ $tc('vrpayment-order.refundAction.confirmButton.text') }} {{ $tc('vrpayment-order.refundAction.confirmButton.text') }}
</sw-button> </mt-button>
</template> </template>
{% endblock %} {% endblock %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</sw-modal> </sw-modal>
{% endblock %} {% endblock %}
@@ -47,7 +47,9 @@ Component.register('vrpayment-order-action-refund-partial', {
createdComponent() { createdComponent() {
this.isLoading = false; this.isLoading = false;
this.currency = this.transactionData.transactions[0].currency; this.currency = this.transactionData.transactions[0].currency;
this.refundAmount = this.$parent.$parent.itemRefundableAmount; if (!this.refundAmount) {
this.refundAmount = this.$parent.$parent.itemRefundableAmount;
}
}, },
createPartialRefund(itemUniqueId) { createPartialRefund(itemUniqueId) {
@@ -5,12 +5,12 @@
{% block vrpayment_order_action_refund_confirm_button_selected %} {% block vrpayment_order_action_refund_confirm_button_selected %}
<template #modal-footer> <template #modal-footer>
<sw-button variant="primary" @click="refundSelected()"> <mt-button variant="primary" @click="refundSelected()">
{{ $tc('vrpayment-order.refundAction.confirmButton.text') }} {{ $tc('vrpayment-order.refundAction.confirmButton.text') }}
</sw-button> </mt-button>
</template> </template>
{% endblock %} {% endblock %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</sw-modal> </sw-modal>
{% endblock %} {% endblock %}
@@ -5,12 +5,12 @@
{% block vrpayment_order_action_refund_amount %} {% block vrpayment_order_action_refund_amount %}
<sw-number-field <mt-number-field
:max="this.$parent.$parent.itemRefundableQuantity" :max="this.$parent.$parent.itemRefundableQuantity"
:min="0" :min="0"
v-model:value="refundQuantity" v-model="refundQuantity"
:label="$tc('vrpayment-order.refund.refundQuantity.label')"> :label="$tc('vrpayment-order.refund.refundQuantity.label')">
</sw-number-field> </mt-number-field>
<div> <div>
{{ $tc('vrpayment-order.refundAction.maxAvailableItemsToRefund') }}: {{ $tc('vrpayment-order.refundAction.maxAvailableItemsToRefund') }}:
@@ -20,12 +20,12 @@
{% block vrpayment_order_action_refund_confirm_button %} {% block vrpayment_order_action_refund_confirm_button %}
<template #modal-footer> <template #modal-footer>
<sw-button variant="primary" @click="refund()"> <mt-button variant="primary" @click="refund()">
{{ $tc('vrpayment-order.refundAction.confirmButton.text') }} {{ $tc('vrpayment-order.refundAction.confirmButton.text') }}
</sw-button> </mt-button>
</template> </template>
{% endblock %} {% endblock %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</sw-modal> </sw-modal>
{% endblock %} {% endblock %}
@@ -4,21 +4,22 @@
@modal-close="$emit('modal-close')"> @modal-close="$emit('modal-close')">
{% block vrpayment_order_action_void_amount %} {% block vrpayment_order_action_void_amount %}
<sw-checkbox-field {# Review if this v-model:checked="isVoid" needs to change to checked #}
<mt-checkbox
:label="$tc('vrpayment-order.voidAction.confirm.message')" :label="$tc('vrpayment-order.voidAction.confirm.message')"
v-model:value="isVoid"> v-model:checked="isVoid">
</sw-checkbox-field> </mt-checkbox>
{% endblock %} {% endblock %}
{% block vrpayment_order_action_void_confirm_button %} {% block vrpayment_order_action_void_confirm_button %}
<template #modal-footer> <template #modal-footer>
<sw-button variant="primary" <mt-button variant="primary"
@click="voidPayment"> @click="voidPayment">
{{ $tc('vrpayment-order.refundAction.confirmButton.text') }} {{ $tc('vrpayment-order.refundAction.confirmButton.text') }}
</sw-button> </mt-button>
</template> </template>
{% endblock %} {% endblock %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</sw-modal> </sw-modal>
{% endblock %} {% endblock %}
@@ -1,6 +1,7 @@
{% block sw_order_detail_content_tabs_general %} {% block sw_order_detail_content_tabs_general %}
{% parent %} {% parent %}
{# sw-tabs-item will dissappear. See: https://github.com/shopware/shopware/blob/trunk/UPGRADE-6.7.md#sw-tabs-is-removed #}
<sw-tabs-item v-if="isVRPaymentPayment" <sw-tabs-item v-if="isVRPaymentPayment"
:route="{ name: 'vrpayment.order.detail', params: { id: $route.params.id } }" :route="{ name: 'vrpayment.order.detail', params: { id: $route.params.id } }"
:title="$tc('vrpayment-order.header')"> :title="$tc('vrpayment-order.header')">
@@ -3,7 +3,7 @@
margin-top: 40px; margin-top: 40px;
} }
.sw-order-detail-base .sw-card-view__content { .sw-order-detail-base .mt-card-view__content {
overflow-x: visible; overflow-x: visible;
overflow-y: visible; overflow-y: visible;
} }
@@ -1,61 +1,61 @@
{% block vrpayment_order_detail %} {% block vrpayment_order_detail %}
<div class="vrpayment-order-detail"> <div class="vrpayment-order-detail">
<div v-if="!isLoading"> <div v-if="!isLoading">
<sw-card :title="$tc('vrpayment-order.paymentDetails.cardTitle')"> <mt-card :title="$tc('vrpayment-order.paymentDetails.cardTitle')">
<template #grid> <template #grid>
{% block vrpayment_order_actions_section %} {% block vrpayment_order_actions_section %}
<sw-card-section secondary slim> <mt-card-section secondary slim>
{% block vrpayment_order_transaction_refunds_action_button %} {% block vrpayment_order_transaction_refunds_action_button %}
<sw-button <mt-button
variant="primary" variant="primary"
size="small" size="small"
:disabled="transaction.state != 'FULFILL' || refundableAmount <= 0" :disabled="transaction.state != 'FULFILL' || refundableAmount <= 0"
@click="spawnModal('refundByAmount')"> @click="spawnModal('refundByAmount')">
{{ $tc('vrpayment-order.buttons.label.refund') }} {{ $tc('vrpayment-order.buttons.label.refund') }}
</sw-button> </mt-button>
{% endblock %} {% endblock %}
{% block vrpayment_order_transaction_completion_action_button %} {% block vrpayment_order_transaction_completion_action_button %}
<sw-button <mt-button
variant="primary" variant="primary"
size="small" size="small"
:disabled="transaction.state != 'AUTHORIZED' || isLoading" :disabled="transaction.state != 'AUTHORIZED' || isLoading"
@click="spawnModal('completion')"> @click="spawnModal('completion')">
{{ $tc('vrpayment-order.buttons.label.completion') }} {{ $tc('vrpayment-order.buttons.label.completion') }}
</sw-button> </mt-button>
{% endblock %} {% endblock %}
{% block vrpayment_order_transaction_void_action_button %} {% block vrpayment_order_transaction_void_action_button %}
<sw-button <mt-button
variant="primary" variant="primary"
size="small" size="small"
:disabled="transaction.state != 'AUTHORIZED' || isLoading" :disabled="transaction.state != 'AUTHORIZED' || isLoading"
@click="spawnModal('void')"> @click="spawnModal('void')">
{{ $tc('vrpayment-order.buttons.label.void') }} {{ $tc('vrpayment-order.buttons.label.void') }}
</sw-button> </mt-button>
{% endblock %} {% endblock %}
{% block vrpayment_order_transaction_download_invoice_action_button %} {% block vrpayment_order_transaction_download_invoice_action_button %}
<sw-button <mt-button
variant="primary" variant="primary"
size="small" size="small"
:disabled="transaction.state != 'FULFILL'" :disabled="transaction.state != 'FULFILL'"
@click="downloadInvoice()"> @click="downloadInvoice()">
{{ $tc('vrpayment-order.buttons.label.download-invoice') }} {{ $tc('vrpayment-order.buttons.label.download-invoice') }}
</sw-button> </mt-button>
{% endblock %} {% endblock %}
{% block vrpayment_order_transaction_download_packing_slip_action_button %} {% block vrpayment_order_transaction_download_packing_slip_action_button %}
<sw-button <mt-button
variant="primary" variant="primary"
size="small" size="small"
:disabled="transaction.state != 'FULFILL'" :disabled="transaction.state != 'FULFILL'"
@click="downloadPackingSlip()"> @click="downloadPackingSlip()">
{{ $tc('vrpayment-order.buttons.label.download-packing-slip') }} {{ $tc('vrpayment-order.buttons.label.download-packing-slip') }}
</sw-button> </mt-button>
{% endblock %} {% endblock %}
</sw-card-section> </mt-card-section>
{% endblock %} {% endblock %}
</template> </template>
</sw-card> </mt-card>
{% block vrpayment_order_transaction_history_card %} {% block vrpayment_order_transaction_history_card %}
<sw-card :title="$tc('vrpayment-order.transactionHistory.cardTitle')"> <mt-card :title="$tc('vrpayment-order.transactionHistory.cardTitle')">
<template #grid> <template #grid>
{% block vrpayment_order_transaction_history_grid %} {% block vrpayment_order_transaction_history_grid %}
@@ -78,10 +78,10 @@
{% endblock %} {% endblock %}
</template> </template>
</sw-card> </mt-card>
{% endblock %} {% endblock %}
{% block vrpayment_order_transaction_line_items_card %} {% block vrpayment_order_transaction_line_items_card %}
<sw-card :title="$tc('vrpayment-order.lineItem.cardTitle')"> <mt-card :title="$tc('vrpayment-order.lineItem.cardTitle')">
<template #grid> <template #grid>
{% block vrpayment_order_transaction_line_items_grid %} {% block vrpayment_order_transaction_line_items_grid %}
@@ -131,10 +131,10 @@
</sw-data-grid> </sw-data-grid>
{% endblock %} {% endblock %}
</template> </template>
</sw-card> </mt-card>
{% endblock %} {% endblock %}
{% block vrpayment_order_transaction_refunds_card %} {% block vrpayment_order_transaction_refunds_card %}
<sw-card :title="$tc('vrpayment-order.refund.cardTitle')" v-if="transactionData.refunds.length > 0"> <mt-card :title="$tc('vrpayment-order.refund.cardTitle')" v-if="transactionData.refunds.length > 0">
<template #grid> <template #grid>
{% block vrpayment_order_transaction_refunds_grid %} {% block vrpayment_order_transaction_refunds_grid %}
@@ -147,7 +147,7 @@
{% endblock %} {% endblock %}
</template> </template>
</sw-card> </mt-card>
{% endblock %} {% endblock %}
{% block vrpayment_order_actions_modal_refund_partial %} {% block vrpayment_order_actions_modal_refund_partial %}
<vrpayment-order-action-refund-partial <vrpayment-order-action-refund-partial
@@ -195,6 +195,6 @@
</vrpayment-order-action-void> </vrpayment-order-action-void>
{% endblock %} {% endblock %}
</div> </div>
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
</div> </div>
{% endblock %} {% endblock %}
@@ -1,4 +1,4 @@
<sw-card class="sw-card" <mt-card class="mt-card"
:title="$tc('vrpayment-settings.settingForm.advancedOptions.cardTitle')"> :title="$tc('vrpayment-settings.settingForm.advancedOptions.cardTitle')">
<sw-container> <sw-container>
<div v-if="actualConfigData" class="vrpayment-settings-advanced-options-fields"> <div v-if="actualConfigData" class="vrpayment-settings-advanced-options-fields">
@@ -7,16 +7,16 @@
:inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED]" :inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED]"
:customInheritationCheckFunction="checkBoolFieldInheritance"> :customInheritationCheckFunction="checkBoolFieldInheritance">
<template #content="props"> <template #content="props">
<sw-switch-field <mt-switch
:name="CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED" :name="CONFIG_STOREFRONT_WEBHOOKS_UPDATE_ENABLED"
bordered bordered
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.advancedOptions.webhooksUpdateEnabled.label')" :label="$tc('vrpayment-settings.settingForm.advancedOptions.webhooksUpdateEnabled.label')"
:helpText="$tc('vrpayment-settings.settingForm.advancedOptions.webhooksUpdateEnabled.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.advancedOptions.webhooksUpdateEnabled.tooltipText')"
:disabled="props.isInherited" :disabled="props.isInherited"
:value="props.currentValue" :checked="props.currentValue"
@update:value="props.updateCurrentValue"> @update:checked="props.updateCurrentValue">
</sw-switch-field> </mt-switch>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
@@ -25,19 +25,19 @@
:inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED]" :inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED]"
:customInheritationCheckFunction="checkBoolFieldInheritance"> :customInheritationCheckFunction="checkBoolFieldInheritance">
<template #content="props"> <template #content="props">
<sw-switch-field <mt-switch
:name="CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED" :name="CONFIG_STOREFRONT_PAYMENTS_UPDATE_ENABLED"
bordered bordered
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.advancedOptions.paymentsUpdateEnabled.label')" :label="$tc('vrpayment-settings.settingForm.advancedOptions.paymentsUpdateEnabled.label')"
:helpText="$tc('vrpayment-settings.settingForm.advancedOptions.paymentsUpdateEnabled.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.advancedOptions.paymentsUpdateEnabled.tooltipText')"
:disabled="props.isInherited" :disabled="props.isInherited"
:value="props.currentValue" :checked="props.currentValue"
@update:value="props.updateCurrentValue"> @update:checked="props.updateCurrentValue">
</sw-switch-field> </mt-switch>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
</div> </div>
</sw-container> </sw-container>
</sw-card> </mt-card>
@@ -1,6 +1,6 @@
{% block vrpayment_settings_content_card_channel_config_credentials %} {% block vrpayment_settings_content_card_channel_config_credentials %}
<sw-card <mt-card
class="sw-card" class="mt-card"
:title="$tc('vrpayment-settings.settingForm.credentials.cardTitle')" :title="$tc('vrpayment-settings.settingForm.credentials.cardTitle')"
v-if="actualConfigData" v-if="actualConfigData"
> >
@@ -17,17 +17,17 @@
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_SPACE_ID]" :inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_SPACE_ID]"
:customInheritationCheckFunction="checkNumberFieldInheritance"> :customInheritationCheckFunction="checkNumberFieldInheritance">
<template #content="props"> <template #content="props">
<sw-number-field <mt-number-field
:name="CONFIG_SPACE_ID" :name="CONFIG_SPACE_ID"
:required="true" :required="true"
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.credentials.spaceId.label')" :label="$tc('vrpayment-settings.settingForm.credentials.spaceId.label')"
:helpText="$tc('vrpayment-settings.settingForm.credentials.spaceId.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.credentials.spaceId.tooltipText')"
:disabled="props.isInherited || !acl.can('vrpayment.editor')" :disabled="props.isInherited || !acl.can('vrpayment.editor')"
:value="props.currentValue" :model-value="props.currentValue"
:error="spaceIdErrorState" :error="spaceIdErrorState"
@update:value="props.updateCurrentValue"> @update:model-value="props.updateCurrentValue">
</sw-number-field> </mt-number-field>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
{% endblock %} {% endblock %}
@@ -38,17 +38,17 @@
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_USER_ID]" :inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_USER_ID]"
:customInheritationCheckFunction="checkNumberFieldInheritance"> :customInheritationCheckFunction="checkNumberFieldInheritance">
<template #content="props"> <template #content="props">
<sw-number-field <mt-number-field
:name="CONFIG_USER_ID" :name="CONFIG_USER_ID"
:required="true" :required="true"
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.credentials.userId.label')" :label="$tc('vrpayment-settings.settingForm.credentials.userId.label')"
:helpText="$tc('vrpayment-settings.settingForm.credentials.userId.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.credentials.userId.tooltipText')"
:disabled="props.isInherited || !acl.can('vrpayment.editor')" :disabled="props.isInherited || !acl.can('vrpayment.editor')"
:value="props.currentValue" :model-value="props.currentValue"
:error="userIdErrorState" :error="userIdErrorState"
@update:value="props.updateCurrentValue"> @update:model-value="props.updateCurrentValue">
</sw-number-field> </mt-number-field>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
{% endblock %} {% endblock %}
@@ -59,7 +59,7 @@
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_APPLICATION_KEY]" :inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_APPLICATION_KEY]"
:customInheritationCheckFunction="checkTextFieldInheritance"> :customInheritationCheckFunction="checkTextFieldInheritance">
<template #content="props"> <template #content="props">
<sw-password-field <mt-password-field
:name="CONFIG_APPLICATION_KEY" :name="CONFIG_APPLICATION_KEY"
:required="true" :required="true"
:passwordToggleAble="true" :passwordToggleAble="true"
@@ -67,26 +67,29 @@
:label="$tc('vrpayment-settings.settingForm.credentials.applicationKey.label')" :label="$tc('vrpayment-settings.settingForm.credentials.applicationKey.label')"
:helpText="$tc('vrpayment-settings.settingForm.credentials.applicationKey.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.credentials.applicationKey.tooltipText')"
:disabled="props.isInherited || !acl.can('vrpayment.editor')" :disabled="props.isInherited || !acl.can('vrpayment.editor')"
:value="props.currentValue" :model-value="props.currentValue"
:error="applicationKeyErrorState" :error="applicationKeyErrorState"
@update:value="props.updateCurrentValue"> @update:model-value="props.updateCurrentValue">
</sw-password-field> </mt-password-field>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
{% endblock %} {% endblock %}
</div> </div>
{% endblock %} {% endblock %}
{% verbatim %}
<sw-container columns="1fr 1fr" gap="0px 30px"> <sw-container columns="1fr 1fr" gap="0px 30px">
<sw-button-process <mt-button
variant="primary"
:isLoading="isTesting" :isLoading="isTesting"
@click="emitCheckApiConnectionEvent"> @click="emitCheckApiConnectionEvent">
{{ $tc('vrpayment-settings.settingForm.credentials.button.label') }} {{ $tc('vrpayment-settings.settingForm.credentials.button.label') }}
</sw-button-process> </mt-button>
</sw-container> </sw-container>
{% endverbatim %}
</sw-container> </sw-container>
{% endblock %} {% endblock %}
</sw-card> </mt-card>
{% endblock %} {% endblock %}
@@ -1,5 +1,5 @@
{% block vrpayment_settings_content_card_channel_config_options %} {% block vrpayment_settings_content_card_channel_config_options %}
<sw-card class="sw-card" <mt-card class="mt-card"
:title="$tc('vrpayment-settings.settingForm.options.cardTitle')"> :title="$tc('vrpayment-settings.settingForm.options.cardTitle')">
{% block vrpayment_settings_content_card_channel_config_credentials_card_container %} {% block vrpayment_settings_content_card_channel_config_credentials_card_container %}
@@ -14,15 +14,15 @@
:inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_SPACE_VIEW_ID]" :inheritedValue="selectedSalesChannelId === null ? null : allConfigs['null'][CONFIG_SPACE_VIEW_ID]"
:customInheritationCheckFunction="checkNumberFieldInheritance"> :customInheritationCheckFunction="checkNumberFieldInheritance">
<template #content="props"> <template #content="props">
<sw-number-field <mt-number-field
:name="CONFIG_SPACE_VIEW_ID" :name="CONFIG_SPACE_VIEW_ID"
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.options.spaceViewId.label')" :label="$tc('vrpayment-settings.settingForm.options.spaceViewId.label')"
:helpText="$tc('vrpayment-settings.settingForm.options.spaceViewId.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.options.spaceViewId.tooltipText')"
:disabled="props.isInherited" :disabled="props.isInherited"
:value="props.currentValue" :model-value="props.currentValue"
@update:value="props.updateCurrentValue"> @update:model-value="props.updateCurrentValue">
</sw-number-field> </mt-number-field>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
{% endblock %} {% endblock %}
@@ -55,16 +55,16 @@
:inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_LINE_ITEM_CONSISTENCY_ENABLED]" :inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_LINE_ITEM_CONSISTENCY_ENABLED]"
:customInheritationCheckFunction="checkBoolFieldInheritance"> :customInheritationCheckFunction="checkBoolFieldInheritance">
<template #content="props"> <template #content="props">
<sw-switch-field <mt-switch
:name="CONFIG_LINE_ITEM_CONSISTENCY_ENABLED" :name="CONFIG_LINE_ITEM_CONSISTENCY_ENABLED"
bordered bordered
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.options.lineItemConsistencyEnabled.label')" :label="$tc('vrpayment-settings.settingForm.options.lineItemConsistencyEnabled.label')"
:helpText="$tc('vrpayment-settings.settingForm.options.lineItemConsistencyEnabled.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.options.lineItemConsistencyEnabled.tooltipText')"
:disabled="props.isInherited" :disabled="props.isInherited"
:value="props.currentValue" :checked="props.currentValue"
@update:value="props.updateCurrentValue"> @update:checked="props.updateCurrentValue">
</sw-switch-field> </mt-switch>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
{% endblock %} {% endblock %}
@@ -75,16 +75,16 @@
:inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_EMAIL_ENABLED]" :inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_EMAIL_ENABLED]"
:customInheritationCheckFunction="checkBoolFieldInheritance"> :customInheritationCheckFunction="checkBoolFieldInheritance">
<template #content="props"> <template #content="props">
<sw-switch-field <mt-switch
:name="CONFIG_EMAIL_ENABLED" :name="CONFIG_EMAIL_ENABLED"
bordered bordered
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.options.emailEnabled.label')" :label="$tc('vrpayment-settings.settingForm.options.emailEnabled.label')"
:helpText="$tc('vrpayment-settings.settingForm.options.emailEnabled.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.options.emailEnabled.tooltipText')"
:disabled="props.isInherited" :disabled="props.isInherited"
:value="props.currentValue" :checked="props.currentValue"
@update:value="props.updateCurrentValue"> @update:checked="props.updateCurrentValue">
</sw-switch-field> </mt-switch>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
{% endblock %} {% endblock %}
@@ -92,6 +92,6 @@
{% endblock %} {% endblock %}
</sw-container> </sw-container>
{% endblock %} {% endblock %}
</sw-card> </mt-card>
{% endblock %} {% endblock %}
@@ -1,5 +1,5 @@
{% block vrpayment_settings_icon %} {% block vrpayment_settings_icon %}
<span class="sw-icon icon--vrpayment-multicolor sw-icon--multicolor"> <span class="mt-icon icon--vrpayment-multicolor mt-icon--multicolor" style="width: 16px; height: 16px;">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" contentScriptType="text/ecmascript" y="0px" zoomAndPan="magnify" style="enable-background:new 0 0 632.126 170.079;" contentStyleType="text/css" viewBox="0 0 632.126 170.079" preserveAspectRatio="xMidYMid meet" xml:space="preserve" version="1.1"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" contentScriptType="text/ecmascript" y="0px" zoomAndPan="magnify" style="enable-background:new 0 0 632.126 170.079;" contentStyleType="text/css" viewBox="0 0 632.126 170.079" preserveAspectRatio="xMidYMid meet" xml:space="preserve" version="1.1">
<style type="text/css" xml:space="preserve"> <style type="text/css" xml:space="preserve">
.st0{fill:none;} .st0{fill:none;}
@@ -1,4 +1,4 @@
<sw-card class="sw-card" <mt-card class="mt-card"
:title="$tc('vrpayment-settings.settingForm.storefrontOptions.cardTitle')"> :title="$tc('vrpayment-settings.settingForm.storefrontOptions.cardTitle')">
<sw-container> <sw-container>
<div v-if="actualConfigData" class="vrpayment-settings-storefront-options-fields"> <div v-if="actualConfigData" class="vrpayment-settings-storefront-options-fields">
@@ -7,19 +7,19 @@
:inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_STOREFRONT_INVOICE_DOWNLOAD_ENABLED]" :inheritedValue="selectedSalesChannelId == null ? null : allConfigs['null'][CONFIG_STOREFRONT_INVOICE_DOWNLOAD_ENABLED]"
:customInheritationCheckFunction="checkBoolFieldInheritance"> :customInheritationCheckFunction="checkBoolFieldInheritance">
<template #content="props"> <template #content="props">
<sw-switch-field <mt-switch
:name="CONFIG_STOREFRONT_INVOICE_DOWNLOAD_ENABLED" :name="CONFIG_STOREFRONT_INVOICE_DOWNLOAD_ENABLED"
bordered bordered
:mapInheritance="props" :mapInheritance="props"
:label="$tc('vrpayment-settings.settingForm.storefrontOptions.invoiceDownloadEnabled.label')" :label="$tc('vrpayment-settings.settingForm.storefrontOptions.invoiceDownloadEnabled.label')"
:helpText="$tc('vrpayment-settings.settingForm.storefrontOptions.invoiceDownloadEnabled.tooltipText')" :helpText="$tc('vrpayment-settings.settingForm.storefrontOptions.invoiceDownloadEnabled.tooltipText')"
:disabled="props.isInherited" :disabled="props.isInherited"
:value="props.currentValue" :checked="props.currentValue"
@update:value="props.updateCurrentValue"> @update:checked="props.updateCurrentValue">
</sw-switch-field> </mt-switch>
</template> </template>
</sw-inherit-wrapper> </sw-inherit-wrapper>
</div> </div>
</sw-container> </sw-container>
</sw-card> </mt-card>
@@ -5,7 +5,7 @@
<template #smart-bar-header> <template #smart-bar-header>
<h2> <h2>
{{ $tc('sw-settings.index.title') }} {{ $tc('sw-settings.index.title') }}
<sw-icon name="small-arrow-medium-right" small></sw-icon> <mt-icon name="small-arrow-medium-right" size="16px"></mt-icon>
{{ $tc('vrpayment-settings.header') }} {{ $tc('vrpayment-settings.header') }}
</h2> </h2>
</template> </template>
@@ -14,7 +14,7 @@
{% block vrpayment_settings_actions %} {% block vrpayment_settings_actions %}
<template #smart-bar-actions> <template #smart-bar-actions>
{% block vrpayment_settings_actions_save %} {% block vrpayment_settings_actions_save %}
<sw-button-process <mt-button
v-model:value="isSaveSuccessful" v-model:value="isSaveSuccessful"
class="sw-settings-login-registration__save-action" class="sw-settings-login-registration__save-action"
variant="primary" variant="primary"
@@ -22,7 +22,7 @@
:disabled="isLoading" :disabled="isLoading"
@click="onSave"> @click="onSave">
{{ $tc('vrpayment-settings.settingForm.save') }} {{ $tc('vrpayment-settings.settingForm.save') }}
</sw-button-process> </mt-button>
{% endblock %} {% endblock %}
</template> </template>
{% endblock %} {% endblock %}
@@ -31,7 +31,7 @@
<template #content> <template #content>
{% block vrpayment_settings_content_card %} {% block vrpayment_settings_content_card %}
<sw-card-view> <mt-card-view>
{% block vrpayment_settings_content_card_channel_config %} {% block vrpayment_settings_content_card_channel_config %}
<sw-sales-channel-config v-model:value="config" <sw-sales-channel-config v-model:value="config"
@@ -42,7 +42,7 @@
<template #select="{ onInput, selectedSalesChannelId, salesChannel }"> <template #select="{ onInput, selectedSalesChannelId, salesChannel }">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card %} {% block vrpayment_settings_content_card_channel_config_sales_channel_card %}
<sw-card title="Sales Channel Switch"> <mt-card title="Sales Channel Switch">
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_title %} {% block vrpayment_settings_content_card_channel_config_sales_channel_card_title %}
<sw-single-select <sw-single-select
@@ -66,18 +66,19 @@
{% endblock %} {% endblock %}
{% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container_button %} {% block vrpayment_settings_content_card_channel_config_sales_channel_card_footer_container_button %}
<sw-button-process <sw-button
variant="primary"
v-model:value="isSetDefaultPaymentSuccessful" v-model:value="isSetDefaultPaymentSuccessful"
:isLoading="isSettingDefaultPaymentMethods" :isLoading="isSettingDefaultPaymentMethods"
@click="onSetPaymentMethodDefault"> @click="onSetPaymentMethodDefault">
{{ $tc('vrpayment-settings.salesChannelCard.button.label') }} {{ $tc('vrpayment-settings.salesChannelCard.button.label') }}
</sw-button-process> </sw-button>
{% endblock %} {% endblock %}
</sw-container> </sw-container>
{% endblock %} {% endblock %}
</template> </template>
{% endblock %} {% endblock %}
</sw-card> </mt-card>
{% endblock %} {% endblock %}
</template> </template>
{% endblock %} {% endblock %}
@@ -134,12 +135,12 @@
{% endblock %} {% endblock %}
{% block vrpayment_settings_content_card_loading %} {% block vrpayment_settings_content_card_loading %}
<sw-loader v-if="isLoading"></sw-loader> <mt-loader v-if="isLoading"></mt-loader>
{% endblock %} {% endblock %}
</sw-card-view> </mt-card-view>
{% endblock %} {% endblock %}
</template> </template>
{% endblock %} {% endblock %}
</sw-page> </sw-page>
{% endblock %} {% endblock %}
@@ -65,18 +65,6 @@ Component.register('vrpayment-settings', {
}; };
}, },
created() {
// Registers a listener for the 'check-api-connection-event'.
// Triggered when this event is emitted.
this.$on('check-api-connection-event', this.onCheckApiConnection);
},
beforeDestroy() {
// Removes the listener for the 'check-api-connection-event'
// before the component is destroyed to prevent memory leaks.
this.$off('check-api-connection-event', this.onCheckApiConnection);
},
watch: { watch: {
config: { config: {
handler(configData) { handler(configData) {
File diff suppressed because one or more lines are too long
@@ -6,12 +6,21 @@
<services> <services>
<service id="VRPaymentPayment\Core\Checkout\PaymentHandler\VRPaymentPaymentHandler"> <service id="VRPaymentPayment\Core\Checkout\PaymentHandler\VRPaymentPaymentHandler">
<argument type="service" id="VRPaymentPayment\Core\Checkout\Cart\CustomCartPersister"/>
<argument type="service" id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService"/> <argument type="service" id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService"/>
<argument type="service" id="Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler"/> <argument type="service" id="Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler"/>
<argument type="service" id="Shopware\Core\System\SalesChannel\Context\SalesChannelContextService"/>
<argument type="service" id="order_transaction.repository"/>
<call method="setLogger"> <call method="setLogger">
<argument type="service" id="monolog.logger.vrpayment_payment"/> <argument type="service" id="monolog.logger.vrpayment_payment"/>
</call> </call>
<tag name="shopware.payment.method.async"/> <tag name="shopware.payment.method"/>
</service>
<service id="VRPaymentPayment\Core\Checkout\Cart\CustomCartPersister"
decorates="Shopware\Core\Checkout\Cart\CartPersister"
decoration-inner-name="VRPaymentPayment\Core\Checkout\Cart\CustomCartPersister.inner">
<argument type="service" id="VRPaymentPayment\Core\Checkout\Cart\CustomCartPersister.inner"/>
</service> </service>
</services> </services>
@@ -13,17 +13,16 @@
<argument type="service" id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService"/> <argument type="service" id="VRPaymentPayment\Core\Api\Transaction\Service\TransactionService"/>
<argument type="service" id="Shopware\Storefront\Page\GenericPageLoader"/> <argument type="service" id="Shopware\Storefront\Page\GenericPageLoader"/>
<argument type="service" id="Shopware\Core\Checkout\Order\SalesChannel\OrderRoute"/> <argument type="service" id="Shopware\Core\Checkout\Order\SalesChannel\OrderRoute"/>
<argument type="service" id="Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStateHandler"/>
<argument type="service" id="Shopware\Core\System\StateMachine\StateMachineRegistry"/>
<call method="setLogger"> <call method="setLogger">
<argument type="service" id="monolog.logger.vrpayment_payment"/> <argument type="service" id="monolog.logger.vrpayment_payment"/>
</call> </call>
<call method="setContainer"> <call method="setContainer">
<argument type="service" id="service_container"/> <argument type="service" id="service_container"/>
</call> </call>
<call method="setTwig"> <!-- Removed in 6.7 -->
<!-- <call method="setTwig">
<argument type="service" id="twig"/> <argument type="service" id="twig"/>
</call> </call> -->
</service> </service>
<!-- Subscribers --> <!-- Subscribers -->
@@ -0,0 +1,25 @@
{
"base": "/bundles/vrpaymentpayment/administration/",
"entryPoints": {
"v-r-payment-payment": {
"css": [
"/bundles/vrpaymentpayment/administration/assets/v-r-payment-payment-D4AH6HY2.css"
],
"dynamic": [],
"js": [
"/bundles/vrpaymentpayment/administration/assets/v-r-payment-payment-CRU13hxm.js"
],
"legacy": false,
"preload": []
}
},
"legacy": false,
"metadatas": {},
"version": [
"7.1.0",
7,
1,
0
],
"viteServer": null
}
@@ -0,0 +1,11 @@
{
"main.js": {
"file": "assets/v-r-payment-payment-CRU13hxm.js",
"name": "v-r-payment-payment",
"src": "main.js",
"isEntry": true,
"css": [
"assets/v-r-payment-payment-D4AH6HY2.css"
]
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
.sw-order-detail .sw-tabs{margin-top:40px}.sw-order-detail .sw-order-detail-base .mt-card-view__content{overflow-x:visible;overflow-y:visible}.vrpayment-order-detail__data{display:grid}.vrpayment-order-detail__heading{padding-top:15px}
+2 -2
View File
@@ -29,7 +29,7 @@
payment_method_handler_status: 'input[name="vrpayment_payment_handler_validation_status"]', payment_method_handler_status: 'input[name="vrpayment_payment_handler_validation_status"]',
payment_form_id: 'confirmOrderForm', payment_form_id: 'confirmOrderForm',
button_cancel_id: 'vrpaymentOrderCancel', button_cancel_id: 'vrpaymentOrderCancel',
button_home_override: 'vrpaymentHomeLink', // button_home_override: 'vrpaymentHomeLink',
loader_id: 'vrpaymentLoader', loader_id: 'vrpaymentLoader',
checkout_url: null, checkout_url: null,
checkout_url_id: 'checkoutUrl', checkout_url_id: 'checkoutUrl',
@@ -46,7 +46,7 @@
this.cart_recreate_url = document.getElementById(this.cart_recreate_url_id).value; this.cart_recreate_url = document.getElementById(this.cart_recreate_url_id).value;
document.getElementById(this.button_cancel_id).addEventListener('click', this.recreateCart, false); document.getElementById(this.button_cancel_id).addEventListener('click', this.recreateCart, false);
document.getElementById(this.button_home_override).addEventListener('click', this.recreateCart, false); // document.getElementById(this.button_home_override).addEventListener('click', this.recreateCart, false);
document.getElementById(this.payment_form_id).addEventListener('submit', this.submitPayment, false); document.getElementById(this.payment_form_id).addEventListener('submit', this.submitPayment, false);
VRPaymentCheckout.getIframe(); VRPaymentCheckout.getIframe();
@@ -1,15 +1,11 @@
{% sw_extends '@Storefront/storefront/page/checkout/_page.html.twig' %} {% sw_extends '@Storefront/storefront/page/checkout/_page.html.twig' %}
{% block base_header %}
{% sw_include '@VRPaymentPayment/storefront/page/checkout/order/vrpayment_header.html.twig' %}
{% endblock %}
{% block base_navigation %}{% endblock %}
{% block base_body_classes %}vrpayment-payment is-act-confirmpage{% endblock %} {% block base_body_classes %}vrpayment-payment is-act-confirmpage{% endblock %}
{% block page_checkout_main_content %} {% block page_checkout_main_content %}
{% block page_checkout_pay %} <div id="vrpaymentOrderCancel"></div>
{% block page_checkout_confirm_header %} {% block page_checkout_pay %}
{% block page_checkout_confirm_header %}
<h1 class="confirm-main-header"> <h1 class="confirm-main-header">
{{ "vrpayment.payHeader"|trans|sw_sanitize }} {{ "vrpayment.payHeader"|trans|sw_sanitize }}
</h1> </h1>
@@ -144,10 +140,6 @@
</div> </div>
{% endblock %} {% endblock %}
{% block base_footer %}
{% sw_include '@Storefront/storefront/layout/footer/footer-minimal.html.twig' %}
{% endblock %}
{% block base_body_script %} {% block base_body_script %}
{{ parent() }} {{ parent() }}
{% if page.extensions.vRPaymentData %} {% if page.extensions.vRPaymentData %}
@@ -1,53 +0,0 @@
{% sw_extends '@Storefront/storefront/layout/header/header-minimal.html.twig' %}
{% block layout_header_minimal_logo %}
<div class="col-6 col-md-4 header-minimal-logo">
{% block layout_header_logo_inner %}
<div class="header-logo-main">
{% block layout_header_logo_link %}
<a class="header-logo-main-link"
id="vrpaymentHomeLink"
href="{{ path('frontend.home.page') }}"
title="{{ "header.logoLink"|trans|striptags }}">
{% block layout_header_logo_image %}
<picture class="header-logo-picture">
{% block layout_header_logo_image_tablet %}
{% if theme_config('sw-logo-tablet') and theme_config('sw-logo-tablet') != theme_config('sw-logo-desktop') %}
<source srcset="{{ theme_config('sw-logo-tablet') |sw_encode_url }}"
media="(min-width: {{ theme_config('breakpoint.md') }}px) and (max-width: {{ theme_config('breakpoint.lg') - 1 }}px)">
{% endif %}
{% endblock %}
{% block layout_header_logo_image_mobile %}
{% if theme_config('sw-logo-mobile') and theme_config('sw-logo-mobile') != theme_config('sw-logo-desktop') %}
<source srcset="{{ theme_config('sw-logo-mobile') |sw_encode_url }}"
media="(max-width: {{ theme_config('breakpoint.md') - 1 }}px)">
{% endif %}
{% endblock %}
{% block layout_header_logo_image_default %}
{% if theme_config('sw-logo-desktop') %}
<img src="{{ theme_config('sw-logo-desktop') |sw_encode_url }}"
alt="{{ "header.logoLink"|trans|striptags }}"
class="img-fluid header-logo-main-img"/>
{% endif %}
{% endblock %}
</picture>
{% endblock %}
</a>
{% endblock %}
</div>
{% endblock %}
</div>
{% endblock %}
{% block layout_header_minimal_button %}
<div class="col-md-4 header-minimal-back-to-shop">
<button type="button"
id="vrpaymentOrderCancel"
class="btn btn-outline-primary header-minimal-back-to-shop-button"
title="{{ "checkout.finishButtonBackToShop"|trans|striptags }}">
{{ "checkout.finishButtonBackToShop"|trans|striptags }}
</button>
</div>
{% endblock %}
+10 -6
View File
@@ -3,6 +3,7 @@
namespace VRPaymentPayment; namespace VRPaymentPayment;
use Shopware\Core\{ use Shopware\Core\{
Framework\Feature,
Framework\Plugin, Framework\Plugin,
Framework\Plugin\Context\ActivateContext, Framework\Plugin\Context\ActivateContext,
Framework\Plugin\Context\DeactivateContext, Framework\Plugin\Context\DeactivateContext,
@@ -21,6 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader; use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
use Symfony\Component\DependencyInjection\Loader\GlobFileLoader; use Symfony\Component\DependencyInjection\Loader\GlobFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
// expect the vendor folder on Shopware store releases // expect the vendor folder on Shopware store releases
if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
@@ -82,19 +84,21 @@ class VRPaymentPayment extends Plugin {
{ {
parent::build($container); parent::build($container);
$locator = new FileLocator('Resources/config'); $confDir = \rtrim($this->getPath(), '/') . '/Resources/config';
$locator = new FileLocator($confDir);
$resolver = new LoaderResolver([ $resolver = new LoaderResolver([
new YamlFileLoader($container, $locator), new YamlFileLoader($container, $locator),
new GlobFileLoader($container, $locator), new XmlFileLoader($container, $locator),
new DirectoryLoader($container, $locator), new GlobFileLoader($container, $locator),
new DirectoryLoader($container, $locator),
]); ]);
$configLoader = new DelegatingLoader($resolver); $configLoader = new DelegatingLoader($resolver);
$confDir = \rtrim($this->getPath(), '/') . '/Resources/config';
$configLoader->load($confDir . '/{packages}/*.yaml', 'glob'); $configLoader->load($confDir . '/{packages}/*.yaml', 'glob');
$configLoader->load('services/core/checkout.xml');
} }
public function enrichPrivileges(): array public function enrichPrivileges(): array