59

I have a function that does this:

$order = new WC_Order($order_id);
$customer = new WC_Customer($order_id);

How can I get customer details from this?

I have tried everything in the documentation, but somehow, just some details are present, but the rest aren't. For example.

$data['Address'] = $customer->get_address() . ' ' . $customer->get_address_2();
$data['ZipCode'] = $customer->get_postcode();

Is empty.

Doing

var_dump($customer)

Produces:

object(WC_Customer)#654 (2) { ["_data":protected]=> array(14) { ["country"]=> string(2) "IT" >["state"]=> string(0) "" ["postcode"]=> string(0) "" ["city"]=> string(0) "" ["address"]=> >string(0) "" ["address_2"]=> string(0) "" ["shipping_country"]=> string(2) "IT" ["shipping_state"]=> string(2) "BG" ["shipping_postcode"]=> string(0) "" ["shipping_city"]=> >string(0) "" ["shipping_address"]=> string(0) "" ["shipping_address_2"]=> string(0) "" ["is_vat_exempt"]=> bool(false) ["calculated_shipping"]=> bool(false) } ? ["_changed":"WC_Customer":private]=> bool(false) }

As you can see, the city is present, but the rest are empty. I have checked in wp_usermeta database table and in the administrator panel of the customer and all the data is there.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Alfonso Embid-Desmet
  • 3,561
  • 3
  • 32
  • 45

15 Answers15

77

2017-2020 WooCommerce versions 3+ and CRUD Objects

1). You can use getter methods from WC_Order and WC_Abstract_Order classes on the WC_Order object instance like:

// Get an instance of the WC_Order Object from the Order ID (if required)
$order = wc_get_order( $order_id );

// Get the Customer ID (User ID)
$customer_id = $order->get_customer_id(); // Or $order->get_user_id();

// Get the WP_User Object instance
$user = $order->get_user();

// Get the WP_User roles and capabilities
$user_roles = $user->roles;

// Get the Customer billing email
$billing_email  = $order->get_billing_email();

// Get the Customer billing phone
$billing_phone  = $order->get_billing_phone();

// Customer billing information details
$billing_first_name = $order->get_billing_first_name();
$billing_last_name  = $order->get_billing_last_name();
$billing_company    = $order->get_billing_company();
$billing_address_1  = $order->get_billing_address_1();
$billing_address_2  = $order->get_billing_address_2();
$billing_city       = $order->get_billing_city();
$billing_state      = $order->get_billing_state();
$billing_postcode   = $order->get_billing_postcode();
$billing_country    = $order->get_billing_country();

// Customer shipping information details
$shipping_first_name = $order->get_shipping_first_name();
$shipping_last_name  = $order->get_shipping_last_name();
$shipping_company    = $order->get_shipping_company();
$shipping_address_1  = $order->get_shipping_address_1();
$shipping_address_2  = $order->get_shipping_address_2();
$shipping_city       = $order->get_shipping_city();
$shipping_state      = $order->get_shipping_state();
$shipping_postcode   = $order->get_shipping_postcode();
$shipping_country    = $order->get_shipping_country();

2). You can also use the WC_Order get_data() method, to get an unprotected data array from Order meta data like:

// Get an instance of the WC_Order Object from the Order ID (if required)
$order = wc_get_order( $order_id );

// Get the Order meta data in an unprotected array
$data  = $order->get_data(); // The Order data

$order_id        = $data['id'];
$order_parent_id = $data['parent_id'];

// Get the Customer ID (User ID)
$customer_id     = $data['customer_id'];

## BILLING INFORMATION:

$billing_email      = $data['billing']['email'];
$billing_phone      = $order_data['billing']['phone'];

$billing_first_name = $data['billing']['first_name'];
$billing_last_name  = $data['billing']['last_name'];
$billing_company    = $data['billing']['company'];
$billing_address_1  = $data['billing']['address_1'];
$billing_address_2  = $data['billing']['address_2'];
$billing_city       = $data['billing']['city'];
$billing_state      = $data['billing']['state'];
$billing_postcode   = $data['billing']['postcode'];
$billing_country    = $data['billing']['country'];

## SHIPPING INFORMATION:

