Skip to content

Commit

Permalink
Add support for inline apple pay (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
aashwin-rvvup authored Dec 16, 2024
1 parent 473f84e commit d3d0438
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ test-results/
playwright-report/
hyva/
.idea/
nohup.out

vendor/
.env
11 changes: 10 additions & 1 deletion src/Magewire/Checkout/Payment/AbstractProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ abstract class AbstractProcessor extends Component
/** @var array */
public $parameters = [];

/** @var string */
public $quoteCurrency = 'GBP';

/** @var string */
public $quoteAmount = '0';

/**
* @param SerializerInterface $serializer
* @param Assets $assetsModel
Expand All @@ -55,9 +61,12 @@ public function __construct(
$this->sdkProxy = $sdkProxy;
}

public function mount(): void

public function boot(): void
{
$this->parameters = $this->serializer->unserialize($this->assetsModel->getRvvupParametersJsObject());
$this->quoteAmount = $this->checkoutSession->getQuote()->getGrandTotal();
$this->quoteCurrency = $this->checkoutSession->getQuote()->getQuoteCurrencyCode();
}

abstract function getMethodCode(): string;
Expand Down
79 changes: 79 additions & 0 deletions src/Magewire/Checkout/Payment/ApplePayProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,96 @@

namespace Rvvup\PaymentsHyvaCheckout\Magewire\Checkout\Payment;

use Magento\Checkout\Model\Session;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Framework\UrlFactory;
use Rvvup\Payments\Controller\Redirect\In;
use Rvvup\Payments\Model\SdkProxy;
use Rvvup\Payments\Service\PaymentSessionService;
use Rvvup\Payments\ViewModel\Assets;
use Rvvup\PaymentsHyvaCheckout\Service\GetPaymentActions;

class ApplePayProcessor extends AbstractProcessor
{
protected $listeners = [
'shipping_method_selected' => 'refresh',
'coupon_code_applied' => 'refresh',
'coupon_code_revoked' => 'refresh'
];

/** @var PaymentSessionService */
private $paymentSessionService;

/** @var UrlFactory */
private $urlFactory;

/** @var array */
public $paymentSessionResult;

/**
* @param SerializerInterface $serializer
* @param Assets $assetsModel
* @param GetPaymentActions $getPaymentActions
* @param Session $checkoutSession
* @param SdkProxy $sdkProxy
* @param PaymentSessionService $paymentSessionService
* @param UrlFactory $urlFactory
*/
public function __construct(
SerializerInterface $serializer,
Assets $assetsModel,
GetPaymentActions $getPaymentActions,
Session $checkoutSession,
SdkProxy $sdkProxy,
PaymentSessionService $paymentSessionService,
UrlFactory $urlFactory
) {
parent::__construct($serializer, $assetsModel, $getPaymentActions, $checkoutSession, $sdkProxy);
$this->paymentSessionService = $paymentSessionService;
$this->urlFactory = $urlFactory;
}

public $hydrated = false;

public function getMethodCode(): string
{
return 'rvvup_APPLE_PAY';
}
public function boot(): void
{
parent::boot();

if ($this->showInline()) {
$this->switchTemplate('Rvvup_PaymentsHyvaCheckout::component/payment/apple-pay-inline-processor.phtml');
}
}

public function placeOrder(): void
{
$this->loadPaymentActions();
$redirectUrl = $this->getRedirectUrl();
$this->redirect($redirectUrl);
}

/**
* @return bool
*/
public function showInline(): bool
{
if (isset($this->parameters['settings']['apple_pay']['applePayFlow'])) {
return $this->parameters['settings']['apple_pay']['applePayFlow'] == 'INLINE';
}
return false;
}

public function createPaymentSession(string $checkoutId): void
{
$quote = $this->checkoutSession->getQuote();

$paymentSession = $this->paymentSessionService->create($quote, $checkoutId);

$url = $this->urlFactory->create();
$url->setQueryParam(In::PARAM_RVVUP_ORDER_ID, $paymentSession["id"]);
$this->paymentSessionResult = ["paymentSessionId" => $paymentSession["id"], "redirectUrl" => $url->getUrl('rvvup/redirect/in')];
}
}
2 changes: 1 addition & 1 deletion src/view/frontend/layout/hyva_checkout_index_index.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

<block name="checkout.payment.method.rvvup.apple-pay-processor"
as="rvvup.apple-pay-processor"
template="Rvvup_PaymentsHyvaCheckout::component/payment/apple-pay-processor.phtml"
template="Rvvup_PaymentsHyvaCheckout::component/payment/apple-pay-hosted-processor.phtml"
after="hyva.checkout.main">
<arguments>
<argument name="magewire" xsi:type="object">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);

use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

