I'm looking to find a solution to my problem. I would like to change the PayPal email based on WooCommerce order total.
So, if order total is < 10$
Receiver PayPal = paypalemail1#domain.com
Else
Receiver PayPal = paypalemail2#domain.com
I tried to search here and the only code that I found was this:
add_filter( 'woocommerce_paypal_args', 'woocommerce_paypal_args', 10, 2 );
function woocommerce_paypal_args( $paypal_args, $order ) {
//Get the customer ID
$user_id = $order->get_user_id();
// Get the user data
$user_data = get_userdata( $customer_id );
// Adding an additional recipient for a custom user role
if ( in_array( 'wholesale_customer', $user_data->roles ) )
$paypal_args['business'] = 'email#email.com';
return $paypal_args;
}
But here is not based on WooCommerce order total but on the user role. Is there any way to personalise it?
woocommerce_paypal_args has two arguments, the settings and the $order object. So based on the order, we can get the total and based on that, change the email
function filter_woocommerce_paypal_args( $paypal_args, $order ) {
// Get total
$order_total = $order->get_total();
// Less then 10
if ( $order_total < 10 ) {
$paypal_args['business'] = 'paypalemail1#domain.com';
} else {
$paypal_args['business'] = 'paypalemail2#domain.com';
}
return $paypal_args;
}
add_filter( 'woocommerce_paypal_args', 'filter_woocommerce_paypal_args', 10, 2 );
Related
I am creating a 'Build Your Own' page. After selecting 4 products from the options, 1 main product gets added to the basket with 4 of the selected products being added as meta_data under that main product.
You can see below the main product with 4 selected products (IDs).
After paying for this item, I need to add each selected product to the order, so that they are within the order on the backend. I'm having to do it like this, because I need the stock of the selected product to go down, eventually pulling into a stock management system we use (veeqo)
Any help is appreciated. The code below allows me get the some meta_data for woocommerce_thankyou but I am not sure if it will work then...
add_action('woocommerce_thankyou', 'BuildYourOwn', 10, 1);
function BuildYourOwn( $order_id ) {
if ( !$order_id ){
return;
}
$firstTime = get_post_meta( $order_id, '_thankyou_action_done', true );
// Allow code execution only once
if( !$firstTime ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
$exItems = '';
// Loop through order items
foreach ( $order->get_items() as $item_id => $item ) {
//print_r($item);
// Get the product object
$product = $item->get_product();
// Get the product sku
$product_sku = $product->get_sku();
// Get the product name
$product_id = $product->get_name();
$extras = $item->get_formatted_meta_data('_', true);
$exItems.=$product_sku;
if(!empty($extras)){
$exItems.=$product_sku.' -';
foreach($extras as $extra){
$exItems.= ' ['.$extra->key.' : '. preg_replace("/[^A-Za-z0-9?#,.&%!\s]/","",$extra->value).'] ';
}
}
$exItems.="\n";
}
var_dump($exItems);
Maybe I worded the question wrong - But I figured it out:
I used the code below to get the meta_data which I then looped through and got individual item id and added it to the basket this way.
// Get the product meta data
$extras = $item->get_formatted_meta_data('_', true);
if ($product_id == 60023){
if(!empty($extras)){
$args = array(
'subtotal' => 0,
'total' => 0,
);
foreach($extras as $extra){
$mini_name = $extra->value;
$mini = get_page_by_title( $mini_name, OBJECT, 'product' );
$mini_id = $mini->ID;
$order->add_product( wc_get_product($mini_id), 1, $args); // Add Minis
}
}
}
The only slight issue is woocommerce_thankyou hook not firing if paypal users don't come back to the site after paying.
I have a WooCommerce site that sells consumer goods. We have a referral program where doctors around the US get compensation based profits created by those who use the doctors referral/discount code.
This is all fine, however the code is a 1 per customer use as we only want the customers first order to receive the discount.
This is where the problem lies, the doctors still need to be compensated for all the profit brought in from people who used their code on their first purchase.
My idea is to use Groups(docs). Then monthly use the group filter in orders to pull down orders for each doctor.
So what I am trying to do is create a little script that adds a customer to a group based on the coupon code they use. I am manually creating group and coupon code at the same time (they will alway be the same). I also just grabbed the group_id from the groups plugin section. wondering if we can also pull group id from name.
Here is what I currently have that is not working. Any help is appreciated.
add_action('woocommerce_thankyou', 'coupon_group', 10, 1);
function coupon_group( $order_id ){
$order = wc_get_order( $order_id );
$coupon_codes = $order->get_coupon_codes();
$coupon_name = 'dr_x';
$group_id = 2;
foreach($coupon_codes as $coupon_code ){
if ($coupon_code->get_name() == $coupon_name) {
$user_id = $order->get_user_id();
if ($user_id) {
$group = Groups_Group::read_by_name($coupon_name);
$is_a_member = Groups_User_Group::read( $user_id , $group_id ->group_id );
if (!$is_a_member) {
Groups_User_Group::create( array( 'user_id' => $user_id, 'group_id' => $group ) );
}
}
}
}
}
Well I ended up going the route of roles over Groups as i couldnt get that to update properly.
I used User Role Editor to create new roles.
add_action('woocommerce_thankyou', 'coupon_group', 10, 1);
function coupon_group( $order_id ){
$order = wc_get_order( $order_id );
$coupon_codes = $order->get_coupon_codes();
$coupon_name = 'CouponCode'; //manually created coupon code
foreach($coupon_codes as $coupon_code ){
$user_id = $order->get_user_id();
if ($coupon_code == $coupon_name) {
if ($user_id) {
$user = new WP_User( $user_id );
$user->remove_role('customer');
$user->add_role($coupon_name);
}
}
}
}
I have made a simple webshop with woocommerce, with three payment methods. iDeal and by direct bank transfer and on account. The order ID is created based on the payment method. for example, if payment is made with iDEAL, the order id becomes ID190100; if payment is made on account, the order id becomes RK190100. I get this working with the plugin
"Sequential Order Numbers for WooCommerce" from BeRocket but these are already created before the payment is complete. The order ID must only be finalized once the payment has been made. Now orders that have not yet paid, and may not be paying, will receive a fixed order ID. So is it possible to create a temporary order id and when the order is completed change the order id based on payment method?
Woocommerce by default will use the post ID of the order for the order ID. This is evident when viewing the WC_Order::get_order_number() method. If you want to use a custom order number to display, you'll need to add a filter on woocommerce_order_number to load in a different value.
An example script would be:
add_action( 'woocommerce_order_status_completed', 'wc_change_order_id' );
function wc_change_order_id( $order_id ) {
$order = wc_get_order( $order_id );
$method = $order->get_payment_method(); // need check this
if ( $method === 'account' ) {
$number = 'ID' . $order->get_id();
$order->update_meta_data('_new_order_number', $number );
}
}
add_filter('woocommerce_order_number', function($default_order_number, \WC_Order $order) {
//Load in our meta value. Return it, if it's not empty.
$order_number = $order->get_meta('_new_order_number');
if(!empty($order_number)) {
return $order_number;
}
// use whatever the previous value was, if a plugin modified it already.
return $default_order_number;
},10,2);
Try this. It's very quick example. Hope help.
add_action( 'woocommerce_order_status_completed', 'wc_change_order_id' );
function wc_change_order_id( $order_id ) {
$order = wc_get_order( $order_id );
$method = $order->get_payment_method(); // need check this
if ( $method === 'account' ) {
$number = 'ID' . $order->get_id();
$order->set_id( $number );
$order->save();
}
}
I need to add a new role to my recently registered user (upon buying any of my four specific subscription products). Until now, every recently registered user (those who buy a subscription product) get a Subscriber role. While I want them to be Subscriber + Advertiser if they buy any of my 4 target subscription products.
I have tried to use woocommerce_order_status_completed, woocommerce_order_status_processing and woocommerce_order_status_changed hooks, but none of them are working with my code.
I have modified the function and code inside these hooks several times but I got nothing special.
Until now, I have used this code.
add_action( 'woocommerce_order_status_completed', 'so_29647785_convert_customer_role' );
function so_29647785_convert_customer_role( $order_id ) {
$order = new WC_Order( $order_id );
if ( $order->user_id > 0 ) {
foreach ( $order->get_items() as $order_item ) {
if( 4008 == $order_item[ 'product_id' ] ) {
$user = new WP_User( $order->user_id );
// Add new role
$user->add_role( 'advertiser' );
}
}
}
}
I will appreciate any help or track.
I have also tried this code and it is helpful in creating a user with both Subscriber + Advertiser roles but I can't do so in my case. Because I need users to be registered with both Subscriber + Advertiser roles only if they will buy four of my target subscription products. While this code is adding both Subscriber + Advertiser to every new user regardless of the product they choose.
add_filter('woocommerce_new_customer_data', 'bbloomer_assign_custom_role', 10, 1);
function bbloomer_assign_custom_role($args) {
$args['role'] = 'advertiser';
return $args;
}
Any help will highly be appreciated!
Since Woocommerce 3, your code is outdated and there are some errors and mistakes in your code, like $order_item['product_id'] will not work… Try the following instead:
add_action( 'woocommerce_order_status_processing', 'order_status_change_add_user_role', 10, 2 );
add_action( 'woocommerce_order_status_completed', 'order_status_change_add_user_role', 10, 2 );
function order_status_change_add_user_role( $order_id, $order ) {
if ( $order->get_user_id() > 0 ) {
$user = $order->get_user(); // Get an instance of the WP_User object
foreach ( $order->get_items() as $item ) {
// Check that user role is not set yet and that is matching with a product ID
if( 4008 == $item->get_product_id() && ! in_array('advertiser', $user->roles) ) {
$user->add_role( 'advertiser' ); // Add new role
break; // Stop the loop
}
}
}
}
Code goes in function.php file of your active child theme (or active theme). It should works now.
Order and order items related since Woocommerce 3:
How to get WooCommerce order details
Get Order items and WC_Order_Item_Product in Woocommerce 3
add_action( 'woocommerce_order_status_completed', 'add_advertiser_role' );
function add_advertiser_role( $order_id ) {
$order = new WC_Order( $order_id );
if ( $order->get_user_id() > 0 ) {
foreach ( $order->get_items() as $order_item ) {
if( 4008 == $order_item->get_product_id() ) {
$user = new WP_User( $order->get_user_id() );
// Add new role
$user->add_role( 'advertiser' );
}
}
}
}
Programatically get WooCommerce Order details
I'm trying to disable email notification when order total is equal to 0. It looks that my hook code works with this simple condition, but i don't know how to retrieve order details at this step.
$array = array('woocommerce_order_status_completed' );
function filter_woocommerce_email_actions( $array ) {
if (0>1){
return $array;
}
};
add_filter( 'woocommerce_email_actions', 'filter_woocommerce_email_actions', 10, 1 );
Or should i use other hook for this? Any ideas?
You can remove recipient from email notifications for new order based on order total. Use this piece of code and customize it based on order total for your requirement.
add_filter( 'woocommerce_email_recipient_new_order', 'wc_new_order_cash_on_delivery_recipient', 10, 2 );
function wc_new_order_cash_on_delivery_recipient( $recipient, $order ) {
if ( 'cod' == $order->payment_method ) {
$recipient .= ', john#example.com';
}
return $recipient;
}