/** * Script JavaScript pour le frontend B-PAY Bankily * Fichier: assets/bankily-bpay.js * Version: 1.0.0 */ jQuery(document).ready(function($) { 'use strict'; // Variables globales var bankily_form = 'form.checkout, form#order_review'; var bankily_gateway = '#payment_method_bankily_bpay'; // Initialisation initializeBankilyCheckout(); function initializeBankilyCheckout() { // Gestion de la sélection de la méthode de paiement $(document).on('change', 'input[name="payment_method"]', function() { toggleBankilyFields(); if ($(this).val() === 'bankily_bpay') { // Focus sur le premier champ et pré-remplir en mode test setTimeout(function() { $('#bankily_phone').focus(); if (bankily_bpay_params.testmode === '1') { fillTestData(); } }, 100); } }); // Validation en temps réel setupRealtimeValidation(); // Formatage des champs setupFieldFormatting(); // Gestion de la soumission $(bankily_form).on('checkout_place_order_bankily_bpay', function() { return validateBankilyForm(); }); // Stylisation CSS addBankilyStyles(); // État initial toggleBankilyFields(); } function setupRealtimeValidation() { // Validation du numéro de téléphone $(document).on('input blur', '#bankily_phone', function() { validatePhoneField($(this)); }); // Validation du code PIN $(document).on('input blur', '#bankily_passcode', function() { validatePasscodeField($(this)); }); } function validatePhoneField($field) { var phone = $field.val().replace(/\D/g, ''); // Supprimer tous les caractères non numériques var isValid = /^[0-9]{8}$/.test(phone); // Mettre à jour la valeur avec uniquement les chiffres $field.val(phone); // Validation visuelle updateFieldValidation($field, isValid, phone.length > 0, 'Format requis: 8 chiffres (ex: 22123456)'); // Limiter à 8 chiffres if (phone.length > 8) { $field.val(phone.substring(0, 8)); } } function validatePasscodeField($field) { var passcode = $field.val(); var isValid = passcode.length >= 4 && passcode.length <= 6; updateFieldValidation($field, isValid, passcode.length > 0, 'Le code PIN doit contenir entre 4 et 6 caractères'); } function updateFieldValidation($field, isValid, hasContent, errorMessage) { $field.removeClass('valid invalid'); $field.next('.bankily-field-error').remove(); if (hasContent) { if (isValid) { $field.addClass('valid'); } else { $field.addClass('invalid'); $field.after('' + errorMessage + ''); } } } function setupFieldFormatting() { // Permettre uniquement les chiffres pour le téléphone $(document).on('keypress', '#bankily_phone', function(e) { // Permettre uniquement les chiffres, backspace, delete, tab, escape, enter if ($.inArray(e.keyCode, [46, 8, 9, 27, 13]) !== -1 || // Permettre Ctrl+A, Ctrl+C, Ctrl+V, Ctrl+X (e.keyCode === 65 && e.ctrlKey === true) || (e.keyCode === 67 && e.ctrlKey === true) || (e.keyCode === 86 && e.ctrlKey === true) || (e.keyCode === 88 && e.ctrlKey === true)) { return; } // S'assurer que c'est un chiffre if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { e.preventDefault(); } }); // Permettre uniquement les chiffres pour le code PIN $(document).on('keypress', '#bankily_passcode', function(e) { if ($.inArray(e.keyCode, [46, 8, 9, 27, 13]) !== -1 || (e.keyCode === 65 && e.ctrlKey === true) || (e.keyCode === 67 && e.ctrlKey === true) || (e.keyCode === 86 && e.ctrlKey === true) || (e.keyCode === 88 && e.ctrlKey === true)) { return; } if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { e.preventDefault(); } }); } function validateBankilyForm() { if (!$(bankily_gateway).is(':checked')) { return true; // Pas notre méthode de paiement } var isValid = true; var $phone = $('#bankily_phone'); var $passcode = $('#bankily_passcode'); // Supprimer les anciens messages d'erreur $('.bankily-checkout-error').remove(); // Validation du téléphone var phone = $phone.val().replace(/\D/g, ''); if (!phone || !/^[0-9]{8}$/.test(phone)) { showCheckoutError($phone, 'Veuillez entrer un numéro de téléphone valide (8 chiffres)'); isValid = false; } // Validation du code PIN var passcode = $passcode.val(); if (!passcode || passcode.length < 4 || passcode.length > 6) { showCheckoutError($passcode, 'Veuillez entrer votre code PIN B-PAY (4 à 6 chiffres)'); isValid = false; } if (!isValid) { // Faire défiler vers le premier champ avec erreur $('html, body').animate({ scrollTop: $('.payment_method_bankily_bpay').offset().top - 100 }, 500); // Focus sur le premier champ invalide setTimeout(function() { $('.payment_method_bankily_bpay .invalid').first().focus(); }, 600); } return isValid; } function showCheckoutError($field, message) { $field.addClass('invalid'); if (!$field.next('.bankily-checkout-error').length) { $field.after('
' + message + '
'); } } function toggleBankilyFields() { if ($(bankily_gateway).is(':checked')) { $('.payment_method_bankily_bpay').slideDown(300); } else { $('.payment_method_bankily_bpay').slideUp(300); } } function fillTestData() { if (bankily_bpay_params.testmode === '1') { $('#bankily_phone').val('22123456'); $('#bankily_passcode').val('1234'); } } function addBankilyStyles() { var styles = ` `; if (!$('#bankily-bpay-frontend-styles').length) { $('head').append(styles); } } // Gestion du chargement lors de la soumission $(document).on('submit', bankily_form, function() { if ($(bankily_gateway).is(':checked')) { $('.payment_method_bankily_bpay').addClass('processing'); } }); // Nettoyer l'état de chargement si la soumission échoue $(document).on('checkout_error', function() { $('.payment_method_bankily_bpay').removeClass('processing'); }); // Écouter les changements de checkout (pour WooCommerce AJAX) $(document).on('updated_checkout', function() { toggleBankilyFields(); // Réappliquer la validation sur les champs existants setTimeout(function() { $('#bankily_phone').trigger('blur'); $('#bankily_passcode').trigger('blur'); }, 100); }); // Amélioration UX: Auto-complétion du préfixe $(document).on('focus', '#bankily_phone', function() { var $this = $(this); if ($this.val() === '' && bankily_bpay_params.testmode !== '1') { // Suggestion visuelle pour le format attendu $this.attr('placeholder', '22XXXXXX'); } }); $(document).on('blur', '#bankily_phone', function() { $(this).attr('placeholder', 'Exemple: 22123456'); }); // Gestion des raccourcis clavier $(document).on('keydown', '#bankily_phone, #bankily_passcode', function(e) { // Enter pour aller au champ suivant if (e.keyCode === 13) { e.preventDefault(); var $current = $(this); var $next = $current.closest('.form-row').next('.form-row').find('input'); if ($next.length) { $next.focus(); } else { // Si c'est le dernier champ, déclencher la soumission $(bankily_form).find('.place-order').click(); } } }); // Validation immédiate lors du collage $(document).on('paste', '#bankily_phone', function() { var $this = $(this); setTimeout(function() { validatePhoneField($this); }, 10); }); // Messages d'aide contextuelle $(document).on('focus', '#bankily_phone', function() { if (!$(this).next('.bankily-help').length) { $(this).after('💡 Saisissez votre numéro sans l\'indicatif (+222)'); } }); $(document).on('blur', '#bankily_phone', function() { $(this).next('.bankily-help').fadeOut(300, function() { $(this).remove(); }); }); $(document).on('focus', '#bankily_passcode', function() { if (!$(this).next('.bankily-help').length) { $(this).after('🔐 Votre code PIN personnel B-PAY'); } }); $(document).on('blur', '#bankily_passcode', function() { $(this).next('.bankily-help').fadeOut(300, function() { $(this).remove(); }); }); // Fonctions utilitaires function logDebug(message, data) { if (typeof console !== 'undefined' && console.log && bankily_bpay_params.testmode === '1') { console.log('[B-PAY Frontend] ' + message, data || ''); } } // Log d'initialisation logDebug('Script B-PAY initialisé', { testmode: bankily_bpay_params.testmode, gateway_selector: bankily_gateway }); // Nettoyage lors du changement de page $(window).on('beforeunload', function() { $('.payment_method_bankily_bpay').removeClass('processing'); $('.bankily-field-error, .bankily-checkout-error, .bankily-help').remove(); }); });