Soporte » Plugins y Hacks » WooCommerce » Guardar cupón personalizado en datos del pedido y enviar por correo

  • Buenos días,
    Tengo el código para crear un cupón personalizado para cada cliente que se muestra en la página de GRACIAS, pero si cierran esa página el cupón ya no es accesible al cliente en ninguna parte. Me gustaría poder guardar ese cupón en los datos del pedido y que se enviara automáticamente en el mail de procesando y de completado.
    Adjunto el código que tengo actualmente:

    // Crea un cupón descuento único para cada cliente al terminar su compra
    if ( in_array( 'woocommerce/woocommerce.php', get_option( 'active_plugins' ) ) ){
    
    	add_filter( 'woocommerce_thankyou_order_received_text', 'create_automatic_coupon_only_for_this_customer', 99, 2 );
    	function create_automatic_coupon_only_for_this_customer( $message, $order ){
    
    		// Configuración del cupón
    		$discount_type = 'percent'; // Aquí defines el tipo de descuento que aplica este cupón. Por defecto está configurado en porcentaje 'percent', para 	descuento fijo usa 'fixed_cart'
    		$amount = 10; //Aquí defines la cantidad de descuento asociada a este cupón
    		$expiration = 180; // Aquí debes indicar la validez del cupón en días
    
    		// Elimina cupones caducados y comprueba si ya existe un cupón asociado a este pedido
    		$coupon_id = clean_expired_coupons_and_check_coupons_order( $order );
    
            	$order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : wc_clean( $_GET['key'] ) );
    
            	if ( $order->get_id() > 0 ) {
    	
            	    	// Comprueba que el pedido existe y que todavía no hay cupón asociado al pedido
            	    	if ( $order->get_order_key() == $order_key ) {
    			
    				if ( !$coupon_id ) {
    					
            				//Crea un código de cupón único para este cliente
    					$customer_email = $order->get_billing_email();
    					$customer_email = explode( '@', $customer_email );
    					$customer_email = $customer_email[0];
    					$sufix = date( 'Hms' );
    				
    					// Calcula la fecha de caducidad
    					$date = date( 'Y-m-d' );
    					$expiry_date = strtotime( $date .'+ '. $expiration .' days' );
    					$expiry_date = date( 'Y-m-d', $expiry_date );
    				
    					$args = array(
    						'coupon_code' 			=> $customer_email.'_'.$sufix,
    						'discount_type' 		=> $discount_type,
    						'amount' 			=> $amount,
    						'individual_use' 		=> 'yes',
    						'usage_limit' 			=> 1,
    						'product_ids' 			=> '',
    						'exclude_product_ids' 		=> '',
    						'expiry_date' 			=> $expiry_date,
    						'apply_before_tax' 		=> '',
    						'free_shipping' 		=> 'no',
    					);
    				
    					$coupon_code = strtoupper( $args[ 'coupon_code' ] );
    				
    					$coupon = array(
    						'post_title' => $coupon_code,
    						'post_content' => '',
    						'post_status' => 'publish',
    						'post_author' => 1,
    						'post_type'		=> 'shop_coupon'
    					);
    				
    					$new_coupon_id = wp_insert_post( $coupon );
    				
    					update_post_meta( $new_coupon_id, 'discount_type', $args[ 'discount_type' ] );
    					update_post_meta( $new_coupon_id, 'coupon_amount', $args[ 'amount' ] );
    					update_post_meta( $new_coupon_id, 'individual_use', $args[ 'individual_use' ] );
    					update_post_meta( $new_coupon_id, 'product_ids', $args[ 'product_ids' ] );
    					update_post_meta( $new_coupon_id, 'exclude_product_ids', $args[ 'exclude_product_ids' ] );
    					update_post_meta( $new_coupon_id, 'usage_limit', $args[ 'usage_limit' ] );
    					update_post_meta( $new_coupon_id, 'expiry_date', $args[ 'expiry_date' ] );
    					update_post_meta( $new_coupon_id, 'apply_before_tax', $args[ 'apply_before_tax' ] );
    					update_post_meta( $new_coupon_id, 'free_shipping', $args[ 'free_shipping' ] );
    					update_post_meta( $new_coupon_id, 'order-id', $order->get_id() );
    				
    					if ( is_wp_error( $new_coupon_id ) ){
    				
    						return false;
    					}
    				}else{
    
    					$coupon = get_post( $coupon_id );
    					$coupon_code = $coupon->post_title;
    				}
    		
    				// Muestra el cupón en la página de finalizar compra
    				$message .= get_coupon_discount_for_the_next_purchase( $coupon_code, $expiration, $amount, $discount_type );
            	    	}
            	}
    
            	return $message;
    	}
    	
    	function get_coupon_discount_for_the_next_purchase( $coupon_code, $expiration, $amount, $discount_type ){
    	
    		$discount = $amount;
    		$discount .= 'percent' == $discount_type? '%' : get_woocommerce_currency();
    		ob_start();
    		?>
    		<div style="margin: 0 0 3.5em; text-align:center;">
    			Para agradecerte tu confianza en nosotros, te hemos preparado un <strong>cupón de descuento del <?php echo $discount; ?> para tu próxima compra:</strong>
    
    			<h3 style="text-align:center;">TU DESCUENTO</h3>
    			<div style="text-align: center; font-weight: bold; border: 2px #c7c7c7; border-style: dashed; padding: 13px; width: 50%; margin: 10px auto;"><?php echo $coupon_code;?></div>
    			<strong>El cupón tiene una validez de <?php echo $expiration; ?> días</strong>. Pero no lo dejes demasiado porque una vez transcurrido ese periodo, el cupón ya no será valido.
    
    		</div>
    		<?php
    		$content = ob_get_contents();
    		ob_end_clean();
    
    		return $content;
    	}
    
    	function clean_expired_coupons_and_check_coupons_order( $order = false ){
    		$coupon_exist = false;
    
    		if ( isset( $order ) ) {
    			
    			$arg = array(
    				'post_type' => array( 'shop_coupon' ),
    			        'meta_key' => 'order-id'
    			);
    
    			$auto_coupon_list = new WP_Query( $arg );
    
    			foreach ( $auto_coupon_list->posts as $key => $coupon ) {
    				
    				// Elimina cupones caducados
    				$coupon_expiry_date = get_post_meta( $coupon->ID, 'expiry_date', true );
    				$today_date = date( 'Y-m-d' );
    
    				if ( !empty( $coupon_expiry_date ) && ( $today_date > $coupon_expiry_date ) ) {
    					
    					wp_delete_post( $coupon->ID );
    					continue;
    				}
    
    				// Busca un cupón automático asociado a este pedido
    				$order_id_coupon_vinculated = get_post_meta( $coupon->ID, 'order-id', true );
    				if ( !$coupon_exist && ( $order_id_coupon_vinculated == $order->get_id() ) ) {
    
    					$coupon_exist = $coupon->ID;
    				}
    			}
    		}
    
    		return $coupon_exist;
    	}
    }
