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);
}
}
}
}
Related
I want a code that the password generated by woocommerce will be taken from the phone field on the checkout page when the user fills in the details for the billing
I tried the following code and it did not work
I would love a code that works. thanks.
<?php
//Use user phone number as auto-generated password
function wcs_filter_password_phone_number( $args ) {
$args['user_pass'] = $args['dbem_phone'];
return $args;
}
add_filter( 'woocommerce_new_customer_data', 'wcs_filter_password_phone_number' );
It's not really secure setting the password based on the customer's phone number. Anyone could find a way in to be honest.
Having said that, the task is interesting, and based on WooCommerce: Update Order Field Value After a Successful Order it is possible indeed to alter an order/user field after a successful checkout.
You could hook into "woocommerce_thankyou" as per the article, or even into "woocommerce_payment_complete" if you wanted to do that in the background and only for paid/completed orders.
Also, you should look into https://developer.wordpress.org/reference/functions/wp_set_password/ which is the WP function to set a new password programmatically.
Here's my attempt:
add_action( 'woocommerce_thankyou', 'bbloomer_alter_password_after_order' );
function bbloomer_alter_password_after_order( $order_id ) {
$order = wc_get_order( $order_id );
$phone = $order->get_billing_phone();
$user_id = $order->get_user_id();
if ( $phone && $user_id ) {
wp_set_password( $phone, $user_id );
}
}
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 );
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 using woocommerce subscriptions and I'm writing a plugin to update an external system, if the user upgrade or downgrade his subscription it shows as a new order with its ID, but I can't get the subscription ID (which it's constant) related to the order ID, I check the documentation but I couldn't find a solution.
I was able to achieve like this.
$subscriptions = wcs_get_subscriptions_for_order($order_id, array( 'order_type' => 'any' ));
foreach( $subscriptions as $subscription_id => $subscription_obj )
{
$current_subs_id = $subscription_obj->get_id(); // This is current subscription id
$parent_id = $subscription_obj->get_parent_id(); // This is subscription parent id
}
You can access this data by hooking into the processed_subscription_payment action provided by WooCommerce Subscriptions:
add_action( 'processed_subscription_payment', 'se43079522_process_subscription', 10, 2 );
function se43079522_process_subscription($user_id, $subscription_key) {
// here you have access to the $subscription_key (ID) and the $user_id associated
}
Take a look at this link: https://docs.woocommerce.com/document/subscriptions/develop/action-reference/ for more information on the available actions with this plugin.
OR, you can do this manually like so:
Read comments for walk-through
global $woocommerce;
// Get the order ID and save as variable
$order_id = [ORDER_ID];
// Get the order object
$order = new WC_Order( $order_id );
// Loop through the subscription order
foreach ( WC_Subscriptions_Order::get_recurring_items( $order ) as $order_item ) {
// Get the subscription key
$subscription_key = WC_Subscriptions_Manager::get_subscription_key( $order->id, WC_Subscriptions_Order::get_items_product_id( $order_item ) );
}
// This is your subscription key (ID)
echo $subscription_key;
Get Subscription ID from Order. You can use wcs_get_subscriptions_for_order woocommerce function to get an object with the subscription related to that order and get the subscription ID from there.
$subscriptions = wcs_get_subscriptions_for_order($order_id);
var_dump($subscriptions);