435 lines
15 KiB
JavaScript
435 lines
15 KiB
JavaScript
/**
|
|
* 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('<span class="bankily-field-error">' + errorMessage + '</span>');
|
|
}
|
|
}
|
|
}
|
|
|
|
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('<div class="bankily-checkout-error">' + message + '</div>');
|
|
}
|
|
}
|
|
|
|
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 = `
|
|
<style id="bankily-bpay-frontend-styles">
|
|
.payment_method_bankily_bpay .form-row input.valid {
|
|
border-color: #28a745 !important;
|
|
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25) !important;
|
|
}
|
|
|
|
.payment_method_bankily_bpay .form-row input.invalid {
|
|
border-color: #dc3545 !important;
|
|
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important;
|
|
}
|
|
|
|
.bankily-field-error,
|
|
.bankily-checkout-error {
|
|
color: #dc3545;
|
|
font-size: 12px;
|
|
margin-top: 5px;
|
|
display: block;
|
|
animation: slideDown 0.3s ease;
|
|
}
|
|
|
|
@keyframes slideDown {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.payment_method_bankily_bpay .form-row {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.payment_method_bankily_bpay label {
|
|
font-weight: 600;
|
|
margin-bottom: 5px;
|
|
display: block;
|
|
}
|
|
|
|
.payment_method_bankily_bpay input[type="tel"],
|
|
.payment_method_bankily_bpay input[type="password"] {
|
|
width: 100%;
|
|
padding: 10px 12px;
|
|
border: 2px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
transition: border-color 0.3s, box-shadow 0.3s;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.payment_method_bankily_bpay input[type="tel"]:focus,
|
|
.payment_method_bankily_bpay input[type="password"]:focus {
|
|
outline: none;
|
|
border-color: #007cba;
|
|
box-shadow: 0 0 0 0.2rem rgba(0, 124, 186, 0.25);
|
|
}
|
|
|
|
.payment_method_bankily_bpay small {
|
|
color: #666;
|
|
font-size: 12px;
|
|
margin-top: 3px;
|
|
display: block;
|
|
}
|
|
|
|
.bankily-test-notice {
|
|
background: #fff3cd !important;
|
|
border: 1px solid #ffeaa7 !important;
|
|
color: #856404 !important;
|
|
padding: 10px !important;
|
|
border-radius: 4px !important;
|
|
margin-bottom: 15px !important;
|
|
border-left: 4px solid #ffc107 !important;
|
|
}
|
|
|
|
#wc-bankily_bpay-form {
|
|
background: #f9f9f9;
|
|
padding: 20px;
|
|
border-radius: 5px;
|
|
margin-top: 10px;
|
|
border: 1px solid #e1e1e1;
|
|
}
|
|
|
|
/* Animation de chargement */
|
|
.payment_method_bankily_bpay.processing::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(255, 255, 255, 0.8);
|
|
z-index: 10;
|
|
}
|
|
|
|
.payment_method_bankily_bpay.processing::before {
|
|
content: '⏳ Traitement en cours...';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
z-index: 11;
|
|
background: #007cba;
|
|
color: white;
|
|
padding: 8px 15px;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 768px) {
|
|
#wc-bankily_bpay-form {
|
|
padding: 15px;
|
|
}
|
|
|
|
.payment_method_bankily_bpay input[type="tel"],
|
|
.payment_method_bankily_bpay input[type="password"] {
|
|
padding: 12px 14px;
|
|
font-size: 16px; /* Évite le zoom sur mobile */
|
|
}
|
|
}
|
|
</style>
|
|
`;
|
|
|
|
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('<small class="bankily-help" style="color: #007cba;">💡 Saisissez votre numéro sans l\'indicatif (+222)</small>');
|
|
}
|
|
});
|
|
|
|
$(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('<small class="bankily-help" style="color: #007cba;">🔐 Votre code PIN personnel B-PAY</small>');
|
|
}
|
|
});
|
|
|
|
$(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();
|
|
});
|
|
}); |