diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 0da3f673..a81366c7 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -14,7 +14,8 @@ jobs: timeout-minutes: 20 strategy: fail-fast: false - if: ${{ github.actor != 'renovate[bot]' || github.actor != 'lgtm-com[bot]' }} + # if: ${{ github.actor != 'renovate[bot]' || github.actor != 'lgtm-com[bot]' }} + if: false # Prevent bots from initiating E2E pipeline steps: - name: Clone Code diff --git a/README.md b/README.md index 567ec239..3bae9bcb 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,6 @@ The plugin integrates card component (Secured Fields) using Adyen Checkout for a - Blik - Billie - Clearpay - - Dotpay - Electronic Payment Service (EPS) - Gift cards - GiroPay @@ -52,6 +51,7 @@ The plugin integrates card component (Secured Fields) using Adyen Checkout for a - Klarna Pay Later - Klarna Pay Now - Klarna Pay Over Time + - Klarna Debit Risk - MB Way - MobilePay - Multibanco @@ -61,13 +61,14 @@ The plugin integrates card component (Secured Fields) using Adyen Checkout for a - PaySafeCard - RatePay, RatePay Direct Debit - SEPA Direct Debit - - Sofort - Swish - Trustly - Twint - Vipps - WeChat Pay - Open Banking / Pay by Bank + - Online Banking Finland + - Online Banking Poland ## API Library This module is using the Adyen APIs Library for PHP for all (API) connections to Adyen. diff --git a/composer.json b/composer.json index 26335263..5eb28cef 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ } ], "description": "Official Shopware 6 Plugin to connect to Payment Service Provider Adyen", - "version": "3.16.3", + "version": "3.17.0", "type": "shopware-platform-plugin", "license": "MIT", "require": { diff --git a/src/AdyenPaymentShopware6.php b/src/AdyenPaymentShopware6.php index d2393037..696cc940 100644 --- a/src/AdyenPaymentShopware6.php +++ b/src/AdyenPaymentShopware6.php @@ -28,6 +28,8 @@ use Adyen\Shopware\Entity\Notification\NotificationEntityDefinition; use Adyen\Shopware\Entity\PaymentResponse\PaymentResponseEntityDefinition; use Adyen\Shopware\Entity\PaymentStateData\PaymentStateDataEntityDefinition; +use Adyen\Shopware\Handlers\KlarnaDebitRiskPaymentMethodHandler; +use Adyen\Shopware\PaymentMethods\KlarnaDebitRiskPaymentMethod; use Adyen\Shopware\Service\ConfigurationService; use Shopware\Core\Checkout\Payment\PaymentMethodEntity; use Shopware\Core\Framework\Plugin; @@ -47,6 +49,8 @@ class AdyenPaymentShopware6 extends Plugin { + public const SOFORT = 'Adyen\Shopware\Handlers\SofortPaymentMethodHandler'; + public function installJsAssets($shopwareVersion) { $storefrontAssetPath = __DIR__ . '/Resources/app/storefront/dist/storefront/js/adyen-payment-shopware6.js'; @@ -174,6 +178,19 @@ public function update(UpdateContext $updateContext): void if (\version_compare($currentVersion, '3.16.0', '<')) { $this->updateTo3160($updateContext); } + + if (\version_compare($currentVersion, '3.17.0', '<')) { + $this->updateTo3170($updateContext); + } + } + + public function postUpdate(UpdateContext $updateContext): void + { + $currentVersion = $updateContext->getCurrentPluginVersion(); + if (\version_compare($currentVersion, '3.17.0', '<')) { + $handler = $this->container->get("Adyen\Shopware\Service\FetchLogosService"); + $handler->getHandler()->run(); + } } private function addPaymentMethod(PaymentMethods\PaymentMethodInterface $paymentMethod, Context $context): void @@ -184,6 +201,31 @@ private function addPaymentMethod(PaymentMethods\PaymentMethodInterface $payment $pluginIdProvider = $this->container->get(PluginIdProvider::class); $pluginId = $pluginIdProvider->getPluginIdByBaseClass(get_class($this), $context); + /** @var EntityRepository $paymentRepository */ + $paymentRepository = $this->container->get('payment_method.repository'); + + // Rename if Klarna Debit Risk doesnt exist from previous installations + if ($paymentMethod->getPaymentHandler() === KlarnaDebitRiskPaymentMethodHandler::class + && $paymentMethodId === null) { + $sofortMethodId = $this->getPaymentMethodId(self::SOFORT); + + if ($sofortMethodId) { + // update Sofort to Klarna Debit Risk + $method = new PaymentMethods\KlarnaDebitRiskPaymentMethod(); + + $paymentMethodData = [ + 'id' => $sofortMethodId, + 'handlerIdentifier' => $method->getPaymentHandler(), + 'name' => $method->getName(), + 'description' => $method->getDescription(), + ]; + + $paymentRepository->update([$paymentMethodData], $context); + + return; + } + } + // Payment method exists already, set the pluginId if ($paymentMethodId) { $this->setPluginId($paymentMethodId, $pluginId, $context); @@ -198,8 +240,6 @@ private function addPaymentMethod(PaymentMethods\PaymentMethodInterface $payment 'afterOrderEnabled' => true ]; - /** @var EntityRepository $paymentRepository */ - $paymentRepository = $this->container->get('payment_method.repository'); $paymentRepository->create([$paymentData], $context); } @@ -320,11 +360,11 @@ private function updateTo160(UpdateContext $updateContext): void { //Version 1.6.0 introduces applepay, paywithgoogle, dotpay and bancontact foreach ([ - new PaymentMethods\ApplePayPaymentMethod, - new PaymentMethods\GooglePayPaymentMethod, - new PaymentMethods\DotpayPaymentMethod, - new PaymentMethods\BancontactCardPaymentMethod - ] as $method) { + new PaymentMethods\ApplePayPaymentMethod, + new PaymentMethods\GooglePayPaymentMethod, + new PaymentMethods\DotpayPaymentMethod, + new PaymentMethods\BancontactCardPaymentMethod + ] as $method) { $this->addPaymentMethod( $method, $updateContext->getContext() @@ -341,9 +381,9 @@ private function updateTo200(UpdateContext $updateContext): void { //Version 2.0.0 introduces amazonpay, blik foreach ([ - new PaymentMethods\AmazonPayPaymentMethod, - new PaymentMethods\BlikPaymentMethod, - ] as $method) { + new PaymentMethods\AmazonPayPaymentMethod, + new PaymentMethods\BlikPaymentMethod, + ] as $method) { $this->addPaymentMethod( $method, $updateContext->getContext() @@ -360,23 +400,23 @@ private function updateTo300(UpdateContext $updateContext): void { //Version 3.0.0 introduces the following payment methods foreach ([ - new PaymentMethods\AfterpayDefaultPaymentMethod, - new PaymentMethods\AlipayPaymentMethod, - new PaymentMethods\AlipayHkPaymentMethod, - new PaymentMethods\ClearpayPaymentMethod, - new PaymentMethods\EpsPaymentMethod, - new PaymentMethods\Facilypay3xPaymentMethod, - new PaymentMethods\Facilypay4xPaymentMethod, - new PaymentMethods\Facilypay6xPaymentMethod, - new PaymentMethods\Facilypay10xPaymentMethod, - new PaymentMethods\Facilypay12xPaymentMethod, - new PaymentMethods\PaysafecardPaymentMethod, - new PaymentMethods\RatepayPaymentMethod, - new PaymentMethods\RatepayDirectdebitPaymentMethod, - new PaymentMethods\SwishPaymentMethod, - new PaymentMethods\TrustlyPaymentMethod, - new PaymentMethods\TwintPaymentMethod, - ] as $method) { + new PaymentMethods\AfterpayDefaultPaymentMethod, + new PaymentMethods\AlipayPaymentMethod, + new PaymentMethods\AlipayHkPaymentMethod, + new PaymentMethods\ClearpayPaymentMethod, + new PaymentMethods\EpsPaymentMethod, + new PaymentMethods\Facilypay3xPaymentMethod, + new PaymentMethods\Facilypay4xPaymentMethod, + new PaymentMethods\Facilypay6xPaymentMethod, + new PaymentMethods\Facilypay10xPaymentMethod, + new PaymentMethods\Facilypay12xPaymentMethod, + new PaymentMethods\PaysafecardPaymentMethod, + new PaymentMethods\RatepayPaymentMethod, + new PaymentMethods\RatepayDirectdebitPaymentMethod, + new PaymentMethods\SwishPaymentMethod, + new PaymentMethods\TrustlyPaymentMethod, + new PaymentMethods\TwintPaymentMethod, + ] as $method) { $this->addPaymentMethod( $method, $updateContext->getContext() @@ -426,15 +466,15 @@ private function updateTo370(UpdateContext $updateContext): void * MB Way, Multibanco, WeChat Pay, MobilePay, Vipps, Affirm & PayBright */ foreach ([ - new PaymentMethods\MbwayPaymentMethod(), - new PaymentMethods\MultibancoPaymentMethod(), - new PaymentMethods\WechatpayqrPaymentMethod(), - new PaymentMethods\WechatpaywebPaymentMethod(), - new PaymentMethods\MobilePayPaymentMethod(), - new PaymentMethods\VippsPaymentMethod(), - new PaymentMethods\AffirmPaymentMethod(), - new PaymentMethods\PayBrightPaymentMethod() - ] as $method) { + new PaymentMethods\MbwayPaymentMethod(), + new PaymentMethods\MultibancoPaymentMethod(), + new PaymentMethods\WechatpayqrPaymentMethod(), + new PaymentMethods\WechatpaywebPaymentMethod(), + new PaymentMethods\MobilePayPaymentMethod(), + new PaymentMethods\VippsPaymentMethod(), + new PaymentMethods\AffirmPaymentMethod(), + new PaymentMethods\PayBrightPaymentMethod() + ] as $method) { $this->addPaymentMethod( $method, $updateContext->getContext() @@ -454,8 +494,8 @@ private function updateTo3100(UpdateContext $updateContext): void * Open Banking / Pay by Bank */ foreach ([ - new PaymentMethods\OpenBankingPaymentMethod(), - ] as $method) { + new PaymentMethods\OpenBankingPaymentMethod(), + ] as $method) { $this->addPaymentMethod( $method, $updateContext->getContext() @@ -521,6 +561,66 @@ private function updateTo3160(UpdateContext $updateContext): void ); } + private function updateTo3170(UpdateContext $updateContext): void + { + // Version 3.17.0 introduces Online Banking Finland and Online Banking Poland + $paymentMethods = [ + new PaymentMethods\OnlineBankingFinlandPaymentMethod(), + new PaymentMethods\OnlineBankingPolandPaymentMethod(), + ]; + + foreach ($paymentMethods as $method) { + $this->addPaymentMethod( + $method, + $updateContext->getContext() + ); + + $this->setPaymentMethodIsActive( + true, + $updateContext->getContext(), + $method + ); + } + + // Version 3.17.0 removes Dotpay + $paymentMethodHandler = 'Adyen\Shopware\Handlers\DotpayPaymentMethodHandler'; + $this->deactivateAndRemovePaymentMethod($updateContext, $paymentMethodHandler); + + // Version 3.17.0 replaces Sofort with Klarna Debit Risk + $paymentRepository = $this->container->get('payment_method.repository'); + $paymentMethodId = $this->getPaymentMethodId(self::SOFORT); + $klarnaDebitRisktMethodId = $this->getPaymentMethodId( + 'Adyen\Shopware\Handlers\KlarnaDebitRiskPaymentMethodHandler' + ); + + // If Sofort does not exist, return + if (!$paymentMethodId) { + return; + } + + if ($klarnaDebitRisktMethodId !== null) { + // Klarna Debit Risk exists, deactivate Sofort and skip renaming + $this->deactivateAndRemovePaymentMethod( + $updateContext, + self::SOFORT + ); + + return; + } + + // Update Sofort to Klarna Debit Risk + $method = new PaymentMethods\KlarnaDebitRiskPaymentMethod(); + + $paymentMethodData = [ + 'id' => $paymentMethodId, + 'handlerIdentifier' => $method->getPaymentHandler(), + 'name' => $method->getName(), + 'description' => $method->getDescription(), + ]; + + $paymentRepository->update([$paymentMethodData], $updateContext->getContext()); + } + private function safeCopyAsset($source, $destination): bool { try { diff --git a/src/Core/Checkout/Order/Aggregate/OrderTransaction/OrderTransactionExtension.php b/src/Core/Checkout/Order/Aggregate/OrderTransaction/OrderTransactionExtension.php index cf0dceb4..d7d52fcf 100644 --- a/src/Core/Checkout/Order/Aggregate/OrderTransaction/OrderTransactionExtension.php +++ b/src/Core/Checkout/Order/Aggregate/OrderTransaction/OrderTransactionExtension.php @@ -23,7 +23,10 @@ namespace Adyen\Shopware\Core\Checkout\Order\Aggregate\OrderTransaction; +use Adyen\Shopware\Entity\AdyenPayment\AdyenPaymentEntityDefinition; +use Adyen\Shopware\Entity\PaymentCapture\PaymentCaptureEntityDefinition; use Adyen\Shopware\Entity\PaymentResponse\PaymentResponseEntityDefinition; +use Adyen\Shopware\Entity\Refund\RefundEntityDefinition; use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition; use Shopware\Core\Framework\Api\Context\SalesChannelApiSource; use Shopware\Core\Framework\DataAbstractionLayer\EntityExtension; @@ -49,14 +52,47 @@ public function extendFields(FieldCollection $collection): void 'order_transaction_id' ); + $refundField = new OneToManyAssociationField( + 'adyenRefund', + RefundEntityDefinition::class, + 'order_transaction_id' + ); + + $captureField = new OneToManyAssociationField( + 'adyenCapture', + PaymentCaptureEntityDefinition::class, + 'order_transaction_id' + ); + + $paymentField = new OneToManyAssociationField( + 'adyenPayment', + AdyenPaymentEntityDefinition::class, + 'order_transaction_id' + ); + // Ensure the data is not available via the Store API in older Shopware versions. if (!class_exists(ApiAware::class) && class_exists(Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\ReadProtected::class)) { $field->addFlags( new Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\ReadProtected(SalesChannelApiSource::class) ); + + $refundField->addFlags( + new Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\ReadProtected(SalesChannelApiSource::class) + ); + + $captureField->addFlags( + new Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\ReadProtected(SalesChannelApiSource::class) + ); + + $paymentField->addFlags( + new Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\ReadProtected(SalesChannelApiSource::class) + ); } $collection->add($field); + $collection->add($refundField); + $collection->add($captureField); + $collection->add($paymentField); } } diff --git a/src/Entity/AdyenPayment/AdyenPaymentEntity.php b/src/Entity/AdyenPayment/AdyenPaymentEntity.php index d9407f80..d66e3f56 100644 --- a/src/Entity/AdyenPayment/AdyenPaymentEntity.php +++ b/src/Entity/AdyenPayment/AdyenPaymentEntity.php @@ -24,6 +24,7 @@ namespace Adyen\Shopware\Entity\AdyenPayment; +use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity; use Shopware\Core\Framework\DataAbstractionLayer\Entity; use Shopware\Core\Framework\DataAbstractionLayer\EntityIdTrait; @@ -96,6 +97,11 @@ class AdyenPaymentEntity extends Entity */ protected $updatedAt; + /** + * @var OrderTransactionEntity + */ + protected OrderTransactionEntity $orderTransaction; + /** * @return string */ @@ -171,7 +177,7 @@ public function getOrderTransactionId(): string /** * @param int $orderTransactionId */ - public function setEventCode(int $orderTransactionId): void + public function setOrderTransactionId(int $orderTransactionId): void { $this->orderTransactionId = $orderTransactionId; } @@ -279,4 +285,20 @@ public function getCreatedAt(): ?\DateTimeInterface { return $this->createdAt; } + + /** + * @return OrderTransactionEntity + */ + public function getOrderTransaction(): OrderTransactionEntity + { + return $this->orderTransaction; + } + + /** + * @param OrderTransactionEntity $orderTransaction + */ + public function setOrderTransaction(OrderTransactionEntity $orderTransaction): void + { + $this->orderTransaction = $orderTransaction; + } } diff --git a/src/Entity/AdyenPayment/AdyenPaymentEntityDefinition.php b/src/Entity/AdyenPayment/AdyenPaymentEntityDefinition.php index cb90cc56..ec7b308d 100644 --- a/src/Entity/AdyenPayment/AdyenPaymentEntityDefinition.php +++ b/src/Entity/AdyenPayment/AdyenPaymentEntityDefinition.php @@ -26,7 +26,6 @@ use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition; use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; -use Shopware\Core\Framework\DataAbstractionLayer\Field\FkField; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\PrimaryKey; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; use Shopware\Core\Framework\DataAbstractionLayer\Field\IdField; @@ -34,7 +33,6 @@ use Shopware\Core\Framework\DataAbstractionLayer\Field\ManyToOneAssociationField; use Shopware\Core\Framework\DataAbstractionLayer\Field\StringField; use Shopware\Core\Framework\DataAbstractionLayer\Field\IntField; -use Shopware\Core\Framework\DataAbstractionLayer\Field\DateTimeField; use Shopware\Core\Framework\DataAbstractionLayer\Field\UpdatedAtField; use Shopware\Core\Framework\DataAbstractionLayer\Field\CreatedAtField; use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection; @@ -65,11 +63,7 @@ protected function defineFields(): FieldCollection { return new FieldCollection([ (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), - (new FkField( - 'order_transaction_id', - 'orderTransactionId', - OrderTransactionDefinition::class - ))->addFlags(new Required()), + new IdField('order_transaction_id', 'orderTransactionId'), new StringField('pspreference', 'pspreference'), new StringField('original_reference', 'originalReference'), new StringField('merchant_reference', 'merchantReference'), diff --git a/src/Entity/PaymentCapture/PaymentCaptureEntityDefinition.php b/src/Entity/PaymentCapture/PaymentCaptureEntityDefinition.php index a17902dc..de59d3e9 100644 --- a/src/Entity/PaymentCapture/PaymentCaptureEntityDefinition.php +++ b/src/Entity/PaymentCapture/PaymentCaptureEntityDefinition.php @@ -58,11 +58,7 @@ protected function defineFields(): FieldCollection { return new FieldCollection([ (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), - (new FkField( - 'order_transaction_id', - 'orderTransactionId', - OrderTransactionDefinition::class - ))->addFlags(new Required()), + new IdField('order_transaction_id', 'orderTransactionId'), new StringField('psp_reference', 'pspReference'), (new IntField('amount', 'amount'))->addFlags(new Required()), (new StringField('source', 'source'))->addFlags(new Required()), diff --git a/src/Entity/PaymentResponse/PaymentResponseEntity.php b/src/Entity/PaymentResponse/PaymentResponseEntity.php index a5dee447..ec6d1ab1 100644 --- a/src/Entity/PaymentResponse/PaymentResponseEntity.php +++ b/src/Entity/PaymentResponse/PaymentResponseEntity.php @@ -46,16 +46,6 @@ class PaymentResponseEntity extends Entity */ protected $resultCode; - /** - * @var string - */ - protected $refusalReason; - - /** - * @var string - */ - protected $refusalReasonCode; - /** * @var string */ @@ -119,38 +109,6 @@ public function setResultCode(string $resultCode): void $this->resultCode = $resultCode; } - /** - * @return string - */ - public function getRefusalReason(): ?string - { - return $this->refusalReason; - } - - /** - * @param string $refusalReason - */ - public function setRefusalReason(string $refusalReason): void - { - $this->refusalReason = $refusalReason; - } - - /** - * @return string - */ - public function getRefusalReasonCode(): ?string - { - return $this->refusalReasonCode; - } - - /** - * @param string $refusalReasonCode - */ - public function setRefusalReasonCode(string $refusalReasonCode): void - { - $this->refusalReasonCode = $refusalReasonCode; - } - /** * @return string */ @@ -182,4 +140,14 @@ public function setPspreference(?string $pspreference): void { $this->pspreference = $pspreference; } + + public function getCreatedAt(): ?\DateTimeInterface + { + return $this->createdAt; + } + + public function setCreatedAt(?\DateTimeInterface $createdAt): void + { + $this->createdAt = $createdAt; + } } diff --git a/src/Entity/PaymentResponse/PaymentResponseEntityDefinition.php b/src/Entity/PaymentResponse/PaymentResponseEntityDefinition.php index 55163ef6..873aa61a 100644 --- a/src/Entity/PaymentResponse/PaymentResponseEntityDefinition.php +++ b/src/Entity/PaymentResponse/PaymentResponseEntityDefinition.php @@ -59,11 +59,7 @@ protected function defineFields(): FieldCollection { return new FieldCollection([ (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), - (new FkField( - 'order_transaction_id', - 'orderTransactionId', - OrderTransactionDefinition::class - ))->addFlags(new Required()), + new IdField('order_transaction_id', 'orderTransactionId'), new StringField('result_code', 'resultCode'), new StringField('pspreference', 'pspreference'), new LongTextField('response', 'response'), diff --git a/src/Entity/Refund/RefundEntityDefinition.php b/src/Entity/Refund/RefundEntityDefinition.php index e76201ab..416e55dd 100644 --- a/src/Entity/Refund/RefundEntityDefinition.php +++ b/src/Entity/Refund/RefundEntityDefinition.php @@ -25,11 +25,7 @@ namespace Adyen\Shopware\Entity\Refund; use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition; -use Shopware\Core\Checkout\Order\OrderDefinition; use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition; -use Shopware\Core\Framework\DataAbstractionLayer\Field\BoolField; -use Shopware\Core\Framework\DataAbstractionLayer\Field\CreatedAtField; -use Shopware\Core\Framework\DataAbstractionLayer\Field\FkField; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\PrimaryKey; use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Required; use Shopware\Core\Framework\DataAbstractionLayer\Field\IdField; @@ -61,11 +57,7 @@ protected function defineFields(): FieldCollection { return new FieldCollection([ (new IdField('id', 'id'))->addFlags(new PrimaryKey(), new Required()), - (new FkField( - 'order_transaction_id', - 'orderTransactionId', - OrderTransactionDefinition::class - ))->addFlags(new Required()), + new IdField('order_transaction_id', 'orderTransactionId'), new StringField('psp_reference', 'pspReference'), (new IntField('amount', 'amount'))->addFlags(new Required()), (new StringField('source', 'source'))->addFlags(new Required()), diff --git a/src/Handlers/AbstractPaymentMethodHandler.php b/src/Handlers/AbstractPaymentMethodHandler.php index ec756283..806a2170 100644 --- a/src/Handlers/AbstractPaymentMethodHandler.php +++ b/src/Handlers/AbstractPaymentMethodHandler.php @@ -68,6 +68,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\RouterInterface; abstract class AbstractPaymentMethodHandler implements AsynchronousPaymentHandlerInterface @@ -331,9 +332,28 @@ public function pay( ); // Payment had no error, continue the process + + // If Bancontact mobile payment is used, redirect to proxy finalize transaction endpoint + if ($stateData['paymentMethod']['type'] === 'bcmc_mobile') { + return new RedirectResponse($this->getReturnUrl($transaction)); + } + return new RedirectResponse($transaction->getReturnUrl()); } + private function getReturnUrl(AsyncPaymentTransactionStruct $transaction): string + { + $query = parse_url($transaction->getReturnUrl(), PHP_URL_QUERY); + parse_str($query, $params); + $token = $params['_sw_payment_token'] ?? ''; + + return $this->symfonyRouter->generate( + 'payment.adyen.proxy-finalize-transaction', + ['_sw_payment_token' => $token, 'orderId' => $transaction->getOrder()->getId()], + UrlGeneratorInterface::ABSOLUTE_URL + ); + } + private function createAdyenOrder(SalesChannelContext $salesChannelContext, $transaction) { $uuid = Uuid::randomHex(); @@ -582,7 +602,11 @@ protected function preparePaymentsRequest( $paymentRequest->setMerchantAccount( $this->configurationService->getMerchantAccount($salesChannelContext->getSalesChannel()->getId()) ); - $paymentRequest->setReturnUrl($transaction->getReturnUrl()); + if ($paymentMethodType === 'bcmc_mobile') { + $paymentRequest->setReturnUrl($this->getReturnUrl($transaction)); + } else { + $paymentRequest->setReturnUrl($transaction->getReturnUrl()); + } if (static::$isOpenInvoice) { $orderLines = $transaction->getOrder()->getLineItems(); diff --git a/src/Handlers/SofortPaymentMethodHandler.php b/src/Handlers/KlarnaDebitRiskPaymentMethodHandler.php similarity index 93% rename from src/Handlers/SofortPaymentMethodHandler.php rename to src/Handlers/KlarnaDebitRiskPaymentMethodHandler.php index 0c17a4f3..511173cd 100644 --- a/src/Handlers/SofortPaymentMethodHandler.php +++ b/src/Handlers/KlarnaDebitRiskPaymentMethodHandler.php @@ -25,7 +25,7 @@ namespace Adyen\Shopware\Handlers; -class SofortPaymentMethodHandler extends AbstractPaymentMethodHandler +class KlarnaDebitRiskPaymentMethodHandler extends AbstractPaymentMethodHandler { public static function getPaymentMethodCode() { diff --git a/src/Handlers/DotpayPaymentMethodHandler.php b/src/Handlers/OnlineBankingFinlandPaymentMethodHandler.php similarity index 87% rename from src/Handlers/DotpayPaymentMethodHandler.php rename to src/Handlers/OnlineBankingFinlandPaymentMethodHandler.php index cc9ae051..2314e283 100644 --- a/src/Handlers/DotpayPaymentMethodHandler.php +++ b/src/Handlers/OnlineBankingFinlandPaymentMethodHandler.php @@ -16,7 +16,7 @@ * * Adyen Payment Module * - * Copyright (c) 2021 Adyen B.V. + * Copyright (c) 2022 Adyen N.V. * This file is open source and available under the MIT license. * See the LICENSE file for more info. * @@ -25,10 +25,10 @@ namespace Adyen\Shopware\Handlers; -class DotpayPaymentMethodHandler extends AbstractPaymentMethodHandler +class OnlineBankingFinlandPaymentMethodHandler extends AbstractPaymentMethodHandler { public static function getPaymentMethodCode() { - return 'dotpay'; + return 'ebanking_FI'; } } diff --git a/src/Handlers/OnlineBankingPolandPaymentMethodHandler.php b/src/Handlers/OnlineBankingPolandPaymentMethodHandler.php new file mode 100644 index 00000000..23ab8ae3 --- /dev/null +++ b/src/Handlers/OnlineBankingPolandPaymentMethodHandler.php @@ -0,0 +1,34 @@ + + */ + +namespace Adyen\Shopware\Handlers; + +class OnlineBankingPolandPaymentMethodHandler extends AbstractPaymentMethodHandler +{ + public static function getPaymentMethodCode() + { + return 'onlineBanking_PL'; + } +} diff --git a/src/Handlers/PaymentResponseHandlerResult.php b/src/Handlers/PaymentResponseHandlerResult.php index 89414305..2bf33869 100644 --- a/src/Handlers/PaymentResponseHandlerResult.php +++ b/src/Handlers/PaymentResponseHandlerResult.php @@ -25,8 +25,6 @@ public function createFromPaymentResponse(PaymentResponseEntity $paymentResponse { // Set result code $this->setResultCode($paymentResponse->getResultCode()); - $this->setRefusalReason($paymentResponse->getRefusalReason()); - $this->setRefusalReasonCode($paymentResponse->getRefusalReasonCode()); $response = $paymentResponse->getResponse(); diff --git a/src/PaymentMethods/SofortPaymentMethod.php b/src/PaymentMethods/KlarnaDebitRiskPaymentMethod.php old mode 100755 new mode 100644 similarity index 86% rename from src/PaymentMethods/SofortPaymentMethod.php rename to src/PaymentMethods/KlarnaDebitRiskPaymentMethod.php index 2941cadb..306a1a8c --- a/src/PaymentMethods/SofortPaymentMethod.php +++ b/src/PaymentMethods/KlarnaDebitRiskPaymentMethod.php @@ -24,9 +24,9 @@ namespace Adyen\Shopware\PaymentMethods; -use Adyen\Shopware\Handlers\SofortPaymentMethodHandler; +use Adyen\Shopware\Handlers\KlarnaDebitRiskPaymentMethodHandler; -class SofortPaymentMethod implements PaymentMethodInterface +class KlarnaDebitRiskPaymentMethod implements PaymentMethodInterface { /** * {@inheritDoc} @@ -35,7 +35,7 @@ class SofortPaymentMethod implements PaymentMethodInterface */ public function getName(): string { - return 'Sofort'; + return 'Klarna Debit Risk'; } /** @@ -55,7 +55,7 @@ public function getDescription(): string */ public function getPaymentHandler(): string { - return SofortPaymentMethodHandler::class; + return KlarnaDebitRiskPaymentMethodHandler::class; } /** @@ -65,7 +65,7 @@ public function getPaymentHandler(): string */ public function getGatewayCode(): string { - return 'ADYEN_SOFORT'; + return 'ADYEN_KLARNA_DEBIT_RISK'; } /** @@ -85,7 +85,7 @@ public function getTemplate(): ?string */ public function getLogo(): string { - return 'sofort.png'; + return 'directEbanking.png'; } /** diff --git a/src/PaymentMethods/DotpayPaymentMethod.php b/src/PaymentMethods/OnlineBankingFinlandPaymentMethod.php old mode 100755 new mode 100644 similarity index 82% rename from src/PaymentMethods/DotpayPaymentMethod.php rename to src/PaymentMethods/OnlineBankingFinlandPaymentMethod.php index 9c57add9..f9fa06f6 --- a/src/PaymentMethods/DotpayPaymentMethod.php +++ b/src/PaymentMethods/OnlineBankingFinlandPaymentMethod.php @@ -15,7 +15,7 @@ * * Adyen Payment Module * - * Copyright (c) 2021 Adyen B.V. + * Copyright (c) 2020 Adyen B.V. * This file is open source and available under the MIT license. * See the LICENSE file for more info. * @@ -24,9 +24,9 @@ namespace Adyen\Shopware\PaymentMethods; -use Adyen\Shopware\Handlers\DotpayPaymentMethodHandler; +use Adyen\Shopware\Handlers\OnlineBankingFinlandPaymentMethodHandler; -class DotpayPaymentMethod implements PaymentMethodInterface +class OnlineBankingFinlandPaymentMethod implements PaymentMethodInterface { /** * {@inheritDoc} @@ -35,7 +35,7 @@ class DotpayPaymentMethod implements PaymentMethodInterface */ public function getName(): string { - return 'Dotpay'; + return 'Online Banking Finland'; } /** @@ -45,7 +45,7 @@ public function getName(): string */ public function getDescription(): string { - return 'Online banking payments'; + return 'Online Banking Finland payment method'; } /** @@ -55,7 +55,7 @@ public function getDescription(): string */ public function getPaymentHandler(): string { - return DotpayPaymentMethodHandler::class; + return OnlineBankingFinlandPaymentMethodHandler::class; } /** @@ -65,7 +65,7 @@ public function getPaymentHandler(): string */ public function getGatewayCode(): string { - return 'ADYEN_DOTPAY'; + return 'ADYEN_EBANKING_FI'; } /** @@ -85,7 +85,7 @@ public function getTemplate(): ?string */ public function getLogo(): string { - return 'dotpay.png'; + return 'ebanking_FI.png'; } /** diff --git a/src/PaymentMethods/OnlineBankingPolandPaymentMethod.php b/src/PaymentMethods/OnlineBankingPolandPaymentMethod.php new file mode 100644 index 00000000..e369b656 --- /dev/null +++ b/src/PaymentMethods/OnlineBankingPolandPaymentMethod.php @@ -0,0 +1,100 @@ + + */ + +namespace Adyen\Shopware\PaymentMethods; + +use Adyen\Shopware\Handlers\OnlineBankingPolandPaymentMethodHandler; + +class OnlineBankingPolandPaymentMethod implements PaymentMethodInterface +{ + /** + * {@inheritDoc} + * + * @return string + */ + public function getName(): string + { + return 'Online Banking Poland'; + } + + /** + * {@inheritDoc} + * + * @return string + */ + public function getDescription(): string + { + return 'Online Banking Poland payment method'; + } + + /** + * {@inheritDoc} + * + * @return string + */ + public function getPaymentHandler(): string + { + return OnlineBankingPolandPaymentMethodHandler::class; + } + + /** + * {@inheritDoc} + * + * @return string + */ + public function getGatewayCode(): string + { + return 'ADYEN_ONLINEBANKING_PL'; + } + + /** + * {@inheritDoc} + * + * @return string|null + */ + public function getTemplate(): ?string + { + return null; + } + + /** + * {@inheritDoc} + * + * @return string + */ + public function getLogo(): string + { + return 'onlineBanking_PL.png'; + } + + /** + * {@inheritDoc} + * + * @return string + */ + public function getType(): string + { + return 'redirect'; + } +} diff --git a/src/PaymentMethods/PaymentMethods.php b/src/PaymentMethods/PaymentMethods.php index 25ac411e..ce3c396c 100644 --- a/src/PaymentMethods/PaymentMethods.php +++ b/src/PaymentMethods/PaymentMethods.php @@ -35,13 +35,12 @@ class PaymentMethods RatepayPaymentMethod::class, RatepayDirectdebitPaymentMethod::class, SepaPaymentMethod::class, - SofortPaymentMethod::class, + KlarnaDebitRiskPaymentMethod::class, PaypalPaymentMethod::class, OneClickPaymentMethod::class, GiroPayPaymentMethod::class, ApplePayPaymentMethod::class, GooglePayPaymentMethod::class, - DotpayPaymentMethod::class, BancontactCardPaymentMethod::class, BancontactMobilePaymentMethod::class, AmazonPayPaymentMethod::class, @@ -70,6 +69,8 @@ class PaymentMethods VippsPaymentMethod::class, MobilePayPaymentMethod::class, OpenBankingPaymentMethod::class, - BilliePaymentMethod::class + BilliePaymentMethod::class, + OnlineBankingFinlandPaymentMethod::class, + OnlineBankingPolandPaymentMethod::class ]; } diff --git a/src/Resources/app/storefront/dist/storefront/js/adyen-payment-shopware6.js b/src/Resources/app/storefront/dist/storefront/js/adyen-payment-shopware6.js index ec94b8d3..49ebf9d6 100755 --- a/src/Resources/app/storefront/dist/storefront/js/adyen-payment-shopware6.js +++ b/src/Resources/app/storefront/dist/storefront/js/adyen-payment-shopware6.js @@ -1 +1 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([["adyen-payment-shopware6"],{6253:(e,t,n)=>{var a=n(6285),i=n(3206),o=n(8254),r=n(4690);class d extends a.Z{init(){let e=this;this._client=new o.Z,this.adyenCheckout=Promise,this.paymentMethodInstance=null,this.selectedGiftcard=null,this.initializeCheckoutComponent().then(function(){this.observeGiftcardSelection()}.bind(this)),this.adyenGiftcardDropDown=i.Z.querySelectorAll(document,"#giftcardDropdown"),this.adyenGiftcard=i.Z.querySelectorAll(document,".adyen-giftcard"),this.giftcardHeader=i.Z.querySelector(document,".adyen-giftcard-header"),this.giftcardItem=i.Z.querySelector(document,".adyen-giftcard-item"),this.giftcardComponentClose=i.Z.querySelector(document,".adyen-close-giftcard-component"),this.minorUnitsQuotient=adyenGiftcardsConfiguration.totalInMinorUnits/adyenGiftcardsConfiguration.totalPrice,this.giftcardDiscount=adyenGiftcardsConfiguration.giftcardDiscount,this.remainingAmount=(adyenGiftcardsConfiguration.totalPrice-this.giftcardDiscount).toFixed(2),this.remainingGiftcardBalance=(adyenGiftcardsConfiguration.giftcardBalance/this.minorUnitsQuotient).toFixed(2),this.shoppingCartSummaryBlock=i.Z.querySelectorAll(document,".checkout-aside-summary-list"),this.offCanvasSummaryDetails=null,this.shoppingCartSummaryDetails=null,this.giftcardComponentClose.onclick=function(t){t.currentTarget.style.display="none",e.selectedGiftcard=null,e.giftcardItem.innerHTML="",e.giftcardHeader.innerHTML=" ",e.paymentMethodInstance&&e.paymentMethodInstance.unmount()},document.getElementById("showGiftcardButton").addEventListener("click",(function(){this.style.display="none",document.getElementById("giftcardDropdown").style.display="block"})),window.addEventListener("DOMContentLoaded",(()=>{document.getElementById("giftcardsContainer").addEventListener("click",(e=>{if(e.target.classList.contains("adyen-remove-giftcard")){const t=e.target.getAttribute("dataid");this.removeGiftcard(t)}}))})),window.addEventListener("DOMContentLoaded",(e=>{parseInt(adyenGiftcardsConfiguration.giftcardDiscount,10)&&this.fetchRedeemedGiftcards()}))}async initializeCheckoutComponent(){const{locale:e,clientKey:t,environment:n}=adyenCheckoutConfiguration,a={locale:e,clientKey:t,environment:n,amount:{currency:adyenGiftcardsConfiguration.currency,value:adyenGiftcardsConfiguration.totalInMinorUnits}};this.adyenCheckout=await AdyenCheckout(a)}observeGiftcardSelection(){let e=this,t=document.getElementById("giftcardDropdown"),n=document.querySelector(".btn-outline-info");t.addEventListener("change",(function(){t.value&&(e.selectedGiftcard=JSON.parse(event.currentTarget.options[event.currentTarget.selectedIndex].dataset.giftcard),e.mountGiftcardComponent(e.selectedGiftcard),t.value="",n.style.display="none")}))}mountGiftcardComponent(e){this.paymentMethodInstance&&this.paymentMethodInstance.unmount(),this.giftcardItem.innerHTML="",r.Z.create(i.Z.querySelector(document,"#adyen-giftcard-component"));var t=document.createElement("img");t.src="https://checkoutshopper-live.adyen.com/checkoutshopper/images/logos/"+e.brand+".svg",t.classList.add("adyen-giftcard-logo"),this.giftcardItem.insertBefore(t,this.giftcardItem.firstChild),this.giftcardHeader.innerHTML=e.name,this.giftcardComponentClose.style.display="block";const n=Object.assign({},e,{showPayButton:!0,onBalanceCheck:this.handleBalanceCheck.bind(this,e)});try{this.paymentMethodInstance=this.adyenCheckout.create("giftcard",n),this.paymentMethodInstance.mount("#adyen-giftcard-component")}catch(e){console.log("giftcard not available")}r.Z.remove(i.Z.querySelector(document,"#adyen-giftcard-component"))}handleBalanceCheck(e,t,n,a){let i={};i.paymentMethod=JSON.stringify(a.paymentMethod),i.amount=JSON.stringify({currency:adyenGiftcardsConfiguration.currency,value:adyenGiftcardsConfiguration.totalInMinorUnits}),this._client.post(`${adyenGiftcardsConfiguration.checkBalanceUrl}`,JSON.stringify(i),function(t){if((t=JSON.parse(t)).hasOwnProperty("pspReference")){const n=t.transactionLimit?parseFloat(t.transactionLimit.value):parseFloat(t.balance.value);a.giftcard={currency:adyenGiftcardsConfiguration.currency,value:(n/this.minorUnitsQuotient).toFixed(2),title:e.name},this.saveGiftcardStateData(a)}else n(t.resultCode)}.bind(this))}fetchRedeemedGiftcards(){this._client.get(adyenGiftcardsConfiguration.fetchRedeemedGiftcardsUrl,function(e){e=JSON.parse(e);let t=document.getElementById("giftcardsContainer"),n=document.querySelector(".btn-outline-info");t.innerHTML="",e.redeemedGiftcards.giftcards.forEach((function(e){let n=parseFloat(e.deductedAmount);n=n.toFixed(2);let a=adyenGiftcardsConfiguration.translationAdyenGiftcardDeductedBalance+": "+adyenGiftcardsConfiguration.currencySymbol+n,i=document.createElement("div");var o=document.createElement("img");o.src="https://checkoutshopper-live.adyen.com/checkoutshopper/images/logos/"+e.brand+".svg",o.classList.add("adyen-giftcard-logo");let r=document.createElement("a");r.href="#",r.textContent=adyenGiftcardsConfiguration.translationAdyenGiftcardRemove,r.setAttribute("dataid",e.stateDataId),r.classList.add("adyen-remove-giftcard"),r.style.display="block",i.appendChild(o),i.innerHTML+=`${e.title}`,i.appendChild(r),i.innerHTML+=`

