I need a query that returns me all the users with orders with payment approved.
I'm having a hard time finding where in the db this is stored. I found only post_status 'wc-complete', but I don't think this is the right info.
SELECT a.post_status, b.meta_value FROM wp_posts a, wp_postmeta b
WHERE a.ID = b.post_id
AND a.post_type = 'shop_order'
AND a.post_status = 'wc-completed'
Using "completed" order status for paid orders is correct
Here is a custom function with a SQL query, that will output an formatted array of User IDs with their completed orders (paid / accepted):
function completed_orders_ids_by_costumer_id(){
global $wpdb;
$query = $wpdb->get_results("
SELECT pm.meta_value AS user_id, pm.post_id AS order_id
FROM {$wpdb->prefix}postmeta AS pm
LEFT JOIN {$wpdb->prefix}posts AS p
ON pm.post_id = p.ID
WHERE p.post_type = 'shop_order'
AND p.post_status = 'wc-completed'
AND pm.meta_key = '_customer_user'
ORDER BY pm.meta_value ASC, pm.post_id DESC
");
// We format the array by user ID
foreach($query as $result)
$results[$result->user_id][] = $result->order_id;
return $results;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works.
EXAMPLE USAGE just for test to see the raw outputted data
echo '<pre>'; print_r(completed_orders_ids_by_costumer_id()); echo '</pre>';
You will get something like:
Array
(
[9] => Array
(
[0] => 505
[0] => 497
)
[12] => Array
(
[0] => 626
[1] => 584
[2] => 483
)
[15] => Array
(
[0] => 614
[1] => 598
)
[17] => Array
(
[0] => 634
)
… / … and so on …
)
Now in
wp_postmeta
table you will also some other meta keys related to paid orders that you could use:
•'_paid_date'
•'_date_paid'
•'_date_completed'
•'_completed_date'
But targeting "completed" order status is just fine
Using that others listed meta keys, you can make your SQL query (that can replace our first query in the function):
$query = $wpdb->get_results("
SELECT DISTINCT pm.meta_value AS user_id, pm.post_id AS order_id
FROM {$wpdb->prefix}postmeta AS pm
LEFT JOIN {$wpdb->prefix}posts AS p
ON pm.post_id = p.ID
LEFT JOIN {$wpdb->prefix}postmeta AS pm2
ON p.ID = pm2.post_id
WHERE p.post_type = 'shop_order'
AND pm.meta_key = '_customer_user'
AND pm2.meta_key IN ( '_paid_date', '_paid_date', '_date_completed', '_completed_date' )
AND pm2.meta_value != ''
ORDER BY pm.meta_value ASC, pm.post_id DESC
");
Tested and works too…