Aplique programáticamente un cupón en WooCommerce 3.0+ para el primer pedido realizado por un cliente

4 minutos de lectura

avatar de usuario
Demis Cunningham

Uso este código para aplicar programáticamente un cupón en WooCommerce, para el primer pedido realizado por los clientes. Necesito una función que vea si el cliente es nuevo y, de ser así, aplica el código de cupón.

Estoy tratando de usar esto dentro de mi functions.php de mi tema secundario sin éxito.

add_action('woocommerce_after_checkout_validation','check_new_customer_coupon', 0);
function check_new_customer_coupon(){
    global $woocommerce;
    // you might change the name of your coupon
    $new_cust_coupon_code="new2022";

    $has_apply_coupon = false;

    foreach ( WC()->cart->get_coupons() as $code => $coupon ) {
        if($code == $new_cust_coupon_code) {
            $has_apply_coupon = true;
        }
    }

    if($has_apply_coupon) {

        if(is_user_logged_in()) {
            $user_id = get_current_user_id();

            // retrieve all orders
            $customer_orders = get_posts( array(
                    'meta_key'    => '_customer_user',
                    'meta_value'  => $user_id,
                    'post_type'   => 'shop_order',
                    'numberposts'=> -1
            ) );

            if(count($customer_orders) > 0) {
                $has_ordered = false;

                $statuses = array('wc-failed', 'wc-cancelled', 'wc-refunded');

                // loop thru orders, if the order is not falled into failed, cancelled or refund then it consider valid
                foreach($customer_orders as $tmp_order) {

                    $order = wc_get_order($tmp_order->ID);
                    if(!in_array($order->get_status(), $statuses)) {
                        $has_ordered = true;
                    }
                }

                // if this customer already ordered, we remove the coupon
                if($has_ordered == true) {
                    WC()->cart->remove_coupon( $new_cust_coupon_code );
                    wc_add_notice( sprintf( "Coupon code: %s is only applicable for new customer." , $new_cust_coupon_code), 'error' );
                    return false;
                }
            } else {
                // customer has no order, so valid to use this coupon
                return true;
            }

        } else {
            // new user is valid
            return true;
        }
    }
}

¿Solo que esto ya no parece funcionar en la versión actual de WooCommerce? ¿Qué estoy haciendo mal? Mi versión de WordPress es 6.0 y WooCommerce es 6.5.1

  • como no funciona el código parece legítimo. tal vez verifique su lógica con respecto a los estados de los pedidos. Por cierto, no es necesario que devuelvas verdadero/falso, ya que es un gancho de acción, no un filtro.

    – Ash0ur

    hace 2 días


avatar de usuario
7uc1f3r

El código que está utilizando ya no funciona en las versiones actuales de WooCommere porque contiene código obsoleto, deficiencias y algunos pasos superfluos:

  • No es necesario usar get_posts() con varios argumentos, utilice wc_get_customer_order_count() en cambio
  • $tmp_order->ID cambiado a $tmp_order->get_id() desde WooCommerce 3
  • Tu código no tiene en cuenta a los usuarios invitados, por lo que pueden aplicar manualmente el cupón
  • El cupón no se otorga automáticamente, su código asume que los clientes han aplicado este cupón
  • los woocommerce_after_checkout_validation gancho contiene 2 parámetros
  • No es necesario que devuelva verdadero/falso, ya que es un gancho de acción, no un filtro.

Esta versión actualizada tiene en cuenta:

  • Si el se aplicó el cupónpero el cliente es NO iniciado sesión, el cupón será eliminado
  • Si el se aplicó el cupónel cliente es iniciado sesión, pero NO el primer pedidoel cupón será remoto
  • Si el se aplicó el cupónla el cliente está conectado y es el primer pedido, el cupón permanece
  • Si el cupón NO aplicadola el cliente está logueado y es el primer pedido, se aplica el cupón

Entonces obtienes:

function action_woocommerce_after_checkout_validation( $data, $error ) {
    // Change the name to your coupon
    $new_cust_coupon_code="coupon1";

    // Initialize
    $coupon_been_applied = false;
    $remove_coupon = false;

    // Get applied coupons
    $applied_coupons = WC()->cart->get_applied_coupons();

    // Has coupon already been applied by the customer
    if ( in_array( $new_cust_coupon_code, $applied_coupons ) ) {
        $coupon_been_applied = true;

        // Coupon has been applied, but customer is a guest user
        if ( ! is_user_logged_in() ) {
            $remove_coupon = true;
        }
    }

    // Customer is logged in
    if ( is_user_logged_in() ) {    
        // Check if the customer has bought before
        $has_bought_before = wc_get_customer_order_count( get_current_user_id() ) >= 1 ? true : false;

        // Coupon been applied, but customer has bought before
        if ( $coupon_been_applied && $has_bought_before ) {
            $remove_coupon = true;
        // NOT been applied AND NOT has bought before
        } elseif ( ! $coupon_been_applied && ! $has_bought_before ) {
            // Apply coupon
            WC()->cart->apply_coupon( $new_cust_coupon_code );
        }
    }

    // When true
    if ( $remove_coupon ) {
        // Remove coupon
        WC()->cart->remove_coupon( $new_cust_coupon_code );

        // Show message
        $error->add( 'validation', sprintf( __( 'Coupon code: "%s" is only applicable for logged in new customers. So the coupon has been removed', 'woocommerce' ), $new_cust_coupon_code ) );
    }
}
add_action( 'woocommerce_after_checkout_validation', 'action_woocommerce_after_checkout_validation', 10, 2 );

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad