如何将自定义数据同步至WooCommerce订单及订单邮件?
Hey there! I totally get where you're coming from—getting custom cart data to show up in admin orders and emails can be tricky when you're new to WooCommerce hooks. Let's break down what went wrong and fix this step by step.
First, Why Your Previous Snippet Broke the Cart
The woocommerce_order_item_product filter you used isn't meant for saving custom metadata to orders. That hook is actually for modifying the product data attached to an order item, which is why it caused your cart to crash. We need to use the right hooks to save and display your custom fields properly.
Step 1: Save Custom Data to Order Line Items
We'll use the woocommerce_checkout_create_order_line_item hook (recommended for WooCommerce 3.0+) to save your custom wcpc_custom_product field to the order. This ensures the data gets stored with the order permanently.
Step 2: Show Custom Data in Admin Order Page
Next, we'll add a hook to display the custom info in the order details section of the admin dashboard.
Step 3: Add Custom Data to Order Emails
Finally, we'll hook into the email order details to include your custom field in customer order emails.
Full Corrected Code
Replace your problematic snippet with this complete code (keep your existing cart and price modification functions—we're adding the new parts):
<?php // Your existing code (keep this!) function wcpc_save_custom_product_field( $cart_item_data, $product_id ) { if( isset( $_REQUEST['wcpc_custom_product'] ) ) { $cart_item_data[ 'wcpc_custom_product' ] = sanitize_text_field($_REQUEST['wcpc_custom_product']); $cart_item_data[ 'wcpc_custom_price' ] = floatval($_REQUEST['wcpc_custom_price']); $cart_item_data['unique_key'] = md5( microtime().rand() ); } return $cart_item_data; } add_action( 'woocommerce_add_cart_item_data', 'wcpc_save_custom_product_field', 10, 2 ); function render_meta_on_cart_and_checkout( $cart_data, $cart_item = null ) { $custom_items = array(); if( !empty( $cart_data ) ) { $custom_items = $cart_data; } if( isset( $cart_item['wcpc_custom_product'] ) && $cart_item['wcpc_custom_product'] != '' ) { $custom_items[] = array( "name" => 'Custom', "value" => $cart_item['wcpc_custom_product'] ); } return $custom_items; } add_filter( 'woocommerce_get_item_data', 'render_meta_on_cart_and_checkout', 10, 2 ); add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' ); function add_custom_price( $cart_object ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; foreach ( $cart_object->get_cart() as $key => $value ) { if(isset($value['wcpc_custom_price'])) { $value['data']->set_price( $value['wcpc_custom_price'] ); } } } // New code to save custom data to orders function wcpc_save_order_item_meta( $item, $cart_item_key, $values, $order ) { if ( isset( $values['wcpc_custom_product'] ) && !empty( $values['wcpc_custom_product'] ) ) { $item->add_meta_data( 'Custom', $values['wcpc_custom_product'], true ); } } add_action( 'woocommerce_checkout_create_order_line_item', 'wcpc_save_order_item_meta', 10, 4 ); // Show custom data in admin order page function wcpc_display_admin_order_meta( $item_id, $item, $order ) { $custom_data = $item->get_meta( 'Custom' ); if ( !empty( $custom_data ) ) { echo '<ul class="wc-item-meta"><li><strong>' . esc_html__( 'Custom', 'woocommerce' ) . ':</strong> ' . esc_html( $custom_data ) . '</li></ul>'; } } add_action( 'woocommerce_after_order_itemmeta', 'wcpc_display_admin_order_meta', 10, 3 ); // Add custom data to order emails function wcpc_display_email_order_meta( $item, $is_visible, $plain_text, $order ) { $custom_data = $item->get_meta( 'Custom' ); if ( !empty( $custom_data ) ) { if ( $plain_text ) { echo 'Custom: ' . $custom_data . "\n"; } else { echo '<li><strong>' . esc_html__( 'Custom', 'woocommerce' ) . ':</strong> ' . esc_html( $custom_data ) . '</li>'; } } } add_filter( 'woocommerce_order_item_display_meta_key', '__return_false' ); // Hide default meta label if needed add_action( 'woocommerce_order_item_meta_end', 'wcpc_display_email_order_meta', 10, 4 ); ?>
Key Notes:
- I added
sanitize_text_field()andfloatval()to sanitize user input—this is important for security! - The
woocommerce_checkout_create_order_line_itemhook passes the order item directly, so we useadd_meta_data()to attach our custom field. - The admin display hook
woocommerce_after_order_itemmetainserts the custom data right after the default item meta in the order details. - For emails, we handle both HTML and plain text formats to ensure compatibility with all WooCommerce email templates.
How to Test:
- Add a product to your cart, fill in the custom info.
- Proceed to checkout and complete the order.
- Check the admin order page—you should see the custom "Custom" field under the order item.
- Check the customer's order email—your custom info will be included in the order details section.
That should fix both the missing order meta and the cart crash issue. Let me know if you run into any hiccups!
内容的提问来源于stack exchange,提问作者Tostino