Viendo 5 respuestas - de la 1 a la 5 (de un total de 5)
  • Hola @carlosgj87,

    Añadiendo el mismo mensaje en las notas del pedido creo que te valdría:

    // Add the order note
    $order->add_order_note( $message );
    
    // Save the data
    $order->save();

    Tu código quedaría así:

    // Crea un cupón descuento único para cada cliente al terminar su compra
    if ( in_array( 'woocommerce/woocommerce.php', get_option( 'active_plugins' ) ) ){
    
    	add_filter( 'woocommerce_thankyou_order_received_text', 'create_automatic_coupon_only_for_this_customer', 99, 2 );
    	function create_automatic_coupon_only_for_this_customer( $message, $order ){
    
    		// Configuración del cupón
    		$discount_type = 'percent'; // Aquí defines el tipo de descuento que aplica este cupón. Por defecto está configurado en porcentaje 'percent', para 	descuento fijo usa 'fixed_cart'
    		$amount = 10; //Aquí defines la cantidad de descuento asociada a este cupón
    		$expiration = 180; // Aquí debes indicar la validez del cupón en días
    
    		// Elimina cupones caducados y comprueba si ya existe un cupón asociado a este pedido
    		$coupon_id = clean_expired_coupons_and_check_coupons_order( $order );
    
            	$order_key = apply_filters( 'woocommerce_thankyou_order_key', empty( $_GET['key'] ) ? '' : wc_clean( $_GET['key'] ) );
    
            	if ( $order->get_id() > 0 ) {
    	
            	    	// Comprueba que el pedido existe y que todavía no hay cupón asociado al pedido
            	    	if ( $order->get_order_key() == $order_key ) {
    			
    						if ( !$coupon_id ) {
    							
    								//Crea un código de cupón único para este cliente
    							$customer_email = $order->get_billing_email();
    							$customer_email = explode( '@', $customer_email );
    							$customer_email = $customer_email[0];
    							$sufix = date( 'Hms' );
    						
    							// Calcula la fecha de caducidad
    							$date = date( 'Y-m-d' );
    							$expiry_date = strtotime( $date .'+ '. $expiration .' days' );
    							$expiry_date = date( 'Y-m-d', $expiry_date );
    						
    							$args = array(
    								'coupon_code' 			=> $customer_email.'_'.$sufix,
    								'discount_type' 		=> $discount_type,
    								'amount' 			=> $amount,
    								'individual_use' 		=> 'yes',
    								'usage_limit' 			=> 1,
    								'product_ids' 			=> '',
    								'exclude_product_ids' 		=> '',
    								'expiry_date' 			=> $expiry_date,
    								'apply_before_tax' 		=> '',
    								'free_shipping' 		=> 'no',
    							);
    						
    							$coupon_code = strtoupper( $args[ 'coupon_code' ] );
    						
    							$coupon = array(
    								'post_title' => $coupon_code,
    								'post_content' => '',
    								'post_status' => 'publish',
    								'post_author' => 1,
    								'post_type'		=> 'shop_coupon'
    							);
    						
    							$new_coupon_id = wp_insert_post( $coupon );
    						
    							update_post_meta( $new_coupon_id, 'discount_type', $args[ 'discount_type' ] );
    							update_post_meta( $new_coupon_id, 'coupon_amount', $args[ 'amount' ] );
    							update_post_meta( $new_coupon_id, 'individual_use', $args[ 'individual_use' ] );
    							update_post_meta( $new_coupon_id, 'product_ids', $args[ 'product_ids' ] );
    							update_post_meta( $new_coupon_id, 'exclude_product_ids', $args[ 'exclude_product_ids' ] );
    							update_post_meta( $new_coupon_id, 'usage_limit', $args[ 'usage_limit' ] );
    							update_post_meta( $new_coupon_id, 'expiry_date', $args[ 'expiry_date' ] );
    							update_post_meta( $new_coupon_id, 'apply_before_tax', $args[ 'apply_before_tax' ] );
    							update_post_meta( $new_coupon_id, 'free_shipping', $args[ 'free_shipping' ] );
    							update_post_meta( $new_coupon_id, 'order-id', $order->get_id() );
    						
    							if ( is_wp_error( $new_coupon_id ) ){
    						
    								return false;
    							}
    						}else{
    
    							$coupon = get_post( $coupon_id );
    							$coupon_code = $coupon->post_title;
    						}
    				
    						// Muestra el cupón en la página de finalizar compra
    						$message .= get_coupon_discount_for_the_next_purchase( $coupon_code, $expiration, $amount, $discount_type );
    
    						// Add the order note
    						$order->add_order_note( $message );
    
    						// Save the data
    						$order->save();
            	    	}
            	}
    
            	return $message;
    	}
    	
    	function get_coupon_discount_for_the_next_purchase( $coupon_code, $expiration, $amount, $discount_type ){
    	
    		$discount = $amount;
    		$discount .= 'percent' == $discount_type? '%' : get_woocommerce_currency();
    		ob_start();
    		?>
    		<div style="margin: 0 0 3.5em; text-align:center;">
    			Para agradecerte tu confianza en nosotros, te hemos preparado un <strong>cupón de descuento del <?php echo $discount; ?> para tu próxima compra:</strong>
    
    			<h3 style="text-align:center;">TU DESCUENTO</h3>
    			<div style="text-align: center; font-weight: bold; border: 2px #c7c7c7; border-style: dashed; padding: 13px; width: 50%; margin: 10px auto;"><?php echo $coupon_code;?></div>
    			<strong>El cupón tiene una validez de <?php echo $expiration; ?> días</strong>. Pero no lo dejes demasiado porque una vez transcurrido ese periodo, el cupón ya no será valido.
    
    		</div>
    		<?php
    		$content = ob_get_contents();
    		ob_end_clean();
    
    		return $content;
    	}
    
    	function clean_expired_coupons_and_check_coupons_order( $order = false ){
    		$coupon_exist = false;
    
    		if ( isset( $order ) ) {
    			
    			$arg = array(
    				'post_type' => array( 'shop_coupon' ),
    			        'meta_key' => 'order-id'
    			);
    
    			$auto_coupon_list = new WP_Query( $arg );
    
    			foreach ( $auto_coupon_list->posts as $key => $coupon ) {
    				
    				// Elimina cupones caducados
    				$coupon_expiry_date = get_post_meta( $coupon->ID, 'expiry_date', true );
    				$today_date = date( 'Y-m-d' );
    
    				if ( !empty( $coupon_expiry_date ) && ( $today_date > $coupon_expiry_date ) ) {
    					
    					wp_delete_post( $coupon->ID );
    					continue;
    				}
    
    				// Busca un cupón automático asociado a este pedido
    				$order_id_coupon_vinculated = get_post_meta( $coupon->ID, 'order-id', true );
    				if ( !$coupon_exist && ( $order_id_coupon_vinculated == $order->get_id() ) ) {
    
    					$coupon_exist = $coupon->ID;
    				}
    			}
    		}
    
    		return $coupon_exist;
    	}
    }

    Para que esas notas salgan en el email del usuario habría que añadir también el siguiente script en el functions.php:

    
    add_action( 'woocommerce_email_order_meta', 'woo_add_order_notes_to_email' );
    function woo_add_order_notes_to_email() {
    
    	global $woocommerce, $post;
    
    	$args = array(
    		'post_id' 	=> $post->ID,
    		'approve' 	=> 'approve',
    		'type' 		=> 'order_note'
    	);
    
    	$notes = get_comments( $args );
    	
    	echo '<h2>' . __( 'Order Notes', 'woocommerce' ) . '</h2>';
    
    	echo '<ul class="order_notes">';
    
    		foreach($notes as $note) :
    			echo '<li rel="'. $note->comment_ID.'" class="">';
    				echo $note->comment_content . '<br />';
    			echo '</li>';
    		endforeach;
    
    	echo '</ul>';
    }

    Espero que te sirva.

    Un saludo

    Iniciador del debate carlosgj87

    (@carlosgj87)

    Muchísimas gracias @jose-lazo, funciona perfectamente!!!

    Iniciador del debate carlosgj87

    (@carlosgj87)

    Hola de nuevo @jose-lazo, tengo un problema. El cupón de guarda en las notas del pedido, pero no es visible por el cliente desde el apartado de mis pedidos en mi cuenta y no se envía por email… En el correo solo aparece «order notes»…
    Muchas gracias por todo.

    Iniciador del debate carlosgj87

    (@carlosgj87)

    @jose-lazo sería posible usar una función que cree un campo personalizado en el checkout que no sea visible al comprador y se rellene con el valor del cupón personalizado en vez de agregarlo a una nota de pedido??
    Algo parecido a esto pero que no te pida que lo rellenes, que no sea visible, que coja el valor del cupón personalizado con el código del principio.

    add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
    
    function my_custom_checkout_field( $checkout ) {
    
        echo '<div id="my_custom_checkout_field"><h2>' . __('Cupón personalizado') . '</h2>';
    
        woocommerce_form_field( 'my_field_name', array(
            'type'          => 'text',
            'class'         => array('my-field-class form-row-wide'),
            'label'         => __('Cupón personalizado'),
            'placeholder'   => __('Código del cupón'),
            ), $checkout->get_value( 'my_field_name' ));
    
        echo '</div>';
    
    }
    add_action ('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
    
    function my_custom_checkout_field_update_order_meta ($ order_id) {
        if (! empty ($ _POST ['my_field_name'])) {
            update_post_meta ($ order_id, 'Cupón personalizado', sanitize_text_field ($ _POST ['my_field_name']));
        }
    }
    add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
    
    function my_custom_checkout_field_display_admin_order_meta($order){
        echo '<p><strong>'.__('Cupón personalizado').':</strong> ' . get_post_meta( $order->id, 'Cupón personalizado', true ) . '</p>';
    }
    add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
    
    function my_custom_order_meta_keys( $keys ) {
         $keys[] = 'Cupón personalizado';
         return $keys;
    }
    • Esta respuesta fue modificada hace 4 años, 11 meses por carlosgj87.

    Hola @jose-lazo acabo de implementar tu código muchas gracias, aunque no me funcionó aún, en el correo que llega sale ORDER NOTES, pero vacío, no sale el código de cupón, te agradezco inmensamente si me puedes ayudar a resolverlo.

    Saludos!

Viendo 5 respuestas - de la 1 a la 5 (de un total de 5)
  • El debate ‘Guardar cupón personalizado en datos del pedido y enviar por correo’ está cerrado a nuevas respuestas.