$shipping_first_name = $data['shipping']['first_name'];
$shipping_last_name  = $data['shipping']['last_name'];
$shipping_company    = $data['shipping']['company'];
$shipping_address_1  = $data['shipping']['address_1'];
$shipping_address_2  = $data['shipping']['address_2'];
$shipping_city       = $data['shipping']['city'];
$shipping_state      = $data['shipping']['state'];
$shipping_postcode   = $data['shipping']['postcode'];
$shipping_country    = $data['shipping']['country'];

Now to get the user account data (from an Order ID):

1). You can use the methods from WC_Customer Class:

// Get the user ID from an Order ID
$user_id = get_post_meta( $order_id, '_customer_user', true );

// Get an instance of the WC_Customer Object from the user ID
$customer = new WC_Customer( $user_id );

$username     = $customer->get_username(); // Get username
$user_email   = $customer->get_email(); // Get account email
$first_name   = $customer->get_first_name();
$last_name    = $customer->get_last_name();
$display_name = $customer->get_display_name();

// Customer billing information details (from account)
$billing_first_name = $customer->get_billing_first_name();
$billing_last_name  = $customer->get_billing_last_name();
$billing_company    = $customer->get_billing_company();
$billing_address_1  = $customer->get_billing_address_1();
$billing_address_2  = $customer->get_billing_address_2();
$billing_city       = $customer->get_billing_city();
$billing_state      = $customer->get_billing_state();
$billing_postcode   = $customer->get_billing_postcode();
$billing_country    = $customer->get_billing_country();

// Customer shipping information details (from account)
$shipping_first_name = $customer->get_shipping_first_name();
$shipping_last_name  = $customer->get_shipping_last_name();
$shipping_company    = $customer->get_shipping_company();
$shipping_address_1  = $customer->get_shipping_address_1();
$shipping_address_2  = $customer->get_shipping_address_2();
$shipping_city       = $customer->get_shipping_city();
$shipping_state      = $customer->get_shipping_state();
$shipping_postcode   = $customer->get_shipping_postcode();
$shipping_country    = $customer->get_shipping_country();

2). The WP_User object (WordPress):

// Get the user ID from an Order ID
$user_id = get_post_meta( $order_id, '_customer_user', true );

// Get the WP_User instance Object
$user = new WP_User( $user_id );

$username     = $user->username; // Get username
$user_email   = $user->email; // Get account email
$first_name   = $user->first_name;
$last_name    = $user->last_name;
$display_name = $user->display_name;

// Customer billing information details (from account)
$billing_first_name = $user->billing_first_name;
$billing_last_name  = $user->billing_last_name;
$billing_company    = $user->billing_company;
$billing_address_1  = $user->billing_address_1;
$billing_address_2  = $user->billing_address_2;
$billing_city       = $user->billing_city;
$billing_state      = $user->billing_state;
$billing_postcode   = $user->billing_postcode;
$billing_country    = $user->billing_country;

// Customer shipping information details (from account)
$shipping_first_name = $user->shipping_first_name;
$shipping_last_name  = $user->shipping_last_name;
$shipping_company    = $user->shipping_company;
$shipping_address_1  = $user->shipping_address_1;
$shipping_address_2  = $user->shipping_address_2;
$shipping_city       = $user->shipping_city;
$shipping_state      = $user->shipping_state;
$shipping_postcode   = $user->shipping_postcode;
$shipping_country    = $user->shipping_country;

Related: How to get WooCommerce order details

Laurel
  • 5,965
  • 14
  • 31
  • 57
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
31

If you want customer's details that customer had entered while ordering, then you can use the following code:

$order = new WC_Order($order_id);
$billing_address = $order->get_billing_address();
$billing_address_html = $order->get_formatted_billing_address();

// For printing or displaying on the web page
$shipping_address = $order->get_shipping_address();
$shipping_address_html = $order->get_formatted_shipping_address(); // For printing or displaying on web page

Apart from this, $customer = new WC_Customer( $order_id ); can not get you customer details.

First of all, new WC_Customer() doesn't take any arguments.

