如何在WooCommerce结账页按产品类别及数量分产品生成自定义字段?
WooCommerce结账页按产品生成对应数量的邮箱字段解决方案
核心实现代码
以下代码会遍历购物车中的每个邮箱套餐产品,为每个产品生成独立的字段区块,区块内的邮箱输入框数量和该产品的购买数量一致,字段命名关联产品ID,彻底区分不同套餐的字段:
// 在结账页添加按产品分组的邮箱字段 add_action( 'woocommerce_before_order_notes', 'add_per_product_email_fields_checkout' ); function add_per_product_email_fields_checkout( $checkout ) { // 遍历购物车所有商品 foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $product = $cart_item['data']; $product_id = $product->get_id(); $product_name = $product->get_name(); $quantity = $cart_item['quantity']; // 输出产品专属字段组容器 echo '<div class="per-product-email-fields" style="margin: 20px 0; padding: 10px; border: 1px solid #eee;">'; echo '<h4>' . esc_html( $product_name ) . ' (需填写 ' . $quantity . ' 个邮箱地址)</h4>'; // 根据购买数量生成对应数目的邮箱输入框 for ( $i = 1; $i <= $quantity; $i++ ) { woocommerce_form_field( 'product_' . $product_id . '_email_' . $i, array( 'type' => 'email', 'class' => array('form-row-wide'), 'label' => '邮箱地址 ' . $i, 'required' => true, ), $checkout->get_value( 'product_' . $product_id . '_email_' . $i ) ); } echo '</div>'; } } // 验证邮箱字段是否填写正确 add_action( 'woocommerce_checkout_process', 'validate_per_product_email_fields' ); function validate_per_product_email_fields() { foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $product_id = $cart_item['data']->get_id(); $quantity = $cart_item['quantity']; for ( $i = 1; $i <= $quantity; $i++ ) { $field_key = 'product_' . $product_id . '_email_' . $i; if ( empty( $_POST[$field_key] ) ) { wc_add_notice( sprintf( '请填写 %s 的第 %d 个邮箱地址', $cart_item['data']->get_name(), $i ), 'error' ); } elseif ( ! is_email( $_POST[$field_key] ) ) { wc_add_notice( sprintf( '%s 的第 %d 个邮箱地址格式不正确', $cart_item['data']->get_name(), $i ), 'error' ); } } } } // 将邮箱数据保存到订单商品元数据 add_action( 'woocommerce_checkout_update_order_meta', 'save_per_product_email_fields_to_order' ); function save_per_product_email_fields_to_order( $order_id ) { $order = wc_get_order( $order_id ); foreach ( $order->get_items() as $item ) { $product_id = $item->get_product_id(); $quantity = $item->get_quantity(); $emails = array(); for ( $i = 1; $i <= $quantity; $i++ ) { $field_key = 'product_' . $product_id . '_email_' . $i; if ( ! empty( $_POST[$field_key] ) ) { $emails[] = sanitize_email( $_POST[$field_key] ); } } if ( ! empty( $emails ) ) { $item->update_meta_data( '_product_emails', $emails ); $item->save(); } } } // 在订单详情页显示对应产品的邮箱 add_action( 'woocommerce_order_item_meta_end', 'display_per_product_emails_on_order', 10, 3 ); function display_per_product_emails_on_order( $item_id, $item, $order ) { $emails = $item->get_meta( '_product_emails' ); if ( ! empty( $emails ) ) { echo '<div style="margin-top: 10px;">'; echo '<strong>邮箱地址:</strong><br>'; foreach ( $emails as $email ) { echo esc_html( $email ) . '<br>'; } echo '</div>'; } } // 在订单邮件中显示对应产品的邮箱 add_action( 'woocommerce_email_order_details', 'display_per_product_emails_in_email', 15, 4 ); function display_per_product_emails_in_email( $order, $sent_to_admin, $plain_text, $email ) { foreach ( $order->get_items() as $item ) { $emails = $item->get_meta( '_product_emails' ); if ( ! empty( $emails ) ) { echo '<h4>' . esc_html( $item->get_name() ) . ' 邮箱地址</h4>'; echo '<ul>'; foreach ( $emails as $email_addr ) { echo '<li>' . esc_html( $email_addr ) . '</li>'; } echo '</ul>'; } } }
使用说明
- 把代码复制到主题的
functions.php文件,或者用「Code Snippets」这类自定义代码插件添加 - 测试添加不同邮箱套餐到购物车,检查结账页是否按产品生成对应数量的字段
- 提交订单后,查看订单详情和邮件,确认邮箱信息正确关联对应产品
可选样式优化
如果需要美化字段组样式,可添加以下CSS到主题自定义CSS面板:
.per-product-email-fields { background-color: #f9f9f9; border-radius: 8px; } .per-product-email-fields h4 { margin-top: 0; color: #2d3748; } .per-product-email-fields .form-row-wide { margin-bottom: 10px; }
内容的提问来源于stack exchange,提问作者Tayfun
相关产品推荐
相关产品推荐

