为何PHP代码无法修改WooCommerce订阅产品的金额?
问题原因及解决方案
核心问题分析
你的代码无法修改WooCommerce订阅产品的定期价格,主要有3个关键原因:
- 自定义字段未对订阅产品开放:第一个函数里的
options_group容器只添加了show_if_simple show_if_external show_if_composite类,订阅产品(subscription类型)看不到这个"采购价"输入框,自然无法触发后续的价格计算逻辑。 - 直接修改元数据无效:WooCommerce订阅产品的定期价格有专门的产品对象方法管理,不是简单通过
update_post_meta修改_subscription_price就能生效的——订阅插件内部会通过产品类的方法同步价格数据,直接改元数据会被覆盖或不被系统识别。 - 价格计算逻辑未适配订阅产品:当前代码只调用了普通产品的
set_price()和set_regular_price()方法,订阅产品需要调用专属的价格设置方法,才能正确更新定期价格。
修改后的完整代码
// Adding and displaying additional product pricing custom fields add_action( 'woocommerce_product_options_pricing', 'additional_product_pricing_option_fields', 50 ); function additional_product_pricing_option_fields() { $domain = "woocommerce"; global $post; // 新增show_if_subscription类,让订阅产品也能看到该字段 echo '</div><div class="options_group pricing show_if_simple show_if_external show_if_composite show_if_subscription">'; woocommerce_wp_text_input( array( 'id' => '_purchase_price', 'label' => __("Prix d'achat ($) (si supérieur à 0, il calcule le prix régulier de vente)", $domain ) . ' ('. get_woocommerce_currency_symbol() . ')', 'placeholder' => '', 'description' => __("Prix d'achat ($) (si supérieur à 0, il calcule le prix régulier de vente)", $domain ), 'desc_tip' => true, ) ); echo '<input type="hidden" name="_custom_price_nonce" value="' . wp_create_nonce() . '">'; } // Utility function that save "Rate margin" and "Purchase_price" custom fields values function saving_rate_margin_and_purchase_price( $product ) { // Security check if ( isset($_POST['_custom_price_nonce']) && ! wp_verify_nonce($_POST['_custom_price_nonce']) ) { return; } // Save "Rate margin" and "Purchase_price" custom fields values if(isset($_POST['_purchase_price']) ) { $product->update_meta_data('_purchase_price', sanitize_text_field( (float) $_POST['_purchase_price'] ) ); } } // Utility function: Calculate and save product price from the "Rate margin" and the "Purchase price" custom fields function calculate_and_save_new_product_price( $product ) { // Disable when product is on sale if( isset($_POST['_sale_price']) && $_POST['_sale_price'] > 0 ){ return; } // Calculate and save the new price if(isset($_POST['_purchase_price']) && $_POST['_purchase_price'] > 0 ) { // Catch the pricing data $rate_margin = (float) get_option( 'dbi_example_plugin_options' )['pctrate']; $purchase_price = (float) $_POST['_purchase_price']; $new_price = (100-$rate_margin)/100 * $purchase_price; // 根据产品类型处理价格更新 if ( $product->is_type('subscription') ) { // 订阅产品:使用专属方法设置定期价格 $product->set_regular_price( $new_price ); // 如果需要设置订阅的初始价格或其他价格维度,可添加对应方法 // $product->set_price( $new_price ); } else { // 普通产品:原逻辑保留 $active_price = (float) $product->get_price(); if( $new_price !== $active_price ) { $product->set_price( $new_price ); $product->set_regular_price( $new_price ); } } } } // Saving and calculating prices add_action( 'woocommerce_admin_process_product_object', 'update_product_meta_data' ); function update_product_meta_data( $product ) { // Saving "Rate margin" and "Purchase_price" custom fields values saving_rate_margin_and_purchase_price( $product ); // Calculate and save product price from the "Rate margin" and the "Purchase price" custom fields calculate_and_save_new_product_price( $product ); }
关键修改说明
- 开放订阅产品的自定义字段:在
options_group的类中添加show_if_subscription,让订阅产品的编辑页面能显示"采购价"输入框。 - 适配订阅产品的价格设置:通过
$product->is_type('subscription')判断产品类型,调用订阅产品类的set_regular_price()方法——这是WooCommerce订阅插件官方推荐的方式,能确保价格数据同步到所有相关的订阅属性中,避免直接修改元数据的无效问题。 - 移除无效的元数据更新:删掉了原代码中的
update_post_meta($product->get_id(),'_subscription_price',$new_price);,改用产品对象的原生方法处理价格更新。
内容的提问来源于stack exchange,提问作者user22656153
相关产品推荐
相关产品推荐