/** @var Template $block */
/** @var Escaper $escaper */
?>
<div wire:ignore>
<style>
#payment-method-option-rvvup_APPLE_PAY {
display: none;
}
</style>
<script>
(() => {
window.addEventListener('checkout:payment:method-activate', event => {
if (event.detail.method !== 'rvvup_APPLE_PAY') {
return;
}

const component = Magewire.find('<?= $escaper->escapeJs($block->getNameInLayout()) ?>');
hyvaCheckout.payment.activate('rvvup_APPLE_PAY', {
placeOrderViaJs() {
return document.querySelector('[wire\\:key="rvvup_APPLE_PAY"].active') !== null;
},

placeOrder() {
return component.placeOrder();
}
}, document.querySelector('[wire\\:key="rvvup_APPLE_PAY"].active'));
});
window.addEventListener('checkout:payment:method-activate', () => {
enableApplePay();
}, {once: false});
window.addEventListener('checkout:shipping:method-activate', () => {
enableApplePay();
}, {once: false});
window.addEventListener('checkout:step:loaded', () => {
enableApplePay();
}, {once: false});

function enableApplePay() {
let applePay = document.getElementById('payment-method-option-rvvup_APPLE_PAY');
if (applePay && window.ApplePaySession && window.ApplePaySession.canMakePayments()) {
applePay.style.display = 'block';
}
}
})();
</script>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php
declare(strict_types=1);

use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

/** @var Template $block */
/** @var Escaper $escaper */
/** @var \Rvvup\PaymentsHyvaCheckout\Magewire\Checkout\Payment\ApplePayProcessor $magewire */
?>
<div id="rvvup-apple-pay-inline" data-quoteamount="<?php echo $magewire->quoteAmount; ?>" data-quotecurrency="<?php echo $magewire->quoteCurrency; ?>">
<style>
#payment-method-option-rvvup_APPLE_PAY {
display: block;
}
.rvvup_APPLE_PAY_place_order_button {
display: none;
}
</style>
<script>
(() => {
const getQuoteTotal = () => {
const dataSet = document.querySelector('#rvvup-apple-pay-inline').dataset;
return {
amount: dataSet.quoteamount,
currency: dataSet.quotecurrency
};
};
const triggerApplePayDisplayEvent = () => {
if (!$showApplePay) {
window.dispatchEvent(new CustomEvent('rvvup:methods:apple-pay:hide'));
}
};
let applePayPromise = window.rvvup_sdk.createPaymentMethod("APPLE_PAY", {
checkoutSessionKey: rvvup_parameters.checkout.token,
total: getQuoteTotal(),
}).catch(e => {
console.error("Error creating Apple Pay payment method", e);
});
let $showApplePay = true;

applePayPromise.then(applePay => {
applePay.on("ready", async () => {
$showApplePay = await applePay.canMakePayment();
triggerApplePayDisplayEvent();
});
});
window.addEventListener('checkout:payment:method-activate', triggerApplePayDisplayEvent);
window.addEventListener('checkout:step:loaded', triggerApplePayDisplayEvent);

window.addEventListener('rvvup:methods:apple-pay:hide', () => {
let element = document.getElementById("payment-method-option-rvvup_APPLE_PAY");
if (element) {
element.parentElement.removeChild(element);
}
});

window.addEventListener('checkout:payment:method-activate', event => {
let placeOrderButton = document.querySelector('.nav-main .btn-primary');
const divId = "rvvup-apple-pay-button";

if (event.detail.method !== 'rvvup_APPLE_PAY') {
if (document.getElementById(divId)) {
document.getElementById(divId).style.display = 'none';
document.querySelector('.nav-main .btn-primary').classList.remove('rvvup_APPLE_PAY_place_order_button');
}
return;
}


const component = Magewire.find('<?= $escaper->escapeJs($block->getNameInLayout()) ?>');
hyvaCheckout.payment.activate('rvvup_APPLE_PAY', {
initialize() {
if(document.getElementById(divId)){
document.getElementById(divId).style.display = 'block';
placeOrderButton.classList.add('rvvup_APPLE_PAY_place_order_button');

return;
}
const applePayButtonDiv = document.createElement('div');
applePayButtonDiv.id = divId;
applePayButtonDiv.className = 'rvvup-applepay-button z-0';
if (placeOrderButton.className && placeOrderButton.className.indexOf("w-full") > -1) {
applePayButtonDiv.className += ' w-full';
}
placeOrderButton.classList.add('rvvup_APPLE_PAY_place_order_button');
placeOrderButton.appendChild(applePayButtonDiv);
placeOrderButton.parentNode.insertBefore(applePayButtonDiv, placeOrderButton);


applePayPromise.then(async function (applePay) {
if($showApplePay){
await applePay.mount({
selector: "#rvvup-apple-pay-button",
});
}
applePay.on("click", () => {
applePay.update({total: getQuoteTotal()});
});
applePay.on("beforePaymentAuth", async () => {
await component.createPaymentSession(rvvup_parameters.checkout.id)
return {
paymentSessionId: component.paymentSessionResult.paymentSessionId
};
});
applePay.on("paymentAuthorized", () => {
let magewire = document.getElementById('magewire-loader');
magewire.children[0].style.display = 'block';
window.location.href = component.paymentSessionResult.redirectUrl;
});
applePay.on("paymentFailed", (data) => {
window.dispatchMessages && window.dispatchMessages([{
type: 'error',
text: 'Payment ' + data.reason
}], 5000);
});
});

},
placeOrderViaJs() {
return document.querySelector('[wire\\:key="rvvup_APPLE_PAY"].active') !== null;
},

placeOrder() {
return component.placeOrder();
}
}, document.querySelector('[wire\\:key="rvvup_APPLE_PAY"].active'));

});
})();
</script>
</div>

This file was deleted.

Loading

0 comments on commit d3d0438

Please sign in to comment.