Secondly, WC_Customer will get customer's details only when the user is logged in and he/she is not on the admin side. Instead he/she should be on website's front-end like the 'My Account', 'Shop', 'Cart', or 'Checkout' page.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ratnakar - StoreApps
  • 4,261
  • 23
  • 17
  • But there is no way to access directly to the information stored in wp_usermeta through woocommerce? could it be a possibility to get the user id out of the order id?. – Alfonso Embid-Desmet Apr 03 '14 at 16:50
  • 6
    You can use this code to get user id from order id $user_id = get_post_meta( $order_id, '_customer_user', true ); – Ratnakar - StoreApps Apr 03 '14 at 17:07
  • I am having the same problem as the OP, but I still get an empty address even when I'm logged in as a non-admin user. I have tried `$customer = new WC_Customer();` and `global $woocommerce; $customer = $woocommerce->customer;` but both still leave me with empty address info. – ban-geoengineering Jul 21 '14 at 15:14
  • More info on the classes pages [WC_Order](https://docs.woocommerce.com/wc-apidocs/class-WC_Order.html) and [WC_Abstract_Order](https://docs.woocommerce.com/wc-apidocs/class-WC_Abstract_Order.html#methods) – adrianthedev Feb 27 '17 at 11:41
  • 3
    $order->get_billing_address() isn't a method on WC_Order. – user3751385 Sep 06 '17 at 04:54
  • This works, but there is another way to get the $order. Not sure if one way is better than the other, the end result is the same. The main function to return an order is `wc_get_order( $order_id)` – jer0dh May 23 '19 at 16:17
30

Having tried $customer = new WC_Customer(); and global $woocommerce; $customer = $woocommerce->customer; I was still getting empty address data even when I logged in as a non-admin user.

My solution was as follows:

function mwe_get_formatted_shipping_name_and_address($user_id) {

    $address = '';
    $address .= get_user_meta( $user_id, 'shipping_first_name', true );
    $address .= ' ';
    $address .= get_user_meta( $user_id, 'shipping_last_name', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_company', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_address_1', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_address_2', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_city', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_state', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_postcode', true );
    $address .= "\n";
    $address .= get_user_meta( $user_id, 'shipping_country', true );

    return $address;
}

...and this code works regardless of whether you are logged in as admin or not.

Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
ban-geoengineering
  • 18,324
  • 27
  • 171
  • 253
  • 1
    actually that was somehow the method I followed to resolve this so therefore I mark this solution as accepted – Alfonso Embid-Desmet Sep 29 '14 at 10:26
  • 1
    What if the person who bought the products in the order was a guest on the site? How to get that information now? There will be no user_id – Solomon Closson Feb 09 '16 at 16:25
  • Yeah, I'm not sure about that. Maybe you can retrieve it from their email address or (if you're lucky) from the session. Might not be possible but may be worth raising as a new question. :-) – ban-geoengineering Mar 27 '16 at 16:22
25

Maybe look at the WooCommerce Order class? For example, to get the customer's email address:

$order = new WC_Order($order_id);
echo $order->get_billing_email();

Just a thought...

deltab
  • 2,498
  • 23
  • 28
Caio Mar
  • 2,344
  • 5
  • 31
  • 37
9

Although, this may not be advisable.

If you want to get customer details, even when the user doesn’t create an account, but only makes an order, you could just query it, directly from the database.

Although, there may be performance issues, querying directly. But this surely works 100%.

You can search by post_id and meta_keys.

 global $wpdb; // Get the global $wpdb
 $order_id = {Your Order Id}

 $table = $wpdb->prefix . 'postmeta';
 $sql = 'SELECT * FROM `'. $table . '` WHERE post_id = '. $order_id;

        $result = $wpdb->get_results($sql);
        foreach($result as $res) {
            if( $res->meta_key == 'billing_phone'){
                   $phone = $res->meta_value;      // get billing phone
            }
            if( $res->meta_key == 'billing_first_name'){
                   $firstname = $res->meta_value;   // get billing first name
            }

            // You can get other values
            // billing_last_name
            // billing_email
            // billing_country
            // billing_address_1
            // billing_address_2
            // billing_postcode
            // billing_state

            // customer_ip_address
            // customer_user_agent

            // order_currency
            // order_key
            // order_total
            // order_shipping_tax
            // order_tax

            // payment_method_title
            // payment_method

            // shipping_first_name
            // shipping_last_name
            // shipping_postcode
            // shipping_state
            // shipping_city
            // shipping_address_1
            // shipping_address_2
            // shipping_company
            // shipping_country
        }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tosin Onikute
  • 3,883
  • 6
  • 38
  • 61
7
$customer_id = get_current_user_id();
print get_user_meta( $customer_id, 'billing_first_name', true );
7

WooCommerce "Orders" are just a custom post type, so all the orders are stored in wp_posts and its order information in stored into wp_postmeta tables.

If you would like to get any details of WooCommerce's "Order" then you can use the below code.

