(function(context,$) { "use strict"; context.JK = context.JK || {}; context.JK.CheckoutPaymentScreen = function(app) { var EVENTS = context.JK.EVENTS; var logger = context.JK.logger; var jamTrackUtils = context.JK.JamTrackUtils; var $screen = null; var $navigation = null; var $billingInfo = null; var $shippingInfo = null; var $paymentMethod = null; var $shippingAddress = null; var $shippingAsBilling = null; var $paymentInfoPanel = null; var $accountSignup = null; var userDetail = null; var step = null; var billing_info = null; var shipping_info = null; var shipping_as_billing = null; var $reuseExistingCard = null; var $reuseExistingCardChk = null; var $existingCardEndsWith = null; var $newCardInfo = null; var selectCountry = null; var selectCountryLoaded = false; var $freeJamTrackPrompt = null; var $noFreeJamTrackPrompt = null; function afterShow() { beforeShowPaymentInfo(); } function beforeShowPaymentInfo() { step = 2; renderNavigation(); renderAccountInfo(); } function renderAccountInfo() { $reuseExistingCard.addClass('hidden'); $newCardInfo.removeClass('hidden'); $freeJamTrackPrompt.addClass('hidden'); $noFreeJamTrackPrompt.addClass('hidden'); $("#payment_error").addClass('hidden').text('') var selectCountryReady = selectCountry.ready(); if(!selectCountryReady) { // one time init of country dropdown selectCountryReady = selectCountry.load('US', null, null); } selectCountryReady.done(function() { var user = rest.getUserDetail() if(user) { user.done(populateAccountInfo).error(app.ajaxError); } else { $reuseExistingCardChk.iCheck('uncheck').attr('checked', false) if(gon.global.one_free_jamtrack_per_user) { $freeJamTrackPrompt.removeClass('hidden') } else { $noFreeJamTrackPrompt.removeClass('hidden') } } }) } function populateAccountInfo(user) { userDetail = user; $reuseExistingCardChk.iCheck(userDetail.reuse_card && userDetail.has_recurly_account ? 'check' : 'uncheck').attr('checked', userDetail.reuse_card) // show appropriate prompt text based on whether user has a free jamtrack if(user.free_jamtrack) { $freeJamTrackPrompt.removeClass('hidden') } else { $noFreeJamTrackPrompt.removeClass('hidden') } if (userDetail.has_recurly_account) { rest.getBillingInfo() .done(function(response) { if(userDetail.reuse_card) { $reuseExistingCard.removeClass('hidden'); toggleReuseExistingCard.call($reuseExistingCardChk) $existingCardEndsWith.text(response.billing_info.last_four); } var isSameAsShipping = true // jamTrackUtils.compareAddress(response.billing_info, response.address); $shippingAsBilling.iCheck(isSameAsShipping ? 'check' : 'uncheck').attr('checked', isSameAsShipping) $billingInfo.find("#billing-first-name").val(response.billing_info.first_name); $billingInfo.find("#billing-last-name").val(response.billing_info.last_name); $billingInfo.find("#billing-address1").val(response.billing_info.address1); $billingInfo.find("#billing-address2").val(response.billing_info.address2); $billingInfo.find("#billing-city").val(response.billing_info.city); $billingInfo.find("#billing-state").val(response.billing_info.state); $billingInfo.find("#billing-zip").val(response.billing_info.zip); $billingInfo.find("#billing-country").val(response.billing_info.country); //$shippingAddress.find("#shipping-first-name").val(response.billing_info.first_name); //$shippingAddress.find("#shipping-last-name").val(response.billing_info.last_name); //$shippingAddress.find("#shipping-address1").val(response.address.address1); //$shippingAddress.find("#shipping-address2").val(response.address.address2); //$shippingAddress.find("#shipping-city").val(response.address.city); //$shippingAddress.find("#shipping-state").val(response.address.state); //$shippingAddress.find("#shipping-zip").val(response.address.zip); //$shippingAddress.find("#shipping-country").val(response.address.country); }) .error(app.ajaxError); } else { $billingInfo.find("#billing-first-name").val(userDetail.first_name); $billingInfo.find("#billing-last-name").val(userDetail.last_name); $billingInfo.find("#billing-city").val(userDetail.city); $billingInfo.find("#billing-state").val(userDetail.state); $billingInfo.find("#billing-country").val(userDetail.country); $shippingAddress.find("#shipping-first-name").val(userDetail.first_name); $shippingAddress.find("#shipping-last-name").val(userDetail.last_name); $shippingAddress.find("#shipping-city").val(userDetail.city); $shippingAddress.find("#shipping-state").val(userDetail.state); $shippingAddress.find("#shipping-country").val(userDetail.country); } } function beforeShow(data) { // XXX : style-test code // moveToThanks({jam_tracks: [{id: 14, jam_track_right_id: 11, name: 'Back in Black'}, {id: 15, jam_track_right_id: 11, name: 'In Bloom'}, {id: 16, jam_track_right_id: 11, name: 'Love Bird Supreme'}]}); } function beforeHide() { } function beforeHide() { } // TODO: Refactor: this function is long and fraught with many return points. function next(e) { $paymentInfoPanel.find('.error-text').remove(); $paymentInfoPanel.find('.error').removeClass('error'); e.preventDefault(); $("#payment_error").addClass("hidden").text('') var reuse_card_this_time = $reuseExistingCardChk.is(':checked'); var reuse_card_next_time = $paymentMethod.find('#save-card').is(':checked'); // validation var billing_first_name = $billingInfo.find("#billing-first-name").val(); var billing_last_name = $billingInfo.find("#billing-last-name").val(); var billing_address1 = $billingInfo.find("#billing-address1").val(); var billing_address2 = $billingInfo.find("#billing-address2").val(); var billing_city = $billingInfo.find("#billing-city").val(); var billing_state = $billingInfo.find("#billing-state").val(); var billing_zip = $billingInfo.find("#billing-zip").val(); var billing_country = $billingInfo.find("#billing-country").val(); var billingInfoValid = true; if (!billing_first_name) { $billingInfo.find('#divBillingFirstName .error-text').remove(); $billingInfo.find('#divBillingFirstName').addClass("error").addClass("transparent"); $billingInfo.find('#billing-first-name').after(""); logger.info("no billing first name"); billingInfoValid = false; } else { $billingInfo.find('#divBillingFirstName').removeClass("error"); } if (!billing_last_name) { $billingInfo.find('#divBillingLastName .error-text').remove(); $billingInfo.find('#divBillingLastName').addClass("error").addClass("transparent"); $billingInfo.find('#billing-last-name').after(""); logger.info("no billing last name"); billingInfoValid = false; } else { $billingInfo.find('#divBillingLastName').removeClass("error"); } if (!billing_address1) { $billingInfo.find('#divBillingAddress1 .error-text').remove(); $billingInfo.find('#divBillingAddress1').addClass("error").addClass("transparent"); $billingInfo.find('#billing-address1').after(""); logger.info("no billing address line 1"); billingInfoValid = false; } else { $billingInfo.find('#divBillingAddress1').removeClass("error"); } if (!billing_zip) { $billingInfo.find('#divBillingZip .error-text').remove(); $billingInfo.find('#divBillingZip').addClass("error").addClass("transparent"); $billingInfo.find('#billing-zip').after(""); logger.info("no billing zip"); billingInfoValid = false; } else { $billingInfo.find('#divBillingZip').removeClass("error"); } if (!billing_state) { $billingInfo.find('#divBillingState .error-text').remove(); $billingInfo.find('#divBillingState').addClass("error").addClass("transparent"); $billingInfo.find('#billing-state').after(""); logger.info("no billing state"); billingInfoValid = false; } else { $billingInfo.find('#divBillingState').removeClass("error"); } if (!billing_city) { $billingInfo.find('#divBillingCity .error-text').remove(); $billingInfo.find('#divBillingCity').addClass("error").addClass("transparent"); $billingInfo.find('#billing-city').after(""); logger.info("no billing city"); billingInfoValid = false; } else { $billingInfo.find('#divBillingCity').removeClass("error"); } if (!billing_country) { $billingInfo.find('#divBillingCountry .error-text').remove(); $billingInfo.find('#divBillingCountry').addClass("error").addClass("transparent"); $billingInfo.find('#billing-country').after(""); logger.info("no billing country"); billingInfoValid = false; } else { $billingInfo.find('#divBillingCountry').removeClass("error"); } /** shipping_as_billing = $shippingAsBilling.is(":checked"); var shipping_first_name, shipping_last_name, shipping_address1, shipping_address2; var shipping_city, shipping_state, shipping_zip, shipping_country; if (!shipping_as_billing) { shipping_first_name = $shippingAddress.find("#shipping-first-name").val(); shipping_last_name = $shippingAddress.find("#shipping-last-name").val(); shipping_address1 = $shippingAddress.find("#shipping-address1").val(); shipping_address2 = $shippingAddress.find("#shipping-address2").val(); shipping_city = $shippingAddress.find("#shipping-city").val(); shipping_state = $shippingAddress.find("#shipping-state").val(); shipping_zip = $shippingAddress.find("#shipping-zip").val(); shipping_country = $shippingAddress.find("#shipping-country").val(); if (!shipping_first_name) { $shippingAddress.find('#divShippingFirstName .error-text').remove(); $shippingAddress.find('#divShippingFirstName').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-first-name').after(""); logger.info("no address first name"); return false; } else { $shippingInfo.find('#divShippingFirstName').removeClass("error"); } if (!shipping_last_name) { $shippingAddress.find('#divShippingLastName .error-text').remove(); $shippingAddress.find('#divShippingLastName').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-last-name').after(""); logger.info("no last name"); return false; } else { $shippingInfo.find('#divShippingLastName').removeClass("error"); } if (!shipping_address1) { $shippingAddress.find('#divShippingAddress1 .error-text').remove(); $shippingAddress.find('#divShippingAddress1').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-address1').after(""); logger.info("no shipping address 1"); return false; } else { $shippingInfo.find('#divShippingAddress1').removeClass("error"); } if (!shipping_zip) { $shippingAddress.find('#divShippingZip .error-text').remove(); $shippingAddress.find('#divShippingZip').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-zip').after(""); logger.info("no shipping address 2"); return false; } else { $shippingInfo.find('#divShippingZip').removeClass("error"); } if (!shipping_state) { $shippingAddress.find('#divShippingState .error-text').remove(); $shippingAddress.find('#divShippingState').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-zip').after(""); logger.info("no shipping state"); return false; } else { $shippingInfo.find('#divShippingState').removeClass("error"); } if (!shipping_city) { $shippingAddress.find('#divShippingCity .error-text').remove(); $shippingAddress.find('#divShippingCity').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-city').after(""); logger.info("no shipping city"); return false; } else { $shippingInfo.find('#divShippingCity').removeClass("error"); } if (!shipping_country) { $shippingAddress.find('#divShippingCountry .error-text').remove(); $shippingAddress.find('#divShippingCountry').addClass("error").addClass("transparent"); $shippingAddress.find('#shipping-country').after(""); logger.info("no shipping country"); return false; } else { $shippingAddress.find('#divShippingCountry').removeClass("error"); } } */ var card_name = $paymentMethod.find("#card-name").val(); var card_number = $paymentMethod.find("#card-number").val(); var card_year = $paymentMethod.find("#card_expire-date_1i").val(); var card_month = $paymentMethod.find("#card_expire-date_2i").val(); var card_verify = $paymentMethod.find("#card-verify").val(); /** if (!card_name) { $paymentMethod.find('#divCardName .error-text').remove(); $paymentMethod.find('#divCardName').addClass("error").addClass("transparent"); $paymentMethod.find('#card-name').after(""); return false; } else { $paymentMethod.find('#divCardName').removeClass("error"); }*/ // don't valid card form fields when reuse card selected if(!reuse_card_this_time) { if (!card_number) { $paymentMethod.find('#divCardNumber .error-text').remove(); $paymentMethod.find('#divCardNumber').addClass("error").addClass("transparent"); $paymentMethod.find('#card-number').after(""); logger.info("no card number"); billingInfoValid = false; } else if (!$.payment.validateCardNumber(card_number)) { $paymentMethod.find('#divCardNumber .error-text').remove(); $paymentMethod.find('#divCardNumber').addClass("error").addClass("transparent"); $paymentMethod.find('#card-number').after(""); logger.info("invalid card number"); billingInfoValid = false; } else { $paymentMethod.find('#divCardNumber').removeClass("error"); } if (!$.payment.validateCardExpiry(card_month, card_year)) { $paymentMethod.find('#divCardExpiry .error-text').remove(); $paymentMethod.find('#divCardExpiry').addClass("error").addClass("transparent"); $paymentMethod.find('#card-expiry').after(""); logger.info("invalid card expiry"); billingInfoValid = false; } else { $paymentMethod.find('#divCardExpiry').removeClass("error"); } if (!card_verify) { $paymentMethod.find('#divCardVerify .error-text').remove(); $paymentMethod.find('#divCardVerify').addClass("error").addClass("transparent"); $paymentMethod.find('#card-verify').after(""); logger.info("no card verify"); billingInfoValid = false; } else if (!$.payment.validateCardCVC(card_verify)) { $paymentMethod.find('#divCardVerify .error-text').remove(); $paymentMethod.find('#divCardVerify').addClass("error").addClass("transparent"); $paymentMethod.find('#card-verify').after(""); logger.info("bad card CVC"); billingInfoValid = false; } else { $paymentMethod.find('#divCardVerify').removeClass("error"); } } if(!billingInfoValid) { logger.debug("billing info is invalid. returning"); return false; } billing_info = {}; shipping_info = {}; billing_info.first_name = billing_first_name; billing_info.last_name = billing_last_name; billing_info.address1 = billing_address1; billing_info.address2 = billing_address2; billing_info.city = billing_city; billing_info.state = billing_state; billing_info.country = billing_country; billing_info.zip = billing_zip; billing_info.number = card_number; billing_info.month = card_month; billing_info.year = card_year; billing_info.verification_value = card_verify; /** if (shipping_as_billing) { shipping_info = $.extend({},billing_info); delete shipping_info.number; delete shipping_info.month; delete shipping_info.year; delete shipping_info.verification_value; } else { shipping_info.first_name = shipping_first_name; shipping_info.last_name = shipping_last_name; shipping_info.address1 = shipping_address1; shipping_info.address2 = shipping_address2; shipping_info.city = shipping_city; shipping_info.state = shipping_state; shipping_info.country = shipping_country; shipping_info.zip = shipping_zip; }*/ var email = null; var password = null; var terms = false; var isLoggedIn = context.JK.currentUserId; if(!isLoggedIn) { email = $accountSignup.find('input[name="email"]').val() password = $accountSignup.find('input[name="password"]').val() terms = $accountSignup.find('input[name="terms-of-service"]').is(':checked'); } $screen.find("#payment-info-next").addClass("disabled"); $screen.find("#payment-info-next").off("click"); rest.createRecurlyAccount({billing_info: billing_info, terms_of_service: terms, email: email, password: password, reuse_card_this_time: reuse_card_this_time, reuse_card_next_time: reuse_card_next_time}) .done(function() { $screen.find("#payment-info-next").on("click", next); if(isLoggedIn) { context.location = '/client#/checkoutOrder' } else { // this means the account was created; we need to reload the page for this to take effect context.JK.currentUserId = 'something' // this is to trick layout.js from getting involved and redirecting to home screen context.location = '/client#/checkoutOrder' context.location.reload() } }) .fail(errorHandling) .always(function(){ $screen.find("#payment-info-next").removeClass("disabled"); }) } function errorHandling(xhr, ajaxOptions, thrownError) { logger.debug("error handling", xhr.responseJSON) if(xhr.responseJSON && xhr.responseJSON.errors) { $.each(xhr.responseJSON.errors, function(key, error) { if (key == 'number') { $paymentMethod.find('#divCardNumber .error-text').remove(); $paymentMethod.find('#divCardNumber').addClass("error").addClass("transparent"); $paymentMethod.find('#card-number').after(""); } else if (key == 'verification_value') { $paymentMethod.find('#divCardVerify .error-text').remove(); $paymentMethod.find('#divCardVerify').addClass("error").addClass("transparent"); $paymentMethod.find('#card-verify').after(""); } else if(key == 'email') { var $email = $accountSignup.find('input[name="email"]') var $field = $email.closest('.field') $field.find('.error-text').remove() $field.addClass("error").addClass("transparent"); $email.after(""); } else if(key == 'password') { var $password = $accountSignup.find('input[name="password"]') var $field = $password.closest('.field') $field.find('.error-text').remove() $field.addClass("error").addClass("transparent"); $password.after(""); } else if(key == 'terms_of_service') { var $terms = $accountSignup.find('input[name="terms-of-service"]') var $field = $terms.closest('.field') $field.find('.error-text').remove() $field.addClass("error").addClass("transparent"); $accountSignup.find('.terms-of-service-label-holder').append(""); } else if(key == 'message') { $("#payment_error").text(error).removeClass('hidden') } }); } else { $("#payment_error").text(xhr.responseText).removeClass('hidden') } $screen.find("#payment-info-next").on('click', next); } function beforeShowOrder() { step = 3; renderNavigation(); populateOrderPage(); } function populateOrderPage() { rest.getShoppingCarts() .done(renderOrderPage) .fail(app.ajaxError); } function toggleShippingAsBilling(e) { e.preventDefault(); var shipping_as_billing = $(e.target).is(':checked'); if (!shipping_as_billing) { $shippingAddress.removeClass("hidden"); } else { $shippingAddress.addClass("hidden"); } } function toggleReuseExistingCard(e) { if(e) { e.preventDefault(); } logger.debug("toggle reuse existing card") var reuse_existing = $(this).is(':checked'); $('#billing-first-name').prop('disabled', reuse_existing); $('#billing-last-name').prop('disabled', reuse_existing); $('#billing-address1').prop('disabled', reuse_existing); $('#billing-address2').prop('disabled', reuse_existing); $('#billing-city').prop('disabled', reuse_existing); $('#billing-state').prop('disabled', reuse_existing); $('#billing-zip').prop('disabled', reuse_existing); $('#billing-country').prop('disabled', reuse_existing); $('#card-name').prop('disabled', reuse_existing); $('#card-number').prop('disabled', reuse_existing); $('#card_expire-date_1i').prop('disabled', reuse_existing); $('#card_expire-date_2i').prop('disabled', reuse_existing); $('#card-verify').prop('disabled', reuse_existing); } function events() { $screen.find("#payment-info-next").on('click', next); $shippingAsBilling.on('ifChanged', toggleShippingAsBilling); $reuseExistingCardChk.on('ifChanged', toggleReuseExistingCard); } function reset() { } function renderNavigation() { $navigation.html(""); var navigationHtml = $( context._.template( $('#template-checkout-navigation').html(), {current: step}, {variable: 'data'} ) ); $navigation.append(navigationHtml); } function initializeControls() { $("form.payment-info").addClass(context.JK.currentUserId ? 'signed-in' : 'not-signed-in').iCheck({ checkboxClass: 'icheckbox_minimal', radioClass: 'iradio_minimal', inheritClass: true }); // Use jquery.payment to limit characters and length: $paymentMethod.find("#card-number").payment('formatCardNumber'); $paymentMethod.find("#card-verify").payment('formatCardCVC'); selectCountry = new context.JK.SelectLocation($('#billing-country'), null, null, app, false) } function initialize() { var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow, 'beforeHide' : beforeHide }; app.bindScreen('checkoutPayment', screenBindings); $screen = $("#checkoutPaymentScreen"); $paymentInfoPanel = $screen.find("#checkout-payment-info"); $navigation = $screen.find(".checkout-navigation-bar"); $billingInfo = $paymentInfoPanel.find(".billing-address"); $shippingInfo = $paymentInfoPanel.find(".shipping-address"); $paymentMethod = $paymentInfoPanel.find(".payment-method"); $accountSignup = $paymentInfoPanel.find('.jamkazam-account-signup') $shippingAddress = $paymentInfoPanel.find(".shipping-address-detail"); $shippingAsBilling = $paymentInfoPanel.find("#shipping-as-billing"); $reuseExistingCard = $paymentInfoPanel.find('.reuse-existing-card') $reuseExistingCardChk = $paymentInfoPanel.find('#reuse-existing-card') $existingCardEndsWith = $paymentInfoPanel.find('.existing-card-ends-with') $newCardInfo = $paymentInfoPanel.find('.new-card-info') $freeJamTrackPrompt = $screen.find('.payment-prompt.free-jamtrack') $noFreeJamTrackPrompt = $screen.find('.payment-prompt.no-free-jamtrack') if($screen.length == 0) throw "$screen must be specified"; if($navigation.length == 0) throw "$navigation must be specified"; initializeControls(); events(); } this.initialize = initialize; return this; } })(window,jQuery);