I have 3 custom fields in woocommerce:
Matter reference number, invoice number and soliciter dealing with case (code next, if you dont want to see it just scroll down, its not that important)
add_action('woocommerce_after_order_notes', 'matter_reference_number_func');
function matter_reference_number_func( $checkout ) {
echo '<div id="matter_ref"><h3>'.__('Matter reference number').'</h3>';
woocommerce_form_field( 'matter_reference_number', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'placeholder' => __('Matter reference number'),
), $checkout->get_value( 'matter_ref_num' ));
echo '</div>';
}
add_action('woocommerce_after_order_notes', 'invoice_number_func');
function invoice_number_func( $checkout ) {
echo '<div id="inv_num"><h3>'.__('Invoice number').'</h3>';
woocommerce_form_field( 'invoice_number', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'placeholder' => __('Invoice number'),
), $checkout->get_value( 'invoice_num' ));
echo '</div>';
}
add_action('woocommerce_after_order_notes', 'sol_deal_func');
function sol_deal_func( $checkout ) {
echo '<div id="sol_deal"><h3>'.__('Solicitor dealing with matter').'</h3>';
woocommerce_form_field( 'matter_reference_number', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'placeholder' => __('Solicitor dealing with matter'),
), $checkout->get_value( 'sol_deal' ));
echo '</div>';
}
Now however when I try to save the values they do not appear in the email to client nor in the admin, or even on confirm page. According the the docs this should be sufficient to do that; but it isnt.
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'matter_ref_num_checkout_field_update_order_meta');
function matter_ref_num_checkout_field_update_order_meta( $order_id ) {
if ($_POST['matter_ref_num']) update_post_meta( $order_id, 'Matter Reference Number', esc_attr($_POST['matter_ref_num']));
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'invoice_num_checkout_field_update_order_meta');
function invoice_num_checkout_field_update_order_meta( $order_id ) {
if ($_POST['invoice_num']) update_post_meta( $order_id, 'Invoice Number', esc_attr($_POST['invoice_num']));
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'sol_deal_checkout_field_update_order_meta');
function sol_deal_checkout_field_update_order_meta( $order_id ) {
if ($_POST['sol_deal']) update_post_meta( $order_id, 'Solicitor Dealing With Matter', esc_attr($_POST['sol_deal']));
}
You are using the hook to update the post meta (being the post id the order id). If you check your database you should be able to see those fields under the appropriate post id meta.
If you want to add them to the emails you'll need to use another hook too:
woocommerce_email_order_meta_keys
Here is a reference from woocommerce documentation:
/**
* Add the field to order emails
**/
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
function my_custom_checkout_field_order_meta_keys( $keys ) {
$keys[] = 'My Field';
return $keys;
}
You really only need to use one hook per action and place your code there, eg:
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta');
function custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['matter_ref_num']) update_post_meta( $order_id, 'Matter Reference Number', esc_attr($_POST['matter_ref_num']));
if ($_POST['invoice_num']) update_post_meta( $order_id, 'Invoice Number', esc_attr($_POST['invoice_num']));
if ($_POST['sol_deal']) update_post_meta( $order_id, 'Solicitor Dealing With Matter', esc_attr($_POST['sol_deal']));
}
Hope this helps.
The accepted answer didn't work for me. I had to remove the second parameter of the update_post_meta function:
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_fields_update_order_meta' );
function custom_checkout_fields_update_order_meta( $order_id ) {
if ($_POST['_billing_vat_number']) update_post_meta( $order_id, '_billing_vat_number', sanitize_text_field( $_POST['_billing_vat_number'] ) );
}
I also used a sanitize function form wordpress, but that wasn't the issue.
Related
Im looking to find some php code that will allow me to extract information (Name, address etc) from the checkout fields and add it to the order meta data.
Looking for this to be a simple as possible
Ive previously found this code which allows a custom box to be added to the checkout page, and I sort of understand how it works, however I want to capture their name when they type it into the billing first name box. I can seem to grasp how to capture this data and put it into the order meta data, Ive tried shortening the code and editing it a few times but I dont seem to be winning
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Phone From Checkout Form').':</strong> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_name'] )
wc_add_notice( __( 'Please enter something into this new shiny field.' ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
update_post_meta( $order_id, 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
I like this and it does work but just not in the way i need it to work. thanks for any and all help
There are some mistakes and missing things in your codeā¦ Try the following replacement code instead:
// Add shipping phone (in checkout and My account edit shipping address) and save field value
add_action( 'woocommerce_shipping_fields', 'add_shipping_phone_field' );
function add_shipping_phone_field( $fields ) {
$fields['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
// Display shipping phone value on the order edit pages under shipping section
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_shipping_phone_in_admin_orders' );
function display_shipping_phone_in_admin_orders( $order ){
$phone_value = $order->get_meta('_shipping_phone');
if ( ! empty($phone_value) ) {
echo '<p><strong>'.__('Shipping phone').':</strong> ' . $phone_value . '</p>';
}
}
// Add a custom checkout field
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_slug', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My custom field'),
'placeholder' => __('Enter somethingā¦ '),
'required' => true,
), $checkout->get_value( 'my_field_slug' ) );
echo '</div>';
}
// Validate required checkout fields
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( isset($_POST['my_field_slug']) && empty($_POST['my_field_slug']) ) {
wc_add_notice( __( '"My custom field" is a required field.' ), 'error' );
}
}
// Add custom checkout field value as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order ) {
if ( isset($_POST['my_field_slug']) && ! empty($_POST['my_field_slug']) ) {
$order->update_meta_data( 'My Field', sanitize_text_field( $_POST['my_field_slug'] ) );
}
}
// Display "My field" value on the order edit pages under billing section
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_my_custom_checkout_field_in_admin_orders', 10, 1 );
function display_my_custom_checkout_field_in_admin_orders($order){
$my_field_value = $order->get_meta('My Field');
if ( ! empty($my_field_value) ) {
echo '<p><strong>'.__('My field').':</strong> ' . $my_field_value . '</p>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Now If you need to extract some data from Woocommerce existing checkout fields and combine it in a custom way to save it as custom order meta data, try to be more explicit:
What fields?
How you want to combine it?
What is the custom field slug to be used to save that data combination?
How do I set the value of a custom field on an order, upon checkout submit, to a selected value in an HTML component?
I've implemented a custom HTML component, inside the checkout form, whose selected value I want to insert in a custom field on my orders. But I can't seem to figure out how to hook these things up.
I've arrived at somthing like:
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
function custom_override_checkout_fields( $fields ) {
$fields['order']['special_delivery'] = 'The value from HTML';
return $fields;
}
But I'm not even sure that's the right way to go.
Any ideas?
Using woocommerce_after_checkout_billing_form allows you to add custom fields to your checkout form. You also need to save the field in the order meta using woocommerce_checkout_update_order_meta.
In the following code there is a custom text field used for saving VAT ID. Feel free to get rid of the "mrank" prefixes. Also rename the field as you need it.
It will show you how to add a field and to save in order meta.
/**
* VAT Number in WooCommerce Checkout
*/
function mrank_vat_field( $checkout ) {
echo '<div id="mrank_vat_field">';
woocommerce_form_field( 'vat_number', array(
'type' => 'text',
'class' => array( 'vat-number-field form-row-wide') ,
'label' => __( 'VAT-ID' ),
'placeholder' => __( 'Enter number' ),
'description' => __( 'Please enter your VAT-ID' ),
'required' => true,
), $checkout->get_value( 'vat_number' ));
echo '</div>';
}
add_action( 'woocommerce_after_checkout_billing_form', 'mrank_vat_field' );
/**
* Save VAT Number in the order meta
*/
function mrank_checkout_vat_number_update_order_meta( $order_id ) {
if ( ! empty( $_POST['vat_number'] ) ) {
update_post_meta( $order_id, '_vat_number', sanitize_text_field( $_POST['vat_number'] ) );
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'mrank_checkout_vat_number_update_order_meta' );
How to add Custom Product Fields in WooCommerce
I followed the guide above and add the code below to my functions.php. That worked fine. My problem is how to I modify this code to save the coupon code $_POST['coupon_code'] entered (during checkout) and save that to the custom field? I am stuck at that point, since my overall goal is to test the coupon code and fill the custom field with the salesperson that promoted that coupon code to the customers.
Thank you for any help!
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
update_post_meta( $order_id, 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('My Field').':</strong> ' . get_post_meta( $order->id, 'My Field', true ) . '</p>';
}
If you are still looking for answers, I managed to spice up your code with some help from my own question as I was in a similair situation.
Fill out custom field with used coupon code WooCommerce
your code and my edits were changed to where it actually saves the coupons to a custom value. On of the problems with your code was how you tried to reach the custom field with 'My field'. I have replaced these with the actual name of the field.
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta',
'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id, $posted ) {
if ( isset($_POST['my_field_name']) && empty( $_POST['my_field_name'])) {
$order = new WC_Order( $order_id );
foreach( $order->get_used_coupons() as $coupon) {
$coupons .= $coupon.', ';
}
update_post_meta( $order_id, 'my_field_name', $coupons);
}
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('My Field').':</strong> ' . get_post_meta( $order->id, 'my_field_name', true ) . '</p>';
}
You might want to clean up a bit before using this code. ;)
Source: Fill out custom field with used coupon code WooCommerce
I am having a hard time figuring out how to add my new custom billing field into my admin notification email. I am not a php expert (by any means) so i'm not sure what I messed up or if it is because it's trying to append the field to the general woo commerce admin notification email or the one from the Bookings plugin.
My custom field is working fine on the billing page, it's just getting it into the admin email and preferably into the back-end admin order management area as well?
To be completely honest, I was working on this before Christmas and completely lost track of what and where I was doing.
Thank you in advance!
Here is what I have for code.
/**
* Add the field to the checkout
**/
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h3>'.__('Referral Source').'</h3>';
/**
* Output the field. This is for 1.4.
*
* To make it compatible with 1.3 use $checkout->checkout_form_field instead:
$checkout->checkout_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class orm-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter a number'),
));
**/
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('How did you hear about us?'),
'placeholder' => __('Please enter how you were referred to our clinic.'),
'required' => true,
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Update the user meta with field value
**/
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
if ($user_id && $_POST['my_field_name']) update_user_meta( $user_id, 'my_field_name', esc_attr($_POST['my_field_name']) );
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['my_field_name']) update_post_meta( $order_id, 'My Field', esc_attr($_POST['my_field_name']));
}
/**
* Add the field to order emails
**/
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
function my_custom_checkout_field_order_meta_keys( $keys ) {
$keys[] = 'Referral Source';
return $keys;
}
UPDATE:
So here is where I am now. It seams to be working but I think I have a doubled function in there. I believe the last function is the one that is working for adding the custom field to my emails.
/**
* Update the user meta with field value
**/
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
if ($user_id && $_POST['my_field_name']) update_user_meta( $user_id, 'my_field_name', esc_attr($_POST['my_field_name']) );
}
/**
* Update the order meta with field value
**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['my_field_name']) update_post_meta( $order_id, 'Referral Source', esc_attr($_POST['my_field_name']));
}
/**
* Add the field to order emails
**/
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
function my_custom_checkout_field_order_meta_keys( $keys ) {
$keys[] = 'Referral Source';
return $keys;
}
// WooCommerce 2.3+
function my_custom_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['_some_field'] = array(
'label' => __( 'Referral Source' ),
'value' => get_post_meta( $order->id, 'my_field_name', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'my_custom_email_order_meta_fields', 10, 3 );
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'Referal Source';
return $keys;
}
This method was updated in WooCommerce 2.3, though it should be backcompatible to your approach. It looks like the key you are adding to the array on the woocommerce_email_order_meta_keys filter does not match the name of the meta key your have updated fall back to a basic array. like you have it, but your key doesn't match the meta key you've updated in the my_custom_checkout_field_update_order_meta() function.
Here's how to add keys to the email in WC 2.3+:
// WooCommerce 2.3+
function kia_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['_some_field'] = array(
'label' => __( 'Some field' ),
'value' => get_post_meta( $order->id, '_some_field', true ),
);
$fields['_another_field'] = array(
'label' => __( 'Another field' ),
'value' => get_post_meta( $order->id, '_another_field', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'kia_email_order_meta_fields', 10, 3 );
I'm new to WooCommerce.I'm unable to figure out where is problem here is my code
I have added a select field in billing form of checkout page.
Problem
records are not saving or updating on submitting. Problem is in Update the order meta with field value.value is not updating in database
// checkout page customization start
global $post, $woocommerce;
// Account select field
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
function custom_override_checkout_fields($fields) {
$fields['billing']['Account'] = array(
'type' => 'select',
'class' => array('billing form-row-wide'),
'label' => __('Choose an Account'),
'placeholder' => _x('Account', 'placeholder', 'woocommerce'),
'options' => array(
'' => __( 'Select Account','' ),
),
'required' => true,
);
return $fields;
}
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
if (!$_POST['Account'])
$woocommerce->add_error( __('Please enter your Account.'.$_POST['Account']));
}
///**
Problem area
value is not updating in database
//* Update the order meta with field value
//**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['Account']) update_post_meta( $order_id, 'Account', esc_attr($_POST['Account']));
}
/**
* Update the user meta with field value
**/
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta');
function my_custom_checkout_field_update_user_meta( $user_id ) {
if ($user_id && $_POST['Account']) update_user_meta( $user_id, 'Account', esc_attr($_POST['Account']) );
}
The functions look pretty accurate to me. Are you sure they aren't updating? Or perhaps you are having difficulty is displaying them.
I've tweaked them a bit. First, to use the $posted variabled that WooCommerce sends to the function, though this is trivial as $_POST should be the same. And secondly, you are using esc_attr() when you should be using sanitize_text_field(). The former is for displaying the data in an HTML attribute while the latter is for sanitizing before saving.
//* Update the order meta with field value
//**/
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta', 10, 2 );
function my_custom_checkout_field_update_order_meta( $order_id, $posted ) {
if ( isset( $posted['Account'] ) ){
update_post_meta( $order_id, 'Account', sanitize_text_field( $posted['Account'] ) );
}
}
/**
* Update the user meta with field value
**/
add_action('woocommerce_checkout_update_user_meta', 'my_custom_checkout_field_update_user_meta', 10, 2 );
function my_custom_checkout_field_update_user_meta( $user_id, $posted ) {
if ( $user_id && isset( $posted['Account'] ) ){
update_user_meta( $user_id, 'Account', sanitize_text_field( $posted['Account'] ) );
}
}