WooCommerce - Disparar la validación del formulario de pago

19 dic 2018, 14:31:20
Vistas: 14.3K
Votos: 2

He estado buscando la respuesta pero no la encontré.

Estoy creando una pasarela de pago en iframe que se carga dentro de la página de pago. Mi objetivo es que, una vez el cliente haga clic en un botón específico, se active la función que valida que el cliente ha completado todos los campos requeridos. Si devuelve true, el iframe se carga.

De lo contrario, se mostrarán los mensajes de error de la función de validación.

Encontré que esta función es un método llamado update_checkout_action dentro de la clase wc_checkout_form.

Espero que sea información suficiente. Si necesitas algo más, házmelo saber y lo proporcionaré.

Gracias.

1
Todas las respuestas a la pregunta 2
0

Me he encontrado con esto varias veces, todavía no he encontrado un método directo para manejarlo. Pero aquí está lo que he hecho en el pasado.

Puedes activar la validación del checkout fácilmente forzando un clic en el botón de enviar.

    $('#myButton').on('click', function(){
        $('#place_order').click();
    });

Sin embargo, esto no es realmente útil para ti porque simplemente enviará el pedido si no hay errores.

También está la devolución de llamada checkout_error, pero solo se activa si hay un error.

    $(document.body).on('checkout_error', function () {
        // Hubo un error de validación
    });

Aquí está lo que necesitamos hacer.

  • Detectar cuando se hace clic en el botón de enviar
  • Verificar si hay errores
  • Si hay errores, dejar que Woo los maneje como de costumbre
  • Si no hay errores, evitar que el pedido se complete
  • Mostrar tu iframe
  • ... Revalidar / Reenviar el pedido


Tan pronto como se haga clic en el botón de enviar, podemos agregar un campo oculto y establecer el valor en 1. Podemos detectar el evento de envío usando checkout_place_order. Esto debería ir en tu archivo JS.

var checkout_form = $('form.woocommerce-checkout');

checkout_form.on('checkout_place_order', function () {
    if ($('#confirm-order-flag').length == 0) {
        checkout_form.append('<input type="hidden" id="confirm-order-flag" name="confirm-order-flag" value="1">');
    }
    return true;
});

Ahora, agrega una función a functions.php que verificará ese campo oculto y detendrá el pedido si el valor == 1. Detiene el pedido agregando un error.

function add_fake_error($posted) {
    if ($_POST['confirm-order-flag'] == "1") {
        wc_add_notice( __( "custom_notice", 'fake_error' ), 'error');
    } 
}

add_action('woocommerce_after_checkout_validation', 'add_fake_error');

De vuelta en nuestro archivo JS, podemos usar la devolución de llamada checkout_error, si tiene 1 error sabemos que fue el error falso que creamos, así que podemos mostrar el iframe. Si tiene más de 1 error, significa que hay otros errores reales en la página.

$(document.body).on('checkout_error', function () {
    var error_count = $('.woocommerce-error li').length;

    if (error_count == 1) { // Validación Aprobada (Solo Existe el Error Falso)
        // Mostrar iFrame
    }else{ // Validación Fallida (Existen Errores Reales, Eliminar el Falso)
        $('.woocommerce-error li').each(function(){
            var error_text = $(this).text();
            if (error_text == 'custom_notice'){
                $(this).css('display', 'none');
            }
        });
    }
});

En la sección comentada, // Mostrar iFrame, probablemente lo abriría en un lightbox. En algún momento necesitarás otro botón de enviar que active el envío del formulario y establezca el campo oculto.

$('#confirm-order-button').click(function () {
    $('#confirm-order-flag').val('');
    $('#place_order').trigger('click');
});
19 dic 2018 17:48:56
0

Tomé una decisión rápida y sencilla con JS para este caso (había formularios de WooCommerce y Stripe). Se basa en evitar que el botón de checkout envíe el formulario pero aún así realiza las verificaciones.

// creando el evento click en un elemento dinámico

$('body').on('click', 'button#place_order_wrap', function(event) { 

    // intervalo principal donde ocurrirán todas las acciones

    var validatoins = setInterval(function(){ 

        // verificando errores

        if(no_errors==0){ 

        // creando la función setTimeout() con un tiempo limitado como 200ms 
        // para limitar la función de checkout solo a realizar verificaciones

        setTimeout(function(){ 

            // activando el botón original

            $('button#place_order').click(); 

            // si hay errores, detener el intervalo, retornar falso

            if(($('element').find('ul.woocommerce_error').length!==0)||($('element').find('.woocommerce-invalid-required-field').length!==0)){ 

                    clearInterval(validatoins);
                    return false;

                }else{

                    no_errors=1;

                }
            }, 200);
        }


        if(no_errors==1){    

            // misma verificación de errores

            if($('#step5').find('ul.woocommerce_error').length!=0||($('#step5').find('.woocommerce-invalid-required-field').length!==0)){ 

                // si hay errores, detener el intervalo, retornar falso

                clearInterval(validatoins);
                return false; 
            }


            setTimeout(function(){

                // si no hay errores

                if(($('#step5').find('ul.woocommerce_error').length==0)&&($('#step5').find('.woocommerce-invalid-required-field').length==0)){ 

                    // hacer algo, marcar como finalizado

                    return false;
                }
            }, 1000);


            // si algo finalizó

            if() {

                setTimeout(function(){

                    // activar el click original de checkout

                    $('button#place_order').click(); 
                    clearInterval(validatoins);
                }, 1000);

            }

        }

    }, 1000);
}
5 feb 2020 16:41:47