/* global console, Klarna */ jQuery( function($) { 'use strict'; var klarna_payments = { authorization_response: {}, iframe_loaded: false, show_form: false, klarna_container_selector: '#klarna_container_2', checkout_values: {}, check_changes: function() { $('.woocommerce-billing-fields input, .woocommerce-billing-fields select, .woocommerce-shipping-fields input, .woocommerce-shipping-fields select').each(function() { var fieldName = $(this).attr('name'); var fieldValue = $(this).val(); if ( klarna_payments.checkout_values[ fieldName ] !== fieldValue ) { klarna_payments.checkout_values[ fieldName ] = fieldValue; $(this).trigger('change'); } }); }, debounce_changes: function(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }, start: function() { // Add page visibility listener to handle tab changes. klarna_payments.page_visibility_listener(); // Store all billing and shipping values. $(document).ready(function() { $('#customer_details input, #customer_details select').each(function() { var fieldName = $(this).attr('name'); var fieldValue = $(this).val(); klarna_payments.checkout_values[ fieldName ] = fieldValue; }); }); /** * When WooCommerce updates checkout * Happens on initial page load, country, state and postal code changes */ $('body').on('updated_checkout', function() { // Unblock the payments element if blocked var blocked_el = $('.woocommerce-checkout-payment'); var blocked_el_data = blocked_el.data(); if (blocked_el.length && 1 === blocked_el_data['blockUI.isBlocked']) { blocked_el.unblock(); } // If Klarna Payments is selected and iframe is not loaded yet, disable the form. if (klarna_payments.isKlarnaPaymentsSelected()) { //$('#place_order').attr('disabled', true); klarna_payments.load().then(klarna_payments.loadHandler); } // Check if we need to hide the shipping fields klarna_payments.maybeHideShippingAddress(); }); /** * Clear auth token if there's checkout error. */ $( document.body ).on( 'checkout_error', function() { $('input[name="klarna_payments_authorization_token"]').remove(); }); /** * When any of the checkout form fields changes, if Klarna Payments is the selected option. */ $('form.checkout').on('change', '.woocommerce-billing-fields input, .woocommerce-billing-fields select', function() { // Make sure all WC required fields are populated. if (!klarna_payments.check_required_fields()) { //$('#place_order').attr('disabled', true); } else { $('#place_order').attr('disabled', false); } }); /** * Phone field changes. Has to be 5 characters or longer for KP to work. */ $('form.checkout').on('keyup', '#billing_phone', klarna_payments.debounce_changes(function() { if (klarna_payments.isKlarnaPaymentsSelected()) { //$('#place_order').attr('disabled', true); if ($(this).val().length > 4) { klarna_payments.load().then(klarna_payments.loadHandler); } } }, 750)); /** * Email field changes, check if WooCommerce says field is valid. */ $('form.checkout').on('keyup', '#billing_email', klarna_payments.debounce_changes(function() { if (klarna_payments.isKlarnaPaymentsSelected()) { //$('#place_order').attr('disabled', true); if (!$(this).parent().hasClass('woocommerce-invalid')) { klarna_payments.load().then(klarna_payments.loadHandler); } } }, 750)); /** * Billing company field changes. */ $('form.checkout').on('keyup', '#billing_company', klarna_payments.debounce_changes(function() { if (klarna_payments.isKlarnaPaymentsSelected()) { $('#place_order').attr('disabled', true); klarna_payments.load().then(klarna_payments.loadHandler); } }, 750)); /** * When changing payment method. */ $('form.checkout').on('change', 'input[name="payment_method"]', function() { // If Klarna Payments is selected and iframe is not loaded yet, disable the form. Also collapse any unselected Klarna Payments gateways. if (klarna_payments.isKlarnaPaymentsSelected()) { //$('#place_order').attr('disabled', true); klarna_payments.load().then(klarna_payments.loadHandler); klarna_payments.collapseGateways(); } // Enable the form if any other payment method is selected. if (!klarna_payments.isKlarnaPaymentsSelected()) { $('#place_order').attr('disabled', false); } // Check if we need to hide the shipping fields klarna_payments.maybeHideShippingAddress(); }); /** * Do this every 100ms in case browser auto-fill changes form fields. */ var checkFormInterval = setInterval(function () { if (klarna_payments.show_form) { clearInterval(checkFormInterval); } if (klarna_payments.isKlarnaPaymentsSelected()) { klarna_payments.check_changes(); } }, 200); /** * Hooking into WooCommerce. * * Firing Klarna.Credit.authorize(), then once it resolves, adding the hidden form field and re-submitting the form. */ $('form.checkout').on('checkout_place_order', function() { if (!klarna_payments.isKlarnaPaymentsSelected()) { return true; } if ($('input[name="klarna_payments_authorization_token"]').length) { return true; } var required_fields_set = true; var failed_fields = []; $('.validate-required').find('input').each(function( nr, field ) { if( $(field).attr('type') !== 'hidden' && $(field).attr('id').indexOf( 'shipping' ) < 0 && $(field).attr('id').indexOf( 'account' ) < 0 ) { if( $(field).is(':checkbox') ) { if( $(field).is(":checked") !== true ) { required_fields_set = false; failed_fields.push( $(field).attr('id') ); $(field).parents('p.form-row').addClass( 'woocommerce-invalid' ); } } else if( $(field).val() === '' && $(field).parents('#payment').length < 0 ) { required_fields_set = false; failed_fields.push( $(field).attr('id') ); $(field).parents('p.form-row').addClass( 'woocommerce-invalid' ); } } }); if( required_fields_set ) { klarna_payments.authorize().done( function(response) { if ('authorization_token' in response) { $('input[name="klarna_payments_authorization_token"]').remove(); $('form.checkout').append('').submit(); } if (false === response.show_form) { // Hide Klarna Payments (for now, do not do this). /* $('li.payment_method_klarna_payments input[type="radio"]').attr('disabled', true) $('li.payment_method_klarna_payments').hide() */ } }); } else { $('ul.woocommerce-error').remove(); $('form.checkout').prepend( '' ); var checkbox = false; $.each( failed_fields, function( key, value ) { if( $( '#' + value ).is(':checkbox') && checkbox === false ) { checkbox = true; $('ul.woocommerce-error').append( '
  • ' + klarna_payments_params.failed_checkbox_validation_text + '
  • ' ); } else if( ! $( '#' + value ).is(':checkbox' ) ) { var field_name = $( '#' + value ).attr( 'name' ); var field_label = $('label[for="' + field_name +'"]').text().replace( '*', '' ); $('ul.woocommerce-error').append( '
  • ' + field_label + '' + klarna_payments_params.failed_field_validation_text + '
  • ' ); } }); var etop = $('form.checkout').offset().top; $('html, body').animate({ scrollTop: etop }, 1000); } return false; }); }, load: function() { var klarna_payments_container_selector_id = '#' + klarna_payments.getSelectorContainerID(); console.log(klarna_payments_container_selector_id); if (klarna_payments_container_selector_id) { var $defer = $.Deferred(); var klarnaLoadedInterval = setInterval(function () { var Klarna = false; try { Klarna = window.Klarna; } catch (e) { console.debug(e); } if (Klarna && Klarna.Credit) { clearInterval(klarnaLoadedInterval); clearTimeout(klarnaLoadedTimeout); var options = { container: klarna_payments_container_selector_id, payment_method_category: klarna_payments.getSelectedPaymentCategory() }; if ( 'US' === $('#billing_country').val() ) { var address = klarna_payments.get_address(); Klarna.Credit.load( options, address, function (response) { $defer.resolve(response); } ); } else { Klarna.Credit.load( options, function (response) { $defer.resolve(response); } ); } } }, 100); var klarnaLoadedTimeout = setTimeout(function () { clearInterval(klarnaLoadedInterval); $defer.reject(); }, 3000); return $defer.promise(); } }, loadHandler: function(response) { klarna_payments.iframe_loaded = true; if (response.show_form) { klarna_payments.show_form = true; if ( klarna_payments.check_required_fields() ) { $('#place_order').attr('disabled', false); } } }, isKlarnaPaymentsSelected: function () { if ($('input[name="payment_method"]:checked').length) { var selected_value = $('input[name="payment_method"]:checked').val(); return selected_value.indexOf('klarna_payments') !== -1; } return false; }, setRadioButtonValues: function () { $('input[name="payment_method"]').each( function( ) { if( $(this).val().indexOf( 'klarna_payments' ) !== -1 ) { $(this).val( 'klarna_payments' ); } }); }, getSelectorContainerID: function() { return $('input[name="payment_method"]:checked').parent().find('.klarna_payments_container').attr('id'); }, getSelectedPaymentCategory: function() { var selected_category = $('input[name="payment_method"]:checked').parent().find('.klarna_payments_container').data('payment_method_category'); return selected_category.replace('klarna_payments_', ''); }, authorize: function() { var $defer = $.Deferred(); var address = klarna_payments.get_address(); klarna_payments.authorization_response = {}; try { Klarna.Credit.authorize( address, {payment_method_category: klarna_payments.getSelectedPaymentCategory()}, function (response) { klarna_payments.authorization_response = response; $defer.resolve(response); } ); } catch (e) { console.log(e); } return $defer.promise(); }, check_required_fields: function() { var input_value; var input_flag = false; if ( $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' ) ) { $('.woocommerce-billing-fields .validate-required[id^="billing"], .woocommerce-shipping-fields .validate-required[id^="shipping"]').each(function() { if ( $(this).find('select').length ) { input_value = $(this).find('select').val(); } else { input_value = $(this).find('input').val(); } if ('' === input_value || undefined === input_value) { input_flag = true; } }); } else { $('.woocommerce-billing-fields .validate-required[id^="billing"]').each(function() { if ( $(this).find('select').length ) { input_value = $(this).find('select').val(); } else { input_value = $(this).find('input').val(); } if ('' === input_value || undefined === input_value) { input_flag = true; } }); } if ( input_flag ) { klarna_payments.show_form = false; return false; } else { return true; } }, page_visibility_listener: function() { var hidden, visibilityChange; if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support hidden = 'hidden'; visibilityChange = 'visibilitychange'; } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden'; visibilityChange = 'msvisibilitychange'; } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden'; visibilityChange = 'webkitvisibilitychange'; } // Warn if the browser doesn't support addEventListener or the Page Visibility API if (typeof document.addEventListener === 'undefined' || typeof document[hidden] === 'undefined') { } else { // Handle page visibility change document.addEventListener(visibilityChange, handleVisibilityChange, false); } function handleVisibilityChange() { if (! document[hidden]) { if (klarna_payments.isKlarnaPaymentsSelected()) { //$('body').trigger('update_checkout'); } } } }, get_address: function() { var address = { billing_address: { given_name : $(klarna_payments_params.default_checkout_fields.billing_given_name).val(), family_name : $(klarna_payments_params.default_checkout_fields.billing_family_name).val(), email : $(klarna_payments_params.default_checkout_fields.billing_email).val(), phone : $(klarna_payments_params.default_checkout_fields.billing_phone).val(), country : $(klarna_payments_params.default_checkout_fields.billing_country).val(), region : $(klarna_payments_params.default_checkout_fields.billing_region).val(), postal_code : ( klarna_payments_params.remove_postcode_spaces === 'yes' ) ? $(klarna_payments_params.default_checkout_fields.billing_postal_code).val().replace(/\s/g, '') : $(klarna_payments_params.default_checkout_fields.billing_postal_code).val(), city : $(klarna_payments_params.default_checkout_fields.billing_city).val(), street_address : $(klarna_payments_params.default_checkout_fields.billing_street_address).val(), street_address2 : $(klarna_payments_params.default_checkout_fields.billing_street_address2).val(), organization_name : $(klarna_payments_params.default_checkout_fields.billing_company).val(), }, shipping_address: {} }; address.shipping_address = $.extend({}, address.billing_address); if ( $( '#ship-to-different-address' ).find( 'input' ).is( ':checked' ) ) { address.shipping_address.given_name = $(klarna_payments_params.default_checkout_fields.shipping_given_name).val(); address.shipping_address.family_name = $(klarna_payments_params.default_checkout_fields.shipping_family_name).val(); address.shipping_address.country = $(klarna_payments_params.default_checkout_fields.shipping_country).val(); address.shipping_address.region = $(klarna_payments_params.default_checkout_fields.shipping_region).val(); address.shipping_address.postal_code = ( klarna_payments_params.remove_postcode_spaces === 'yes' ) ? $(klarna_payments_params.default_checkout_fields.shipping_postal_code).val().replace(/\s/g, '') : $(klarna_payments_params.default_checkout_fields.shipping_postal_code).val(); address.shipping_address.city = $(klarna_payments_params.default_checkout_fields.shipping_city).val(); address.shipping_address.street_address = $(klarna_payments_params.default_checkout_fields.shipping_street_address).val(); address.shipping_address.street_address2 = $(klarna_payments_params.default_checkout_fields.shipping_street_address2).val(); } return address; }, collapseGateways: function() { $('input[name="payment_method"]').each( function() { if ( $(this).is( ':checked' ) ){ $(this).siblings("div.payment_box").show(); } else { $(this).siblings("div.payment_box").hide(); } }); }, maybeHideShippingAddress: function() { if( false !== klarna_payments.isKlarnaPaymentsSelected() ) { if( 'b2b' === klarna_payments_params.customer_type ) { jQuery('#customer_details .col-2').hide(); } } else { jQuery('#customer_details .col-2').show(); } } }; klarna_payments.start(); $('body').ready( function() { klarna_payments.setRadioButtonValues(); }); $('body').ajaxComplete( function() { klarna_payments.setRadioButtonValues(); }); });