First Question: I want to add a user meta after buying a specific product. This specific product defines by ID. How can I achieve this?
add_action( 'woocommerce_thankyou', 'bbloomer_checkout_save_user_meta');
function bbloomer_checkout_save_user_meta( $order_id ) {
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
if ( $order->get_total() > 100 ) {
add_user_meta( $user_id, 'custom_checkbox', 'on');
}
}
Second Question: How to remove order info for a specific user using specific product ID? after removing that wc_customer_bought_product() need show return false.
Answer to your first question:
add_action( 'woocommerce_thankyou', 'bbloomer_checkout_save_user_meta');
function bbloomer_checkout_save_user_meta( $order_id ) {
$order = wc_get_order( $order_id );
foreach ($order->get_items() as $key => $item){
$product_id = $item['product_id'];
if ($product_id == 'YOUR PRODUCT ID HERE'){
add_user_meta( $order->get_user_id(), 'product_'.$product_id, 'Bought on Order ID: '.$order->get_id());
}
}
}
Related
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' );
}
}
}
Im trying to add products from an ACF field automatically when I manually create an order and Im adding a product within a given category, but not sure where to start.
This is what I have so far:
add_action( 'woocommerce_order_status_processing', 'add_unique_id', 10, 1 );
function add_unique_id( $order_id ) {
$order = wc_get_order( $order_id );
foreach ($order->get_items() as $item_id => $item_obj ) {
$category = 'my_product_category';
// If the targeted product ID or the product category is found in the order items.
if( $item_obj->get_product_id() == $targeted_product_id || has_term( $category,'product_cat', $item_obj->get_product_id() ) ) {
$product_id = get_sub_field('product', false);
$productextra = wc_get_product( $product_id );
$new_product_price = 0;
$productextra->set_price( $new_product_price );
$item_id = wc_add_order_item( $productextra );
}
}
}
I am trying to get woocommerce thank you page order_id. Using the code below.
But unfortunately I can't get it.
add_action( 'woocommerce_thankyou', 'bbloomer_check_order_product_id');
function bbloomer_check_order_product_id( $order_id ){
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == XYZ ) {
// do something
}
}
}
This code is outdated for WooCommerce version 3+. You should use instead:
add_action( 'woocommerce_thankyou', 'check_order_product_id', 10, 1);
function check_order_product_id( $order_id ){
# Get an instance of WC_Order object
$order = wc_get_order( $order_id );
# Iterating through each order items (WC_Order_Item_Product objects in WC 3+)
foreach ( $order->get_items() as $item_id => $item_values ) {
// Product_id
$product_id = $item_values->get_product_id();
// OR the Product id from the item data
$item_data = $item_values->get_data();
$product_id = $item_data['product_id'];
# Targeting a defined product ID
if ( $product_id == 326 ) {
// do something
}
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works for WooCommerce version 3+
Reference: How to get WooCommerce order details
I was not satisfied with current answers, as sometimes you need to check multiple products. If you do the same search for each product, it's really a waste, so I put it into a dispatcher format.
add_action('woocommerce_order_status_completed', 'onItemCheckout',10,1);
function onItemCheckout($order_id){
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item_key => $item_values){
$product_id = $item_values->get_product_id();
switch($item_values->get_product_id()){
case 9999 : FreeShipping($order, $product_id); break;
case 1010 : RequireValidation($order, $product_id); break;
default: break;
}
}
}
Alternatively,...
$ItemCheckoutHandler=[];
$ItemCheckoutHandler[9999]='FreeShipping';
$ItemCheckoutHandler[1010]='RequireValidation';
add_action('woocommerce_order_status_completed', 'onItemCheckout',10,1);
function onItemCheckout($order_id){
global $ItemCheckoutHandler;
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item_key => $item_values){
$product_id=$item_values->get_product_id();
$ItemCheckoutHandler[ $product_id ]( $order, $product_id );
} //Call the function assigned to that product id in the array
}
In either case, the assigned functions would take the order object, rather than the id, and the product_id as an argument:
function FreeShipping($order, $product_id){ ... }
function RequireValidation($order, $product_id){ ... }
You can of course customize these inputs to your liking.
Try this, hope it will work
add_action( 'woocommerce_thankyou', 'your_function_name', 10);
function your_function_name($order_id)
{
$order = wc_get_order($order_id);
foreach($order->get_items() as $order_key => $order_value)
{
$product_id = $order_value->get_data()['product_id'];
if($product_id == '123')
{
//do what you wnat and 123 is random product id, you can match product id with other as you want
}
}
}
Thank you.
I am trying to use this snippet of code to update my users from the default role of 'Subscriber' to the role of 'Premium' on the purchase of a product from my store.
add_action( 'woocommerce_order_status_completed','change_role_on_purchase' );
function change_role_on_purchase( $order_id ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
$products_to_check = array( '416' );
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id );
// Change role
$user->remove_role( 'Subscriber' );
$user->add_role( 'Premium' );
// Exit the loop
break;
}
}
}
I only have 1 product in my store and it has the product ID 416 (which I have inserted in the code).
I have put this into functions.php, but i'm not having any luck. The role isn't being updated after any successful purchase. Any ideas?
Have a try with this one:
function change_role_on_purchase( $order_id ) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
if ( $order->user_id > 0 && $product_id == '416' ) {
update_user_meta( $order->user_id, 'paying_customer', 1 );
$user = new WP_User( $order->user_id );
// Remove role
$user->remove_role( 'subscriber' );
// Add role
$user->add_role( 'premium' );
}
}
}
add_action( 'woocommerce_order_status_processing', 'change_role_on_purchase' );
what if we want to check product category instead of product id? How do we tweak this? The code below is for verifying multiple products with their respective IDs.
add_action( 'woocommerce_order_status_processing', 'change_role_on_purchase' );
function change_role_on_purchase( $order_id ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
$products_to_check = array( '27167', '27166' );
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id );
// Change role
$user->remove_role( 'friends' );
$user->add_role( 'customer' );
// Exit the loop
break;
}
}
}
In case someone is interested in this. If your customer wants to have in the future more products that will update the buyers role after purchase, instead of manually adding the product ids in the function, you can use this one
$products_to_check = wc_get_products( array( 'return' => 'ids', 'tag' => array('your tag here') ) );
Your customer can edit by him/herself a product and assign the product tag, that will allow the update of the user role.
Same thing here... Please keep in mind that woocommerce_order_status_processing means just that: that the order status is set to "processing". This does NOT mean that the order is "complete", meaning that it has been paid for. If you use this hook, you run the risk of making content available to your customer even though his order may not have been paid for. This is what woocommerce_order_status_completed is there for, but that one doesn't seem to work for virtual products, which get the order status automatically set to "completed".
woocommerce_order_status_completed only worked for me with virtual products disabled/unchecked in the products section, meaning I had to manually "complete" the order in order to trigger this hook. Still looking for a solution...
So I helped someone launch a site and they wanted a discounted product when someone purchased a specific product. I found a solution and implemented it and it worked at launch of the site and is no longer changing the role of customers when they purchase the products. I tried to get support from Woothemes and they don't support customization and want them to purchase a $129 extension to handle this.
Does anyone out there have a solution for this that still works?
Here is my code:
// Update User on purchase https://gist.github.com/troydean/9322593
function lgbk_add_member( $order_id ) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
}
if ( $order->user_id > 0 && $product_id == '247' || $order->user_id > 0 && $product_id == '255') {
update_user_meta( $order->user_id, 'paying_customer', 1 );
$user = new WP_User( $order->user_id );
// Remove role
$user->remove_role( 'customer' );
// Add role
$user->add_role( 'author' );
}
}
add_action( 'woocommerce_order_status_completed', 'lgbk_add_member' );
UPDATE
Normally this updated code version should work with woocommerce_order_status_completed and then you should try this code before. (This code is also compatible with next upcoming major WooCommerce update 2.7).
Here is the code:
add_action( 'woocommerce_order_status_completed', 'custom_action_on_completed_customer_email_notification' );
function custom_action_on_completed_customer_email_notification( $order_id ) {
// Set HERE your targetted products IDs:
$targetted_products = array( 247, 255 );
$order = wc_get_order( $order_id );
if ( $order->get_user_id() > 0 ) {
foreach ( $order->get_items() as $order_item ) {
// Here we detect if the a target product is part of this order items
if ( in_array( $order_item['product_id'], $targetted_products ) ){
// I think tha this is not really needed as it's set when an order has been paid…
update_user_meta( $order->get_user_id(), 'paying_customer', 1 ); // 1 => true
// Remove all roles and set 'editor' as user role (for current user)
$user = new WP_User( $order->get_user_id() );
$user->set_role( 'author' );
// Product is found, we break the loop…
break;
}
}
}
}
But as I don't know how your order is changed to 'completed' status, if you want to be sure (in all possible cases) that the customer that will buy one of your 2 specific products, will have his role changed from 'customer' to 'author' when order status is set to 'completed', I will recommend you trying to use this an email notification hook (if the first code snippet doesn't work).
For example here I use woocommerce_email_before_order_table hook, that will be executed and fired on "Completed order customer email notification" with the help of some conditions. (This code is also compatible with next upcoming major WooCommerce update 2.7).
Here is your revisited and tested code:
add_action( 'woocommerce_email_before_order_table', 'custom_action_on_completed_customer_email_notification', 10, 4 );
function custom_action_on_completed_customer_email_notification( $order, $sent_to_admin, $plain_text, $email ) {
if( 'customer_completed_order' == $email->id ){
// Set HERE your targetted products IDs:
$targetted_products = array( 247, 255 );
if ( $order->get_user_id() > 0 ) {
foreach ( $order->get_items() as $order_item ) {
// Here we detect if the a target product is part of this order items
if ( in_array( $order_item['product_id'], $targetted_products ) ){
// I think tha this is not really needed as it's set when an order has been paid…
update_user_meta( $order->get_user_id(), 'paying_customer', 1 ); // 1 => true
// Remove all roles and set 'editor' as user role (for current user)
$user = new WP_User( $order->get_user_id() );
$user->set_role( 'author' );
// Product is found, we break the loop…
break;
}
}
}
}
}
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.