1(function ($) { 2 3 class PayLaterMessages { 4 constructor(stripe) { 5 6 7 this.init_stripe(stripe); 8 this.events(); 9 10 } 11 12 init_stripe(stripe) { 13 let body = $('body'); 14 let font_family = body.css('font-family'); 15 let color = body.css('color'); 16 let font_weight = body.css('font-weight'); 17 let loop_product_title = $('.woocommerce-loop-product__title'); 18 let single_product_title = $('.product_title'); 19 if (loop_product_title.length > 0) { 20 font_family = loop_product_title.css('font-family'); 21 color = loop_product_title.css('color'); 22 font_weight = loop_product_title.css('font-weight'); 23 } else if (single_product_title.length > 0) { 24 font_family = single_product_title.css('font-family'); 25 color = single_product_title.css('color'); 26 font_weight = single_product_title.css('font-weight'); 27 } 28 let font_size = '14px'; 29 let appearance = { 30 variables: { 31 colorText: color, 32 colorTextSecondary: 'rgb(28, 198, 255)', // "Learn more" text color 33 fontSizeBase: font_size, 34 fontSizeSm: font_size, 35 fontSizeXs: font_size, 36 fontSize2Xs: font_size, 37 fontWeightMedium: font_weight, 38 fontFamily: font_family, 39 } 40 }; 41 42 if (fkwcs_paylater.appearance && typeof fkwcs_paylater.appearance === 'object') { 43 for (let i in fkwcs_paylater.appearance) { 44 if (fkwcs_paylater.appearance.hasOwnProperty(i)) { 45 appearance[i] = fkwcs_paylater.appearance[i]; 46 } 47 } 48 } else { 49 console.log('Invalid appearance object:', fkwcs_paylater.appearance); 50 } 51 52 53 this.elements = stripe.elements({appearance}); 54 } 55 56 events() { 57 58 try { 59 60 let self = this; 61 if (document.readyState === 'complete' || document.readyState === 'loading') { 62 $(document).ready(function () { 63 self.attachEvents(); 64 }); 65 } else { 66 $(window).on('load', function () { 67 self.attachEvents(); 68 }); 69 } 70 71 72 } catch (e) { 73 74 } 75 } 76 77 attachEvents() { 78 /** 79 * Align with the jQuery build WooCommerce is using. 80 * 81 * This file captures the jQuery that exists when it executes. If a theme or plugin loads a 82 * second jQuery build later (a raw code.jquery.com tag is the usual case), WooCommerce's 83 * footer scripts capture that later build instead. jQuery keeps event handlers per build, 84 * so updated_checkout, checkout_place_order_* and our own submit triggers would never cross 85 * between the two. By DOM ready every synchronous script has run, so the global is the build 86 * WooCommerce has. Adopt it, but only when blockUI is attached to that build: WooCommerce's 87 * frontend scripts cannot run without it, so its presence proves WooCommerce lives there. If 88 * a rogue build loads after WooCommerce's scripts instead, blockUI is missing on it and we 89 * stay put. On a normal page the condition is false and nothing changes. 90 */ 91 if (window.jQuery && window.jQuery !== $ && window.jQuery.fn && typeof window.jQuery.fn.on === 'function' && typeof window.jQuery.fn.block === 'function') { 92 $ = window.jQuery; 93 } 94 95 $('body').on('updated_wc_div', () => { 96 this.cartPage(); 97 }); 98 $('body').on('fkwcs_express_button_init', () => { 99 100 this.fkcartMiniCart(); 101 }); 102 // Dedicated hook so the FunnelKit slide cart can refresh ONLY the drawer BNPL messaging 103 $('body').on('fkcart_paylater_refresh', () => { 104 this.fkcartMiniCart(); 105 }); 106 this.singleProduct(); 107 this.cartPage(); 108 this.archiveProduct(); 109 } 110
111 createMessage(amount, methods, selector) { 112 try { 113 if (!Array.isArray(methods) || methods.length === 0) { 114 $(selector).hide(); 115 return; 116 } 117 let supported_currency = ["USD", "GBP", "EUR", "DKK", "NOK", "SEK", "CAD", "AUD"]; 118 let supported_countries = ["US", "CA", "AU", "NZ", "GB", "IE", "FR", "ES", "DE", "AT", "BE", "DK", "FI", "IT", "NL", "NO", "SE", "GR"]; 119 120 let currency = fkwcs_paylater.currency.toUpperCase(); 121 if (supported_currency.indexOf(currency) < 0 || supported_countries.indexOf(fkwcs_paylater.country_code) < 0) { 122 return; 123 } 124 let element = this.elements.create('paymentMethodMessaging', { 125 amount: amount, 126 currency: currency, 127 paymentMethodTypes: methods, 128 countryCode: fkwcs_paylater.country_code, 129 }); 130 131 //klarna modal z-index was too less that fkcart modal so we are setting it to 2147483646 to make it compatible 132 let fkcartModal = $('#fkcart-modal'); 133 if (fkcartModal.length > 0) { 134 fkcartModal.css('z-index', '2147483646'); 135 } 136 137 element.mount(selector); 138 $(selector).show(); 139 } catch (Exception) { 140 console.log('Exception', Exception); 141 $(selector).hide(); 142 } 143 144 } 145 146 singleProduct() { 147 148 if (!('yes' === fkwcs_paylater.is_product_page || '1' === fkwcs_paylater.is_product_page)) { 149 return; 150 } 151 let single_div = $('.fkwcs_paylater_messaging.fkwcs_single_product'); 152 if (single_div.length === 0) { 153 return; 154 } 155 let paylater_data = JSON.parse(single_div.attr('paylater-data')); 156 let variation_form = $('.variations_form.cart'); 157 let is_variable_type = variation_form.length > 0; 158 if (is_variable_type) { 159 variation_form.on('found_variation', (e, variation) => { 160 this.createMessage(variation.fkwcs_stripe_amount, fkwcs_paylater.paylater_messaging.single, '.fkwcs_paylater_messaging.fkwcs_single_product'); 161 single_div.show(); 162 }); 163 variation_form.on('reset_data', () => { 164 single_div.hide(); 165 }); 166 } else { 167 this.createMessage(paylater_data.amount, fkwcs_paylater.paylater_messaging.single, '.fkwcs_paylater_messaging.fkwcs_single_product'); 168 } 169 170 171 } 172 173 174 cartPage() { 175 if (!('yes' === fkwcs_paylater.is_cart || '1' === fkwcs_paylater.is_cart)) { 176 return; 177 } 178 let single_div = $('.fkwcs_paylater_messaging.fkwcs_cart_page'); 179 if (single_div.length === 0) { 180 return; 181 } 182 let paylater_data = JSON.parse(single_div.attr('paylater-data')); 183 this.createMessage(paylater_data.amount, fkwcs_paylater.paylater_messaging.cart, '.fkwcs_paylater_messaging.fkwcs_cart_page'); 184 } 185 186 fkcartMiniCart() { 187 let single_div = $('.fkwcs_paylater_messaging.fkwcs_fkcart_drawer'); 188 if (single_div.length === 0) { 189 return; 190 } 191 let paylater_data = JSON.parse(single_div.attr('paylater-data')); 192 this.createMessage(paylater_data.amount, fkwcs_paylater.paylater_messaging.cart, '.fkwcs_paylater_messaging.fkwcs_fkcart_drawer'); 193 } 194 195 archiveProduct() { 196 let archive_pro = $('.fkwcs_shop_page'); 197 if (archive_pro.length === 0) { 198 return; 199 } 200 let self = this; 201 archive_pro.each(function () { 202 let product_id = $(this).attr('paylater-product-id'); 203 let paylater_data = JSON.parse($(this).attr('paylater-data')); 204 self.createMessage(paylater_data.amount, fkwcs_paylater.paylater_messaging.shop, `.fkwcs_shop_pro_${product_id}`); 205 }); 206 } 207 208 } 209 210 211 /** 212 * One Stripe instance per publishable key, shared by every FunnelKit script on the page. 213 * 214 * stripe-elements.js, express-checkout.js and paylater.js each used to call Stripe() 215 * separately, so a checkout page could carry three instances. Each opens its own 216 * connection and iframes, refetches shared.js, and keeps its own Link/wallet state. 217 * Keyed by publishable key, since paylater does not pass it through the 218 * fkwcs_api_client_public_key filter and could in theory differ. Defined defensively so 219 * whichever script loads first creates it. 220 */ 221 window.fkwcsGetStripe = window.fkwcsGetStripe || function (pubKey, options) { 222 window.fkwcsStripeInstances = window.fkwcsStripeInstances || {}; 223 224 if (!window.fkwcsStripeInstances[pubKey]) { 225 window.fkwcsStripeInstances[pubKey] = Stripe(pubKey, options); 226 } 227 228 return window.fkwcsStripeInstances[pubKey]; 229 }; 230 231 function init_bnpl_messages() { 232 const pubKey = fkwcs_paylater.pub_key; 233 const mode = fkwcs_paylater.mode; 234 if ('' === pubKey) { 235 console.log('Live Payment Mode only work only https protocol '); 236 return; 237 } 238 try { 239 const stripe = window.fkwcsGetStripe(pubKey, {locale: fkwcs_paylater.locale}); 240 new PayLaterMessages(stripe); 241 242 } catch (e) { 243 console.log(e); 244 } 245 246 } 247 248 init_bnpl_messages(); 249})(jQuery)
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.