Update user meta field after WooCommerce checkout - php

I use WooCommerce with WordPress and I would like to update a custom field for the purchase of a single product at the time of payment validation with the display of the thank you page.
I started from this code but it does not work for the moment.
add_action( 'woocommerce_thankyou', 'checkout_update_user_meta' );
function checkout_update_user_meta( $order_id ) {
$order = new WC_Order( '$order_id' );
$user_id = $order->get_user_id();
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == '777' ) {
update_user_meta( $user_id, 'masterclass-1', 'ok' );
}
}
}

add_action( 'woocommerce_thankyou', 'checkout_update_user_meta' );
function checkout_update_user_meta( $order_id ) {
$order = new WC_Order( $order_id );
$user_id = $order->get_user_id();
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id === 777 ) {
update_user_meta( $user_id, 'masterclass-1', 'ok' );
}
}
}
The issue with your code was that you wrapped the $order_id in single quotes. This line $order = new WC_Order( $order_id ); can also be replaced as $order = wc_get_order( $order_id );

I just modified your code to Update user meta field after woocommerce checkout according to your need. Please check my changes and hope it will work 👍
add_action( 'woocommerce_thankyou', 'checkout_update_user_meta' );
function checkout_update_user_meta( $order_id ) {
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
if ( $product_id == 777 ) {
update_user_meta( $user_id, 'masterclass-1', 'ok' );
}
}
}

Related

Save meta value when WooCommerce order status is completed

I made a code to save a value based on a meta key when a certain product is purchased (order status = completed).
I have written the code below to complete this task. However, the meta data does not appear to be saved? Any advice?
add_action( 'woocommerce_order_status_completed', 'wpglorify_change_role_on_purchase2' );
function wpglorify_change_role_on_purchase2( $order_id ) {
// get order object and items
$order = new WC_Order( $order_id );
$items = $order->get_items();
$user_is= $user->ID;
$meta_key = get_field("field");
$field = get_user_meta($user_is, $meta_key);
$meta_value = 5;
$product_id = 1289;
foreach ( $items as $item ) {
if( $product_id == $item['product_id'] && $order->user_id ) {
$user = new WP_User( $order->user_id );
update_user_meta($user_is, $field, $meta_value, '');
}
}
}
Your code contains some mistakes:
get_field() is a ACF function, and doesn't seem to apply here
You're using $user->ID; but $user is undefined
Furthermore, it is important to determine whether you want to update user meta or post meta data
1) To update user meta you can use:
// Update user meta
function action_woocommerce_order_status_completed( $order_id, $order ) {
// Product IDs
$product_id = 1289;
// Meta data
$meta_value = 5;
$meta_key = 'my_meta_key';
// Is a order
if ( is_a( $order, 'WC_Order' ) ) {
// Getting the user ID
$user_id = $order->get_user_id();
// User ID exists
if ( $user_id >= 1 ) {
// Loop through order items
foreach ( $order->get_items() as $key => $item ) {
// Compare
if ( $item->get_product_id() == $product_id ) {
// Update user meta
update_user_meta( $user_id, $meta_key, $meta_value );
// Break loop
break;
}
}
}
}
}
add_action( 'woocommerce_order_status_completed', 'action_woocommerce_order_status_completed', 10, 2 );
2) To update post meta you can use:
// Update post meta
function action_woocommerce_order_status_completed( $order_id, $order ) {
// Product IDs
$product_id = 1289;
// Meta data
$meta_value = 5;
$meta_key = 'my_meta_key';
// Is a order
if ( is_a( $order, 'WC_Order' ) ) {
// Loop through order items
foreach ( $order->get_items() as $key => $item ) {
// Compare
if ( $item->get_product_id() == $product_id ) {
// Add the meta data
$order->update_meta_data( $meta_key, $meta_value );
// Save
$order->save();
/** OR the older way **/
// update_post_meta( $order_id, $meta_key, $meta_value );
// Break loop
break;
}
}
}
}
add_action( 'woocommerce_order_status_completed', 'action_woocommerce_order_status_completed', 10, 2 );

Save custom item meta data once order has been saved in WooCommerce

