I have a few custom fields within my WooCommerce setup, however I am trying to get them to display on the order view.
This is my code (one custom field for the sake of it):
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h3>'.__('Extra Information').'</h3>';
woocommerce_form_field( 'date_of_birth', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Date of Birth'),
'placeholder' => __('Enter something'),
'required' => true,
'options' => array(
'1995' => __('1995', 'woocommerce' ),
'1994' => __('1994', 'woocommerce' )
)
),
$checkout->get_value( 'date_of_birth' ));
I thought this below would do the job on adding it to the order view, however it does not.. or I am completely wrong and the custom field is not saving?
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['date_of_birth']) update_post_meta( $order_id, 'Extra Information', esc_attr($_POST['date_of_birth']));
I then looked through stackoverflow and found some more information and tried this:
function my_custom_checkout_field1($order){
echo "<p><strong>Date of Birth:</strong> " . $order->order_custom_fields['_date_of_birth'][0] . "</p>";
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field1', 10, 1 );
That does add a "Date of Birth:" to the order view, but unfortunately it is empty afterwards. I tried both _date_of_birth and date_of_birth, apparently it needed the extra _ infront, I got that answer from here: Show custom field on order in woocommerce
I have tried to look inside the database, but can not find the extra details on an order displayed anywhere (no regular details either except order id's).
Can anyone tell me what I am doing wrong and what I can do to make the field show up on the order view?
Thanks
I don´t know, but this:
'Extra Information'
here:
update_post_meta($post_id, $meta_key, $meta_value, $prev_value);
Are you sure 'Extra Information' is the $meta_key? Is not "date_of_birth"?
Related
This question already has answers here:
Order custom fields not displayed on WooCommerce email notifications
(2 answers)
Show the result of custom delivery field on the checkout page in WooCommerce frontend, backend & email notifications
(1 answer)
Closed 8 months ago.
Thanks to some help, I've created a dropdown list on the checkout page of my Woocommerce site. It works beautifully but on my email notification, it shows the code and not the value of the selection. Eg: "My Marketer: mariaMarais" instead of "My Marketer: Maria Marais - Natal." How can I change it to show the string and not the code?
// add marketer list
//* Add select field to the checkout page
add_action('woocommerce_before_order_notes', 'dd_add_select_two_checkout_field');
function dd_add_select_two_checkout_field( $checkout ) {
woocommerce_form_field( 'myquestion', array(
'type' => 'select',
'class' => array( 'select2-wrapper' ),
'label' => __( 'Please select your marketer.' ),
'required' => true,
'input_class' => array( 'add-select2' ),
'options' => array( // added extra for effect.
'headoffice' => __( 'Head Office', 'wps' ),
'mariaMarais' => __( 'Maria Marais - Natal', 'wps' )
)
),
$checkout->get_value( 'myquestion' ));
wc_enqueue_js( "$( '.add-select2' ).selectWoo(); ");
}
//* Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {
if ($_POST['myquestion']) update_post_meta( $order_id, 'myquestion', esc_attr($_POST['myquestion']));
}
//* Display field value on the order edition page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'wps_select_checkout_field_display_admin_order_meta', 10, 1 );
function wps_select_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Found by').':</strong> ' . get_post_meta( $order->id, 'myquestion', true ) . '</p>';
}
//* Add selection field value to emails
add_filter('woocommerce_email_order_meta_keys', 'wps_select_order_meta_keys');
function wps_select_order_meta_keys( $keys ) {
$keys['My Marketer:'] = 'myquestion';
return $keys;
}
I'm trying to have the value from 2 custom fields that the user put in through My Account/Edit-Address shown in the same custom fields but in checkout, right now it gets override by old (input) values even though the field (seen through browser inspector) has the new value. How do I stop this?
I'm fairly new to both woocommerce, plugin-making and wordpress. Right now I've not really tried much that made any difference (put the code in different order, changed up the priorities, changed names... As you see, I don't really know what I'm doing).
This is how I made the fields:
add_filter( 'woocommerce_checkout_fields' , 'plugin_add_custom_billing_fields' );
function plugin_add_custom_billing_fields($fields) {
$fields['billing']['billing_org_number'] = array(
'label' => __('Organisationsnummer', 'woocommerce'),
'placeholder' => __('T.ex. 1234-5678', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true,
);
$fields['billing']['billing_org_reference'] = array(
'label' => __('Kostnadsställe/referens', 'woocommerce'),
'placeholder' => __('T.ex. Per Olofsson', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true,
);
return $fields;
}
This is how I save the fields:
function reigel_woocommerce_checkout_update_user_meta( $customer_id, $posted ) {
var_dump($customer_id, $posted);
if (isset($posted['billing_org_number'])) {
$dob = sanitize_text_field( $posted['billing_org_number'] );
update_user_meta( $customer_id, 'billing_org_number', $dob);
}
if (isset($posted['billing_org_reference'])) {
$dob = sanitize_text_field( $posted['billing_org_reference'] );
update_user_meta( $customer_id, 'billing_org_reference', $dob);
}
}
add_action( 'woocommerce_update_user_meta', 'reigel_woocommerce_checkout_update_user_meta', 10, 2 );
As you see, I've been searching through StackOverflow before and got some help from Reigel! Tell me if you need any more code.
The results I want: My value (from database) to be shown in Checkout after edited in My Account/Edit-Address.
Actual results: The old value is shown in Checkout, the new in My Account/Edit-Address.
EDIT: Seems like the plugin for Klarna Checkout is messing up with sessions.
EDIT 2: Yes, it was Klarna. I'll push this problem for a later time because the team discussed and opted to remove the plugin instead.
I have an Ajax checkout on my woocommerce installation and I am trying to capture the custom fields on the checkout. I am using below code to try to capture the field called add_gift_box, the field appears fine on my checkout page.
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['add_gift_box']) {
update_post_meta( $order_id, '_add_gift_box', esc_attr($_POST['add_gift_box']));
}
}
When I press "place order" button it creates a new order but the value of this field does not get saved in the database. I don't think even the hook gets fired. As I said everything is being handled by Ajax. The checkout page is one page checkout.
I need help sorting this out. Thanks in advance.
UPDATE
I am setting the field as follows:
add_action( 'woocommerce_after_checkout_billing_form', 'add_box_option_to_checkout' );
function add_box_option_to_checkout( $checkout ) {
woocommerce_form_field( 'add_gift_box', array(
'type' => 'radio',
'class' => array('add_gift_box form-row-wide'),
'label_class' => array('checkbox'),
'input_class' => array('input-checkbox'),
'required' => true,
'options' => array(
'option_1' => 'option1</br>' ,
'option_2' =>'option2</br>',
'option_3' =>'option3</br>',
'option_4' =>'option4</br>',
'option_5' =>'option5</br>',
'option_6' =>'option6</br>',
'option_7' =>'option7</br>',
),
'label' => __('Select Option'),
'placeholder' => __(''),
), $checkout->get_value( 'add_gift_box' ));
}
here is a plugin to add custom field on checkout page woocomerce https://wordpress.org/plugins/woo-custom-checkout-field/
or if you want to add by code you can follow codding from here
https://www.cloudways.com/blog/custom-field-woocommerce-checkout-page/
add_action('woocommerce_after_order_notes', 'customise_checkout_field');
function customise_checkout_field($checkout)
{
echo '<div id="customise_checkout_field"><h2>' . __('Heading') . '</h2>';
woocommerce_form_field('customised_field_name', array(
'type' => 'text',
'class' => array(
'my-field-class form-row-wide'
) ,
'label' => __('Customise Additional Field') ,
'placeholder' => __('Guidence') ,
'required' => true,
) , $checkout->get_value('customised_field_name'));
echo '</div>';
}
Do you have a plugin activated which creates the order by hooking into woocommerce_create_order filter? I don't see any other reason why add_gift_box isn't saved or why woocommerce_checkout_update_order_meta isn't firing.
The original code from includes/class-wc-checkout.php is
/**
* Action hook to adjust order before save.
* #since 3.0.0
*/
do_action( 'woocommerce_checkout_create_order', $order, $data );
// Save the order.
$order_id = $order->save();
do_action( 'woocommerce_checkout_update_order_meta', $order_id, $data );
So, you could create log files in your themes directory to see which hooks are firing like this:
add_action('woocommerce_checkout_update_order_meta', function ($order_id) {
file_put_contents(__DIR__ . '/woocommerce_checkout_update_order_meta.log', 'woocommerce_checkout_update_order_meta fired for order id ' . $order_id);
});
add_action('woocommerce_checkout_create_order', function () {
file_put_contents(__DIR__ . '/woocommerce_checkout_create_order.log', 'woocommerce_checkout_create_order fired');
});
I am trying to add a form to my checkout page so when a user clicks the 'Tax Exempt' checkbox, a textbox will popup and ask the user what the Tax Exempt Id number is.
I got all of that working great, and I even added the update_totals_on_change class to my form field so it will update the totals.
My next step was to add an action/filter on a method so when the update_totals_on_change executes, I can set the tax to 0 and then it will finish calculating the total.
Does anyone know which functions I can hook on to?
Looking at the checkout.js file in WooCommerce, they set the action to woocommerce_update_order_review for the ajax operation.
I tried following that but soon got lost.
I was thinking I could add some post data by hooking in to woocommerce_checkout_update_order_review
and then hooking in to woocommerce_before_calculate_totals to modify the tax stuff, but I have no idea what I need to modify.
Am I even on the right path?
Alright, I finally figured it out in case anyone is interested.
In my plugin, I made a form after the order notes by hooking in to this function: 'woocommerce_before_order_notes'
add_action('woocommerce_before_order_notes', array(&$this, 'taxexempt_before_order_notes') );
my 'taxexempt_before_order_notes' function contained:
function taxexempt_before_order_notes( $checkout ) {
echo '<div style="clear: both"></div>
<h3>Tax Exempt Details</h3>';
woocommerce_form_field( 'tax_exempt_checkbox', array(
'type' => 'checkbox',
'class' => array('tiri taxexempt'),array( 'form-row-wide', 'address-field' ),
'label' => __('Tax Exempt'),
), $checkout->get_value( 'tax_exempt_checkbox' ));
woocommerce_form_field( 'tax_exempt_name', array(
'type' => 'text',
'class' => array('form-row-first', 'tiri', 'taxexempt', 'textbox', 'hidden'),
'label' => __('Tax Exempt Name'),
), $checkout->get_value( 'tax_exempt_name' ));
woocommerce_form_field( 'tax_exempt_id', array(
'type' => 'text',
'class' => array('form-row-last', 'tiri', 'taxexempt', 'textbox', 'hidden', 'update_totals_on_change'),
'label' => __('Tax Exempt Id'),
), $checkout->get_value( 'tax_exempt_id' ));
}
Then the most important woocommerce function to hook was: 'woocommerce_checkout_update_order_review'
add_action( 'woocommerce_checkout_update_order_review', array(&$this, 'taxexempt_checkout_update_order_review' ));
function taxexempt_checkout_update_order_review( $post_data ) {
global $woocommerce;
$woocommerce->customer->set_is_vat_exempt(FALSE);
parse_str($post_data);
if ( isset($tax_exempt_checkbox) && isset($tax_exempt_id) && $tax_exempt_checkbox == '1' && !empty($tax_exempt_id))
$woocommerce->customer->set_is_vat_exempt(true);
}
I simply parsed out the $post_data that is the serialized form data from the checkout.js file in woocommerce and checked if my part of the form was filled out correctly.
If it was, then I would set the tax exempt for the user.
The accepted solution didn't work for me, but I modified it to use the following:
//=============================================================================
// ADD TAX EXEMPT CHECKMARK
// =============================================================================
add_action( 'woocommerce_after_order_notes', 'qd_tax_exempt');
function qd_tax_exempt( $checkout ) {
echo '<div id="qd-tax-exempt"><h3>'.__('Tax Exempt').'</h3>';
woocommerce_form_field( 'shipping_method_tax_exempt', array(
'type' => 'checkbox',
'class' => array(),
'label' => __('My organization is tax exempt.'),
'required' => false,
), $checkout->get_value( 'shipping_method_tax_exempt' ));
echo '</div>';
}
add_action( 'woocommerce_checkout_update_order_review', 'taxexempt_checkout_update_order_review');
function taxexempt_checkout_update_order_review( $post_data ) {
global $woocommerce;
$woocommerce->customer->set_is_vat_exempt(FALSE);
parse_str($post_data);
if ( isset($shipping_method_tax_exempt) && $shipping_method_tax_exempt == '1')
$woocommerce->customer->set_is_vat_exempt(true);
}
The key here is understanding that any field with a name that starts with shipping_method is going to inherit this updating order functionality (which was the part that didn't work for me). I found this answer at http://www.affectivia.com/blog/have-a-checkbox-on-the-checkout-page-which-updates-the-order-totals/
After a long search I found that there is a method for the cart object called remove_taxes() .
So, after setting a user meta for the tax exempt users, this cancels the tax totals.
function remove_tax_for_exempt( $cart ) {
global $current_user;
$ok_taxexp = get_the_author_meta( 'granted_taxexempt', $current_user->ID );
if ($ok_taxexp){ // now 0 the tax if user is tax exempt
$cart->remove_taxes();
}
return $cart;
}
add_action( 'woocommerce_calculate_totals', 'remove_tax_for_exempt' );
Because $cart->remove_taxes(); is deprecated. This is what I used instead.
I didn't have a form on the frontend, but have a user roll that is tax exempt. This was my solution.
Also worth noting that set_is_vat_exempt(true) also works in the US to set as tax exempt.
/**
* Set customer as tax exempt if user is a wholesale customer
*/
function remove_tax_for_exempt( $cart ) {
global $woocommerce;
if ( is_user_logged_in() && current_user_can( 'wholesale_customer' ) ) {
$woocommerce->customer->set_is_vat_exempt(true);
}
return $cart;
}
add_action( 'woocommerce_calculate_totals', 'remove_tax_for_exempt' );
Since this answer still pops up on google, I thought I'd share that setting the customer as tax exempt only works during checkout, if you need to edit the order on the back-end after it is placed and use the "recalculate" button, the taxes will still appear. Fortunately there is a hook for this as well:
function remove_tax_for_exempt($exempt, $order){
return $exempt || user_can($order->get_user_id(), 'wholesale_customer');
}
add_filter('woocommerce_order_is_vat_exempt', 'remove_tax_for_exempt', 10, 2);
I'm totally new to wordpress, so apologies for the poor explanation.
I'm trying to return a list of values of the array 'options' I know I could filter this info (and ADD to this array) by using add_filter with 'woocommerce_currencies' but how can I see the values already contained in the array?
Here is a snippet of code, it's from the woocommerce functions.php file - Basically.. I'm trying to echo the values in this options array.
'options' => array_unique(apply_filters('woocommerce_currencies', array(
'USD' => __( 'US Dollars ($)', 'woocommerce' ),
'EUR' => __( 'Euros (€)', 'woocommerce' ),
'GBP' => __( 'Pounds Sterling (£)', 'woocommerce' ).....
You can use the get_option function to retrieve any named option from the database.
$values = get_option('woocommerce_curencies');
foreach ( (array) $values as $option ) {
print_r( $option );
}
You can do:
add_filter('woocommerce_currencies', function($currencies) {
var_dump($currencies);
}, 10, 1 );
You can then modify currencies as you wish.
FYI, 10 is the priority within the woocommerce_currencies filter, and 1 is the number of parameters being passed by the filter.