2026年7月25日

2026年7月25日

WordPressのWooCommerceエラーを解決する方法

はじめに

WooCommerceで商品アーカイブページに商品が一覧表示されない・「カートに追加」ボタンをクリックしてもエラーになる・決済ページでリダイレクトループが発生する・注文確認メールが顧客に届かない・在庫数が正しく更新されないといった問題は、WooCommerceのフックシステムとWC関数の使い方を正しく理解することで解決できます。

症状・原因

  • woocommerce_product_querypre_get_postsでクエリを変更しているため商品が表示されない
  • カートページのURLが正しく設定されていないか、カートショートコードが削除されている
  • 決済ゲートウェイの設定(API キー・Webhook URL)が間違っている
  • WordPressのメール送信設定(SMTPプラグイン競合・From アドレス不一致)が原因でメールが届かない

解決手順

ステップ1:WooCommerceの状態を診断する

# WooCommerce のシステム情報を確認
wp wc tool run verify_checkout_files --user=1
wp wc system_status list --format=table

# WooCommerce のページ設定を確認
wp eval "
echo 'Cart: ' . wc_get_cart_url() . PHP_EOL;
echo 'Checkout: ' . wc_get_checkout_url() . PHP_EOL;
echo 'My Account: ' . wc_get_page_permalink('myaccount') . PHP_EOL;
"

# 在庫状態の確認
wp wc product list --format=table --fields=id,name,stock_status,stock_quantity

# 注文一覧の確認
wp wc shop_order list --format=table --fields=id,status,total

# WooCommerce のキャッシュをクリア
wp wc tool run clear_transients --user=1

ステップ2:商品クエリの問題を修正する

// WooCommerce 商品クエリを正しくカスタマイズ
add_action('woocommerce_product_query', function(WC_Query $q): void {
    // ✅ woocommerce_product_query フックを使う(pre_get_posts より安全)
    if (!is_admin()) {
        $q->set('orderby', 'date');
        $q->set('order', 'DESC');
        $q->set('posts_per_page', 12);
    }
}, 10);

// 商品を条件でフィルタリング(カスタムフィールド)
add_action('woocommerce_product_query', function(WP_Query $q): void {
    $tax_query = (array) $q->get('tax_query');
    $tax_query[] = [
        'taxonomy' => 'product_cat',
        'field'    => 'slug',
        'terms'    => ['sale', 'featured'],
        'operator' => 'IN',
    ];
    $q->set('tax_query', $tax_query);
});

// wc_get_products() で商品を取得(WP_Query の代替)
$products = wc_get_products([
    'status'       => 'publish',
    'stock_status' => 'instock',
    'limit'        => 10,
    'orderby'      => 'date',
    'order'        => 'DESC',
    'category'     => ['sale'],
    'return'       => 'objects',
]);

foreach ($products as $product) {
    echo esc_html($product->get_name()) . ': ';
    echo wc_price($product->get_price()) . '<br>';
}

ステップ3:カートと決済の問題を修正する

// カートページのショートコードが削除されていないか確認して再設定
add_action('admin_init', function(): void {
    $cart_page_id = wc_get_page_id('cart');
    if ($cart_page_id > 0) {
        $page = get_post($cart_page_id);
        if ($page && strpos($page->post_content, '[woocommerce_cart]') === false) {
            // ショートコードが消えていたら復元
            wp_update_post([
                'ID'           => $cart_page_id,
                'post_content' => '[woocommerce_cart]',
            ]);
        }
    }
});

// カートへの追加をプログラムで実行
function add_product_to_cart(int $product_id, int $quantity = 1, array $variation = []): bool {
    if (!class_exists('WooCommerce')) {
        return false;
    }

    $cart_item_key = WC()->cart->add_to_cart(
        $product_id,
        $quantity,
        0,           // variation_id
        $variation,  // variation attributes
        []           // extra cart item data
    );

    return $cart_item_key !== false;
}

// カートの合計・商品数を取得
add_action('wp_ajax_get_cart_count', 'get_cart_count_handler');
add_action('wp_ajax_nopriv_get_cart_count', 'get_cart_count_handler');

function get_cart_count_handler(): void {
    wp_send_json_success([
        'count'    => WC()->cart->get_cart_contents_count(),
        'total'    => WC()->cart->get_cart_total(),
        'subtotal' => WC()->cart->get_cart_subtotal(),
    ]);
}

