You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取客户所选的WooCommerce订阅产品变体

解决WooCommerce订阅订单中获取选中变体属性的问题

我看到你在处理WooCommerce收款后获取订阅订单的变体属性时遇到了卡点——核心问题是你混淆了订单项目(Order Item)对象和产品/变体(Product/Variation)对象的差异,直接调用订单项目的get_variation_attributes()方法才会触发内部错误。下面给你拆解问题并提供修正方案:

问题根源

你循环中的$product其实是WC_Order_Item_Product对象(订单里的商品条目),而非真正的产品/变体实例。这类对象没有get_variation_attributes()方法,所以直接调用会报错。我们需要先从订单项中拿到对应的变体ID,再获取真正的变体产品对象。

修正后的代码实现

// 假设这是在合适的WooCommerce钩子中,比如woocommerce_payment_complete
add_action('woocommerce_payment_complete', 'get_subscription_variation_details', 10, 1);
function get_subscription_variation_details($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    foreach ($order->get_items() as $item_id => $order_item) {
        // 获取订单项的基础信息
        $product_name = $order_item->get_name();
        $product_id = $order_item->get_product_id();
        $variation_id = $order_item->get_variation_id(); // 关键:拿到选中的变体ID
        $payment_amount = $order_item->get_total();

        // 获取产品实例,判断是否为订阅产品
        $product = wc_get_product($product_id);
        if (!WC_Subscriptions_Product::is_subscription($product)) continue;

        // 如果是变体产品(variation类型)
        if ($variation_id > 0) {
            $variation = wc_get_product($variation_id);
            if (!$variation) continue;

            // 方式1:从变体产品对象获取选中的属性
            $variation_attributes = $variation->get_variation_attributes();
            foreach ($variation_attributes as $attribute_taxonomy => $term_slug) {
                $taxonomy = str_replace('attribute_', '', $attribute_taxonomy);
                $attribute_name = get_taxonomy($taxonomy)->labels->singular_name;
                $selected_term = get_term_by('slug', $term_slug, $taxonomy);
                $business_speciality = $selected_term ? $selected_term->name : $term_slug;
                // 这里可以处理获取到的属性值,比如存入变量或输出
                // echo "{$attribute_name}: {$business_speciality}<br>";
            }

            // 方式2:从订单项的元数据中直接获取(更快捷)
            $formatted_meta = $order_item->get_formatted_meta_data('_', true);
            foreach ($formatted_meta as $meta) {
                // 变体属性的元数据key通常以attribute_开头
                if (str_starts_with($meta->key, 'attribute_')) {
                    $attribute_name = str_replace('attribute_', '', $meta->key);
                    $taxonomy = wc_attribute_taxonomy_name($attribute_name);
                    if (taxonomy_exists($taxonomy)) {
                        $term = get_term_by('slug', $meta->value, $taxonomy);
                        $attribute_label = wc_attribute_label($attribute_name);
                        $selected_value = $term ? $term->name : $meta->value;
                        // echo "{$attribute_label}: {$selected_value}<br>";
                    }
                }
            }
        }
    }
}

关键改进点

  • 区分订单项和产品对象:通过$order_item->get_variation_id()拿到用户选中的变体ID,再用wc_get_product()获取真正的变体实例。
  • 两种属性获取方式:既可以从变体产品对象中拿原始属性,也可以直接从订单项的元数据中读取格式化后的属性信息,后者更贴合订单中显示的内容。
  • 容错处理:增加了对变体实例、分类、术语的存在判断,避免因数据异常导致的错误。

内容的提问来源于stack exchange,提问作者Debbie Kurth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:45:12