Skip Navigation

[Resolved] get product id from order id in woocommerce

This support ticket is created 7 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

This topic contains 10 replies, has 2 voices.

Last updated by Nicholas 6 years, 12 months ago.

Assisted by: Beda.

Author
Posts
#515619

Hello I found this
https://wordpress.stackexchange.com/questions/97176/get-product-id-from-order-id-in-woocommerce
and would now like to display the following on a product page:

the following customers bought this product:

How would i set up my views filter?

I already made the order post type public and set the post status to wc_completed.

#516004

WooCommerce has a function to retrieve teh "already bought products" by user.
It is "wc_customer_bought_product"

I go into detail here:
https://toolset.com/forums/topic/show-full-video-to-paid-users-and-trailer-to-others/#post-424693

You could query products and then use the ShortCode I mention there, to show only the already bought products.

#516010

Hello Beda.
In the thread you say "This shortcode evaluates if a certain (logged in) user has bought a certain (current in loop) product."

For my case. The names of the product customer should be displayed to every user.

I am using the following custom post fields to do this:

[wpv-post-field name='_billing_first_name']
[wpv-post-field name='_billing_last_name']

However all of the customers get displayed on the product page. Even customers who bought an entirely different product.

The view should just ouput the customers of the accompanying product.

What do I have to set my views filter to in order to achieve this?

Have a good weekend
Nicholas

#516023

There are some Plugin that does this out of the box:
https://wordpress.org/plugins/wc-product-customer-list/
hidden link

Now if you want to do that on a list of prodcts you first need all order ID's for those prodcuts.
Then, from that ID you can get the Users who purchased it.
http://stackoverflow.com/questions/21665476/woocommerce-how-to-get-detailed-list-of-orders-for-a-product
https://wordpress.stackexchange.com/questions/138123/woocommerce-how-to-get-the-user-belonging-to-an-order

I think some custom code is needed here.

I can make some trials if you can send me a working copz of your website, where some users/orders exist already.

Here are the instructions on how to send me such a copy:
https://toolset.com/faq/provide-supporters-copy-site/

#516178

This Database is not working; I cannot even edit the options table, or set it up with the Duplicator.

It mentions permission errors, syntax errors and more.

Might you rebuild a package with the Duplicator Plugin and send it to me again?

Or, you might give me access to the Site if I can make changes there, but this will include changes on the Front End, disabling Plugins, and more.
A backup would be mandatory and eventual Visitors could experience downtimes or changes while viewing the site.

#516481

I am sorry, but I cannot follow those steps.

Please provide to me the access to the live site; I will grab a Duplicator Package, and deploy it locally.

About "In my case you need to import all three databases."

This is a very important detail.
We do not support, and neither does WordPress, multiple Database Websites.

A WordPress WebSite has one Database with 12 tables in it.
A number of tables might vary depending on what Custom Plugins you use, but that would be the minimum.
All those tables must be editable and writable by the Root user of the Website.

If you use a customised method, I cannot assist troubleshooting.

I am quite sure your Website uses one Database only.

Anyway.

1. I reccomend this Plugin, it does exactly what you want, and it has ShortCodes so you can use it in views or content templates as well
hidden link

2. Otherwise this little Custom Code should do the trick.

function get_user_who_bought_the_product(){

	//We get all orders (post type shop_order, completed)
	$customer_orders = get_posts( array(
	        'numberposts' => -1,
	        'post_type'   => 'shop_order', // WC orders post type
	        'post_status' => 'wc-completed' // Only orders with status "completed"
	    ) );

	//We create an array for later use
	$customer_name = array();

	//We foreach over each found order post and get some data
	foreach ($customer_orders as $customer_order) {
		//customer ID from the post meta
	 	$customer_id = get_post_meta($customer_order->ID, '_customer_user', true);
	 	//get the user data
	 	$customer_object = get_userdata($customer_id);
	 	//get the user name (first)
	 	$customer_name[] = $customer_object->first_name;
	}

	//return above array joined
	return join(" ", $customer_name);
}

add_shortcode('get_user_who_bought_the_product','get_user_who_bought_the_product');

It has to be added to functions.php in your theme, then called in the Content Template with the ShortCode [get_user_who_bought_the_product], this will then display the user First name (of the user who bought the product).

This is custom code and cannot be assisted 100% by us, but it should give an idea of how you can do that.

The feature you are asking for is not officially supported in Toolset or even WooCommerce Core.

#516498

