I added a field at the checkout following the woocommerce documentation this way:
/*Add document ID to checkout form*/
add_filter( 'woocommerce_checkout_fields' , 'ebani_cedula_checkout_field' );
// Our hooked in function - $fields is passed via the filter!
function ebani_cedula_checkout_field( $fields ) {
$fields['billing']['cedula'] = array(
'label' => __('Cédula de ciudadanía', 'woocommerce'),
'placeholder' => _x('Cédula', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-last'),
'clear' => true,
'priority' => 15
);
return $fields;
}
Then I want to show it on the admin order edit page this way:
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'cedula_checkout_field_display_admin_order_meta', 10, 1 );
function cedula_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Cédula').':</strong> ' . get_post_meta( $order->get_id(), '_cedula', true ) . '</p>';
}
When I go to the order edit page I get an empty value for _cedula I don't know why, I'm just following the documentation, but it is not working, how can I get the data stored in the custom checkout field?
If you want this custom billing field to be saved when order is placed, it's better to use
the action hook woocommerce_billing_fields instead of woocommerce_checkout_fields like:
add_filter( 'woocommerce_billing_fields' , 'ebani_cedula_checkout_field' );
function ebani_cedula_checkout_field( $fields ) {
$fields['billing_cedula'] = array(
'label' => __('Cédula de ciudadanía', 'woocommerce'),
'placeholder' => _x('Cédula', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-last'),
'clear' => true,
'priority' => 15
);
return $fields;
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'cedula_checkout_field_display_admin_order_meta', 10, 1 );
function cedula_checkout_field_display_admin_order_meta($order){
if( $value = $order->get_meta('_billing_cedula') )
echo '<p><strong>'.__('Cédula').':</strong> ' . $value . '</p>';
}
Now your custom checkout billing field is saved.
Related
UPDATE:
I used the following code from here and it is fixed. The custom billing field is showing up in the backend and e-mails. Seemed like I needed to save the data to meta. Strange this isn't described on woocommerce's own documentation. Hope some else benefits from it too.
I've added some custom date fields to my checkout page. They are showing and I can input dates. But the input isn't showing in my admin order page or in de emails. I've searched some topics, but can't figure it out. I've followed this instruction under 'Adding Custom Shipping And Billing Fields'. I only see the label at the oder edit page and not the value. What is wrong here?
I only tried it with de 'date_from' field for testing purpose. 'date_till' also needs to be shown.
Code I got:
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_new_checkout_fields_date_from' );
// Our hooked in function – $fields is passed via the filter!
function custom_new_checkout_fields_date_from( $newDateFrom ) {
$newDateFrom['billing']['date_from'] = array(
'type' => 'date',
'label' => __('Datum huur vanaf', 'woocommerce'),
'placeholder' => _x('Datum huur vanaf', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $newDateFrom;
}
// Datum tot veld
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_new_checkout_fields_date_till' );
// Our hooked in function – $fields is passed via the filter!
function custom_new_checkout_fields_date_till( $newDateTill ) {
$newDateTill['billing']['date_till'] = array(
'type' => 'date',
'label' => __('Datum huur tot', 'woocommerce'),
'placeholder' => _x('Datum huur tot', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $newDateTill;
}
/**
* 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>'.__('Datum huur van').':</strong> ' . get_post_meta( $order->get_id(), '_date_from', true ) . '</p>';
}
/**
* Add a custom field (in an order) to the emails
*/
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $keys, $sent_to_admin, $order ) {
$keys['_date_from'] = array(
'label' => __( 'Datum huur vanaf' ),
'value' => get_post_meta( $order->id, '_date_from', true ),
);
return $keys;
}
This question already has answers here:
Add custom field data to WooCommerce order
(2 answers)
Add Custom checkout field to Order in WooCommerce
(2 answers)
Save checkout custom field value and display it in WooCommerce admin orders
(1 answer)
Closed 1 year ago.
I added three fields extra to my WooCommerce checkout (CVR nummer, reference nummer and ønsket leveringsdato). They show up correctly in the checkout but once the order is placed, the information is not sent to the WooCommerce backend/order overview. How do I send over the information so we receive it?
function add_woocommerce_billing_fields($billing_fields){
//reorder woo my billing address form fields
$billing_fields2['billing_first_name'] = $billing_fields['billing_first_name'];
$billing_fields2['billing_last_name'] = $billing_fields['billing_last_name'];
$billing_fields2['billing_vat'] = array(
'type' => 'text',
'label' => __('CVR nummer', 'keyelp-shop-customization' ),
'class' => array('form-row-wide'),
'required' => true,
'clear' => true
);
$billing_fields2['billing_ref'] = array(
'type' => 'text',
'label' => __('Reference nummer', 'keyelp-shop-customization' ),
'class' => array('form-row-wide'),
'required' => false,
'clear' => true
);
$billing_fields2['billing_date'] = array(
'type' => 'text',
'label' => __('Ønsket leveringsdato', 'keyelp-shop-customization' ),
'class' => array('form-row-wide'),
'required' => false,
'clear' => true
);
$merged_billing_fields = $billing_fields2 + $billing_fields;
return $merged_billing_fields;
}
You can use woocommerce_checkout_update_order_meta and woocommerce_admin_order_data_after_billing_address action hook. code goes in your ative theme functions.php file.
Using woocommerce_checkout_update_order_meta hook you can
save value meta.
function custom_checkout_field_update_order_meta( $order_id ) {
if ( $_POST['billing_vat'] ){
update_post_meta( $order_id, 'billing_vat', esc_attr($_POST['billing_vat']) );
}
if ( $_POST['billing_ref'] ){
update_post_meta( $order_id, 'billing_ref', esc_attr($_POST['billing_ref']) );
}
if ( $_POST['billing_date'] ){
update_post_meta( $order_id, 'billing_date', esc_attr($_POST['billing_date']) );
}
}
add_action('woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta');
Using woocommerce_admin_order_data_after_billing_address hook
you can display meta value after billing address.
function custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('CVR nummer').':</strong> ' . get_post_meta( $order->get_id(), 'billing_vat', true ) . '</p>';
echo '<p><strong>'.__('Reference nummer').':</strong> ' . get_post_meta( $order->get_id(), 'billing_ref', true ) . '</p>';
echo '<p><strong>'.__('Ønsket leveringsdato').':</strong> ' . get_post_meta( $order->get_id(), 'billing_date', true ) . '</p>';
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
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?
I try to add a birthdate field in the Woocommerce Checkout form, then save it as a user meta.
I can display it with the code below but i can't save it in order to see it in the user profile page.
add_filter( 'woocommerce_billing_fields', 'add_birth_date_billing_field', 20, 1 );
function add_birth_date_billing_field($billing_fields) {
$billing_fields['billing_birth_date'] = array(
'type' => 'date',
'label' => __('Birth date'),
'class' => array('form-row-wide'),
'priority' => 25,
'required' => true,
'clear' => true,
);
return $billing_fields;
}
add_action( 'woocommerce_checkout_update_customer', 'save_checkout_account_birthday_field', 10, 2 );
function save_checkout_account_birthday_field( $customer, $data ){
if ( isset($_POST['billing_birth_date']) && ! empty($_POST['billing_birth_date']) ) {
$customer->update_meta_data( 'billing_birth_date', sanitize_text_field($_POST['billing_birth_date']) );
}
}
Here is the complete code that will display billing birthdate in checkout, in My account Addresses, In admin Orders pages and in WordPress user dashboard:
// Display Billing birthdate field to checkout and My account addresses
add_filter( 'woocommerce_billing_fields', 'display_birthdate_billing_field', 20, 1 );
function display_birthdate_billing_field($billing_fields) {
$billing_fields['billing_birthdate'] = array(
'type' => 'date',
'label' => __('Birthdate'),
'class' => array('form-row-wide'),
'priority' => 25,
'required' => true,
'clear' => true,
);
return $billing_fields;
}
// Save Billing birthdate field value as user meta data
add_action( 'woocommerce_checkout_update_customer', 'save_account_billing_birthdate_field', 10, 2 );
function save_account_billing_birthdate_field( $customer, $data ){
if ( isset($_POST['billing_birthdate']) && ! empty($_POST['billing_birthdate']) ) {
$customer->update_meta_data( 'billing_birthdate', sanitize_text_field($_POST['billing_birthdate']) );
}
}
// Admin orders Billing birthdate editable field and display
add_filter('woocommerce_admin_billing_fields', 'admin_order_billing_birthdate_editable_field');
function admin_order_billing_birthdate_editable_field( $fields ) {
$fields['birthdate'] = array( 'label' => __('Birthdate', 'woocommerce') );
return $fields;
}
// WordPress User: Add Billing birthdate editable field
add_filter('woocommerce_customer_meta_fields', 'wordpress_user_account_billing_birthdate_field');
function wordpress_user_account_billing_birthdate_field( $fields ) {
$fields['billing']['fields']['billing_birthdate'] = array(
'label' => __('Birthdate', 'woocommerce'),
'description' => __('', 'woocommerce')
);
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I have the function in functions.php:
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['billing']['billing_infos'] = array(
'type' => 'textarea',
'label' => __('Podaj NIP', 'woocommerce'),
'placeholder' => _x('Tutaj możesz wpisać NIP', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
This code is adding custom field to billing form. It's working fine because I see it when I make an order like normal user. The problem is with data from this field in admin panel. I can't see it. Any help on this please?
This missing hooked function will display your custom fields in Order edit page, below Billing details:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_billing_infos_to_admin_order_meta', 20, 1 );
function display_billing_infos_to_admin_order_meta( $order ){
echo '<p><strong>'.__('Podaj NIP').':</strong> ' . get_post_meta( $order->get_id(), '_billing_infos', true ) . '</p>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.