$order_meta = get_post_meta($order_id); 

The above code returns an array of WooCommerce "Order" information. You can use that information as shown below:

$shipping_first_name = $order_meta['_shipping_first_name'][0];

To view all data that exist in "$order_meta" array, you can use the below code:

print("<pre>");
print_r($order_meta);
print("</pre>");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AddWeb Solution Pvt Ltd
  • 21,025
  • 5
  • 26
  • 57
5

I was looking for something like this. It works well.

So get the mobile number in WooCommerce plugin like this -

$customer_id = get_current_user_id();
print get_user_meta($customer_id, 'billing_phone', true);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vikas Kumar
  • 205
  • 2
  • 9
4

This is happening because the WC_Customer abstract doesn't hold hold address data (among other data) apart from within a session. This data is stored via the cart/checkout pages, but again—only in the session (as far as the WC_Customer class goes).

If you take a look at how the checkout page gets the customer data, you'll follow it to the WC_Checkout class method get_value, which pulls it directly out of user meta. You'd do well to follow the same pattern :-)

Josh Levinson
  • 283
  • 3
  • 14
4

I just dealt with this. Depending on what you really want, you can get the details from the order like this:

$field = get_post_meta($order->id, $field_name, true);

Where $field_name is '_billing_address_1' or '_shipping_address_1'or 'first_name'. You can google the other fields, but don't forget the "" at the beginning.

If you want to retrieve the customer for this order, and get its field directly, it works as in your solution, except you do not need to retrieve the full customer object:

$customer_id = (int)$order->user_id;

$field = get_user_meta($customer_id, $field_name, true);

Now in this case, the $field_name does not start with "_". For example: 'first_name' and 'billing_address_1'.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pieter van Kampen
  • 1,957
  • 17
  • 21
2

And another example to get the customer details from the database:

$order = new WC_Order($order_id);
$order_detail['status']              = $order->get_status();
$order_detail['customer_first_name'] = get_post_meta($order_id, '_billing_first_name', true);
$order_detail['customer_last_name']  = get_post_meta($order_id, '_billing_last_name', true);
$order_detail['customer_email']      = get_post_meta($order_id, '_billing_email', true);
$order_detail['customer_company']    = get_post_meta($order_id, '_billing_company', true);
$order_detail['customer_address']    = get_post_meta($order_id, '_billing_address_1', true);
$order_detail['customer_city']       = get_post_meta($order_id, '_billing_city', true);
$order_detail['customer_state']      = get_post_meta($order_id, '_billing_state', true);
$order_detail['customer_postcode']   = get_post_meta($order_id, '_billing_postcode', true);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mostafa Soufi
  • 645
  • 10
  • 17
2

Here in LoicTheAztec's answer is shown how to retrieve this information.

Only for WooCommerce v3.0+

Basically, you can call

// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );

This will return an array to the billing order data, including billing and shipping properties. Explore it by var_dump-ing it.

Here's an example:

$order_billing_data = array(
    "first_name" => $order_data['billing']['first_name'],
    "last_name" => $order_data['billing']['last_name'],
    "company" => $order_data['billing']['company'],
    "address_1" => $order_data['billing']['address_1'],
    "address_2" => $order_data['billing']['address_2'],
    "city" => $order_data['billing']['city'],
    "state" => $order_data['billing']['state'],
    "postcode" => $order_data['billing']['postcode'],
    "country" => $order_data['billing']['country'],
    "email" => $order_data['billing']['email'],
    "phone" => $order_data['billing']['phone'],
);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

Get the customer id from the order object:

$order = new WC_Order($order_id);

// Here the customer data
$customer = get_userdata($order->customer_user);
echo $customer->display_name;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lafif Astahdziq
  • 3,788
  • 29
  • 38
0

I did manage to figure it out:

$order_meta    = get_post_meta($order_id);
$email         = $order_meta["_shipping_email"][0] ?: $order_meta["_billing_email"][0];

I do know know for sure if the shipping email is part of the metadata, but if so I would rather have it than the billing email - at least for my purposes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fwho
  • 248
  • 2
  • 14
0

WooCommerce is using this function to show billing and shipping addresses in the customer profile. So this will might help.

The user needs to be logged in to get address using this function.

wc_get_account_formatted_address( 'billing' );

or

wc_get_account_formatted_address( 'shipping' );
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bhautik Nada
  • 377
  • 3
  • 6