Hey Beda. Sorry there are no three databases. My bad. I meant sql files. I didn't mean to confuse you.

Thank you. Here's also some custom code that's working for me.

// Add Shortcode
function wpcl_shortcode( $atts ) {
$output = '';
// Attributes
$customer_atts = shortcode_atts( array(
            'product' => get_the_id(),
'quantity' => false,
    ), $atts );
  
// Code
global $post, $wpdb;
$post_id = $customer_atts['product'];
$wpcl_orders = '';
$columns = array();
$customerquery = "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_itemmeta woim
LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi
ON woim.order_item_id = oi.order_item_id
WHERE meta_key = '_product_id' AND meta_value = %d
GROUP BY order_id;";
$order_ids = $wpdb->get_col( $wpdb->prepare( $customerquery, $post_id ) );
$order_status = get_option( 'wpcl_order_status_select', array('wc-completed') );
if( $order_ids ) {
$args = array(
'post_type'       =>'shop_order',
'post__in'   => $order_ids,
'posts_per_page' =>  999,
'order'          => 'ASC',
'post_status' => $order_status,
);
$wpcl_orders = new WP_Query( $args );
}
if($wpcl_orders) {
$output .= '<table>';
foreach($wpcl_orders->posts as $wpcl_order) {
$order = new WC_Order($wpcl_order->ID);
$output .= '<tr>';
$output .= '<td>' . $order->billing_first_name . ' ' . $order->billing_last_name . '</td>';
$currency =get_woocommerce_currency_symbol();
$datetime=$order->order_date;
$time=strtotime($datetime);
            $output .= '<td>' . date("D, d M Y ",$time) ;
$output .= '<td>' .$currency. $order->order_total ;
if($customer_atts['quantity'] == true) {
if (sizeof($order->get_items())>0) { $singlecount = ''; foreach($order->get_items() as $item) { if( $item['product_id'] == $post_id ) { $productcount[] = $item['qty']; $singlecount+= $item['qty'];  }  } $items['order-qty'] = $singlecount;  $output .= '<td>' . $singlecount . '</td>'; }
}
$output .= '</tr>';
}
$output .= '</table>';
}
return $output;
}
add_shortcode( 'customer_list', 'wpcl_shortcode' );

However I would like to achieve this with toolset. I am sure it is possible. I just couldn't figure it out myself.
Displaying the customer details using a view already works on my site. I just need that final step to display the related customers on the single product pages. Not all of them. Only the customers that bought that specific product.

[wpv-post-field name='_billing_first_name']
[wpv-post-field name='_billing_last_name']

These wc shortcodes are only a couple of examples of what I would like to display.
Of course there's more. The plugin you mentioned just can't display all of the information I'd like to display on the frontend.

If you make the next reply private. I'll give you the credentials to my site. Please just take a look at it and test it.

Thanks,
Nicholas

#517270

You can make the Order Post Type public, then make the hidden Field "_customer_user" and "_product_id" also visible, in the Toolset > Settings > Front End Content > Hidden custom fields.

This will then allow you to Query in a view those Orders, and filter them by "_product_id" (current Post -> Product) and then display the User ID with "_customer_user" or use that as an ID attribute in a Toolset Field for the User.

But as said, this is not supported for several reasons, being the highest, Orders are not public and that is for security reasons.
It's not on us to make that Post Type public, and I cannot recommend it as it would mean change the behaviour of a Third Party Plugin.

It seems that this is not possible because WooCommerce orders post type is not publicly queryable
The best approach of this to query orders, and then dissect users from that.
However, it seems this is not publicly queryable because of security reasons.

As such, I can not really recommend making that public, it would go against the native behaviour of WooCommerce.
I recommend either use the code or that plugin, it makes everything work safe and smooth.

#517286

Thank you so much Beda for taking the time to look into this.

Unfortunately I can't find the hidden field _product_id.

What I do find is _order_key, _transaction_id, _view_loop_id, _recorded_sales...

I understand. Sounds like that this is not within the scope of your support policy.
If you like you can go ahead and close the ticket.

Regards,
Nicholas

#517338

That field is from your code.
Somehow WooCommerce must link the Product and the Order, right?

But actually I see now that your code there uses a field that does not exist, I wonder how it can work as that, but anyway, WooCommerce connects the order and the product in a custom table, that is fully inaccessible by us.

This will not be doable by Toolset only.

#517340

Ok thank you a lot Beda.

I'll use your code. It works perfectly.

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.