Skip to content

Commit

Permalink
[CHK-4614] Adding Express Pay modal to the PDP
Browse files Browse the repository at this point in the history
Adding before cart add event to clear cart for quick purchase
Adding support for SDK onClick event to add item to cart on pdp
Adding page source argument to express pay xml to facilitate above add
Adding functionality to checkout without a quote active
Adding Endpoint to fetch Quote Mask Id for guest shipping estimate endpoints
  • Loading branch information
nicolenorman authored and boldjoshshea committed Dec 16, 2024
1 parent cac0be2 commit 1723340
Show file tree
Hide file tree
Showing 19 changed files with 393 additions and 47 deletions.
19 changes: 19 additions & 0 deletions Api/Quote/GetQuoteInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Bold\CheckoutPaymentBooster\Api\Quote;

/**
* Hydrate Bold order from Magento quote.
*/
interface GetQuoteInterface
{
/**
* Gets Current Session Quote ID
*
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getQuoteId();
}
2 changes: 1 addition & 1 deletion Model/InitOrderFromQuote.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function init(CartInterface $quote): array
'cart_id' => $quote->getId() ?? '',
];
$orderData = $this->client->post(
(int)$quote->getStore()->getWebsiteId(),
(int)$websiteId,
self::INIT_SIMPLE_ORDER_URI,
$body
);
Expand Down
59 changes: 59 additions & 0 deletions Observer/Product/ExpressPayBeforeAddToCartObserver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php


namespace Bold\CheckoutPaymentBooster\Observer\Product;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Checkout\Model\Session;
use Magento\Quote\Api\CartRepositoryInterface;

/**
* Observer for `controller_action_predispatch_checkout_cart_add` event
*
* @see \Magento\Framework\App\FrontController::dispatchPreDispatchEvents
* @see \Magento\Checkout\Controller\Cart\Add::execute
*/
class ExpressPayBeforeAddToCartObserver implements ObserverInterface
{
/**
* @var Session
*/
protected $checkoutSession;

/**
* @var CartRepositoryInterface
*/
protected $cartRepository;

public function __construct(Session $checkoutSession, CartRepositoryInterface $cartRepository)
{
$this->checkoutSession = $checkoutSession;
$this->cartRepository = $cartRepository;
}

/**
* Clear the cart before checking out with Express Pay from the product detail page
*
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer): void
{
$request = $observer->getEvent()->getRequest();
$isExpressPayOrder = $request->getParam('source') === 'expresspay';

$quote = $this->checkoutSession->getQuote();

if (!$isExpressPayOrder) {
return;
}
$this->checkoutSession->setCheckoutState(true);
$quote->removeAllItems();
$quote->setTotalsCollectedFlag(false);
$this->checkoutSession->clearQuote();

$this->cartRepository->save($quote);
$this->checkoutSession->setQuoteId($quote->getId());
}
}
12 changes: 10 additions & 2 deletions Observer/ShortcutButtons/AddExpressPayButtonsObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Magento\Catalog\Block\ShortcutButtons;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Bold\CheckoutPaymentBooster\UI\PaymentBoosterConfigProvider;

/**
* Observes the `shortcut_buttons_container` event
Expand All @@ -32,14 +33,21 @@ public function execute(Observer $observer): void
$event = $observer->getEvent();
/** @var ShortcutButtons $container */
$container = $event->getData('container');

$layout = $container->getLayout();

if ($layout->getBlock(ExpressPayShortcutButtons::BLOCK_ALIAS) !== false) {
return;
}

/** @var ExpressPayShortcutButtons $expressPayShortcutButtons */
$expressPayShortcutButtons = $container->getLayout()->createBlock(
$expressPayShortcutButtons = $layout->createBlock(
ExpressPayShortcutButtons::class,
ExpressPayShortcutButtons::BLOCK_ALIAS,
[
'data' => [
'express_pay_view_model' => $this->expressPayFactory->create(),
'render_page_source' => 'mini-cart'
'render_page_source' => PaymentBoosterConfigProvider::PAGE_SOURCE_MINICART
]
]
);
Expand Down
41 changes: 30 additions & 11 deletions Service/ExpressPay/Order/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use Bold\CheckoutPaymentBooster\Api\Http\ClientInterface;
use Bold\CheckoutPaymentBooster\Service\ExpressPay\QuoteConverter;
use Exception;
use Magento\Checkout\Model\Session;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Session\SessionManagerInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
use Magento\Quote\Model\Quote;
Expand Down Expand Up @@ -41,18 +43,24 @@ class Create
/**
* @var ClientInterface
*/
private $httpClient;
private $httpClient;
/**
* @var SessionManagerInterface
*/
private $checkoutSession;

public function __construct(
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
CartRepositoryInterface $cartRepository,
QuoteConverter $quoteConverter,
ClientInterface $httpClient
ClientInterface $httpClient,
SessionManagerInterface $checkoutSession
) {
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
$this->cartRepository = $cartRepository;
$this->quoteConverter = $quoteConverter;
$this->httpClient = $httpClient;
$this->checkoutSession = $checkoutSession;
}

/**
Expand All @@ -77,18 +85,29 @@ public function execute($quoteMaskId, $gatewayId, $shippingStrategy): array
$quoteId = $quoteMaskId;
}

try {
/** @var Quote $quote */
$quote = $this->cartRepository->get((int)$quoteId);
} catch (NoSuchEntityException $noSuchEntityException) {
throw new LocalizedException(__('Could not create Express Pay order. Invalid quote ID "%1".', $quoteId));
if ($quoteId !== '') {
try {
/** @var Quote $quote */
$quote = $this->cartRepository->get((int)$quoteId);
} catch (NoSuchEntityException $noSuchEntityException) {
throw new LocalizedException(__('Could not create Express Pay order. Invalid quote ID "%1".', $quoteId));
}
} else {
try {
/** @var Session $session */
$session = $this->checkoutSession;
/** @var Quote $quote */
$quote = $session->getQuote();
} catch (NoSuchEntityException $noSuchEntityException) {
throw new LocalizedException(__('Active quote not found.'));
}
}

$hasBillingData = $quote->getBillingAddress()->getFirstname() && $quote->getBillingAddress()->getStreet();
$hasBillingData = $quote->getBillingAddress()->getFirstname() && $quote->getBillingAddress()->getStreet();

if (!$hasBillingData && !empty($quote->getShippingAddress()->getShippingMethod())) {
$quote->getShippingAddress()->setShippingMethod('');
}
if (!$hasBillingData && !empty($quote->getShippingAddress()->getShippingMethod())) {
$quote->getShippingAddress()->setShippingMethod('');
}

$websiteId = (int)$quote->getStore()->getWebsiteId();
$uri = 'checkout/orders/{{shopId}}/wallet_pay';
Expand Down
33 changes: 26 additions & 7 deletions Service/ExpressPay/Order/Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
use Bold\CheckoutPaymentBooster\Service\ExpressPay\Order\Get as GetExpressPayOrder;
use Bold\CheckoutPaymentBooster\Service\ExpressPay\QuoteConverter;
use Exception;
use Magento\Checkout\Model\Session;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Session\SessionManagerInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
use Magento\Quote\Model\Quote;
Expand Down Expand Up @@ -46,20 +48,26 @@ class Update
/**
* @var GetExpressPayOrder
*/
private $getExpressPayOrder;
private $getExpressPayOrder;
/**
* @var SessionManagerInterface
*/
private $checkoutSession;

public function __construct(
MaskedQuoteIdToQuoteIdInterface $maskedQuoteIdToQuoteId,
CartRepositoryInterface $cartRepository,
QuoteConverter $quoteConverter,
GetExpressPayOrder $getExpressPayOrder,
ClientInterface $httpClient
ClientInterface $httpClient,
SessionManagerInterface $checkoutSession
) {
$this->maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
$this->cartRepository = $cartRepository;
$this->quoteConverter = $quoteConverter;
$this->getExpressPayOrder = $getExpressPayOrder;
$this->httpClient = $httpClient;
$this->checkoutSession = $checkoutSession;
}

/**
Expand All @@ -83,11 +91,22 @@ public function execute($quoteMaskId, $gatewayId, $paypalOrderId): void
$quoteId = $quoteMaskId;
}

try {
/** @var Quote $quote */
$quote = $this->cartRepository->get((int)$quoteId);
} catch (NoSuchEntityException $noSuchEntityException) {
throw new LocalizedException(__('Could not update Express Pay order. Invalid quote ID "%1".', $quoteId));
if ($quoteId !== '') {
try {
/** @var Quote $quote */
$quote = $this->cartRepository->get((int)$quoteId);
} catch (NoSuchEntityException $noSuchEntityException) {
throw new LocalizedException(__('Could not update Express Pay order. Invalid quote ID "%1".', $quoteId));
}
} else {
try {
/** @var Session $session */
$session = $this->checkoutSession;
/** @var Quote $quote */
$quote = $session->getQuote();
} catch (NoSuchEntityException $noSuchEntityException) {
throw new LocalizedException(__('Active quote not found.'));
}
}

$websiteId = (int)$quote->getStore()->getWebsiteId();
Expand Down
45 changes: 45 additions & 0 deletions Service/Quote/GetQuote.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Bold\CheckoutPaymentBooster\Service\Quote;

use Bold\CheckoutPaymentBooster\Api\Quote\GetQuoteInterface;
use Magento\Checkout\Model\Session;
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;

/**
* Get Current Quote ID from Magento quote.
*/
class GetQuote implements GetQuoteInterface
{
/**
* @var Session
*/
private $checkoutSession;

/**
* @var QuoteIdToMaskedQuoteId
*/
private $quoteIdToMaskedQuoteId;

public function __construct(Session $checkoutSession, QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId)
{
$this->checkoutSession = $checkoutSession;
$this->quoteIdToMaskedQuoteId = $quoteIdToMaskedQuoteId;
}

/**
* Gets Current Session Quote ID
*
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getQuoteId()
{
$quoteId = (int)$this->checkoutSession->getQuote()->getId();
$quoteIdMask = $this->quoteIdToMaskedQuoteId->execute($quoteId);

return $quoteIdMask;
}
}
17 changes: 16 additions & 1 deletion UI/PaymentBoosterConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@
use Magento\Directory\Model\Country;
use Magento\Directory\Model\ResourceModel\Country\CollectionFactory;
use Magento\Config\Model\Config\Source\Nooptreq as NooptreqSource;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;

/**
* Config provider for Payment Booster.
*/
class PaymentBoosterConfigProvider implements ConfigProviderInterface
{

public const PAGE_SOURCE_PRODUCT = 'product';
public const PAGE_SOURCE_CART = 'cart';
public const PAGE_SOURCE_MINICART = 'mini-cart';

/**
* @var CheckoutData
*/
Expand Down Expand Up @@ -48,6 +54,11 @@ class PaymentBoosterConfigProvider implements ConfigProviderInterface
*/
private $countries = [];

/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* @param CheckoutData $checkoutData
* @param Config $config
Expand All @@ -59,13 +70,15 @@ public function __construct(
Config $config,
AllowedCountries $allowedCountries,
CollectionFactory $collectionFactory,
LoggerInterface $logger
LoggerInterface $logger,
StoreManagerInterface $storeManager
) {
$this->checkoutData = $checkoutData;
$this->config = $config;
$this->allowedCountries = $allowedCountries;
$this->collectionFactory = $collectionFactory;
$this->logger = $logger;
$this->storeManager = $storeManager;
}

/**
Expand All @@ -86,6 +99,7 @@ public function getConfig(): array
$jwtToken = $this->checkoutData->getJwtToken();
$epsAuthToken = $this->checkoutData->getEpsAuthToken();
$epsGatewayId = $this->checkoutData->getEpsGatewayId();
$currency = $this->storeManager->getStore()->getCurrentCurrency()->getCode();
if ($jwtToken === null || $epsAuthToken === null || $epsGatewayId === null) {
$errorMsgs = [];
if ($jwtToken === null) {
Expand Down Expand Up @@ -127,6 +141,7 @@ public function getConfig(): array
'method' => Service::CODE,
],
],
'currency' => $currency
],
];
}
Expand Down
Loading

0 comments on commit 1723340

Please sign in to comment.