// 決済ページへのリダイレクトループを修正
add_filter('woocommerce_checkout_redirect_empty_cart', '__return_false');

ステップ4:注文処理とメールを修正する

// 注文ステータスのカスタマイズ
add_filter('wc_order_statuses', function(array $statuses): array {
    // カスタム注文ステータスを追加
    $statuses['wc-awaiting-approval'] = '承認待ち';
    return $statuses;
});

// カスタムステータスを登録
add_action('init', function(): void {
    register_post_status('wc-awaiting-approval', [
        'label'                     => '承認待ち',
        'public'                    => true,
        'exclude_from_search'       => false,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop('承認待ち (%s)', '承認待ち (%s)'),
    ]);
});

// 注文ステータス変更時のアクション
add_action('woocommerce_order_status_changed', function(int $order_id, string $old_status, string $new_status): void {
    $order = wc_get_order($order_id);
    if (!$order) {
        return;
    }

    if ($new_status === 'completed') {
        // 注文完了時の処理
        $customer_id = $order->get_customer_id();
        update_user_meta($customer_id, 'last_order_date', current_time('mysql'));

        // カスタムメールを送信
        $mailer = WC()->mailer();
        $mailer->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
    }
}, 10, 3);

// 注文メールのFrom アドレスを変更
add_filter('woocommerce_email_from_address', function(string $from): string {
    return 'orders@example.com';
});

ステップ5:在庫管理とパフォーマンス最適化

// 在庫数をプログラムで更新
function update_product_stock(int $product_id, int $quantity): void {
    $product = wc_get_product($product_id);
    if (!$product) {
        return;
    }

    // 在庫管理を有効化
    $product->set_manage_stock(true);
    $product->set_stock_quantity($quantity);
    $product->set_stock_status($quantity > 0 ? 'instock' : 'outofstock');
    $product->save();

    // WooCommerce キャッシュをクリア
    wc_delete_product_transients($product_id);
}

// 在庫切れ商品の非表示(カタログから除外)
add_filter('woocommerce_product_is_visible', function(bool $visible, int $product_id): bool {
    $product = wc_get_product($product_id);
    if ($product && !$product->is_in_stock()) {
        // 在庫切れ商品をカタログから除外(設定に応じて)
        $hide_oos = get_option('woocommerce_hide_out_of_stock_items') === 'yes';
        return $hide_oos ? false : $visible;
    }
    return $visible;
}, 10, 2);

// WooCommerce のクエリパフォーマンス改善
add_filter('woocommerce_product_data_store_cpt_get_products_query', function(array $query, array $query_vars): array {
    // 不要なメタクエリを削減
    if (isset($query_vars['no_found_rows'])) {
        $query['no_found_rows'] = $query_vars['no_found_rows'];
    }
    return $query;
}, 10, 2);

注意事項

  • WooCommerceのカート・決済・マイアカウントページを削除しないでください。これらのページには必須のショートコード([woocommerce_cart]等)が含まれており、削除すると決済フローが完全に壊れます。「WooCommerce → ステータス → ツール → WCページを作成」で再作成できます
  • WC()->cartはフロントエンドでのみ初期化されます。管理画面やWP-CLIでカートを操作する場合はwc_load_cart()を呼び出してから使用してください

まとめ

WooCommerceエラーの解決は①wp wc system_statusでシステム状態を確認・wc_get_cart_url()でページURL確認・wp wc tool run clear_transientsでキャッシュクリア、②woocommerce_product_queryフックでクエリカスタマイズ・wc_get_products()でWP_Queryより安全に商品取得・tax_queryで商品カテゴリーフィルタリング、③カートページのショートコードを確認・WC()->cart->add_to_cart()でプログラム追加・wp_ajaxでカート件数をAJAX取得、④register_post_statusでカスタム注文ステータス追加・woocommerce_order_status_changedフックで完了処理・WC()->mailer()でメール送信、⑤$product->set_stock_quantity()で在庫数更新・wc_delete_product_transients()でキャッシュ削除・woocommerce_product_is_visibleで在庫切れ商品を非表示の手順で解決します。

お気軽にご相談ください

お見積りへ お問い合わせへ