A ti no te habrá pasado pero a tus clientes muchas veces que, al llegar a la página de finalizar compra, han rellenado una serie de datos y que, por algún motivo, han vuelto al carrito a modificar una cantidad o incluso a la tienda para añadir algún otro producto y, al volver a la página de finalizar compra, algunos de los datos antes rellenados ya no están, teniendo que volver a completarlos.
Y no, no es que WooCommerce funcione mal, es que ese es el comportamiento por defecto, que no se guarden todos los datos de los visitantes mientras no finalicen la compra. Ahora bien ¿es eso lo que quieres?
Porque igual prefieres ahorrarle a tus clientes ese bonito tiempo de volver a rellenar los datos, simplemente configurando tu sitio para que guarde todos los datos al finalizar compra, para que les estén esperando cuando vuelvan ya a realizar el pago definitivamente.
La solución está en añadir esta función:
/* Guardar campos de finalizar compra */ add_action( 'woocommerce_checkout_update_order_review', 'ayudawp_guarda_campos_pago', 9999 ); function ayudawp_guarda_campos_pago( $posted_data ) { parse_str( $posted_data, $output ); WC()->session->set( 'checkout_data', $output ); return $posted_data; } add_filter( 'woocommerce_checkout_get_value', 'ayudawp_recupera_campos_pago', 9999, 2 ); function ayudawp_recupera_campos_pago( $value, $index ) { $data = WC()->session->get( 'checkout_data' ); if ( ! $data || empty( $data[$index] ) ) return $value; return is_bool( $data[$index] ) ? (int) $data[$index] : $data[$index]; } add_filter( 'woocommerce_ship_to_different_address_checked', 'ayudawp_recupera_campos_pago_envio' ); function ayudawp_recupera_campos_pago_envio( $checked ) { $data = WC()->session->get( 'checkout_data' ); if ( ! $data || empty( $data['ship_to_different_address'] ) ) return $checked; return true; }
- El primer filtro guarda los datos rellenados por el cliente cuando los completa en su primera visita a la página de finalizar compra.
- El segundo filtro recupera esos datos rellenados en los campos cuando vuelve a la página de finalizar compra.
- El tercer filtro hace lo mismo pero con los datos de enviar a una dirección diferente, si existía.
Todo este código debes añadirlo según las indicaciones de esta sencilla guía:
Cómo y dónde pegar en WordPress códigos PHP, JS, CSS y funciones que encuentres por ahí
Cuando hayas guardado los cambios en el código ahora WooCommerce recordará todos los campos que tus clientes hayan rellenado previamente en la página de finalizar compra.
¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!
Hola Fernando, primero agradecerte que tan bien nos ilustres en WordPress.
Y segundo, al hilo de éste post, me gustaría preguntarte cómo hacer que en la parte de Finalizar compra no salgan todos los campos adicionales definidos que fueron creados y filtrados para otros productos.
Si hago una compra de un sólo producto sí salen los campos adicionales que corresponden, pero si en una misma compra pongo diferentes productos de diferentes categorías, WooCommerce pide todos los campos adicionales.
Muchas gracias
Hola Mayte ¿a qué campos adicionales te refieres y dónde salen en concreto?
Salen en la página «finalizar compra» cuando en una misma compra hay varios productos que llevan asociados campos adicionales creados en la pantalla que aparece accediendo dentro de WordPress a woocommerce/finalizar compra/adicional
Brillante Fernando!
Muchas gracias, probado, instalado y funcionando.
Esto es muy util, siempre había querido algo así.
Navegue por todo el site, agregué mas productos, continué navegando, agregué mas productos y los datos seguían ahí. Fantástico.
Eso devia estar integrado en el «core».
Muchas gracias.
Sí y no, porque no olvides las leyes de privacidad. Debes avisar de esta cookie en tus avisos de privacidad 😉
Ah, las famosas «galletitas»…
Genio! Funciono a la perfección, gracias Fernando!
Buenas. Muchas gracias ante todo por tu labor y por compartir este tipo de cosas.
He probado el código en un cliente y me funciona bien con todos los campos excepto el teléfono, que no lo recupera al volver al checkout.
¿Sabes si ese campo tiene algo especial o a qué pueda deberse?
Un saludo.
Fue hace un año, la cosa es que siempre me quedo dando vueltas lo del «consentimiento», llegué a una versión mejorada, que dejo aqui:
// Request consent before saving user data
add_action( 'woocommerce_before_checkout_billing_form', 'wcs_add_consent_checkbox' );
function wcs_add_consent_checkbox( $checkout ) {
woocommerce_form_field( 'wcs_consent_checkbox', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label' => __('I consent to the storage of my personal data.'),
'required' => true,
), $checkout->get_value( 'wcs_consent_checkbox' ) );
}
// Saves the data filled in by customer on his first visit to the checkout page (without consent)
add_action( 'woocommerce_checkout_update_order_review', 'wcs_save_checkout_contact_fields', 9999 );
function wcs_save_checkout_contact_fields( $posted_data ) {
parse_str( $posted_data, $output );
if ( isset( $output['wcs_consent_checkbox'] ) ) {
WC()->session->set( 'checkout_data', $output );
setcookie( 'wcs_consent_given', 1, time() + 2592000, '/' );
}
return $posted_data;
}
// Retrieves data filled in when returning to the checkout page.
add_filter( 'woocommerce_checkout_get_value', 'wcs_retrieve_checkout_contact_fields', 9999, 2 );
function wcs_retrieve_checkout_contact_fields( $value, $index ) {
if ( ! isset( $_COOKIE['wcs_consent_given'] ) || ! $_COOKIE['wcs_consent_given'] ) {
return $value;
}
$data = WC()->session->get( 'checkout_data' );
if ( ! empty( $data[$index] ) ) {
return is_bool( $data[$index] ) ? (int) $data[$index] : $data[$index];
}
return $value;
}
// Retrieves data filled in as "ship to a different address", if any.
add_filter( 'woocommerce_ship_to_different_address_checked', 'wcs_retrieve_checkout_ship_to_different_address_fields' );
function wcs_retrieve_checkout_ship_to_different_address_fields( $checked ) {
if ( ! isset( $_COOKIE['wcs_consent_given'] ) || ! $_COOKIE['wcs_consent_given'] ) {
return $checked;
}
$data = WC()->session->get( 'checkout_data' );
if ( ! empty( $data['ship_to_different_address'] ) ) {
return true;
}
return $checked;
}