${a}


`,t.appendChild(i)})),this.remainingAmount=e.redeemedGiftcards.remainingAmount,this.giftcardDiscount=e.redeemedGiftcards.totalDiscount,this.paymentMethodInstance&&this.paymentMethodInstance.unmount(),this.giftcardComponentClose.style.display="none",this.giftcardItem.innerHTML="",this.giftcardHeader.innerHTML=" ",this.appendGiftcardSummary(),this.remainingAmount>0?n.style.display="block":(this.adyenGiftcardDropDown.length>0&&(this.adyenGiftcardDropDown[0].style.display="none"),n.style.display="none");document.getElementById("giftcardsContainer")}.bind(this))}saveGiftcardStateData(e){e=JSON.stringify(e),this._client.post(adyenGiftcardsConfiguration.setGiftcardUrl,JSON.stringify({stateData:e}),function(e){"token"in(e=JSON.parse(e))&&(this.fetchRedeemedGiftcards(),r.Z.remove(document.body))}.bind(this))}removeGiftcard(e){r.Z.create(document.body),this._client.post(adyenGiftcardsConfiguration.removeGiftcardUrl,JSON.stringify({stateDataId:e}),(e=>{"token"in(e=JSON.parse(e))&&(this.fetchRedeemedGiftcards(),r.Z.remove(document.body))}))}appendGiftcardSummary(){if(this.shoppingCartSummaryBlock.length){let e=this.shoppingCartSummaryBlock[0].querySelectorAll(".adyen-giftcard-summary");for(let t=0;t
'+adyenGiftcardsConfiguration.currencySymbol+e+'
'+adyenGiftcardsConfiguration.translationAdyenGiftcardRemainingAmount+'
'+adyenGiftcardsConfiguration.currencySymbol+t+"
";this.shoppingCartSummaryBlock[0].innerHTML+=n}}}var s=n(207);const c={updatablePaymentMethods:["scheme","ideal","sepadirectdebit","oneclick","dotpay","bcmc","bcmc_mobile","blik","klarna_b2b","eps","facilypay_3x","facilypay_4x","facilypay_6x","facilypay_10x","facilypay_12x","afterpay_default","ratepay","ratepay_directdebit","giftcard","paybright","affirm","multibanco","mbway","vipps","mobilepay","wechatpayQR","wechatpayWeb","paybybank"],componentsWithPayButton:{applepay:{extra:{},onClick(e,t,n){return n.confirmOrderForm.checkValidity()?(e(),!0):(t(),!1)}},googlepay:{extra:{buttonSizeMode:"fill"},onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()?(e(),!0):(t(),!1)},onError:function(e,t,n){"CANCELED"!==e.statusCode&&("statusMessage"in e?console.log(e.statusMessage):console.log(e.statusCode))}},paypal:{extra:{},onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()},onError:function(e,t,n){t.setStatus("ready"),window.location.href=n.errorUrl.toString()},onCancel:function(e,t,n){t.setStatus("ready"),window.location.href=n.errorUrl.toString()},responseHandler:function(e,t){try{(t=JSON.parse(t)).isFinal&&(location.href=e.returnUrl),this.handleAction(t.action)}catch(e){console.error(e)}}},amazonpay:{extra:{productType:"PayAndShip",checkoutMode:"ProcessOrder",returnUrl:location.href},prePayRedirect:!0,sessionKey:"amazonCheckoutSessionId",onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()?(e(),!0):(t(),!1)},onError:(e,t)=>{console.log(e),t.setStatus("ready")}}},paymentMethodTypeHandlers:{scheme:"handler_adyen_cardspaymentmethodhandler",ideal:"handler_adyen_idealpaymentmethodhandler",klarna:"handler_adyen_klarnapaylaterpaymentmethodhandler",klarna_account:"handler_adyen_klarnaaccountpaymentmethodhandler",klarna_paynow:"handler_adyen_klarnapaynowpaymentmethodhandler",ratepay:"handler_adyen_ratepaypaymentmethodhandler",ratepay_directdebit:"handler_adyen_ratepaydirectdebitpaymentmethodhandler",sepadirectdebit:"handler_adyen_sepapaymentmethodhandler",sofort:"handler_adyen_sofortpaymentmethodhandler",paypal:"handler_adyen_paypalpaymentmethodhandler",oneclick:"handler_adyen_oneclickpaymentmethodhandler",giropay:"handler_adyen_giropaypaymentmethodhandler",applepay:"handler_adyen_applepaypaymentmethodhandler",googlepay:"handler_adyen_googlepaypaymentmethodhandler",dotpay:"handler_adyen_dotpaypaymentmethodhandler",bcmc:"handler_adyen_bancontactcardpaymentmethodhandler",bcmc_mobile:"handler_adyen_bancontactmobilepaymentmethodhandler",amazonpay:"handler_adyen_amazonpaypaymentmethodhandler",twint:"handler_adyen_twintpaymentmethodhandler",eps:"handler_adyen_epspaymentmethodhandler",swish:"handler_adyen_swishpaymentmethodhandler",alipay:"handler_adyen_alipaypaymentmethodhandler",alipay_hk:"handler_adyen_alipayhkpaymentmethodhandler",blik:"handler_adyen_blikpaymentmethodhandler",clearpay:"handler_adyen_clearpaypaymentmethodhandler",facilypay_3x:"handler_adyen_facilypay3xpaymentmethodhandler",facilypay_4x:"handler_adyen_facilypay4xpaymentmethodhandler",facilypay_6x:"handler_adyen_facilypay6xpaymentmethodhandler",facilypay_10x:"handler_adyen_facilypay10xpaymentmethodhandler",facilypay_12x:"handler_adyen_facilypay12xpaymentmethodhandler",afterpay_default:"handler_adyen_afterpaydefaultpaymentmethodhandler",trustly:"handler_adyen_trustlypaymentmethodhandler",paysafecard:"handler_adyen_paysafecardpaymentmethodhandler",giftcard:"handler_adyen_giftcardpaymentmethodhandler",mbway:"handler_adyen_mbwaypaymentmethodhandler",multibanco:"handler_adyen_multibancopaymentmethodhandler",wechatpayQR:"handler_adyen_wechatpayqrpaymentmethodhandler",wechatpayWeb:"handler_adyen_wechatpaywebpaymentmethodhandler",mobilepay:"handler_adyen_mobilepaypaymentmethodhandler",vipps:"handler_adyen_vippspaymentmethodhandler",affirm:"handler_adyen_affirmpaymentmethodhandler",paybright:"handler_adyen_paybrightpaymentmethodhandler",paybybank:"handler_adyen_openbankingpaymentmethodhandler",klarna_b2b:"handler_adyen_billiepaymentmethodhandler"}};class l extends a.Z{init(){this._client=new o.Z,this.selectedAdyenPaymentMethod=this.getSelectedPaymentMethodKey(),this.confirmOrderForm=i.Z.querySelector(document,"#confirmOrderForm"),this.confirmFormSubmit=i.Z.querySelector(document,'#confirmOrderForm button[type="submit"]'),this.shoppingCartSummaryBlock=i.Z.querySelectorAll(document,".checkout-aside-summary-list"),this.minorUnitsQuotient=adyenCheckoutOptions.amount/adyenCheckoutOptions.totalPrice,this.giftcardDiscount=adyenCheckoutOptions.giftcardDiscount,this.remainingAmount=adyenCheckoutOptions.totalPrice-this.giftcardDiscount,this.responseHandler=this.handlePaymentAction,this.adyenCheckout=Promise,this.initializeCheckoutComponent().then(function(){adyenCheckoutOptions.selectedPaymentMethodPluginId===adyenCheckoutOptions.adyenPluginId&&(adyenCheckoutOptions&&adyenCheckoutOptions.paymentStatusUrl&&adyenCheckoutOptions.checkoutOrderUrl&&adyenCheckoutOptions.paymentHandleUrl?(this.selectedAdyenPaymentMethod in c.componentsWithPayButton&&this.initializeCustomPayButton(),c.updatablePaymentMethods.includes(this.selectedAdyenPaymentMethod)&&!this.stateData?this.renderPaymentComponent(this.selectedAdyenPaymentMethod):this.confirmFormSubmit.addEventListener("click",this.onConfirmOrderSubmit.bind(this))):console.error("Adyen payment configuration missing."))}.bind(this)),adyenCheckoutOptions.payInFullWithGiftcard>0?parseInt(adyenCheckoutOptions.giftcardDiscount,10)&&this.appendGiftcardSummary():this.appendGiftcardSummary()}async initializeCheckoutComponent(){const{locale:e,clientKey:t,environment:n,merchantAccount:a}=adyenCheckoutConfiguration,i=adyenCheckoutOptions.paymentMethodsResponse,o={locale:e,clientKey:t,environment:n,showPayButton:this.selectedAdyenPaymentMethod in c.componentsWithPayButton,hasHolderName:!0,paymentMethodsResponse:JSON.parse(i),onAdditionalDetails:this.handleOnAdditionalDetails.bind(this),countryCode:activeShippingAddress.country,paymentMethodsConfiguration:{card:{hasHolderName:!0,holderNameRequired:!0,clickToPayConfiguration:{merchantDisplayName:a,shopperEmail:shopperDetails.shopperEmail}}}};this.adyenCheckout=await AdyenCheckout(o)}handleOnAdditionalDetails(e){this._client.post(`${adyenCheckoutOptions.paymentDetailsUrl}`,JSON.stringify({orderId:this.orderId,stateData:JSON.stringify(e.data)}),function(e){200===this._client._request.status?this.responseHandler(e):location.href=this.errorUrl.toString()}.bind(this))}onConfirmOrderSubmit(e){const t=i.Z.querySelector(document,"#confirmOrderForm");if(!t.checkValidity())return;e.preventDefault(),r.Z.create(document.body);const n=s.Z.serialize(t);this.confirmOrder(n)}renderPaymentComponent(e){if("oneclick"===e)return void this.renderStoredPaymentMethodComponents();if("giftcard"===e)return;let t=this.adyenCheckout.paymentMethodsResponse.paymentMethods.filter((function(t){return t.type===e}));if(0===t.length)return void("test"===this.adyenCheckout.options.environment&&console.error("Payment method configuration not found. ",e));let n=t[0];this.mountPaymentComponent(n,!1)}renderStoredPaymentMethodComponents(){this.adyenCheckout.paymentMethodsResponse.storedPaymentMethods.forEach((e=>{let t=`[data-adyen-stored-payment-method-id="${e.id}"]`;this.mountPaymentComponent(e,!0,t)})),this.hideStorePaymentMethodComponents();let e=null;i.Z.querySelectorAll(document,"[name=adyenStoredPaymentMethodId]").forEach((t=>{e||(e=t.value),t.addEventListener("change",this.showSelectedStoredPaymentMethod.bind(this))})),this.showSelectedStoredPaymentMethod(null,e)}showSelectedStoredPaymentMethod(e,t=null){this.hideStorePaymentMethodComponents();let n=`[data-adyen-stored-payment-method-id="${t=e?e.target.value:t}"]`;i.Z.querySelector(document,n).style.display="block"}hideStorePaymentMethodComponents(){i.Z.querySelectorAll(document,".stored-payment-component").forEach((e=>{e.style.display="none"}))}confirmOrder(e,t={}){const n=adyenCheckoutOptions.orderId;e.set("affiliateCode",adyenCheckoutOptions.affiliateCode),e.set("campaignCode",adyenCheckoutOptions.campaignCode),n?this.updatePayment(e,n,t):this.createOrder(e,t)}updatePayment(e,t,n){e.set("orderId",t),this._client.post(adyenCheckoutOptions.updatePaymentUrl,e,this.afterSetPayment.bind(this,n))}createOrder(e,t){this._client.post(adyenCheckoutOptions.checkoutOrderUrl,e,this.afterCreateOrder.bind(this,t))}afterCreateOrder(e={},t){let n;try{n=JSON.parse(t)}catch(e){return r.Z.remove(document.body),void console.log("Error: invalid response from Shopware API",t)}if(n.url)return void(location.href=n.url);this.orderId=n.id,this.finishUrl=new URL(location.origin+adyenCheckoutOptions.paymentFinishUrl),this.finishUrl.searchParams.set("orderId",n.id),this.errorUrl=new URL(location.origin+adyenCheckoutOptions.paymentErrorUrl),this.errorUrl.searchParams.set("orderId",n.id);let a={orderId:this.orderId,finishUrl:this.finishUrl.toString(),errorUrl:this.errorUrl.toString()};for(const t in e)a[t]=e[t];this._client.post(adyenCheckoutOptions.paymentHandleUrl,JSON.stringify(a),this.afterPayOrder.bind(this,this.orderId))}afterSetPayment(e={},t){try{JSON.parse(t).success&&this.afterCreateOrder(e,JSON.stringify({id:adyenCheckoutOptions.orderId}))}catch(e){return r.Z.remove(document.body),void console.log("Error: invalid response from Shopware API",t)}}afterPayOrder(e,t){try{t=JSON.parse(t),this.returnUrl=t.redirectUrl}catch(e){return r.Z.remove(document.body),void console.log("Error: invalid response from Shopware API",t)}this.returnUrl===this.errorUrl.toString()&&(location.href=this.returnUrl);try{this._client.post(`${adyenCheckoutOptions.paymentStatusUrl}`,JSON.stringify({orderId:e}),this.responseHandler.bind(this))}catch(e){console.log(e)}}handlePaymentAction(e){try{const t=JSON.parse(e);if((t.isFinal||"voucher"===t.action.type)&&(location.href=this.returnUrl),t.action){const e={};"threeDS2"===t.action.type&&(e.challengeWindowSize="05"),this.adyenCheckout.createFromAction(t.action,e).mount("[data-adyen-payment-action-container]");if(["threeDS2","qrCode"].includes(t.action.type))if(window.jQuery)$("[data-adyen-payment-action-modal]").modal({show:!0});else new bootstrap.Modal(document.getElementById("adyen-payment-action-modal"),{keyboard:!1}).show()}}catch(e){console.log(e)}}initializeCustomPayButton(){const e=c.componentsWithPayButton[this.selectedAdyenPaymentMethod];this.completePendingPayment(this.selectedAdyenPaymentMethod,e);let t=this.adyenCheckout.paymentMethodsResponse.paymentMethods.filter((e=>e.type===this.selectedAdyenPaymentMethod));if(t.length<1&&"googlepay"===this.selectedAdyenPaymentMethod&&(t=this.adyenCheckout.paymentMethodsResponse.paymentMethods.filter((e=>"paywithgoogle"===e.type))),t.length<1)return;let n=t[0];if(!adyenCheckoutOptions.amount)return void console.error("Failed to fetch Cart/Order total amount.");if(e.prePayRedirect)return void this.renderPrePaymentButton(e,n);const a=Object.assign(e.extra,n,{amount:{value:adyenCheckoutOptions.amount,currency:adyenCheckoutOptions.currency},data:{personalDetails:shopperDetails,billingAddress:activeBillingAddress,deliveryAddress:activeShippingAddress},onClick:(t,n)=>{if(!e.onClick(t,n,this))return!1;r.Z.create(document.body)},onSubmit:function(t,n){if(t.isValid){let a={stateData:JSON.stringify(t.data)},i=s.Z.serialize(this.confirmOrderForm);"responseHandler"in e&&(this.responseHandler=e.responseHandler.bind(n,this)),this.confirmOrder(i,a)}else n.showValidation(),"test"===this.adyenCheckout.options.environment&&console.log("Payment failed: ",t)}.bind(this),onCancel:(t,n)=>{r.Z.remove(document.body),e.onCancel(t,n,this)},onError:(t,n)=>{"PayPal"===n.props.name&&"CANCEL"===t.name&&this._client.post(`${adyenCheckoutOptions.cancelOrderTransactionUrl}`,JSON.stringify({orderId:this.orderId})),r.Z.remove(document.body),e.onError(t,n,this),console.log(t)}}),i=this.adyenCheckout.create(n.type,a);try{"isAvailable"in i?i.isAvailable().then(function(){this.mountCustomPayButton(i)}.bind(this)).catch((e=>{console.log(n.type+" is not available",e)})):this.mountCustomPayButton(i)}catch(e){console.log(e)}}renderPrePaymentButton(e,t){"amazonpay"===t.type&&(e.extra=this.setAddressDetails(e.extra));const n=Object.assign(e.extra,t,{configuration:t.configuration,amount:{value:adyenCheckoutOptions.amount,currency:adyenCheckoutOptions.currency},onClick:(t,n)=>{if(!e.onClick(t,n,this))return!1;r.Z.create(document.body)},onError:(t,n)=>{r.Z.remove(document.body),e.onError(t,n,this),console.log(t)}});let a=this.adyenCheckout.create(t.type,n);this.mountCustomPayButton(a)}completePendingPayment(e,t){const n=new URL(location.href);if(n.searchParams.has(t.sessionKey)){r.Z.create(document.body);const a=this.adyenCheckout.create(e,{[t.sessionKey]:n.searchParams.get(t.sessionKey),showOrderButton:!1,onSubmit:function(e,t){if(e.isValid){let t={stateData:JSON.stringify(e.data)},n=s.Z.serialize(this.confirmOrderForm);this.confirmOrder(n,t)}}.bind(this)});this.mountCustomPayButton(a),a.submit()}}getSelectedPaymentMethodKey(){return Object.keys(c.paymentMethodTypeHandlers).find((e=>c.paymentMethodTypeHandlers[e]===adyenCheckoutOptions.selectedPaymentMethodHandler))}mountCustomPayButton(e){let t=document.querySelector("#confirmOrderForm");if(t){let n=t.querySelector("button[type=submit]");if(n&&!n.disabled){let a=document.createElement("div");a.id="adyen-confirm-button",a.setAttribute("data-adyen-confirm-button",""),t.appendChild(a),e.mount(a),n.remove()}}}mountPaymentComponent(e,t=!1,n=null){const a=Object.assign({},e,{data:{personalDetails:shopperDetails,billingAddress:activeBillingAddress,deliveryAddress:activeShippingAddress},onSubmit:function(n,a){if(n.isValid){t&&void 0!==e.holderName&&(n.data.paymentMethod.holderName=e.holderName);let a={stateData:JSON.stringify(n.data)},i=s.Z.serialize(this.confirmOrderForm);r.Z.create(document.body),this.confirmOrder(i,a)}else a.showValidation(),"test"===this.adyenCheckout.options.environment&&console.log("Payment failed: ",n)}.bind(this)});!t&&"scheme"===e.type&&adyenCheckoutOptions.displaySaveCreditCardOption&&(a.enableStoreDetails=!0);let o=t?n:"#"+this.el.id;try{const t=this.adyenCheckout.create(e.type,a);t.mount(o),this.confirmFormSubmit.addEventListener("click",function(e){i.Z.querySelector(document,"#confirmOrderForm").checkValidity()&&(e.preventDefault(),this.el.parentNode.scrollIntoView({behavior:"smooth",block:"start"}),t.submit())}.bind(this))}catch(t){return console.error(e.type,t),!1}}appendGiftcardSummary(){if(parseInt(adyenCheckoutOptions.giftcardDiscount,10)&&this.shoppingCartSummaryBlock.length){let e=parseFloat(this.giftcardDiscount).toFixed(2),t=parseFloat(this.remainingAmount).toFixed(2),n='
'+adyenCheckoutOptions.translationAdyenGiftcardDiscount+'
'+adyenCheckoutOptions.currencySymbol+e+'
'+adyenCheckoutOptions.translationAdyenGiftcardRemainingAmount+'
'+adyenCheckoutOptions.currencySymbol+t+"
";this.shoppingCartSummaryBlock[0].innerHTML+=n}}setAddressDetails(e){return""!==activeShippingAddress.phoneNumber?e.addressDetails={name:shopperDetails.firstName+" "+shopperDetails.lastName,addressLine1:activeShippingAddress.street,city:activeShippingAddress.city,postalCode:activeShippingAddress.postalCode,countryCode:activeShippingAddress.country,phoneNumber:activeShippingAddress.phoneNumber}:e.productType="PayOnly",e}}class h extends a.Z{init(){this._client=new o.Z,this.adyenCheckout=Promise,this.initializeCheckoutComponent().bind(this)}async initializeCheckoutComponent(){const{locale:e,clientKey:t,environment:n}=adyenCheckoutConfiguration,{currency:a,values:i,backgroundUrl:o,logoUrl:r,name:d,description:s,url:c}=adyenGivingConfiguration,l={locale:e,clientKey:t,environment:n},h={amounts:{currency:a,values:i.split(",").map((e=>Number(e)))},backgroundUrl:o,logoUrl:r,description:s,name:d,url:c,showCancelButton:!0,onDonate:this.handleOnDonate.bind(this),onCancel:this.handleOnCancel.bind(this)};this.adyenCheckout=await AdyenCheckout(l),this.adyenCheckout.create("donation",h).mount("#donation-container")}handleOnDonate(e,t){const n=adyenGivingConfiguration.orderId;let a={stateData:JSON.stringify(e.data),orderId:n};a.returnUrl=window.location.href,this._client.post(`${adyenGivingConfiguration.donationEndpointUrl}`,JSON.stringify({...a}),function(e){200!==this._client._request.status?t.setStatus("error"):t.setStatus("success")}.bind(this))}handleOnCancel(){let e=adyenGivingConfiguration.continueActionUrl;window.location=e}}class y extends a.Z{init(){this.adyenCheckout=Promise,this.initializeCheckoutComponent().bind(this)}async initializeCheckoutComponent(){const{locale:e,clientKey:t,environment:n}=adyenCheckoutConfiguration,{action:a}=adyenSuccessActionConfiguration,i={locale:e,clientKey:t,environment:n};this.adyenCheckout=await AdyenCheckout(i),this.adyenCheckout.createFromAction(JSON.parse(a)).mount("#success-action-container")}}const m=window.PluginManager;m.register("CartPlugin",d,"#adyen-giftcards-container"),m.register("ConfirmOrderPlugin",l,"#adyen-payment-checkout-mask"),m.register("AdyenGivingPlugin",h,"#adyen-giving-container"),m.register("AdyenSuccessAction",y,"#adyen-success-action-container")}},e=>{e.O(0,["vendor-node","vendor-shared"],(()=>{return t=6253,e(e.s=t);var t}));e.O()}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([["adyen-payment-shopware6"],{"4Gix":function(e,t,n){"use strict";t.a={updatablePaymentMethods:["scheme","ideal","sepadirectdebit","oneclick","dotpay","bcmc","bcmc_mobile","blik","klarna_b2b","eps","facilypay_3x","facilypay_4x","facilypay_6x","facilypay_10x","facilypay_12x","afterpay_default","ratepay","ratepay_directdebit","giftcard","paybright","affirm","multibanco","mbway","vipps","mobilepay","wechatpayQR","wechatpayWeb","paybybank"],componentsWithPayButton:{applepay:{extra:{},onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()?(e(),!0):(t(),!1)}},googlepay:{extra:{buttonSizeMode:"fill"},onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()?(e(),!0):(t(),!1)},onError:function(e,t,n){"CANCELED"!==e.statusCode&&("statusMessage"in e?console.log(e.statusMessage):console.log(e.statusCode))}},paypal:{extra:{},onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()},onError:function(e,t,n){t.setStatus("ready"),window.location.href=n.errorUrl.toString()},onCancel:function(e,t,n){t.setStatus("ready"),window.location.href=n.errorUrl.toString()},responseHandler:function(e,t){try{(t=JSON.parse(t)).isFinal&&(location.href=e.returnUrl),this.handleAction(t.action)}catch(e){console.error(e)}}},amazonpay:{extra:{productType:"PayAndShip",checkoutMode:"ProcessOrder",returnUrl:location.href},prePayRedirect:!0,sessionKey:"amazonCheckoutSessionId",onClick:function(e,t,n){return n.confirmOrderForm.checkValidity()?(e(),!0):(t(),!1)},onError:function(e,t){console.log(e),t.setStatus("ready")}}},paymentMethodTypeHandlers:{scheme:"handler_adyen_cardspaymentmethodhandler",ideal:"handler_adyen_idealpaymentmethodhandler",klarna:"handler_adyen_klarnapaylaterpaymentmethodhandler",klarna_account:"handler_adyen_klarnaaccountpaymentmethodhandler",klarna_paynow:"handler_adyen_klarnapaynowpaymentmethodhandler",ratepay:"handler_adyen_ratepaypaymentmethodhandler",ratepay_directdebit:"handler_adyen_ratepaydirectdebitpaymentmethodhandler",sepadirectdebit:"handler_adyen_sepapaymentmethodhandler",sofort:"handler_adyen_sofortpaymentmethodhandler",paypal:"handler_adyen_paypalpaymentmethodhandler",oneclick:"handler_adyen_oneclickpaymentmethodhandler",giropay:"handler_adyen_giropaypaymentmethodhandler",applepay:"handler_adyen_applepaypaymentmethodhandler",googlepay:"handler_adyen_googlepaypaymentmethodhandler",dotpay:"handler_adyen_dotpaypaymentmethodhandler",bcmc:"handler_adyen_bancontactcardpaymentmethodhandler",bcmc_mobile:"handler_adyen_bancontactmobilepaymentmethodhandler",amazonpay:"handler_adyen_amazonpaypaymentmethodhandler",twint:"handler_adyen_twintpaymentmethodhandler",eps:"handler_adyen_epspaymentmethodhandler",swish:"handler_adyen_swishpaymentmethodhandler",alipay:"handler_adyen_alipaypaymentmethodhandler",alipay_hk:"handler_adyen_alipayhkpaymentmethodhandler",blik:"handler_adyen_blikpaymentmethodhandler",clearpay:"handler_adyen_clearpaypaymentmethodhandler",facilypay_3x:"handler_adyen_facilypay3xpaymentmethodhandler",facilypay_4x:"handler_adyen_facilypay4xpaymentmethodhandler",facilypay_6x:"handler_adyen_facilypay6xpaymentmethodhandler",facilypay_10x:"handler_adyen_facilypay10xpaymentmethodhandler",facilypay_12x:"handler_adyen_facilypay12xpaymentmethodhandler",afterpay_default:"handler_adyen_afterpaydefaultpaymentmethodhandler",trustly:"handler_adyen_trustlypaymentmethodhandler",paysafecard:"handler_adyen_paysafecardpaymentmethodhandler",giftcard:"handler_adyen_giftcardpaymentmethodhandler",mbway:"handler_adyen_mbwaypaymentmethodhandler",multibanco:"handler_adyen_multibancopaymentmethodhandler",wechatpayQR:"handler_adyen_wechatpayqrpaymentmethodhandler",wechatpayWeb:"handler_adyen_wechatpaywebpaymentmethodhandler",mobilepay:"handler_adyen_mobilepaypaymentmethodhandler",vipps:"handler_adyen_vippspaymentmethodhandler",affirm:"handler_adyen_affirmpaymentmethodhandler",paybright:"handler_adyen_paybrightpaymentmethodhandler",paybybank:"handler_adyen_openbankingpaymentmethodhandler",klarna_b2b:"handler_adyen_billiepaymentmethodhandler"}}},HbFT:function(e,t,n){"use strict";n.r(t);var a=n("FGIj"),o=n("gHbT"),r=n("k8s9"),i=n("u0Tz");function c(e){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function d(){return(d=Object.assign||function(e){for(var t=1;t".concat(e.title,""),o.appendChild(i),o.innerHTML+='

'.concat(a,"


"),t.appendChild(o)})),this.remainingAmount=e.redeemedGiftcards.remainingAmount,this.giftcardDiscount=e.redeemedGiftcards.totalDiscount,this.paymentMethodInstance&&this.paymentMethodInstance.unmount(),this.giftcardComponentClose.style.display="none",this.giftcardItem.innerHTML="",this.giftcardHeader.innerHTML=" ",this.appendGiftcardSummary(),this.remainingAmount>0?n.style.display="block":(this.adyenGiftcardDropDown.length>0&&(this.adyenGiftcardDropDown[0].style.display="none"),n.style.display="none"),document.getElementById("giftcardsContainer")}.bind(this))}},{key:"saveGiftcardStateData",value:function(e){e=JSON.stringify(e),this._client.post(adyenGiftcardsConfiguration.setGiftcardUrl,JSON.stringify({stateData:e}),function(e){"token"in(e=JSON.parse(e))&&(this.fetchRedeemedGiftcards(),i.a.remove(document.body))}.bind(this))}},{key:"removeGiftcard",value:function(e){var t=this;i.a.create(document.body),this._client.post(adyenGiftcardsConfiguration.removeGiftcardUrl,JSON.stringify({stateDataId:e}),(function(e){"token"in(e=JSON.parse(e))&&(t.fetchRedeemedGiftcards(),i.a.remove(document.body))}))}},{key:"appendGiftcardSummary",value:function(){if(this.shoppingCartSummaryBlock.length)for(var e=this.shoppingCartSummaryBlock[0].querySelectorAll(".adyen-giftcard-summary"),t=0;t
'+adyenGiftcardsConfiguration.currencySymbol+n+'
'+adyenGiftcardsConfiguration.translationAdyenGiftcardRemainingAmount+'
'+adyenGiftcardsConfiguration.currencySymbol+a+"
";this.shoppingCartSummaryBlock[0].innerHTML+=o}}}])&&u(n.prototype,a),c&&u(n,c),t}(a.a),f=n("q5xn");function g(e){return(g="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function v(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function b(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function k(e,t,n,a,o,r,i){try{var c=e[r](i),d=c.value}catch(e){return void n(e)}c.done?t(d):Promise.resolve(d).then(a,o)}function C(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function O(e,t){for(var n=0;n0?parseInt(adyenCheckoutOptions.giftcardDiscount,10)&&this.appendGiftcardSummary():this.appendGiftcardSummary()}},{key:"initializeCheckoutComponent",value:(k=regeneratorRuntime.mark((function e(){var t,n,a,o,r,i,c;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=adyenCheckoutConfiguration,n=t.locale,a=t.clientKey,o=t.environment,r=t.merchantAccount,i=adyenCheckoutOptions.paymentMethodsResponse,c={locale:n,clientKey:a,environment:o,showPayButton:this.selectedAdyenPaymentMethod in s.a.componentsWithPayButton,hasHolderName:!0,paymentMethodsResponse:JSON.parse(i),onAdditionalDetails:this.handleOnAdditionalDetails.bind(this),countryCode:activeShippingAddress.country,paymentMethodsConfiguration:{card:{hasHolderName:!0,holderNameRequired:!0,clickToPayConfiguration:{merchantDisplayName:r,shopperEmail:shopperDetails.shopperEmail}}}},e.next=5,AdyenCheckout(c);case 5:this.adyenCheckout=e.sent;case 6:case"end":return e.stop()}}),e,this)})),C=function(){var e=this,t=arguments;return new Promise((function(n,a){var o=k.apply(e,t);function r(e){h(o,n,a,r,i,"next",e)}function i(e){h(o,n,a,r,i,"throw",e)}r(void 0)}))},function(){return C.apply(this,arguments)})},{key:"handleOnAdditionalDetails",value:function(e){this._client.post("".concat(adyenCheckoutOptions.paymentDetailsUrl),JSON.stringify({orderId:this.orderId,stateData:JSON.stringify(e.data)}),function(e){200===this._client._request.status?this.responseHandler(e):location.href=this.errorUrl.toString()}.bind(this))}},{key:"onConfirmOrderSubmit",value:function(e){var t=r.a.querySelector(document,"#confirmOrderForm");if(t.checkValidity()){e.preventDefault(),d.a.create(document.body);var n=c.a.serialize(t);this.confirmOrder(n)}}},{key:"renderPaymentComponent",value:function(e){if("oneclick"!==e){if("giftcard"!==e){var t=this.adyenCheckout.paymentMethodsResponse.paymentMethods.filter((function(t){return t.type===e}));if(0!==t.length){var n=t[0];this.mountPaymentComponent(n,!1)}else"test"===this.adyenCheckout.options.environment&&console.error("Payment method configuration not found. ",e)}}else this.renderStoredPaymentMethodComponents()}},{key:"renderStoredPaymentMethodComponents",value:function(){var e=this;this.adyenCheckout.paymentMethodsResponse.storedPaymentMethods.forEach((function(t){var n='[data-adyen-stored-payment-method-id="'.concat(t.id,'"]');e.mountPaymentComponent(t,!0,n)})),this.hideStorePaymentMethodComponents();var t=null;r.a.querySelectorAll(document,"[name=adyenStoredPaymentMethodId]").forEach((function(n){t||(t=n.value),n.addEventListener("change",e.showSelectedStoredPaymentMethod.bind(e))})),this.showSelectedStoredPaymentMethod(null,t)}},{key:"showSelectedStoredPaymentMethod",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;this.hideStorePaymentMethodComponents(),t=e?e.target.value:t;var n='[data-adyen-stored-payment-method-id="'.concat(t,'"]'),a=r.a.querySelector(document,n);a.style.display="block"}},{key:"hideStorePaymentMethodComponents",value:function(){r.a.querySelectorAll(document,".stored-payment-component").forEach((function(e){e.style.display="none"}))}},{key:"confirmOrder",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=adyenCheckoutOptions.orderId;e.set("affiliateCode",adyenCheckoutOptions.affiliateCode),e.set("campaignCode",adyenCheckoutOptions.campaignCode),n?this.updatePayment(e,n,t):this.createOrder(e,t)}},{key:"updatePayment",value:function(e,t,n){e.set("orderId",t),this._client.post(adyenCheckoutOptions.updatePaymentUrl,e,this.afterSetPayment.bind(this,n))}},{key:"createOrder",value:function(e,t){this._client.post(adyenCheckoutOptions.checkoutOrderUrl,e,this.afterCreateOrder.bind(this,t))}},{key:"afterCreateOrder",value:function(){var e,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;try{e=JSON.parse(n)}catch(e){return d.a.remove(document.body),void console.log("Error: invalid response from Shopware API",n)}if(e.url)location.href=e.url;else{this.orderId=e.id,this.finishUrl=new URL(location.origin+adyenCheckoutOptions.paymentFinishUrl),this.finishUrl.searchParams.set("orderId",e.id),this.errorUrl=new URL(location.origin+adyenCheckoutOptions.paymentErrorUrl),this.errorUrl.searchParams.set("orderId",e.id);var a={orderId:this.orderId,finishUrl:this.finishUrl.toString(),errorUrl:this.errorUrl.toString()};for(var o in t)a[o]=t[o];this._client.post(adyenCheckoutOptions.paymentHandleUrl,JSON.stringify(a),this.afterPayOrder.bind(this,this.orderId))}}},{key:"afterSetPayment",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;try{var n=JSON.parse(t);n.success&&this.afterCreateOrder(e,JSON.stringify({id:adyenCheckoutOptions.orderId}))}catch(e){return d.a.remove(document.body),void console.log("Error: invalid response from Shopware API",t)}}},{key:"afterPayOrder",value:function(e,t){try{t=JSON.parse(t),this.returnUrl=t.redirectUrl}catch(e){return d.a.remove(document.body),void console.log("Error: invalid response from Shopware API",t)}this.returnUrl===this.errorUrl.toString()&&(location.href=this.returnUrl);try{this._client.post("".concat(adyenCheckoutOptions.paymentStatusUrl),JSON.stringify({orderId:e}),this.responseHandler.bind(this))}catch(e){console.log(e)}}},{key:"handlePaymentAction",value:function(t){try{var n=JSON.parse(t);if((n.isFinal||"voucher"===n.action.type)&&(location.href=this.returnUrl),n.action){var o={};"threeDS2"===n.action.type&&(o.challengeWindowSize="05"),this.adyenCheckout.createFromAction(n.action,o).mount("[data-adyen-payment-action-container]"),["threeDS2","qrCode"].includes(n.action.type)&&(e?a("[data-adyen-payment-action-modal]").modal({show:!0}):new bootstrap.Modal(document.getElementById("adyen-payment-action-modal"),{keyboard:!1}).show())}}catch(e){console.log(e)}}},{key:"initializeCustomPayButton",value:function(){var e=this,t=s.a.componentsWithPayButton[this.selectedAdyenPaymentMethod];this.completePendingPayment(this.selectedAdyenPaymentMethod,t);var n=this.adyenCheckout.paymentMethodsResponse.paymentMethods.filter((function(t){return t.type===e.selectedAdyenPaymentMethod}));if(n.length<1&&"googlepay"===this.selectedAdyenPaymentMethod&&(n=this.adyenCheckout.paymentMethodsResponse.paymentMethods.filter((function(e){return"paywithgoogle"===e.type}))),!(n.length<1)){var a=n[0];if(adyenCheckoutOptions.amount)if(t.prePayRedirect)this.renderPrePaymentButton(t,a);else{var o=y(t.extra,a,{amount:{value:adyenCheckoutOptions.amount,currency:adyenCheckoutOptions.currency},data:{personalDetails:shopperDetails,billingAddress:activeBillingAddress,deliveryAddress:activeShippingAddress},onClick:function(n,a){if(!t.onClick(n,a,e))return!1;d.a.create(document.body)},onSubmit:function(e,n){if(e.isValid){var a={stateData:JSON.stringify(e.data)},o=c.a.serialize(this.confirmOrderForm);"responseHandler"in t&&(this.responseHandler=t.responseHandler.bind(n,this)),this.confirmOrder(o,a)}else n.showValidation(),"test"===this.adyenCheckout.options.environment&&console.log("Payment failed: ",e)}.bind(this),onCancel:function(n,a){d.a.remove(document.body),t.onCancel(n,a,e)},onError:function(n,a){"PayPal"===a.props.name&&"CANCEL"===n.name&&e._client.post("".concat(adyenCheckoutOptions.cancelOrderTransactionUrl),JSON.stringify({orderId:e.orderId})),d.a.remove(document.body),t.onError(n,a,e),console.log(n)}}),r=this.adyenCheckout.create(a.type,o);try{"isAvailable"in r?r.isAvailable().then(function(){this.mountCustomPayButton(r)}.bind(this)).catch((function(e){console.log(a.type+" is not available",e)})):this.mountCustomPayButton(r)}catch(e){console.log(e)}}else console.error("Failed to fetch Cart/Order total amount.")}}},{key:"renderPrePaymentButton",value:function(e,t){var n=this;"amazonpay"===t.type&&(e.extra=this.setAddressDetails(e.extra));var a=y(e.extra,t,{configuration:t.configuration,amount:{value:adyenCheckoutOptions.amount,currency:adyenCheckoutOptions.currency},onClick:function(t,a){if(!e.onClick(t,a,n))return!1;d.a.create(document.body)},onError:function(t,a){d.a.remove(document.body),e.onError(t,a,n),console.log(t)}}),o=this.adyenCheckout.create(t.type,a);this.mountCustomPayButton(o)}},{key:"completePendingPayment",value:function(e,t){var n=new URL(location.href);if(n.searchParams.has(t.sessionKey)){var a;d.a.create(document.body);var o=this.adyenCheckout.create(e,(u(a={},t.sessionKey,n.searchParams.get(t.sessionKey)),u(a,"showOrderButton",!1),u(a,"onSubmit",function(e,t){if(e.isValid){var n={stateData:JSON.stringify(e.data)},a=c.a.serialize(this.confirmOrderForm);this.confirmOrder(a,n)}}.bind(this)),a));this.mountCustomPayButton(o),o.submit()}}},{key:"getSelectedPaymentMethodKey",value:function(){return Object.keys(s.a.paymentMethodTypeHandlers).find((function(e){return s.a.paymentMethodTypeHandlers[e]===adyenCheckoutOptions.selectedPaymentMethodHandler}))}},{key:"mountCustomPayButton",value:function(e){var t=document.querySelector("#confirmOrderForm");if(t){var n=t.querySelector("button[type=submit]");if(n&&!n.disabled){var a=document.createElement("div");a.id="adyen-confirm-button",a.setAttribute("data-adyen-confirm-button",""),t.appendChild(a),e.mount(a),n.remove()}}}},{key:"mountPaymentComponent",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,a=y({},e,{data:{personalDetails:shopperDetails,billingAddress:activeBillingAddress,deliveryAddress:activeShippingAddress},onSubmit:function(n,a){if(n.isValid){t&&void 0!==e.holderName&&(n.data.paymentMethod.holderName=e.holderName);var o={stateData:JSON.stringify(n.data)},r=c.a.serialize(this.confirmOrderForm);d.a.create(document.body),this.confirmOrder(r,o)}else a.showValidation(),"test"===this.adyenCheckout.options.environment&&console.log("Payment failed: ",n)}.bind(this)});!t&&"scheme"===e.type&&adyenCheckoutOptions.displaySaveCreditCardOption&&(a.enableStoreDetails=!0);var o=t?n:"#"+this.el.id;try{var i=this.adyenCheckout.create(e.type,a);i.mount(o),this.confirmFormSubmit.addEventListener("click",function(e){r.a.querySelector(document,"#confirmOrderForm").checkValidity()&&(e.preventDefault(),this.el.parentNode.scrollIntoView({behavior:"smooth",block:"start"}),i.submit())}.bind(this))}catch(t){return console.error(e.type,t),!1}}},{key:"appendGiftcardSummary",value:function(){if(parseInt(adyenCheckoutOptions.giftcardDiscount,10)&&this.shoppingCartSummaryBlock.length){var e=parseFloat(this.giftcardDiscount).toFixed(2),t=parseFloat(this.remainingAmount).toFixed(2),n='
'+adyenCheckoutOptions.translationAdyenGiftcardDiscount+'
'+adyenCheckoutOptions.currencySymbol+e+'
'+adyenCheckoutOptions.translationAdyenGiftcardRemainingAmount+'
'+adyenCheckoutOptions.currencySymbol+t+"
";this.shoppingCartSummaryBlock[0].innerHTML+=n}}},{key:"setAddressDetails",value:function(e){return""!==activeShippingAddress.phoneNumber?e.addressDetails={name:shopperDetails.firstName+" "+shopperDetails.lastName,addressLine1:activeShippingAddress.street,city:activeShippingAddress.city,postalCode:activeShippingAddress.postalCode,countryCode:activeShippingAddress.country,phoneNumber:activeShippingAddress.phoneNumber}:e.productType="PayOnly",e}}])&&p(o.prototype,l),b&&p(o,b),n}(o.a)}).call(this,n("UoTJ"),n("UoTJ"))}},[["HbFT","runtime","vendor-node","vendor-shared"]]]); \ No newline at end of file diff --git a/src/Resources/app/storefront/src/configuration/adyen.js b/src/Resources/app/storefront/src/configuration/adyen.js index 73db72c0..9f912f0b 100644 --- a/src/Resources/app/storefront/src/configuration/adyen.js +++ b/src/Resources/app/storefront/src/configuration/adyen.js @@ -22,7 +22,7 @@ export default { updatablePaymentMethods: [ - 'scheme', 'ideal', 'sepadirectdebit', 'oneclick', 'dotpay', 'bcmc', 'bcmc_mobile', 'blik', 'klarna_b2b', 'eps', 'facilypay_3x', + 'scheme', 'ideal', 'sepadirectdebit', 'oneclick', 'bcmc', 'bcmc_mobile', 'blik', 'klarna_b2b', 'eps', 'facilypay_3x', 'facilypay_4x', 'facilypay_6x', 'facilypay_10x', 'facilypay_12x', 'afterpay_default', 'ratepay', 'ratepay_directdebit', 'giftcard', 'paybright', 'affirm', 'multibanco', 'mbway', 'vipps', 'mobilepay', 'wechatpayQR', 'wechatpayWeb', 'paybybank' @@ -115,19 +115,18 @@ export default { paymentMethodTypeHandlers: { 'scheme': 'handler_adyen_cardspaymentmethodhandler', 'ideal': 'handler_adyen_idealpaymentmethodhandler', - 'klarna': 'handler_adyen_klarnapaylaterpaymentmethodhandler', + 'klarna': 'handler_adyen_klarnapaylaterpaaymentmethodhandler', 'klarna_account': 'handler_adyen_klarnaaccountpaymentmethodhandler', 'klarna_paynow': 'handler_adyen_klarnapaynowpaymentmethodhandler', 'ratepay': 'handler_adyen_ratepaypaymentmethodhandler', 'ratepay_directdebit': 'handler_adyen_ratepaydirectdebitpaymentmethodhandler', 'sepadirectdebit': 'handler_adyen_sepapaymentmethodhandler', - 'sofort': 'handler_adyen_sofortpaymentmethodhandler', + 'directEbanking': 'handler_adyen_klarnadebitriskpaymentmethodhandler', 'paypal': 'handler_adyen_paypalpaymentmethodhandler', 'oneclick': 'handler_adyen_oneclickpaymentmethodhandler', 'giropay': 'handler_adyen_giropaypaymentmethodhandler', 'applepay': 'handler_adyen_applepaypaymentmethodhandler', 'googlepay': 'handler_adyen_googlepaypaymentmethodhandler', - 'dotpay': 'handler_adyen_dotpaypaymentmethodhandler', 'bcmc': 'handler_adyen_bancontactcardpaymentmethodhandler', 'bcmc_mobile': 'handler_adyen_bancontactmobilepaymentmethodhandler', 'amazonpay': 'handler_adyen_amazonpaypaymentmethodhandler', @@ -156,6 +155,8 @@ export default { 'affirm': 'handler_adyen_affirmpaymentmethodhandler', 'paybright': 'handler_adyen_paybrightpaymentmethodhandler', 'paybybank': 'handler_adyen_openbankingpaymentmethodhandler', - 'klarna_b2b': 'handler_adyen_billiepaymentmethodhandler' + 'klarna_b2b': 'handler_adyen_billiepaymentmethodhandler', + 'ebanking_FI': 'handler_adyen_onlinebankingfinlandpaymentmethodhandler', + 'onlineBanking_PL': 'handler_adyen_onlinebankingpolandpaymentmethodhandler' } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 6dd9ffac..5d981b6a 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -97,6 +97,10 @@ + + + + diff --git a/src/Resources/config/services/checkout-api.xml b/src/Resources/config/services/checkout-api.xml index 26107f5c..8521ca7d 100644 --- a/src/Resources/config/services/checkout-api.xml +++ b/src/Resources/config/services/checkout-api.xml @@ -13,6 +13,9 @@ + + + diff --git a/src/Resources/config/services/controllers.xml b/src/Resources/config/services/controllers.xml index 9884f624..340e4f04 100644 --- a/src/Resources/config/services/controllers.xml +++ b/src/Resources/config/services/controllers.xml @@ -50,9 +50,11 @@ + + diff --git a/src/Resources/config/services/payment-handlers.xml b/src/Resources/config/services/payment-handlers.xml index 7fa8ee33..f0b39a00 100644 --- a/src/Resources/config/services/payment-handlers.xml +++ b/src/Resources/config/services/payment-handlers.xml @@ -55,7 +55,7 @@ parent="Adyen\Shopware\Handlers\AbstractPaymentMethodHandler"> - @@ -79,10 +79,6 @@ parent="Adyen\Shopware\Handlers\AbstractPaymentMethodHandler"> - - - @@ -255,6 +251,14 @@ parent="Adyen\Shopware\Handlers\AbstractPaymentMethodHandler"> + + + + + + diff --git a/src/Resources/snippet/de_DE/messages.de-DE.json b/src/Resources/snippet/de_DE/messages.de-DE.json index 4b108601..b5253ad8 100644 --- a/src/Resources/snippet/de_DE/messages.de-DE.json +++ b/src/Resources/snippet/de_DE/messages.de-DE.json @@ -10,6 +10,7 @@ "remainingBalance": "Verbleibendes guthaben der geschenkkarte", "remainingAmount": "Restbetrag", "discount": "Geschenkkarten-Rabatt" - } + }, + "unsuccessful_adyen_transaction": "Payment with Bancontact mobile was unsuccessful. Please change the payment method or try again." } } diff --git a/src/Resources/snippet/en_GB/messages.en-GB.json b/src/Resources/snippet/en_GB/messages.en-GB.json index ae41ceaa..da75f65f 100644 --- a/src/Resources/snippet/en_GB/messages.en-GB.json +++ b/src/Resources/snippet/en_GB/messages.en-GB.json @@ -11,6 +11,7 @@ "deductedAmount": "Deducted Amount", "remainingAmount": "Remaining amount", "discount": "Giftcard discount" - } + }, + "unsuccessful_adyen_transaction": "Payment with Bancontact mobile was unsuccessful. Please change the payment method or try again." } } diff --git a/src/Resources/views/storefront/page/checkout/cart/index.html.twig b/src/Resources/views/storefront/page/checkout/cart/index.html.twig index 1e4d21e8..b5e3bb83 100644 --- a/src/Resources/views/storefront/page/checkout/cart/index.html.twig +++ b/src/Resources/views/storefront/page/checkout/cart/index.html.twig @@ -7,3 +7,27 @@ {% sw_include '@AdyenPaymentShopware6/storefront/component/adyencheckout.html.twig' %} {% sw_include '@AdyenPaymentShopware6/storefront/component/checkout/cart/giftcards.html.twig' %} {% endblock %} + +{% block page_checkout_container %} + {% if page.cart.lineItems.count is same as(0) %} + {{ parent() }} + {% if page.extensions['errorCodes'].errorCode == 'UNSUCCESSFUL_ADYEN_TRANSACTION'%} + {% sw_include '@Storefront/storefront/utilities/alert.html.twig' with { + type: 'danger', + content: 'adyen.unsuccessful_adyen_transaction' | trans + } %} + {% endif %} + {% else %} + {{ parent() }} + {% endif %} +{% endblock %} + +{% block page_checkout_cart_header %} + {{ parent() }} + {% if page.extensions['errorCodes'].errorCode == 'UNSUCCESSFUL_ADYEN_TRANSACTION'%} + {% sw_include '@Storefront/storefront/utilities/alert.html.twig' with { + type: 'danger', + content: 'adyen.unsuccessful_adyen_transaction' | trans + } %} + {% endif %} +{% endblock %} diff --git a/src/ScheduledTask/ProcessNotificationsHandler.php b/src/ScheduledTask/ProcessNotificationsHandler.php index 0ce86a5e..c9369430 100644 --- a/src/ScheduledTask/ProcessNotificationsHandler.php +++ b/src/ScheduledTask/ProcessNotificationsHandler.php @@ -166,6 +166,10 @@ public function run(): void /** @var NotificationEntity $notification */ $logContext = ['eventCode' => $notification->getEventCode()]; + if (is_null($notification->getMerchantReference())) { + continue; + } + /* * Before processing any notification, factory should be created first. * It checks the supported EventCode to use related class in the factory. diff --git a/src/ScheduledTask/Webhook/RefundWebhookHandler.php b/src/ScheduledTask/Webhook/RefundWebhookHandler.php index 530dd1b9..7c846fff 100644 --- a/src/ScheduledTask/Webhook/RefundWebhookHandler.php +++ b/src/ScheduledTask/Webhook/RefundWebhookHandler.php @@ -127,6 +127,18 @@ private function handleSuccessfulNotification( $notificationEntity->getOriginalReference() ); + if ($adyenPayment === null) { + $this->logger->warning( + 'Adyen payment entity not found for the given notification.', + [ + 'originalReference' => $notificationEntity->getOriginalReference(), + 'notificationVars' => $notificationEntity->getVars() + ] + ); + + return; + } + $this->adyenPaymentService->updateTotalRefundedAmount( $adyenPayment, (int) $notificationEntity->getAmountValue() diff --git a/src/Service/FetchLogosService.php b/src/Service/FetchLogosService.php new file mode 100644 index 00000000..5b554e15 --- /dev/null +++ b/src/Service/FetchLogosService.php @@ -0,0 +1,63 @@ + + */ + +namespace Adyen\Shopware\Service; + +use Adyen\Shopware\ScheduledTask\FetchPaymentMethodLogosHandler; + +/** + * Class FetchLogosService + * + * A service responsible for providing the handler to fetch payment method logos. + * This service acts as an intermediary layer for accessing the FetchPaymentMethodLogosHandler. + * + * @package Adyen\Shopware\Service + */ +class FetchLogosService +{ + /** + * @var FetchPaymentMethodLogosHandler + */ + private FetchPaymentMethodLogosHandler $handler; + + /** + * FetchLogosService constructor. + * + * @param FetchPaymentMethodLogosHandler $handler The handler responsible for fetching payment method logos. + */ + public function __construct(FetchPaymentMethodLogosHandler $handler) + { + $this->handler = $handler; + } + + /** + * Get the FetchPaymentMethodLogosHandler. + * + * @return FetchPaymentMethodLogosHandler The handler responsible for executing the logo fetching logic. + */ + public function getHandler(): FetchPaymentMethodLogosHandler + { + return $this->handler; + } +} diff --git a/src/Storefront/Controller/FrontendProxyController.php b/src/Storefront/Controller/FrontendProxyController.php index 6fcda879..34124a2c 100644 --- a/src/Storefront/Controller/FrontendProxyController.php +++ b/src/Storefront/Controller/FrontendProxyController.php @@ -29,6 +29,8 @@ use Adyen\Shopware\Controller\StoreApi\OrderApi\OrderApiController; use Adyen\Shopware\Controller\StoreApi\Payment\PaymentController; use Adyen\Shopware\Exception\ValidationException; +use Adyen\Shopware\Handlers\PaymentResponseHandler; +use Adyen\Shopware\Util\ShopwarePaymentTokenValidator; use Error; use Shopware\Core\Checkout\Cart\Exception\InvalidCartException; use Shopware\Core\Checkout\Cart\SalesChannel\AbstractCartOrderRoute; @@ -41,10 +43,12 @@ use Shopware\Core\System\SalesChannel\SalesChannel\AbstractContextSwitchRoute; use Shopware\Core\System\SalesChannel\SalesChannelContext; use Shopware\Storefront\Controller\StorefrontController; -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\HttpFoundation\RedirectResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\RouterInterface; /** * @Route(defaults={"_routeScope"={"storefront"}}) @@ -71,6 +75,11 @@ class FrontendProxyController extends StorefrontController */ private AbstractHandlePaymentMethodRoute $handlePaymentMethodRoute; + /** + * @var RouterInterface + */ + private RouterInterface $router; + /** * @var PaymentController */ @@ -86,32 +95,42 @@ class FrontendProxyController extends StorefrontController */ private DonateController $donateController; + /** + * @var ShopwarePaymentTokenValidator + */ + private ShopwarePaymentTokenValidator $paymentTokenValidator; /** * @param AbstractCartOrderRoute $cartOrderRoute * @param AbstractHandlePaymentMethodRoute $handlePaymentMethodRoute * @param AbstractContextSwitchRoute $contextSwitchRoute * @param CartService $cartService + * @param RouterInterface $router * @param PaymentController $paymentController * @param OrderApiController $orderApiController * @param DonateController $donateController + * @param ShopwarePaymentTokenValidator $paymentTokenValidator */ - public function __construct( - AbstractCartOrderRoute $cartOrderRoute, - AbstractHandlePaymentMethodRoute $handlePaymentMethodRoute, - AbstractContextSwitchRoute $contextSwitchRoute, - CartService $cartService, - PaymentController $paymentController, - OrderApiController $orderApiController, - DonateController $donateController - ) { + public function __construct(//NOSONAR + AbstractCartOrderRoute $cartOrderRoute,//NOSONAR + AbstractHandlePaymentMethodRoute $handlePaymentMethodRoute,//NOSONAR + AbstractContextSwitchRoute $contextSwitchRoute,//NOSONAR + CartService $cartService,//NOSONAR + RouterInterface $router,//NOSONAR + PaymentController $paymentController,//NOSONAR + OrderApiController $orderApiController,//NOSONAR + DonateController $donateController,//NOSONAR + ShopwarePaymentTokenValidator $paymentTokenValidator//NOSONAR + ) {//NOSONAR $this->cartOrderRoute = $cartOrderRoute; $this->cartService = $cartService; $this->handlePaymentMethodRoute = $handlePaymentMethodRoute; $this->contextSwitchRoute = $contextSwitchRoute; + $this->router = $router; $this->paymentController = $paymentController; $this->orderApiController = $orderApiController; $this->donateController = $donateController; + $this->paymentTokenValidator = $paymentTokenValidator; } /** @@ -176,6 +195,60 @@ public function handlePayment(Request $request, SalesChannelContext $salesChanne return new JsonResponse($routeResponse->getObject()); } + /** + * @Route( + * "/adyen/proxy-finalize-transaction", + * name="payment.adyen.proxy-finalize-transaction", + * defaults={"XmlHttpRequest"=true, "csrf_protected": false}, + * methods={"GET"} + * ) + */ + public function finalizeTransaction(Request $request, SalesChannelContext $salesChannelContext): RedirectResponse + { + $paymentToken = $request->get('_sw_payment_token'); + $redirectResult = $request->get('redirectResult'); + + if ($this->paymentTokenValidator->validateToken($paymentToken) && !$redirectResult) { + return new RedirectResponse( + $this->router->generate( + 'payment.finalize.transaction', + ['_sw_payment_token' => $paymentToken], + UrlGeneratorInterface::ABSOLUTE_URL + ) + ); + } + + $orderId = $request->get('orderId') ?? ''; + $stateData = ['details' => ['redirectResult' => $redirectResult]]; + $request->request->add(['stateData' => json_encode($stateData, JSON_THROW_ON_ERROR)]); + $request->request->add(['orderId' => $orderId]); + $response = $this->paymentController->postPaymentDetails($request, $salesChannelContext); + $resultCode = json_decode( + $response->getContent(), + false, + 512, + JSON_THROW_ON_ERROR + )->resultCode ?? ''; + + if ($resultCode === PaymentResponseHandler::AUTHORISED) { + return new RedirectResponse( + $this->router->generate( + 'frontend.checkout.finish.page', + ['orderId' => $orderId], + UrlGeneratorInterface::ABSOLUTE_URL + ) + ); + } + + return new RedirectResponse( + $this->router->generate( + 'frontend.checkout.cart.page', + ['errorCode' => 'UNSUCCESSFUL_ADYEN_TRANSACTION'], + UrlGeneratorInterface::ABSOLUTE_URL + ) + ); + } + /** * @deprecated This method is deprecated and will be removed in future versions. * @Route( diff --git a/src/Subscriber/PaymentSubscriber.php b/src/Subscriber/PaymentSubscriber.php index 18f20339..4c4549dd 100644 --- a/src/Subscriber/PaymentSubscriber.php +++ b/src/Subscriber/PaymentSubscriber.php @@ -215,6 +215,19 @@ public function onShoppingCartLoaded(PageLoadedEvent $event) { /** @var CheckoutCartPage|OffcanvasCartPage $page */ $page = $event->getPage(); + $errorCodes = []; + if ($event->getRequest()->get('errorCode') + && $event->getRequest()->get('errorCode') === 'UNSUCCESSFUL_ADYEN_TRANSACTION' + ) { + $errorCodes['errorCode'] = 'UNSUCCESSFUL_ADYEN_TRANSACTION'; + $page->addExtension( + 'errorCodes', + new ArrayEntity( + $errorCodes + ) + ); + } + if ($page->getCart()->getLineItems()->count() === 0) { return; } diff --git a/src/Util/ShopwarePaymentTokenValidator.php b/src/Util/ShopwarePaymentTokenValidator.php new file mode 100644 index 00000000..35ec59a5 --- /dev/null +++ b/src/Util/ShopwarePaymentTokenValidator.php @@ -0,0 +1,44 @@ +tokenFactory = $tokenFactory; + } + + /** + * Validates if the Shopware payment token is still valid. + * + * @param string|null $paymentToken + * + * @return bool + */ + public function validateToken(?string $paymentToken): bool + { + try { + $token = $this->tokenFactory->parseToken($paymentToken); + + if ($token->isExpired()) { + return false; + } + + return true; + } catch (PaymentException $exception) { + return false; + } + } +}