From 778b70568d1bd40dbd79dc8dafdc0d05da497535 Mon Sep 17 00:00:00 2001
From: Khushboo ${balanceInnerHtml} {{ $tc(\'adyen.noNotificationsReceived\') }} {{ $tc(\'adyen.noNotificationsReceived\') }}
`;
+
+ // Append the gift card element to the container
+ giftcardsContainer.appendChild(giftcardElement);
+
+ });
+ //Update calculations
+ this.remainingAmount = response.redeemedGiftcards.remainingAmount;
+ this.giftcardDiscount = response.redeemedGiftcards.totalDiscount;
+
+ // Remove component
+ if (this.paymentMethodInstance) {
+ this.paymentMethodInstance.unmount();
+ }
+ this.giftcardComponentClose.style.display = 'none';
+ this.giftcardItem.innerHTML = '';
+ this.giftcardHeader.innerHTML = ' ';
+ this.appendGiftcardSummary();
+
+ //Compare the new total gift card balance with the order amount
+ if (this.remainingAmount > 0.00) {
+ //allow adding new giftcards
+ addButton.style.display = "block";
+ } else {
+ // Hide giftcards dropdown and Add giftcards option
+ if (this.adyenGiftcardDropDown.length > 0) {
+ this.adyenGiftcardDropDown[0].style.display = 'none';
+ }
+ addButton.style.display = "none";
}
+ let giftcardContainerElement = document.getElementById('giftcardsContainer'); // Replace with your actual container ID
+
}.bind(this));
}
- setGiftcardAsPaymentMethod(stateData, balance) {
- this._client.patch(adyenGiftcardsConfiguration.switchContextUrl, JSON.stringify({paymentMethodId: this.selectedGiftcard.id}), function (response) {
- this.saveGiftcardStateData(stateData, adyenGiftcardsConfiguration.totalInMinorUnits, balance, this.selectedGiftcard.id)
- }.bind(this));
+ saveGiftcardStateData(stateData) {
+ // save state data to database, set giftcard as payment method and proceed to checkout
+ stateData = JSON.stringify(stateData);
+ this._client.post(
+ adyenGiftcardsConfiguration.setGiftcardUrl,
+ JSON.stringify({ stateData}),
+ function (response) {
+ response = JSON.parse(response);
+ if ('token' in response) {
+ this.fetchRedeemedGiftcards();
+ ElementLoadingIndicatorUtil.remove(document.body);
+ }
+ }.bind(this)
+ );
}
- removeGiftcard() {
+ removeGiftcard(storeId) {
ElementLoadingIndicatorUtil.create(document.body);
- this._client.post(adyenGiftcardsConfiguration.removeGiftcardUrl, new FormData, function(response) {
+
+ this._client.post(adyenGiftcardsConfiguration.removeGiftcardUrl, JSON.stringify({stateDataId: storeId}), (response) => {
response = JSON.parse(response);
if ('token' in response) {
- this.giftcardDiscount = 0;
- this.remainingAmount = (adyenGiftcardsConfiguration.totalPrice - this.giftcardDiscount).toFixed(2);
-
- if (this.shoppingCartSummaryBlock.length) {
- let giftcardSummary = this.shoppingCartSummaryBlock[0].querySelectorAll('.adyen-giftcard-summary');
- for (let i = 0; i < giftcardSummary.length; i++) {
- giftcardSummary[i].remove();
- }
- }
- this.removeGiftcardButton.style.display = 'none';
- this.remainingBalanceField.style.display = 'none';
- // Show giftcards
- for(var i=0;i
+
+ + {{ "adyen.giftcard.addGiftcards" | trans }}
+
-
{# loop through giftcards and display logo #}
- {% for giftcard in adyenFrontendData.giftcards %}
-
- {% if giftcard.media %}
- {% sw_thumbnails 'payment-method-image-thumbnails' with {
- media: giftcard.media,
- attributes: {
- 'alt': (giftcard.media.translated.alt ?: giftcard.translated.name),
- 'title': (giftcard.media.translated.title ?: giftcard.translated.name)
- }
- } %}
- {% endif %}
-
- {% endfor %}
+
-
- {{ "adyen.giftcard.removeGiftcard" | trans }}
-
- ×
-
-
-
-
+
{% endif %}
{% endfor %}
{% endif %}
+
diff --git a/src/Resources/views/storefront/component/payment/payment-method.html.twig b/src/Resources/views/storefront/component/payment/payment-method.html.twig
index 485d7975..57e7d72c 100644
--- a/src/Resources/views/storefront/component/payment/payment-method.html.twig
+++ b/src/Resources/views/storefront/component/payment/payment-method.html.twig
@@ -14,7 +14,8 @@
{% block component_payment_method_description %}
{{ parent() }}
- {% if payment.id is same as(selectedPaymentMethodId) and 'handler_adyen_' in payment.formattedHandlerIdentifier %}
+ {% if payment.id is same as(selectedPaymentMethodId)
+ and 'handler_adyen_' in payment.formattedHandlerIdentifier %}
{% sw_include '@AdyenPaymentShopware6/storefront/component/payment/payment-component.html.twig' %}
{% endif %}
{% endblock %}
diff --git a/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig b/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig
index 3c0ec966..66942274 100644
--- a/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig
+++ b/src/Resources/views/storefront/page/checkout/confirm/confirm-payment.html.twig
@@ -46,7 +46,6 @@
data-payment-finish-url="{{ adyenFrontendData.paymentFinishUrl }}"
data-payment-error-url="{{ adyenFrontendData.paymentErrorUrl }}"
data-update-payment-url="{{ adyenFrontendData.updatePaymentUrl }}"
- data-create-order-url="{{ adyenFrontendData.createOrderUrl }}"
data-cancel-order-transaction-url="{{ adyenFrontendData.cancelOrderTransactionUrl }}"
data-order-id="{{ adyenFrontendData.orderId }}"
data-currency="{{ adyenFrontendData.currency }}"
diff --git a/src/Service/OrdersService.php b/src/Service/OrdersService.php
index 4967a4ca..6ebaa6d2 100644
--- a/src/Service/OrdersService.php
+++ b/src/Service/OrdersService.php
@@ -84,6 +84,7 @@ public function createOrder(SalesChannelContext $context, $uuid, $orderAmount, $
return $responseData;
}
+
private function buildOrdersRequestData(
SalesChannelContext $context,
$uuid,
diff --git a/src/Service/PaymentMethodsFilterService.php b/src/Service/PaymentMethodsFilterService.php
index 46f44016..39f208fa 100644
--- a/src/Service/PaymentMethodsFilterService.php
+++ b/src/Service/PaymentMethodsFilterService.php
@@ -24,13 +24,16 @@
namespace Adyen\Shopware\Service;
use Adyen\Shopware\Handlers\AbstractPaymentMethodHandler;
+use Adyen\Shopware\Handlers\GiftCardPaymentMethodHandler;
use Adyen\Shopware\Handlers\GooglePayPaymentMethodHandler;
use Adyen\Shopware\Handlers\OneClickPaymentMethodHandler;
use Adyen\Shopware\Handlers\ApplePayPaymentMethodHandler;
use Shopware\Core\Checkout\Payment\PaymentMethodCollection;
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
use Shopware\Core\Checkout\Payment\SalesChannel\AbstractPaymentMethodRoute;
+use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
+use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
@@ -46,13 +49,23 @@ class PaymentMethodsFilterService
* @var AbstractPaymentMethodRoute
*/
private $paymentMethodRoute;
+ private $paymentMethodRepository;
+ /**
+ * PaymentMethodsFilterService constructor.
+ *
+ * @param PaymentMethodsService $paymentMethodsService
+ * @param AbstractPaymentMethodRoute $paymentMethodRoute
+ * @param EntityRepository $paymentMethodRepository
+ */
public function __construct(
PaymentMethodsService $paymentMethodsService,
- AbstractPaymentMethodRoute $paymentMethodRoute
+ AbstractPaymentMethodRoute $paymentMethodRoute,
+ $paymentMethodRepository
) {
$this->paymentMethodsService = $paymentMethodsService;
$this->paymentMethodRoute = $paymentMethodRoute;
+ $this->paymentMethodRepository = $paymentMethodRepository;
}
/**
@@ -67,8 +80,7 @@ public function filterShopwarePaymentMethods(
PaymentMethodCollection $originalPaymentMethods,
SalesChannelContext $salesChannelContext,
string $adyenPluginId,
- array $adyenPaymentMethods = [],
- string $giftcardId = null
+ array $adyenPaymentMethods = []
): PaymentMethodCollection {
if (empty($adyenPaymentMethods)) {
// Get Adyen /paymentMethods response
@@ -97,10 +109,8 @@ function (PaymentMethodEntity $item) use ($adyenPluginId) {
if (empty($adyenPaymentMethods[OneClickPaymentMethodHandler::getPaymentMethodCode()])) {
$originalPaymentMethods->remove($paymentMethodEntity->getId());
}
- } elseif ($pmHandlerIdentifier::$isGiftCard) {
- if ($giftcardId !== $paymentMethodEntity->getId()) {
- $originalPaymentMethods->remove($paymentMethodEntity->getId());
- }
+ } elseif ($pmCode == 'giftcard' && $pmHandlerIdentifier != GiftCardPaymentMethodHandler::class) {
+ $originalPaymentMethods->remove($paymentMethodEntity->getId());
// Remove ApplePay PM if the browser is not Safari
} elseif ($pmCode == ApplePayPaymentMethodHandler::getPaymentMethodCode() && $isSafari !== 1) {
$originalPaymentMethods->remove($paymentMethodEntity->getId());
@@ -183,19 +193,23 @@ public function getAvailableGiftcards(
if (is_null($paymentMethods)) {
$paymentMethods = $this->getShopwarePaymentMethods($context);
}
+ $filteredPaymentMethods = clone $paymentMethods;
$giftcards = $this->filterAdyenPaymentMethodsByType($adyenPaymentMethods, 'giftcard');
$brands = array_column($giftcards, 'brand');
- foreach ($paymentMethods as $entity) {
+ foreach ($filteredPaymentMethods as $entity) {
$methodHandler = $entity->getHandlerIdentifier();
+
/** @var AbstractPaymentMethodHandler $methodHandler */
if ($entity->getPluginId() !== $adyenPluginId) {
// Remove non-Adyen payment methods
- $paymentMethods->remove($entity->getId());
- } elseif (!$methodHandler::$isGiftCard || !in_array($methodHandler::getBrand(), $brands)) {
+ $filteredPaymentMethods->remove($entity->getId());
+ } elseif ((method_exists($methodHandler, 'getPaymentMethodCode') &&
+ $methodHandler::getPaymentMethodCode() != 'giftcard') ||
+ !in_array($methodHandler::getBrand(), $brands)) {
// Remove non-giftcards and giftcards that are not in /paymentMethods response
- $paymentMethods->remove($entity->getId());
+ $filteredPaymentMethods->remove($entity->getId());
} else {
$brand = $methodHandler::getBrand();
$entity->addExtension('adyenGiftcardData', new ArrayStruct(
@@ -206,7 +220,26 @@ public function getAvailableGiftcards(
}
}
- return $paymentMethods;
+ return $filteredPaymentMethods;
+ }
+
+ public function getAvailableNonGiftcardsPaymentMethods(
+ SalesChannelContext $context,
+ ?PaymentMethodCollection $paymentMethods = null
+ ) {
+ if (is_null($paymentMethods)) {
+ $paymentMethods = $this->getShopwarePaymentMethods($context);
+ }
+
+ foreach ($paymentMethods as $entity) {
+ $methodHandler = $entity->getHandlerIdentifier();
+ /** @var AbstractPaymentMethodHandler $methodHandler */
+ if (method_exists($methodHandler, 'getPaymentMethodCode')
+ && $methodHandler::getPaymentMethodCode() === 'giftcard') {
+ // Remove giftcards from the actual collection
+ $paymentMethods->remove($entity->getId());
+ }
+ }
}
public function filterAdyenPaymentMethodsByType(array $paymentMethodsResponse, string $type): array
@@ -223,4 +256,18 @@ private function getShopwarePaymentMethods(SalesChannelContext $context): Paymen
return $this->paymentMethodRoute->load($request, $context, new Criteria())->getPaymentMethods();
}
+
+ public function getGiftCardPaymentMethodId(SalesChannelContext $context): ?string
+ {
+ $paymentMethodHandler = GiftCardPaymentMethodHandler::class;
+
+ $criteria = (new Criteria())->addFilter(new EqualsFilter(
+ 'handlerIdentifier',
+ $paymentMethodHandler
+ ));
+ $paymentMethod = $this->paymentMethodRepository->search($criteria, $context->getContext())->first();
+
+ // Return the payment method ID or null if not found
+ return $paymentMethod ? $paymentMethod->getId() : null;
+ }
}
diff --git a/src/Service/PaymentStateDataService.php b/src/Service/PaymentStateDataService.php
index 6b395039..c57d3c2e 100644
--- a/src/Service/PaymentStateDataService.php
+++ b/src/Service/PaymentStateDataService.php
@@ -26,23 +26,26 @@
use Adyen\AdyenException;
use Adyen\Shopware\Entity\PaymentStateData\PaymentStateDataEntity;
+use Shopware\Core\Checkout\Payment\Exception\AsyncPaymentProcessException;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Psr\Log\LoggerInterface;
+use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
class PaymentStateDataService
{
/**
* @var EntityRepository
*/
- protected $paymentStateDataRepository;
+ protected EntityRepository $paymentStateDataRepository;
/**
* @var LoggerInterface
*/
- protected $logger;
+ protected LoggerInterface $logger;
+
/**
* PaymentStateDataService constructor.
@@ -78,13 +81,8 @@ public function insertPaymentStateData(string $contextToken, string $stateData,
$fields['token'] = $contextToken;
$fields['statedata'] = json_encode($stateDataArray);
- $stateData = $this->getPaymentStateDataFromContextToken($contextToken);
-
- if ($stateData) {
- $fields['id'] = $stateData->getId();
- }
- $this->paymentStateDataRepository->upsert(
+ $this->paymentStateDataRepository->create(
[$fields],
Context::createDefaultContext()
);
@@ -102,6 +100,14 @@ public function getPaymentStateDataFromContextToken(string $contextToken): ?Paym
)->first();
}
+ public function getPaymentStateDataFromId(string $stateDataId): ?PaymentStateDataEntity
+ {
+ return $this->paymentStateDataRepository->search(
+ (new Criteria())->addFilter(new EqualsFilter('id', $stateDataId)),
+ Context::createDefaultContext()
+ )->first();
+ }
+
public function updateStateDataContextToken(PaymentStateDataEntity $stateData, $newToken): void
{
$this->paymentStateDataRepository->update([
@@ -125,14 +131,84 @@ public function deletePaymentStateData(PaymentStateDataEntity $stateData): void
);
}
- /**
- * @param string $contextToken
- */
- public function deletePaymentStateDataFromContextToken(string $contextToken): void
+ public function deletePaymentStateDataFromId(string $stateDataId): void
{
- $stateData = $this->getPaymentStateDataFromContextToken($contextToken);
+ $stateData = $this->getPaymentStateDataFromId($stateDataId);
if (!empty($stateData)) {
$this->deletePaymentStateData($stateData);
}
}
+
+ public function fetchRedeemedGiftCardsFromContextToken(string $contextToken):
+ \Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult
+ {
+ $criteria = new Criteria();
+ $criteria->addFilter(new EqualsFilter('token', $contextToken));
+ $criteria->addSorting(new FieldSorting('createdAt')); // Sorting by 'created_at' in ascending order
+
+ return $this->paymentStateDataRepository->search(
+ $criteria,
+ Context::createDefaultContext()
+ );
+ }
+
+ /**
+ * Get the total gift card discount and balance.
+ *
+ * @param mixed $salesChannelContext The sales channel context.
+ * @param int|mixed $remainingOrderAmount The remaining order amount.
+ * @return array Array containing 'giftcardDiscount' and 'giftcardBalance'.
+ */
+ public function getGiftcardTotalDiscountAndBalance($salesChannelContext, $remainingOrderAmount): array
+ {
+ $fetchedRedeemedGiftcards = $this->fetchRedeemedGiftCardsFromContextToken($salesChannelContext->getToken());
+ $totalGiftcardBalance = 0;
+ foreach ($fetchedRedeemedGiftcards->getElements() as $fetchedRedeemedGiftcard) {
+ $stateData = json_decode($fetchedRedeemedGiftcard->getStateData(), true);
+ if (isset($stateData['paymentMethod']['type']) ||
+ isset($stateData['paymentMethod']['brand']) ||
+ $stateData['paymentMethod']['type'] === 'giftcard') {
+ $totalGiftcardBalance += $stateData['giftcard']['value'];
+ }
+ }
+
+ if ($totalGiftcardBalance > 0) {
+ $totalDiscount = min($totalGiftcardBalance, $remainingOrderAmount);
+ } else {
+ $totalDiscount = 0;
+ }
+ return [
+ 'giftcardDiscount' => $totalDiscount,
+ 'giftcardBalance' => $totalGiftcardBalance
+ ];
+ }
+
+ public function countStoredStateData($salesChannelContext): int
+ {
+ $stateData = $this->fetchRedeemedGiftCardsFromContextToken(
+ $salesChannelContext->getToken()
+ );
+ return $stateData->getTotal();
+ }
+
+ public function getStoredStateData($salesChannelContext, string $transactionId): ?array
+ {
+ // Check for state.data in db using the context token
+ $storedStateData = null;
+ $stateDataEntity = $this->getPaymentStateDataFromContextToken(
+ $salesChannelContext->getToken()
+ );
+ if ($stateDataEntity) {
+ $storedStateData = json_decode($stateDataEntity->getStateData(), true);
+ $storedStateData['id'] = $stateDataEntity->getId();
+ }
+
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new AsyncPaymentProcessException(
+ $transactionId,
+ 'Invalid payment state data.'
+ );
+ }
+ return $storedStateData;
+ }
}
diff --git a/src/Storefront/Controller/FrontendProxyController.php b/src/Storefront/Controller/FrontendProxyController.php
index 9f2476f8..ca2f851f 100644
--- a/src/Storefront/Controller/FrontendProxyController.php
+++ b/src/Storefront/Controller/FrontendProxyController.php
@@ -78,6 +78,7 @@ public function __construct(
}
/**
+ * @deprecated This method is deprecated and will be removed in future versions.
* @Route(
* "/adyen/proxy-switch-context",
* name="payment.adyen.proxy-switch-context",
@@ -120,6 +121,7 @@ public function handlePayment(Request $request, SalesChannelContext $salesChanne
}
/**
+ * @deprecated This method is deprecated and will be removed in future versions.
* @Route(
* "/adyen/proxy-payment-methods",
* name="payment.adyen.proxy-payment-methods",
@@ -197,32 +199,6 @@ public function checkBalance(Request $request, SalesChannelContext $context): Js
return $this->orderApiController->getPaymentMethodsBalance($context, $request);
}
- /**
- * @Route(
- * "/adyen/proxy-create-adyen-order",
- * name="payment.adyen.proxy-create-adyen-order",
- * defaults={"XmlHttpRequest"=true, "csrf_protected": false},
- * methods={"POST"}
- * )
- */
- public function createAdyenOrder(Request $request, SalesChannelContext $context): JsonResponse
- {
- return $this->orderApiController->createOrder($context, $request);
- }
-
- /**
- * @Route(
- * "/adyen/proxy-cancel-adyen-order",
- * name="payment.adyen.proxy-cancel-adyen-order",
- * defaults={"XmlHttpRequest"=true, "csrf_protected": false},
- * methods={"POST"}
- * )
- */
- public function cancelAdyenOrder(Request $request, SalesChannelContext $context): JsonResponse
- {
- return $this->orderApiController->cancelOrder($context, $request);
- }
-
/**
* @Route(
* "/adyen/proxy-store-giftcard-state-data",
@@ -252,6 +228,20 @@ public function removeGiftcardStateData(Request $request, SalesChannelContext $c
return $this->orderApiController->deleteGiftCardStateData($context, $request);
}
+ /**
+ * @Route(
+ * "/adyen/proxy-fetch-redeemed-giftcards",
+ * name="payment.adyen.proxy-fetch-redeemed-giftcards",
+ * defaults={"XmlHttpRequest"=true, "csrf_protected": false},
+ * methods={"GET"}
+ * )
+ *
+ */
+ public function fetchRedeemedGiftcards(SalesChannelContext $context): JsonResponse
+ {
+ return $this->orderApiController->fetchRedeemedGiftcards($context);
+ }
+
/**
* @Route(
* "/adyen/proxy-donate",
diff --git a/src/Subscriber/ContextSubscriber.php b/src/Subscriber/ContextSubscriber.php
index 16604ac3..567ff629 100644
--- a/src/Subscriber/ContextSubscriber.php
+++ b/src/Subscriber/ContextSubscriber.php
@@ -24,21 +24,16 @@
namespace Adyen\Shopware\Subscriber;
-use Adyen\Shopware\Entity\PaymentStateData\PaymentStateDataEntity;
use Adyen\Shopware\Service\ConfigurationService;
use Adyen\Shopware\Service\PaymentStateDataService;
use Adyen\Shopware\Struct\AdyenContextDataStruct;
use Adyen\Util\Currency;
use Shopware\Core\Checkout\Cart\AbstractCartPersister;
use Shopware\Core\Checkout\Cart\CartCalculator;
-use Shopware\Core\Checkout\Cart\Exception\CartTokenNotFoundException;
use Shopware\Core\Framework\Routing\Event\SalesChannelContextResolvedEvent;
-use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
-use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
use Shopware\Core\System\SalesChannel\Event\SalesChannelContextRestoredEvent;
use Shopware\Core\System\SalesChannel\Event\SalesChannelContextTokenChangeEvent;
use Shopware\Core\System\SalesChannel\SalesChannel\AbstractContextSwitchRoute;
-use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ContextSubscriber implements EventSubscriberInterface
@@ -50,6 +45,7 @@ class ContextSubscriber implements EventSubscriberInterface
private CartCalculator $cartCalculator;
private Currency $currency;
+
public function __construct(
ConfigurationService $configurationService,
PaymentStateDataService $paymentStateDataService,
@@ -80,11 +76,9 @@ public function onContextRestored(SalesChannelContextRestoredEvent $event): void
$token = $event->getRestoredSalesChannelContext()->getToken();
$oldToken = $event->getCurrentSalesChannelContext()->getToken();
- $stateData = $this->paymentStateDataService->getPaymentStateDataFromContextToken($oldToken);
-
- if ($stateData) {
- $this->paymentStateDataService->updateStateDataContextToken($stateData, $token);
- $this->setGiftcardPaymentMethodAfterContextRestored($event->getRestoredSalesChannelContext(), $stateData);
+ $stateData = $this->paymentStateDataService->fetchRedeemedGiftCardsFromContextToken($oldToken);
+ foreach ($stateData->getElements() as $statedataArray) {
+ $this->paymentStateDataService->updateStateDataContextToken($statedataArray, $token);
}
}
@@ -93,10 +87,10 @@ public function onContextTokenChange(SalesChannelContextTokenChangeEvent $event)
$token = $event->getCurrentToken();
$oldToken = $event->getPreviousToken();
- $stateData = $this->paymentStateDataService->getPaymentStateDataFromContextToken($oldToken);
+ $stateData = $this->paymentStateDataService->fetchRedeemedGiftCardsFromContextToken($oldToken);
- if ($stateData) {
- $this->paymentStateDataService->updateStateDataContextToken($stateData, $token);
+ foreach ($stateData->getElements() as $statedataArray) {
+ $this->paymentStateDataService->updateStateDataContextToken($statedataArray, $token);
}
}
@@ -114,38 +108,4 @@ public function addAdyenData(SalesChannelContextResolvedEvent $event): void
$data = $this->paymentStateDataService->getPaymentStateDataFromContextToken($context->getToken());
$extension->setHasPaymentStateData(!empty($data));
}
-
- private function setGiftcardPaymentMethodAfterContextRestored(
- SalesChannelContext $context,
- PaymentStateDataEntity $stateData
- ): void {
- $currency = $context->getCurrency()->getIsoCode();
- $decodedStateData = json_decode($stateData->getStateData(), true);
-
- try {
- $cart = $this->cartCalculator->calculate(
- $this->cartPersister->load($context->getToken(), $context),
- $context
- );
- $totalPrice = $cart->getPrice()->getTotalPrice();
- } catch (CartTokenNotFoundException $exception) {
- // No cart information found.
- return;
- }
-
- $amount = $this->currency->sanitize($totalPrice, $currency);
- $giftcardDiscount = $decodedStateData['additionalData']['amount'] ?? 0;
-
- if ($giftcardDiscount >= $amount) {
- $this->contextSwitchRoute->switchContext(
- new RequestDataBag(
- [
- SalesChannelContextService::PAYMENT_METHOD_ID =>
- $decodedStateData['additionalData']['paymentMethodId']
- ]
- ),
- $context
- );
- }
- }
}
diff --git a/src/Subscriber/PaymentSubscriber.php b/src/Subscriber/PaymentSubscriber.php
index 168cacd7..3c403b70 100644
--- a/src/Subscriber/PaymentSubscriber.php
+++ b/src/Subscriber/PaymentSubscriber.php
@@ -35,6 +35,7 @@
use Shopware\Core\Checkout\Cart\AbstractCartPersister;
use Shopware\Core\Checkout\Cart\CartCalculator;
use Shopware\Core\Checkout\Cart\Exception\CartTokenNotFoundException;
+use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\Struct\ArrayEntity;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
@@ -123,6 +124,11 @@ class PaymentSubscriber extends StorefrontSubscriber implements EventSubscriberI
*/
private $salesChannelContextFactory;
+ /**
+ * @var EntityRepository
+ */
+ private $paymentMethodRepository;
+
/**
* PaymentSubscriber constructor.
*
@@ -139,6 +145,7 @@ class PaymentSubscriber extends StorefrontSubscriber implements EventSubscriberI
* @param AbstractContextSwitchRoute $contextSwitchRoute
* @param AbstractSalesChannelContextFactory $salesChannelContextFactory
* @param Currency $currency
+ * @param EntityRepository $paymentMethodRepository
*/
public function __construct(
AdyenPluginProvider $adyenPluginProvider,
@@ -153,10 +160,12 @@ public function __construct(
CartCalculator $cartCalculator,
AbstractContextSwitchRoute $contextSwitchRoute,
AbstractSalesChannelContextFactory $salesChannelContextFactory,
- Currency $currency
+ Currency $currency,
+ $paymentMethodRepository
) {
- $this->paymentStateDataService = $paymentStateDataService;
+ $this->adyenPluginProvider = $adyenPluginProvider;
$this->paymentMethodsFilterService = $paymentMethodsFilterService;
+ $this->paymentStateDataService = $paymentStateDataService;
$this->router = $router;
$this->salesChannelRepository = $salesChannelRepository;
$this->configurationService = $configurationService;
@@ -167,7 +176,7 @@ public function __construct(
$this->contextSwitchRoute = $contextSwitchRoute;
$this->salesChannelContextFactory = $salesChannelContextFactory;
$this->currency = $currency;
- $this->adyenPluginProvider = $adyenPluginProvider;
+ $this->paymentMethodRepository = $paymentMethodRepository;
}
/**
@@ -208,15 +217,15 @@ public function onShoppingCartLoaded(PageLoadedEvent $event)
return;
}
$salesChannelContext = $event->getSalesChannelContext();
+ $currency = $salesChannelContext->getCurrency()->getIsoCode();
+ $currencySymbol = $salesChannelContext->getCurrency()->getSymbol();
+ $amountInMinorUnits = $this->currency->sanitize($page->getCart()->getPrice()->getTotalPrice(), $currency);
+ //Filter Payment Methods
$shopwarePaymentMethods = null;
if ($page instanceof CheckoutCartPage) {
$shopwarePaymentMethods = $page->getPaymentMethods();
}
- $currency = $salesChannelContext->getCurrency()->getIsoCode();
- $currencySymbol = $salesChannelContext->getCurrency()->getSymbol();
- $amountInMinorUnits = $this->currency->sanitize($page->getCart()->getPrice()->getTotalPrice(), $currency);
-
$paymentMethods = $this->paymentMethodsService->getPaymentMethods($salesChannelContext);
$giftcards = $this->paymentMethodsFilterService->getAvailableGiftcards(
$salesChannelContext,
@@ -224,45 +233,17 @@ public function onShoppingCartLoaded(PageLoadedEvent $event)
$this->adyenPluginProvider->getAdyenPluginId(),
$shopwarePaymentMethods
);
- $selectedPaymentMethodId = null;
- $giftcardData = $this->paymentStateDataService
- ->getPaymentStateDataFromContextToken($salesChannelContext->getToken());
- $giftcardDiscount = 0;
- $giftcardBalance = 0;
- if ($giftcardData) {
- $stateData = $giftcardData->getStateData();
- $giftcardDiscount = json_decode($stateData, true)['additionalData']['amount'] ?? 0;
- $selectedPaymentMethodId = json_decode($stateData, true)['additionalData']['paymentMethodId'] ?? 0;
- $giftcardBalance = json_decode($stateData, true)['additionalData']['balance'] ?? 0;
-
- // update discount amount if total becomes less than discount
- if ((int) $giftcardDiscount > $amountInMinorUnits) {
- $newBalance = ($giftcardDiscount - $amountInMinorUnits) + $giftcardBalance;
- $this->paymentStateDataService->insertPaymentStateData(
- $salesChannelContext->getToken(),
- $stateData,
- [
- 'amount' => $amountInMinorUnits,
- 'paymentMethodId' => $selectedPaymentMethodId,
- 'balance' => $newBalance,
- ]
- );
- $giftcardDiscount = $amountInMinorUnits;
- $this->contextSwitchRoute->switchContext(
- new RequestDataBag(
- [
- SalesChannelContextService::PAYMENT_METHOD_ID => $selectedPaymentMethodId
- ]
- ),
- $salesChannelContext
- );
- }
- }
- $minorUnitsQuotient = 1;
- if (0 < $page->getCart()->getPrice()->getTotalPrice()) {
- $minorUnitsQuotient = $amountInMinorUnits / $page->getCart()->getPrice()->getTotalPrice();
- }
+ //Remove giftcards from the Payment Method lists, as this lists gets populated at shipping details on cart page.
+ $this->paymentMethodsFilterService->getAvailableNonGiftcardsPaymentMethods(
+ $salesChannelContext,
+ $shopwarePaymentMethods
+ );
+
+ $giftcardDetails = $this->paymentStateDataService->getGiftcardTotalDiscountAndBalance(
+ $salesChannelContext,
+ $page->getCart()->getPrice()->getTotalPrice()
+ );
$page->addExtension(
self::ADYEN_DATA_EXTENSION_ID,
@@ -273,15 +254,15 @@ public function onShoppingCartLoaded(PageLoadedEvent $event)
'totalInMinorUnits' => $amountInMinorUnits,
'currency' => $currency,
'currencySymbol' => $currencySymbol,
- 'giftcardDiscount' => $giftcardDiscount,
- 'giftcardDiscountDisplay' => $giftcardDiscount / $minorUnitsQuotient,
- 'giftcardBalance' => $giftcardBalance,
+ 'giftcardDiscount' => $giftcardDetails['giftcardDiscount'],
+ 'giftcardBalance' => $giftcardDetails['giftcardBalance'],
'checkBalanceUrl' => $this->router
->generate('payment.adyen.proxy-check-balance'),
'setGiftcardUrl' => $this->router->generate('payment.adyen.proxy-store-giftcard-state-data'),
'removeGiftcardUrl' => $this->router->generate('payment.adyen.proxy-remove-giftcard-state-data'),
- 'switchContextUrl' => $this->router->generate('payment.adyen.proxy-switch-context'),
'shoppingCartPageUrl' => $this->router->generate('frontend.checkout.cart.page'),
+ 'fetchRedeemedGiftcardsUrl' => $this->router
+ ->generate('payment.adyen.proxy-fetch-redeemed-giftcards'),
])
)
);
@@ -296,6 +277,8 @@ public function onCheckoutConfirmLoaded(PageLoadedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
$selectedPaymentMethod = $salesChannelContext->getPaymentMethod();
+ $currency = $salesChannelContext->getCurrency()->getIsoCode();
+ $currencySymbol = $salesChannelContext->getCurrency()->getSymbol();
$page = $event->getPage();
$orderId = '';
$affiliateCode = $this->requestStack->getSession()->get(AffiliateTrackingListener::AFFILIATE_CODE_KEY);
@@ -304,7 +287,7 @@ public function onCheckoutConfirmLoaded(PageLoadedEvent $event)
if (method_exists($page, 'getOrder')) {
$orderId = $page->getOrder()->getId();
}
- $currency = $salesChannelContext->getCurrency()->getIsoCode();
+
$totalPrice = 0;
try {
$cart = $this->cartCalculator->calculate(
@@ -318,6 +301,7 @@ public function onCheckoutConfirmLoaded(PageLoadedEvent $event)
$totalPrice = $page->getOrder()->getPrice()->getTotalPrice();
}
}
+
$amount = $this->currency->sanitize($totalPrice, $currency);
$adyenPluginId = $this->adyenPluginProvider->getAdyenPluginId();
@@ -327,41 +311,26 @@ public function onCheckoutConfirmLoaded(PageLoadedEvent $event)
$adyenPluginId,
);
$paymentMethodsResponse = $this->paymentMethodsService->getPaymentMethods($salesChannelContext, $orderId);
- $giftcardData = $this->paymentStateDataService
- ->getPaymentStateDataFromContextToken($salesChannelContext->getToken());
- $giftcardDiscount = 0;
- $giftcardSelectedId = null;
- $adyenGiftcardSelected = ($selectedPaymentMethod->getPluginId() === $adyenPluginId)
- && $selectedPaymentMethod->getHandlerIdentifier()::$isGiftCard;
- if ($giftcardData) {
- $stateData = $giftcardData->getStateData();
- $giftcardDiscount = json_decode($stateData, true)['additionalData']['amount'] ?? 0;
- if ($giftcardDiscount >= $amount) {
- $giftcardSelectedId = json_decode($stateData, true)['additionalData']['paymentMethodId'];
- }
- }
+
$filteredPaymentMethods = $this->paymentMethodsFilterService->filterShopwarePaymentMethods(
$page->getPaymentMethods(),
$salesChannelContext,
$adyenPluginId,
- $paymentMethodsResponse,
- $giftcardSelectedId
+ $paymentMethodsResponse
);
- if (!isset($giftcardSelectedId) && $adyenGiftcardSelected) {
- $selectedPaymentMethod = $filteredPaymentMethods->first();
- $this->contextSwitchRoute->switchContext(
- new RequestDataBag(
- [
- SalesChannelContextService::PAYMENT_METHOD_ID => $selectedPaymentMethod->getId()
- ]
- ),
- $salesChannelContext
- );
- $adyenGiftcardSelected = false;
- }
+ $giftcardDetails = $this->paymentStateDataService->getGiftcardTotalDiscountAndBalance(
+ $salesChannelContext,
+ $totalPrice
+ );
+ $paymentMethodId = $this->paymentMethodsFilterService->getGiftCardPaymentMethodId($salesChannelContext);
- $currencySymbol = $salesChannelContext->getCurrency()->getSymbol();
+ $payInFullWithGiftcard = 0;
+ if ($giftcardDetails['giftcardDiscount'] >= $totalPrice) { //if full amount is covered
+ $payInFullWithGiftcard = 1;
+ } else {
+ $filteredPaymentMethods->remove($paymentMethodId); //Remove the PM from the list
+ }
$page->setPaymentMethods($filteredPaymentMethods);
@@ -372,7 +341,6 @@ public function onCheckoutConfirmLoaded(PageLoadedEvent $event)
$this->getComponentData($salesChannelContext),
[
'paymentStatusUrl' => $this->router->generate('payment.adyen.proxy-payment-status'),
- 'createOrderUrl' => $this->router->generate('payment.adyen.proxy-create-adyen-order'),
'checkoutOrderUrl' => $this->router->generate('payment.adyen.proxy-checkout-order'),
'paymentHandleUrl' => $this->router->generate('payment.adyen.proxy-handle-payment'),
'paymentDetailsUrl' => $this->router->generate('payment.adyen.proxy-payment-details'),
@@ -399,10 +367,9 @@ public function onCheckoutConfirmLoaded(PageLoadedEvent $event)
'orderId' => $orderId,
'pluginId' => $this->adyenPluginProvider->getAdyenPluginId(),
'totalPrice' => $totalPrice,
- 'giftcardDiscount' => $giftcardDiscount,
+ 'giftcardDiscount' => $giftcardDetails['giftcardDiscount'],
'currencySymbol' => $currencySymbol,
- 'payInFullWithGiftcard' => (int) isset($giftcardSelectedId),
- 'adyenGiftcardSelected' => (int) $adyenGiftcardSelected,
+ 'payInFullWithGiftcard' => $payInFullWithGiftcard,
'storedPaymentMethods' => $paymentMethodsResponse['storedPaymentMethods'] ?? [],
'selectedPaymentMethodHandler' => $selectedPaymentMethod->getFormattedHandlerIdentifier(),
'selectedPaymentMethodPluginId' => $selectedPaymentMethod->getPluginId(),
From ccca9a54be988b5c5ec2e16cbdcc60938514caa2 Mon Sep 17 00:00:00 2001
From: Khushboo \n
\n \n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n
\n\n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
{\n public readonly _id = `${this.constructor['type']}-${uuid()}`;\n public props: P;\n public state;\n protected static defaultProps = {};\n public _node;\n public _component;\n public eventEmitter = new EventEmitter();\n protected readonly _parentInstance: Core;\n\n protected resources: Resources;\n\n protected constructor(props: P) {\n this.props = this.formatProps({ ...this.constructor['defaultProps'], setStatusAutomatically: true, ...props });\n this._parentInstance = this.props._parentInstance;\n this._node = null;\n this.state = {};\n this.resources = this.props.modules ? this.props.modules.resources : undefined;\n }\n\n /**\n * Executed during creation of any payment element.\n * Gives a chance to any paymentMethod to format the props we're receiving.\n */\n protected formatProps(props: P) {\n return props;\n }\n\n /**\n * Executed on the `data` getter.\n * Returns the component data necessary for the /payments request\n *\n * TODO: Replace 'any' by type PaymentMethodData extends BaseElement implements IUIElement {\n protected componentRef: any;\n public elementRef: UIElement;\n\n constructor(props: P) {\n super(props);\n this.submit = this.submit.bind(this);\n this.setState = this.setState.bind(this);\n this.onValid = this.onValid.bind(this);\n this.onComplete = this.onComplete.bind(this);\n this.onSubmit = this.onSubmit.bind(this);\n this.handleAction = this.handleAction.bind(this);\n this.handleOrder = this.handleOrder.bind(this);\n this.handleResponse = this.handleResponse.bind(this);\n this.setElementStatus = this.setElementStatus.bind(this);\n\n this.elementRef = (props && props.elementRef) || this;\n }\n\n public setState(newState: object): void {\n this.state = { ...this.state, ...newState };\n this.onChange();\n }\n\n protected onChange(): object {\n const isValid = this.isValid;\n const state = { data: this.data, errors: this.state.errors, valid: this.state.valid, isValid };\n if (this.props.onChange) this.props.onChange(state, this.elementRef);\n if (isValid) this.onValid();\n\n return state;\n }\n\n private onSubmit(): void {\n //TODO: refactor this, instant payment methods are part of Dropin logic not UIElement\n if (this.props.isInstantPayment) {\n const dropinElementRef = this.elementRef as DropinElement;\n dropinElementRef.closeActivePaymentMethod();\n }\n\n if (this.props.setStatusAutomatically) {\n this.setElementStatus('loading');\n }\n\n if (this.props.onSubmit) {\n // Classic flow\n this.props.onSubmit({ data: this.data, isValid: this.isValid }, this.elementRef);\n } else if (this._parentInstance.session) {\n // Session flow\n // wrap beforeSubmit callback in a promise\n const beforeSubmitEvent = this.props.beforeSubmit\n ? new Promise((resolve, reject) =>\n this.props.beforeSubmit(this.data, this.elementRef, {\n resolve,\n reject\n })\n )\n : Promise.resolve(this.data);\n\n beforeSubmitEvent\n .then(data => this.submitPayment(data))\n .catch(() => {\n // set state as ready to submit if the merchant cancels the action\n this.elementRef.setStatus('ready');\n });\n } else {\n this.handleError(new AdyenCheckoutError('IMPLEMENTATION_ERROR', 'Could not submit the payment'));\n }\n }\n\n private onValid() {\n const state = { data: this.data };\n if (this.props.onValid) this.props.onValid(state, this.elementRef);\n return state;\n }\n\n onComplete(state): void {\n if (this.props.onComplete) this.props.onComplete(state, this.elementRef);\n }\n\n /**\n * Submit payment method data. If the form is not valid, it will trigger validation.\n */\n public submit(): void {\n if (!this.isValid) {\n this.showValidation();\n return;\n }\n\n this.onSubmit();\n }\n\n public showValidation(): this {\n if (this.componentRef && this.componentRef.showValidation) this.componentRef.showValidation();\n return this;\n }\n\n public setElementStatus(status: UIElementStatus, props?: any): this {\n this.elementRef?.setStatus(status, props);\n return this;\n }\n\n public setStatus(status: UIElementStatus, props?): this {\n if (this.componentRef?.setStatus) {\n this.componentRef.setStatus(status, props);\n }\n return this;\n }\n\n private submitPayment(data): Promise