如何获取客户所选的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
相关产品推荐
相关产品推荐

