diff --git a/catalog/view/javascript/paypal.js b/catalog/view/javascript/paypal.js index c416a64..f204408 100644 --- a/catalog/view/javascript/paypal.js +++ b/catalog/view/javascript/paypal.js @@ -3,10 +3,10 @@ var PayPalAPI = (function () { var paypal_script = []; var paypal_sdk = []; var paypal_callback; - - var showPayPalAlert = function(data) { + + var showPayPalAlert = function (data) { $('.alert-paypal').remove(); - + if (data['error'] && data['error']['warning']) { if ($('#paypal_form').length) { $('#paypal_form').prepend('
' + data['error']['warning'] + '
'); @@ -15,131 +15,137 @@ var PayPalAPI = (function () { } } }; - - var getQueryParams = function(url) { + + var getQueryParams = function (url) { const param_arr = url.slice(url.indexOf('?') + 1).split('&'); const params = {}; - + param_arr.map(param => { const [key, val] = param.split('='); params[key] = decodeURIComponent(val); }) - + return params; }; - - var requestPayPalData = async function(url, data) { + + var requestPayPalData = async function (url, data) { return new Promise((resolve, reject) => { $.ajax({ method: 'post', url: url, data: data, dataType: 'json', - success: function(data) { + success: function (data) { resolve(data); }, - error: function(xhr, ajaxOptions, thrownError) { + error: function (xhr, ajaxOptions, thrownError) { console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); } }); }); }; - - var updatePayPalData = async function() { + + var updatePayPalData = async function () { var params = []; var script_file = document.getElementsByTagName('script'); - + for (var i = 0; i < script_file.length; i++) { - if (script_file[i].hasAttribute('src') && (script_file[i].getAttribute('src').indexOf('paypal.js') !== -1)) { - params = getQueryParams(script_file[i].getAttribute('src')); - - break; + if (script_file[i].hasAttribute('src') && script_file[i].getAttribute('src').includes('paypal.js')) { + var src = script_file[i].getAttribute('src'); + //console.log('[PayPal Debug] Found PayPal JS src:', src); + + // Prefer the one WITH query parameters + if (src.includes('?')) { + params = getQueryParams(src); + //console.log('[PayPal Debug] Extracted PayPal query params:', params); + break; + } } } - + paypal_data = params; - + if (window.ApplePaySession && window.ApplePaySession?.supportsVersion(4) && ApplePaySession.canMakePayments()) { paypal_data['applepay'] = true; } - + if (paypal_data['page_code'] == 'product') { paypal_data['product'] = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); } - + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'getData', paypal_data); - + paypal_data = json; - + showPayPalAlert(json); }; - - var readyPayPalSDK = function() { + + var readyPayPalSDK = function () { if (typeof PayPalSDK === 'undefined') { setTimeout(readyPayPalSDK, 100); } else { paypal_sdk[paypal_script.length - 1] = PayPalSDK; - + initPayPalSDK(); } }; - - var loadPayPalSDK = function() { + + var loadPayPalSDK = function () { var html = ''; - + if (paypal_data['components'].includes('buttons')) { if (!$('#paypal_button').length) { if ($(paypal_data['button_insert_tag']).length) { html = '
'; - + eval("$('" + paypal_data['button_insert_tag'] + "')." + paypal_data['button_insert_type'] + "(html)"); } } } - + if (paypal_data['components'].includes('googlepay')) { if (!$('#googlepay_button').length) { if ($(paypal_data['googlepay_button_insert_tag']).length) { html = '
'; - + eval("$('" + paypal_data['googlepay_button_insert_tag'] + "')." + paypal_data['googlepay_button_insert_type'] + "(html)"); } } } - + if (paypal_data['components'].includes('applepay')) { if (!$('#applepay_button').length) { if ($(paypal_data['applepay_button_insert_tag']).length) { html = '
'; - + eval("$('" + paypal_data['applepay_button_insert_tag'] + "')." + paypal_data['applepay_button_insert_type'] + "(html)"); } } } - + if (paypal_data['components'].includes('messages')) { if (!$('#paypal_message').length) { if ($(paypal_data['message_insert_tag']).length) { html = '
'; - + eval("$('" + paypal_data['message_insert_tag'] + "')." + paypal_data['message_insert_type'] + "(html)"); } } } - + if (paypal_data['components'].includes('fastlane')) { if (!$('#form-register .fastlane-watermark').length) { html = '
'; - + $('#form-register input[name=\'email\']').parent().append(html); - + if ($(document).find('input[name=\'account\']:checked').val() == '1') { $('#form-register .fastlane-watermark').addClass('d-none'); } else { $('#form-register .fastlane-watermark').removeClass('d-none'); } - - $(document).on('change', 'input[name=\'account\']', function() { + + $(document).on('change', 'input[name=\'account\']', function () { if (this.value == '1') { $('#form-register .fastlane-watermark').addClass('d-none'); } else { @@ -148,77 +154,77 @@ var PayPalAPI = (function () { }); } } - + var src_data = {}; - + src_data['components'] = paypal_data['components'].join(','); src_data['client-id'] = paypal_data['client_id']; src_data['merchant-id'] = paypal_data['merchant_id']; src_data['currency'] = paypal_data['currency_code']; src_data['intent'] = paypal_data['transaction_method']; - + if (paypal_data['button_enable_funding'] && paypal_data['button_enable_funding'].length) { src_data['enable-funding'] = paypal_data['button_enable_funding'].join(','); } - + if (paypal_data['button_disable_funding'] && paypal_data['button_disable_funding'].length) { src_data['disable-funding'] = paypal_data['button_disable_funding'].join(','); } - + var src = 'https://www.paypal.com/sdk/js?' + $.param(src_data); var script_count = paypal_script.length; var script_load_status = 0; - + for (var i = 0; i < script_count; i++) { if (paypal_script[i].src == src) { script_load_status = 1; - + break; } } - + if (!script_load_status) { if (typeof PayPalSDK !== 'undefined') { delete PayPalSDK; } - + paypal_script[script_count] = document.createElement('script'); paypal_script[script_count].type = 'text/javascript'; paypal_script[script_count].src = src; paypal_script[script_count].setAttribute('data-partner-attribution-id', paypal_data['partner_attribution_id']); paypal_script[script_count].setAttribute('data-namespace', 'PayPalSDK'); - + if (paypal_data['client_token']) { paypal_script[script_count].setAttribute('data-client-token', paypal_data['client_token']); - } - + } + if (paypal_data['sdk_client_token']) { paypal_script[script_count].setAttribute('data-sdk-client-token', paypal_data['sdk_client_token']); } - + if (paypal_data['client_metadata_id']) { paypal_script[script_count].setAttribute('data-client-metadata-id', paypal_data['client_metadata_id']); } - + if (paypal_data['id_token']) { paypal_script[script_count].setAttribute('data-user-id-token', paypal_data['id_token']); } paypal_script[script_count].async = false; paypal_script[script_count].onload = readyPayPalSDK(); - + document.querySelector('body').appendChild(paypal_script[script_count]); } else if (paypal_sdk[i]) { PayPalSDK = paypal_sdk[i]; - + initPayPalSDK(); } }; - - var initPayPalSDK = function() { + + var initPayPalSDK = function () { if (paypal_data['components'].includes('buttons') && $('#paypal_button').length && !$('#paypal_button_container').html()) { $('#paypal_button').css('text-align', paypal_data['button_align']); - + if (paypal_data['button_width']) { $('#paypal_button_container').css('display', 'inline-block'); $('#paypal_button_container').css('width', paypal_data['button_width']); @@ -226,8 +232,8 @@ var PayPalAPI = (function () { $('#paypal_button_container').css('display', 'block'); $('#paypal_button_container').css('width', 'auto'); } - - try { + + try { var paypal_button_data = { env: paypal_data['environment'], locale: paypal_data['locale'], @@ -239,74 +245,74 @@ var PayPalAPI = (function () { label: paypal_data['button_label'], tagline: 'false' }, - createOrder: async function() { + createOrder: async function () { paypal_order_id = false; product_data = false; - + if (paypal_data['page_code'] == 'product') { product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); } - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'button', 'product': product_data}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'button', 'product': product_data }); + showPayPalAlert(json); - + paypal_order_id = json['paypal_order_id']; - - return paypal_order_id; + + return paypal_order_id; }, - onApprove: async function(data) { - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'button', 'paypal_order_id': data.orderID}); - + onApprove: async function (data) { + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'button', 'paypal_order_id': data.orderID }); + showPayPalAlert(json); - + if (json['url']) { location = json['url']; } } }; - + if (paypal_data['button_funding_source']) { paypal_button_data['fundingSource'] = paypal_data['button_funding_source']; } - + var paypal_button = PayPalSDK.Buttons(paypal_button_data); - + if (paypal_button.isEligible()) { paypal_button.render('#paypal_button_container'); } } catch (error) { console.error('PayPal Express failed during startup', error); } - + $('#paypal_button_container').removeClass('paypal-spinner'); } - + if (paypal_data['components'].includes('googlepay') && $('#googlepay_button').length && !$('#googlepay_button_container').html()) { if (google && PayPalSDK.Googlepay) { initGooglePaySDK().catch(console.log); } else { $('#googlepay_button').remove(); - + console.log('This device does not support Google Pay'); } - + $('#googlepay_button_container').removeClass('paypal-spinner'); } - + if (paypal_data['components'].includes('applepay') && $('#applepay_button').length && !$('#applepay_button_container').html()) { if (window.ApplePaySession && window.ApplePaySession?.supportsVersion(4) && ApplePaySession.canMakePayments()) { initApplePaySDK().catch(console.log); } else { $('#applepay_button').remove(); - + console.log('This device does not support Apple Pay'); } } - + if (paypal_data['card_customer_tokens'] && $('#paypal_card_tokens').length && !$('#paypal_card_tokens_container').html()) { $('#paypal_card_tokens').css('text-align', paypal_data['card_align']); - + if (paypal_data['card_width']) { $('#paypal_card_tokens_container').css('display', 'inline-block'); $('#paypal_card_tokens_container').css('width', paypal_data['card_width']); @@ -314,27 +320,27 @@ var PayPalAPI = (function () { $('#paypal_card_tokens_container').css('display', 'block'); $('#paypal_card_tokens_container').css('width', 'auto'); } - - $.each(paypal_data['card_customer_tokens'], function(index, card_customer_token) { + + $.each(paypal_data['card_customer_tokens'], function (index, card_customer_token) { html = '
' + card_customer_token['card_number'] + '
'; - + $('#paypal_card_tokens_container').append(html); }); - - $('#paypal_card_tokens_container').delegate('.card-token-button', 'click', async function(event) { + + $('#paypal_card_tokens_container').delegate('.card-token-button', 'click', async function (event) { event.preventDefault(); - + if (!$('#paypal_card_tokens_container').hasClass('disabled')) { var paypal_card_token = $(this).parents('.paypal-card-token'); var card_token_index = $(this).attr('index'); - + paypal_card_token.addClass('paypal-spinner'); $('#paypal_card_tokens_container').addClass('disabled'); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'card', 'index': card_token_index}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'card', 'index': card_token_index }); + showPayPalAlert(json); - + if (json['url']) { location = json['url']; } else { @@ -343,35 +349,35 @@ var PayPalAPI = (function () { } } }); - - $('#paypal_card_tokens_container').delegate('.card-token-delete-button', 'click', async function(event) { + + $('#paypal_card_tokens_container').delegate('.card-token-delete-button', 'click', async function (event) { event.preventDefault(); - + if (!$('#paypal_card_tokens_container').hasClass('disabled')) { var paypal_card_token = $(this).parents('.paypal-card-token'); var card_token_index = $(this).attr('index'); - + paypal_card_token.addClass('paypal-spinner'); $('#paypal_card_tokens_container').addClass('disabled'); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'deleteCustomerToken', {'index': card_token_index}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'deleteCustomerToken', { 'index': card_token_index }); + showPayPalAlert(json); - + if (json['success']) { paypal_card_token.remove(); } else { paypal_card_token.removeClass('paypal-spinner'); } - + $('#paypal_card_tokens_container').removeClass('disabled'); } - }); + }); } - + if (paypal_data['components'].includes('card-fields') && $('#paypal_card').length && !$('#paypal_card_form').find('iframe').length) { $('#paypal_card').css('text-align', paypal_data['card_align']); - + if (paypal_data['card_width']) { $('#paypal_card_container').css('display', 'inline-block'); $('#paypal_card_container').css('width', paypal_data['card_width']); @@ -379,7 +385,7 @@ var PayPalAPI = (function () { $('#paypal_card_container').css('display', 'block'); $('#paypal_card_container').css('width', 'auto'); } - + try { var paypal_card = PayPalSDK.CardFields({ style: { @@ -390,28 +396,28 @@ var PayPalAPI = (function () { 'padding': '0.75rem 0.75rem', } }, - createOrder: async function() { + createOrder: async function () { paypal_order_id = false; - + var card_save = ($('#paypal_card_form #paypal_card_save:checked').length ? $('#paypal_card_form #paypal_card_save:checked').val() : 0); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'card', 'card_save': card_save}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'card', 'card_save': card_save }); + showPayPalAlert(json); - + paypal_order_id = json['paypal_order_id']; - + return paypal_order_id; }, - onApprove: async function(data) { + onApprove: async function (data) { var card_save = ($('#paypal_card_form #paypal_card_save:checked').length ? $('#paypal_card_form #paypal_card_save:checked').val() : 0); var card_type = $('#paypal_card_form').attr('card_type'); var card_nice_type = $('#paypal_card_form').attr('card_nice_type'); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'card', 'card_save': card_save, 'card_type': card_type, 'card_nice_type': card_nice_type, 'paypal_order_id': data.orderID}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'card', 'card_save': card_save, 'card_type': card_type, 'card_nice_type': card_nice_type, 'paypal_order_id': data.orderID }); + showPayPalAlert(json); - + if (json['url']) { location = json['url']; } else { @@ -420,12 +426,12 @@ var PayPalAPI = (function () { } }, inputEvents: { - onChange: function(data) { + onChange: function (data) { console.log('CCF Event "change", state=' + paypal_card.getState() + ', event=' + data); - + $('#paypal_card_form').removeClass().addClass('well'); $('#paypal_card_form').removeAttr(); - + if (data.cards.length === 1) { $('#paypal_card_form').addClass(data.cards[0].type); $('#paypal_card_form').attr('card_type', data.cards[0].type); @@ -438,15 +444,15 @@ var PayPalAPI = (function () { $('#paypal_card_button').removeClass('show-button'); } }, - onFocus: function(data) { + onFocus: function (data) { console.log('CCF Event "focus", state=' + paypal_card.getState() + ', event=' + data); }, - onBlur: function(data) { + onBlur: function (data) { console.log('CCF Event "blur", state=' + paypal_card.getState() + ', event=' + data); }, - onInputSubmitRequest: function(data) { + onInputSubmitRequest: function (data) { console.log('CCF Event "input submit request", state=' + paypal_card.getState() + ', event=' + data); - + if (data.isFormValid) { $('#paypal_card_button').addClass('show-button'); } else { @@ -455,27 +461,27 @@ var PayPalAPI = (function () { } } }); - + if (paypal_card.isEligible()) { paypal_card.NameField().render('#card_holder_name'); paypal_card.NumberField().render('#card_number'); paypal_card.ExpiryField().render('#expiration_date'); paypal_card.CVVField().render('#cvv'); - + var paypal_card_button = document.querySelector('#paypal_card_button'); - - paypal_card_button.addEventListener('click', function(event) { + + paypal_card_button.addEventListener('click', function (event) { event.preventDefault(); - + if ($('#paypal_card_button').hasClass('show-button')) { console.log('CCF Event "click", state=' + paypal_card.getState() + ', event=' + event); $('#paypal_card_container').addClass('paypal-spinner'); $('#paypal_card_button').prop('disabled', true).addClass('loading'); - - paypal_card.submit().then(function() { + + paypal_card.submit().then(function () { console.log('PayPal CCF submitted:', paypal_card); - }).catch(function(error) { + }).catch(function (error) { console.error('PayPal CCF submit erred:', error); }); } @@ -486,35 +492,35 @@ var PayPalAPI = (function () { } catch (error) { console.error('PayPal Card failed during startup', error); } - + $('#paypal_card_container').removeClass('paypal-spinner'); $('#paypal_card_button').prop('disabled', false).removeClass('loading'); } - - if (paypal_data['components'].includes('messages') && $('#paypal_message').length && !$('#paypal_message_container').html()) { + + if (paypal_data['components'].includes('messages') && $('#paypal_message').length && !$('#paypal_message_container').html()) { var paypal_message = document.createElement('div'); - + paypal_message.setAttribute('data-pp-message', ''); - + if (paypal_data['page_code'] == 'home') { paypal_message.setAttribute('data-pp-placement', 'home'); } - + if (paypal_data['page_code'] == 'product') { paypal_message.setAttribute('data-pp-placement', 'product'); } - + if (paypal_data['page_code'] == 'cart') { paypal_message.setAttribute('data-pp-placement', 'cart'); } - + if (paypal_data['page_code'] == 'checkout') { paypal_message.setAttribute('data-pp-placement', 'payment'); } - + paypal_message.setAttribute('data-pp-amount', paypal_data['message_amount']); paypal_message.setAttribute('data-pp-style-layout', paypal_data['message_layout']); - + if (paypal_data['message_layout'] == 'text') { paypal_message.setAttribute('data-pp-style-logo-type', paypal_data['message_logo_type']); paypal_message.setAttribute('data-pp-style-logo-position', paypal_data['message_logo_position']); @@ -524,16 +530,16 @@ var PayPalAPI = (function () { paypal_message.setAttribute('data-pp-style-color', paypal_data['message_flex_color']); paypal_message.setAttribute('data-pp-style-ratio', paypal_data['message_flex_ratio']); } - + document.querySelector('#paypal_message_container').appendChild(paypal_message); - + $('#paypal_message_container').removeClass('paypal-spinner'); - + if (paypal_data['page_code'] == 'product') { - $('[name^="option"], [name="quantity"]').on('change', function(event) { - setTimeout(async function() { + $('[name^="option"], [name="quantity"]').on('change', function (event) { + setTimeout(async function () { await updatePayPalData(); - + if (paypal_message) { paypal_message.setAttribute('data-pp-amount', paypal_data['message_amount']); } @@ -541,10 +547,10 @@ var PayPalAPI = (function () { }); } } - + if (paypal_data['components'].includes('fastlane') && ($('#fastlane_watermark').length || $('#fastlane_card').length)) { $('#fastlane_card').css('text-align', paypal_data['fastlane_card_align']); - + if (paypal_data['fastlane_card_width']) { $('#fastlane_card_container').css('display', 'inline-block'); $('#fastlane_card_container').css('width', paypal_data['fastlane_card_width']); @@ -552,44 +558,44 @@ var PayPalAPI = (function () { $('#fastlane_card_container').css('display', 'block'); $('#fastlane_card_container').css('width', 'auto'); } - + $('#fastlane_card_container').removeClass('paypal-spinner'); - + initFastlaneSDK().catch(console.log); } - + if (paypal_callback && typeof paypal_callback == 'function') { paypal_callback(); } }; - - var initFastlaneSDK = async function() { + + var initFastlaneSDK = async function () { var fastlane = await PayPalSDK.Fastlane({}); - - var {identity, profile, FastlanePaymentComponent, FastlaneCardComponent, FastlaneWatermarkComponent} = fastlane; + + var { identity, profile, FastlanePaymentComponent, FastlaneCardComponent, FastlaneWatermarkComponent } = fastlane; window.localStorage.setItem('fastlaneEnv', 'sandbox'); fastlane.setLocale(paypal_data['locale']); - + var shippingAddress = false; var billingAddress = false; var fastlaneCardComponent = false; var fastlanePaymentComponent = false; var fastlaneWatermarkComponent = false; var fastlaneTime = false; - - fastlaneWatermarkComponent = await FastlaneWatermarkComponent({includeAdditionalInfo: true}); - + + fastlaneWatermarkComponent = await FastlaneWatermarkComponent({ includeAdditionalInfo: true }); + fastlaneWatermarkComponent.render('#fastlane_watermark_container'); - + if ($('#fastlane_card_form_container').length && !$('#fastlane_card_form_container').html()) { var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'getFastlaneData'); - + shippingAddress = json['shipping_address']; billingAddress = json['billing_address']; cardholderName = json['cardholder_name']; - + var options = { styles: { root: { @@ -597,29 +603,29 @@ var PayPalAPI = (function () { } } }; - - fastlaneCardComponent = await FastlaneCardComponent({options, shippingAddress}); - + + fastlaneCardComponent = await FastlaneCardComponent({ options, shippingAddress }); + fastlaneCardComponent.render('#fastlane_card_form_container'); } - - $('#form-register input[name=\'email\']').on('focusout', async function(event) { + + $('#form-register input[name=\'email\']').on('focusout', async function (event) { if ($(document).find('input[name=\'account\']:checked').val() == '0') { var email = $('#form-register input[name=\'email\']').val(); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlaneCustomer', {'email': email}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlaneCustomer', { 'email': email }); + if (json['success']) { - var {customerContextId} = await identity.lookupCustomerByEmail(email); - - var renderFastlaneMemberExperience = false; + var { customerContextId } = await identity.lookupCustomerByEmail(email); + + var renderFastlaneMemberExperience = false; var authenticationState = false; var profileData = new Object(); - + if (customerContextId) { - var {authenticationState, profileData} = await identity.triggerAuthenticationFlow(customerContextId); + var { authenticationState, profileData } = await identity.triggerAuthenticationFlow(customerContextId); } - + if (authenticationState === 'succeeded') { var options = { styles: { @@ -628,59 +634,59 @@ var PayPalAPI = (function () { } } }; - - fastlanePaymentComponent = await FastlanePaymentComponent({options, shippingAddress}); - + + fastlanePaymentComponent = await FastlanePaymentComponent({ options, shippingAddress }); + $('#fastlane_modal').remove(); - + $('body').append(''); - - $('#fastlane_modal').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlaneModal #fastlane_modal >', function() { + + $('#fastlane_modal').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlaneModal #fastlane_modal >', function () { if ($('#fastlane_modal #fastlane_collapse_shipping').length) { - $('#fastlane_modal #fastlane_collapse_shipping .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlaneShipping', {'authentication_state': authenticationState, 'profile_data': profileData}, function() { + $('#fastlane_modal #fastlane_collapse_shipping .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlaneShipping', { 'authentication_state': authenticationState, 'profile_data': profileData }, function () { var accordion_title = $('#fastlane_modal #fastlane_collapse_shipping').parent().find('.accordion-header .accordion-title'); - + accordion_title.html(''); $('.accordion-button[data-bs-target=\'#fastlane_collapse_shipping\']').trigger('click'); }); } else { - $('#fastlane_modal #fastlane_collapse_payment .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlanePayment', function() { + $('#fastlane_modal #fastlane_collapse_payment .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlanePayment', function () { var accordion_title = $('#fastlane_modal #fastlane_collapse_payment').parent().find('.accordion-header .accordion-title'); - + accordion_title.html(''); $('.accordion-button[data-bs-target=\'#fastlane_collapse_payment\']').trigger('click'); - + fastlanePaymentComponent.render('#fastlane_payment_container'); }); } - + $('#fastlane_modal').modal('show'); }); - } + } } } }); - - $(document).delegate('#fastlane_collapse_shipping .button-edit', 'click', async function(event) { + + $(document).delegate('#fastlane_collapse_shipping .button-edit', 'click', async function (event) { event.preventDefault(); - - var {selectedAddress, selectionChanged} = await profile.showShippingAddressSelector(); + + var { selectedAddress, selectionChanged } = await profile.showShippingAddressSelector(); if (selectionChanged) { - $('#fastlane_modal #fastlane_collapse_shipping .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlaneShipping', {'authentication_state': 'succeeded', 'profile_data': {'shippingAddress': selectedAddress}}); + $('#fastlane_modal #fastlane_collapse_shipping .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlaneShipping', { 'authentication_state': 'succeeded', 'profile_data': { 'shippingAddress': selectedAddress } }); } - }) - - $(document).delegate('#fastlane_collapse_shipping .button-confirm', 'click', async function(event) { - event.preventDefault(); - + }) + + $(document).delegate('#fastlane_collapse_shipping .button-confirm', 'click', async function (event) { + event.preventDefault(); + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlaneShipping', $('#fastlane_collapse_shipping form').serialize()); - + if (json['success']) { shippingAddress = json['shipping_address']; - + var options = { styles: { root: { @@ -688,30 +694,30 @@ var PayPalAPI = (function () { } } }; - - fastlanePaymentComponent = await FastlanePaymentComponent({options, shippingAddress}); - - $('#fastlane_modal #fastlane_collapse_payment .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlanePayment', function() { + + fastlanePaymentComponent = await FastlanePaymentComponent({ options, shippingAddress }); + + $('#fastlane_modal #fastlane_collapse_payment .accordion-body').load('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'fastlanePayment', function () { var accordion_title = $('#fastlane_modal #fastlane_collapse_payment').parent().find('.accordion-header .accordion-title'); - + accordion_title.html(''); $('.accordion-button[data-bs-target=\'#fastlane_collapse_payment\']').trigger('click'); - + fastlanePaymentComponent.render('#fastlane_payment_container'); }); } }); - - $(document).delegate('#fastlane_collapse_payment .button-confirm', 'click', async function(event) { + + $(document).delegate('#fastlane_collapse_payment .button-confirm', 'click', async function (event) { try { - var {id, paymentSource} = await fastlanePaymentComponent.getPaymentToken(); - + var { id, paymentSource } = await fastlanePaymentComponent.getPaymentToken(); + $('#fastlane_card_container').addClass('paypal-spinner'); $('#fastlane_card_button').prop('disabled', true).button('loading'); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlanePayment', {'page_code': paypal_data['page_code'], 'payment_token': id, 'payment_source': paymentSource}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlanePayment', { 'page_code': paypal_data['page_code'], 'payment_token': id, 'payment_source': paymentSource }); + if (json['url']) { location = json['url']; } else { @@ -720,27 +726,27 @@ var PayPalAPI = (function () { } } catch (error) { console.error(error); - + if (error.message == 'FastlaneCardComponent getPaymentToken received invalid billing address') { - showPayPalAlert({'error': {'warning': paypal_data['error_fastlane_billing_address']}}); + showPayPalAlert({ 'error': { 'warning': paypal_data['error_fastlane_billing_address'] } }); } } }); - - $(document).delegate('#paypal_form #fastlane_card_button', 'click', async function(event) { + + $(document).delegate('#paypal_form #fastlane_card_button', 'click', async function (event) { var options = { billingAddress: billingAddress, cardholderName: cardholderName }; - - try { - var {id} = await fastlaneCardComponent.getPaymentToken(options); - + + try { + var { id } = await fastlaneCardComponent.getPaymentToken(options); + $('#fastlane_card_container').addClass('paypal-spinner'); $('#fastlane_card_button').prop('disabled', true).button('loading'); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlanePayment', {'page_code': paypal_data['page_code'], 'payment_token': id}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'confirmFastlanePayment', { 'page_code': paypal_data['page_code'], 'payment_token': id }); + if (json['url']) { location = json['url']; } else { @@ -749,69 +755,69 @@ var PayPalAPI = (function () { } } catch (error) { console.error(error); - + if (error.message == 'FastlaneCardComponent getPaymentToken received invalid billing address') { - showPayPalAlert({'error': {'warning': paypal_data['error_fastlane_billing_address']}}); + showPayPalAlert({ 'error': { 'warning': paypal_data['error_fastlane_billing_address'] } }); } } }); }; - - var initGooglePaySDK = async function() { - const {allowedPaymentMethods, merchantInfo, apiVersion, apiVersionMinor, countryCode} = await PayPalSDK.Googlepay().config(); - + + var initGooglePaySDK = async function () { + const { allowedPaymentMethods, merchantInfo, apiVersion, apiVersionMinor, countryCode } = await PayPalSDK.Googlepay().config(); + const paymentsClient = new google.payments.api.PaymentsClient({ environment: paypal_data['googlepay_environment'], paymentDataCallbacks: { - onPaymentAuthorized: function(paymentData) { - return new Promise(async function(resolve, reject) { + onPaymentAuthorized: function (paymentData) { + return new Promise(async function (resolve, reject) { try { paypal_order_id = false; product_data = false; - + if (paypal_data['page_code'] == 'product') { product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); } - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'product': product_data}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'product': product_data }); + showPayPalAlert(json); - + paypal_order_id = json['paypal_order_id']; - + paymentData.paymentMethodData.info.billingAddress.phoneNumber = paymentData.paymentMethodData.info.billingAddress.phoneNumber.replace('+', ''); - + const confirmOrderResponse = await PayPalSDK.Googlepay().confirmOrder({ orderId: paypal_order_id, paymentMethodData: paymentData.paymentMethodData }); - + if (confirmOrderResponse.status === 'PAYER_ACTION_REQUIRED') { console.log('Confirm Payment Completed Payer Action Required'); - - PayPalSDK.Googlepay().initiatePayerAction({orderId: paypal_order_id}).then(async () => { - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(paymentData)}); - + + PayPalSDK.Googlepay().initiatePayerAction({ orderId: paypal_order_id }).then(async () => { + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(paymentData) }); + showPayPalAlert(json); - + if (json['url']) { location = json['url']; } }); - - resolve({transactionState: 'SUCCESS'}); + + resolve({ transactionState: 'SUCCESS' }); } else if (confirmOrderResponse.status === 'APPROVED') { console.log('Confirm Payment Approved'); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(paymentData)}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'googlepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(paymentData) }); + showPayPalAlert(json); - + if (json['url']) { location = json['url']; } - - resolve({transactionState: 'SUCCESS'}); + + resolve({ transactionState: 'SUCCESS' }); } else { resolve({ transactionState: 'ERROR', @@ -834,13 +840,13 @@ var PayPalAPI = (function () { } } }); - - paymentsClient.isReadyToPay({allowedPaymentMethods, apiVersion, apiVersionMinor}).then(function(response) { - if (response.result) { + + paymentsClient.isReadyToPay({ allowedPaymentMethods, apiVersion, apiVersionMinor }).then(function (response) { + if (response.result) { $('#googlepay_button').css('text-align', paypal_data['googlepay_button_align']); - + var googlepay_button_style = []; - + if (paypal_data['googlepay_button_width']) { googlepay_button_style.push('display: inline-block'); googlepay_button_style.push('width: ' + paypal_data['googlepay_button_width']); @@ -848,11 +854,11 @@ var PayPalAPI = (function () { googlepay_button_style.push('display: block'); googlepay_button_style.push('width: auto'); } - + googlepay_button_style.push('aspect-ratio: 7.5'); - + $('#googlepay_button_container').attr('style', googlepay_button_style.join('; ')); - + if (paypal_data['googlepay_button_shape'] == 'pill') { $('#googlepay_button_container').removeClass('shape-rect'); $('#googlepay_button_container').addClass('shape-pill'); @@ -860,19 +866,19 @@ var PayPalAPI = (function () { $('#googlepay_button_container').removeClass('shape-pill'); $('#googlepay_button_container').addClass('shape-rect'); } - + const googlepay_button = paymentsClient.createButton({ buttonColor: paypal_data['googlepay_button_color'], buttonType: paypal_data['googlepay_button_type'], buttonLocale: paypal_data['locale'].split('_')[0], buttonSizeMode: 'fill', - onClick: function() { - const paymentDataRequest = Object.assign({}, {apiVersion, apiVersionMinor}); - + onClick: function () { + const paymentDataRequest = Object.assign({}, { apiVersion, apiVersionMinor }); + allowedPaymentMethods[0].parameters.billingAddressParameters.phoneNumberRequired = true; - + paymentDataRequest.allowedPaymentMethods = allowedPaymentMethods; - + paymentDataRequest.transactionInfo = { countryCode: countryCode, currencyCode: paypal_data['currency_code'], @@ -880,24 +886,24 @@ var PayPalAPI = (function () { totalPrice: paypal_data['googlepay_amount'], totalPriceLabel: 'Total' } - + paymentDataRequest.merchantInfo = merchantInfo; paymentDataRequest.callbackIntents = ['PAYMENT_AUTHORIZATION']; paymentDataRequest.emailRequired = true; paymentDataRequest.shippingAddressRequired = true; - + paymentsClient.loadPaymentData(paymentDataRequest); } }); - + document.querySelector('#googlepay_button_container').appendChild(googlepay_button); } - }).catch(function(error) { + }).catch(function (error) { console.log(error); }); }; - - var initApplePaySDK = async function() { + + var initApplePaySDK = async function () { const ApplePaySDK = PayPalSDK.Applepay(); const { isEligible, @@ -909,14 +915,14 @@ var PayPalAPI = (function () { if (!isEligible) { $('#applepay_button').remove(); - + throw 'Apple Pay is not eligible'; } - + $('#applepay_button').css('text-align', paypal_data['applepay_button_align']); - + var applepay_button_style = []; - + if (paypal_data['applepay_button_width']) { $('#applepay_button_container').css('display', 'inline-block'); $('#applepay_button_container').css('width', paypal_data['applepay_button_width']); @@ -924,39 +930,39 @@ var PayPalAPI = (function () { $('#applepay_button_container').css('display', 'block'); $('#applepay_button_container').css('width', 'auto'); } - + var applepay_button = document.createElement('apple-pay-button'); - + applepay_button.setAttribute('id', 'apple-pay-button'); applepay_button.setAttribute('buttonstyle', paypal_data['applepay_button_color']); applepay_button.setAttribute('type', paypal_data['applepay_button_type']); applepay_button.setAttribute('locale', paypal_data['locale']); - + var applepay_button_style = []; - + applepay_button_style.push('display: inline-block'); - + if (paypal_data['applepay_button_width']) { applepay_button_style.push('--apple-pay-button-width: ' + paypal_data['applepay_button_width']); } else { applepay_button_style.push('--apple-pay-button-width: 100%'); } - + applepay_button_style.push('--apple-pay-button-height: calc(var(--apple-pay-button-width) / 7.5)'); - + if (paypal_data['applepay_button_shape'] == 'pill') { applepay_button_style.push('--apple-pay-button-border-radius: 1000px'); } else { applepay_button_style.push('--apple-pay-button-border-radius: 4px'); } - + applepay_button.setAttribute('style', applepay_button_style.join('; ')); - + document.querySelector('#applepay_button_container').appendChild(applepay_button); - applepay_button.addEventListener('click', async function(event) { + applepay_button.addEventListener('click', async function (event) { event.preventDefault(); - + const paymentRequest = { countryCode, currencyCode: paypal_data['currency_code'], @@ -970,21 +976,21 @@ var PayPalAPI = (function () { type: 'final', } }; - + var session = new ApplePaySession(4, paymentRequest); - + session.onvalidatemerchant = (event) => { ApplePaySDK.validateMerchant({ validationUrl: event.validationURL, }).then((payload) => { session.completeMerchantValidation(payload.merchantSession); - console.log('Complete Merchant validation Done!', {payload}); + console.log('Complete Merchant validation Done!', { payload }); }).catch((error) => { console.error(error); session.abort(); }); }; - + session.onpaymentmethodselected = (event) => { console.log('onpaymentmethodselected'); console.log(event.paymentMethod); // {type: "credit"} @@ -993,78 +999,78 @@ var PayPalAPI = (function () { newTotal: paymentRequest.total }); }; - + session.onshippingcontactselected = async (event) => { console.log('Your shipping contacts selected is: ' + event.shippingContact); - - const shippingContactUpdate = { + + const shippingContactUpdate = { newTotal: paymentRequest.total, newLineItems: [] }; - + session.completeShippingContactSelection(shippingContactUpdate); }; - + session.onshippingmethodselected = (event) => { console.log('onshippingmethodselected'); console.log(JSON.stringify(event.shippingMethod, null, 4)); console.log('Your shipping method selected is: ', event.shippingMethod); - - var shippingMethodUpdate = { + + var shippingMethodUpdate = { newTotal: paymentRequest.total, newLineItems: [] - }; - + }; + session.completeShippingMethodSelection(shippingMethodUpdate); }; - + session.onpaymentauthorized = async (event) => { try { console.log('onpaymentauthorized'); console.log(JSON.stringify(event, null, 4)); - + paypal_order_id = false; product_data = false; - + if (paypal_data['page_code'] == 'product') { product_data = $('#product input[type=\'text\'], #product input[type=\'hidden\'], #product input[type=\'radio\']:checked, #product input[type=\'checkbox\']:checked, #product select, #product textarea').serialize(); } - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'applepay_button', 'product': product_data}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'createOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'applepay_button', 'product': product_data }); + showPayPalAlert(json); - + paypal_order_id = json['paypal_order_id']; - + event.payment.shippingContact.phoneNumber = event.payment.shippingContact.phoneNumber.replace('+', ''); - + await ApplePaySDK.confirmOrder({ - orderId: paypal_order_id, - token: event.payment.token, - billingContact: event.payment.billingContact, - shippingContact: event.payment.shippingContact + orderId: paypal_order_id, + token: event.payment.token, + billingContact: event.payment.billingContact, + shippingContact: event.payment.shippingContact }); - - var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', {'page_code': paypal_data['page_code'], 'payment_type': 'applepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(event.payment)}); - + + var json = await requestPayPalData('index.php?route=extension/paypal/payment/paypal' + paypal_data['separator'] + 'approveOrder', { 'page_code': paypal_data['page_code'], 'payment_type': 'applepay_button', 'paypal_order_id': paypal_order_id, 'payment_data': JSON.stringify(event.payment) }); + showPayPalAlert(json); - + if (json['url']) { location = json['url']; } - + session.completePayment({ status: window.ApplePaySession.STATUS_SUCCESS }); } catch (error) { console.error(error); - + session.completePayment({ status: window.ApplePaySession.STATUS_FAILURE }); } }; - + session.oncancel = (event) => { console.log(event); console.log('Apple Pay Cancelled!'); @@ -1072,18 +1078,18 @@ var PayPalAPI = (function () { session.begin(); }); - + $('#applepay_button_container').removeClass('paypal-spinner'); }; - - var init = async function(callback = '') { + + var init = async function (callback = '') { await updatePayPalData(); - + paypal_callback = callback; - + loadPayPalSDK(); }; - + return { init: init };