I'm using the save_post_{$post->post_type} hook, which fires once a post (order) has been saved.
The intention is to save product meta based on certain order statuses. This is the code I wrote/used for this:
add_action ( 'save_post_shop_order', function (int $postId, \WP_Post $post, bool $update): void {
$order = new WC_Order( $postId );
$order_status = $order->get_status();
$status_arrays = array( 'processing', 'on-hold', 'to-order', 'needed' );
if ( in_array($order_status, $status_arrays) ) {
return;
}
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$product = wc_get_product( $product_id );
$final_product->update_meta_data( '_test', '_test' );
$final_product->save();
}
},
10,
3
);
However, I can't find the new metadata in my database. Any advice? can anyone help me how to achieve this?
Your code contains some mistakes, for example $final_product
is not equal to $product and is therefore not defined.
This should suffice: (explanation via comment tags, added in the code)
function action_save_post_shop_order( $post_id, $post, $update ) {
// Checking that is not an autosave && current user has the specified capability
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! current_user_can( 'edit_shop_order', $post_id ) ) {
return;
}
// Get $order object
$order = wc_get_order( $post_id );
// Is a WC_Order
if ( is_a( $order, 'WC_Order' ) ) {
// NOT has status
if ( ! $order->has_status( array( 'processing', 'on-hold', 'to-order', 'needed' ) ) ) {
// Loop through order items
foreach( $order->get_items() as $item ) {
// Get an instance of corresponding the WC_Product object
$product = $item->get_product();
// Meta: key - value
$product->update_meta_data( '_test', '_test' );
// Save
$product->save();
}
}
}
}
add_action( 'save_post_shop_order', 'action_save_post_shop_order', 10, 3 );
Note: If the order should have a certain status versus NOT having the status, just remove the ! from:
// NOT has status
if ( ! $order->has_status(..

Get product IDs while using the "woocommerce_payment_complete" hook

My hooks are in theme folder/functions.php
I want tie hook with product_id from order.
tryin this method but they return nothing.
$product->get_id()
or
$product = wc_get_product( $product_id );
Full code
add_action( 'woocommerce_payment_complete', 'so_payment_complete' );
function so_payment_complete($order_id)
{
$order = wc_get_order($order_id);
$billingEmail = $order->billing_email;
$billingName = $order->billing_first_name;
$product_id = $order->product_id;
if ($product_id == 980) {
......
}
If you use Woocommerce 3.0+ version, then it should be this.
I found the answer with this link: https://wordpress.stackexchange.com/questions/97176/get-product-id-from-order-id-in-woocommerce
In an order can be multiple products, so you have to loop through them. In your code it would look like this:
add_action( 'woocommerce_payment_complete', 'so_payment_complete' );
function so_payment_complete($order_id)
{
$order = wc_get_order($order_id);
$billingEmail = $order->billing_email;
$billingName = $order->billing_first_name;
$items = $order->get_items();
foreach ( $items as $item ) {
$product_name = $item->get_name();
$product_id = $item->get_product_id();
$product_variation_id = $item->get_variation_id();
if ($product_id == 980) {
// ....
}
}
}

How to check whether any WooCommerce order contains a product-ID?

I'm coding a plugin which should check whether an order contains an product-ID.
How can I check all orders if any contains the product-ID and then mark this order as finished?
I know how to check an order on thankyou-page, but the order-ID there is already given:
Thank you all and #johnnyd23 for the code below.
foreach ( $order_summary as $order ) {
$order = wc_get_order( $order->order_id );
$order_id = $order->get_id();
$items = $order->get_items();
if ( $order->get_status() == 'processing' ) {
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == XYZ ) {
// do something
}
}
}
}
What you should do is check if this order id is what you need and update order status
if($order_id == 'Your_required_id'){
$order->update_status( 'completed' );
}
You could change your code something as the following
foreach ( $order_summary as $order ) {
$order = wc_get_order( $order->order_id );
$order_id = $order->get_id();
$items = $order->get_items();
if ( $order->get_status() == 'processing' ) {
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == XYZ ) {
// do something
$order->update_status( 'completed' );
}
}
}
}
I haven't tested it. Tailor the code according to your needs

Get category ID from order item inside woocommerce hook

In functions.php we have:
add_action( 'woocommerce_order_status_processing', 'mysite_processing', 10, 1);
then inside this function we get order items:
function mysite_processing($order_id) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
}
}
After getting the product id, we want to get the category id that product belongs. We already try with get_the_terms and has_term functions, both didn't work.
Solved, added to items for: $product = wc_get_product( $product_id );
Try below code
function mysite_processing($order_id) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$term_list = wp_get_post_terms($product_id,'product_cat',array('fields'=>'ids'));
print_r($term_list);
$cat_id = (int) $term_list[0];
echo $cat_id;
die();
}
}

Categories