Q: Добавление товара при вводе купона Пытаемся сделать купон на бесплатный подарок. Подарок рандомно выбирается из 3 возможных товаров.
Делали эти манипуляции через статичный купон, равный цене товаров-подарков, но в системе учета скидка распределяется по всем товаром, что не подходит для такого магазина.
Можно ли все таки как-то применить скидку 100% только к подарку или добавлять товар-подарок в корзину уже с нулевой ценой?
    function wc_apply_coupon( $coupon_code ) {
        if ( 'sherry' === $coupon_code || 'radion' === $coupon_code || 'lentiayka' === $coupon_code || 'efim' === $coupon_code ) {
            $input = array("4398", "4396", "4397", "");
            $rand_keys = array_rand($input, 2);
            $product_id = $input[$rand_keys[0]];
            WC()->cart->add_to_cart( $product_id );
        }
    }
    add_action( 'woocommerce_applied_coupon', 'wc_apply_coupon' );


A: Создайте новый тип купона и при его добавлении добавляйте нужный товар.
// Добавляем новый тип купона в админ панель.
add_filter( 'woocommerce_coupon_discount_types', 'add_free_gift_coupon_type' );
// Добавлям товар при применении купона.
add_action( 'woocommerce_applied_coupon', 'applied_gift_coupon' );
// Меняем цену на ноль при применении купона
add_filter( 'woocommerce_add_cart_item', 'set_gift_price_data', 15 );
add_filter( 'woocommerce_get_cart_item_from_session', 'set_gift_price_data_from_session', 15, 2 );
// Скрываем возможность менять количество товара
add_filter( 'woocommerce_cart_item_quantity', 'cart_item_quantity', 5, 3 );

function add_free_gift_coupon_type($types) {
    $types['free_gift'] = 'Товар в подарок';
    return $types;
}

function applied_gift_coupon($coupon_code) {

    $gift_product = get_gift_data( $coupon_code );

    if ( ! empty ( $gift_product ) ) {
        WC()->cart->add_to_cart( $gift_product->get_id(), 1, $gift_product->get_id(), array(), array( 'free_gift' => $coupon_code ) );

    }
}

function get_gift_data($code) {

    $gift_product = '';

    $code = wc_format_coupon_code( $code );

    $coupon = new WC_Coupon( $code );

    if ( ! is_wp_error( $coupon ) && $coupon->is_type( 'free_gift' ) ) {
        // тут ваша логика для получения рандомного id товара
        return $gift_product = wc_get_product( PRODUCT_ID );
    }

    return $gift_product;
}

function set_gift_price_data($cart_item) {

    if ( ! empty ( $cart_item['free_gift'] ) ){
        $cart_item['data']->set_price( 0 );
        $cart_item['data']->set_regular_price( 0 );
        $cart_item['data']->set_sale_price( 0 );
    }

    return $cart_item;
}

function set_gift_price_data_from_session( $cart_item, $values) {
    if ( ! empty( $values['free_gift'] ) ) {
        $cart_item['free_gift'] = $values['free_gift'];
        $cart_item = set_gift_price_data( $cart_item );
    }

    return $cart_item;
}

function cart_item_quantity( $product_quantity, $cart_item_key, $cart_item ){

    if ( ! empty ( $cart_item['free_gift'] ) ) {
        $product_quantity = sprintf( '%1$s <input type="hidden" name="cart[%2$s][qty]" value="%1$s" />', $cart_item['quantity'], $cart_item_key );
    }

    return $product_quantity;
}

Так же вам понадобится удалять товар при удалении купона, для это можете воспользоваться хуками woocommerce_removed_coupon и woocommerce_check_cart_items
Если хотите доп. данные через админку то можете добавить новые мета поля к типу купона. Для этого можно воспользоваться хуками woocommerce_coupon_options и woocommerce_coupon_options_save

A: // Удалим подарочный товар при удалении купона
add_action( 'woocommerce_removed_coupon', 'delete_free_gift' );
function delete_free_gift( $coupon_code ){
    global $woocommerce;
    $code = wc_format_coupon_code( $coupon_code );
    $coupon = new WC_Coupon( $code );
    if ( ! is_wp_error( $coupon ) && $coupon->is_type( 'free_gift' ) ) {
        foreach($woocommerce->cart->get_cart() as $key => $val ) {
            if ($val["free_gift"] == 'YOUR_COUPON_CODE' ){
                $woocommerce->cart->remove_cart_item( $val["key"] );
            }
        }
    }
}

