Hook in woocommerce on subscription expiration - wordpress

How can I create an Hook in woocommerce (wordpress) to be able to trigger a function when a subscription expires?
Something like this
add_action('woocommerce_subscription_expired', 'my_function', 10, 1);
function my_function($order_id) {
echo "yeahhhh";
}
UPDATE
I found in the developer doc the following
Action: 'subscription_expired'
Parameters: $user_id Integer The ID of the user for whom the
subscription expired. $subscription_key String The key for the
subscription that just expired on the user’s account.
Description: Triggered when a subscription reaches the end of its
term, if a length was set on the subscription when it was purchased.
This event may be triggered by either WooCommerce Subscriptions, which
schedules a cron-job to expire each subscription, or by the payment
gateway extension which can call the
WC_Subscriptions_Manager::expire_subscription() function directly.
Where should I place this to have it working
Thanks

Looks like you are almost there. You just need to use Subscription's action hook and pass the correct parameters. This seems like a start:
add_action( 'subscription_expired', 'my_function', 10, 2 );
function my_function( $user_id, $subscription_key ) {
$sub= wcs_get_subscription_from_key( $subscription_key );
// do something
}

The wcs_get_subscription_from_key is now deprecated, since version 2.0.
You can now use:
add_action( 'woocommerce_subscription_status_expired', 'my_on_subscription_expired', 10 );
function my_on_subscription_expired( $subscription ) {
// do something
}
More hooks (and this one) at Subscriptions Action Reference

Related

WooCommerce woocommerce_new_order not firing when creating an order from the REST API

I have the following code snippet:
add_action('woocommerce_new_order', 'foo_function', 10);
If I create a new order from the admin panel, this fires just fine.
However, creating it via the REST API will not fire the function.
Why is that?
Update
I've tried using the following:
woocommerce_rest_insert_shop_object – this one doesn't fire at all.
wp_insert_post and save_post – they do fire, but don't contain the line items... (on the first run, it's an empty list, and on the second run (where the $update flag is true) there is an item but that item has no data (like product id or quantity).
add_action( "woocommerce_rest_insert_shop_order_object", 'your_prefix_on_insert_rest_api', 10, 3 );
function your_prefix_on_insert_rest_api( $object, $request, $is_creating ) {
if ( ! $is_creating ) {
return;
}
$order_id = $object->get_id();
$wc_order = new WC_Order( $order_id );
do_action( 'woocommerce_new_order', $order_id, $wc_order );
}
You have tried woocommerce_rest_insert_shop_object,
but the hook is woocommerce_rest_insert_shop_order_object
Please use this hook woocommerce_process_shop_order_meta instead of woocommerce_new_order As far as I can determine, woocommerce_new_order is only fired when an order is processed through the checkout. In a lot of instances, staff were creating orders in the wp-admin and assigning them straight to processing or completed, which meant that hook wasn't doing what I thought it would. Using woocommerce_process_shop_order_meta will solve it for you.
On v2 there is the woocommerce_rest_insert_{$this->post_type}_object filter
So the correct hook for what you need is woocommerce_rest_insert_shop_order_object

Kill previous session if the same user logged in again wordpress

Is there an option to destroy all other user session after a user logs in. I found an option for destroying sessions as
// get all sessions for user with ID $user_id
$sessions = WP_Session_Tokens::get_instance( $user->ID );
// we have got the sessions, destroy them all!
$sessions->destroy_all();
It can use on authenticating a user, but I am using a social login plugin for authenticating users, so need to hack the plugin for achieving the same. Can you help me figure out an option to destroy all previous sessions on or after "wp_login" action.
Resolved it!!.
destroy_all() will destroy all the sessions so when we are use this in wp_login hook it will destroy the current session too, instead we can use destroy_others() function.
The final code shown below
function your_function( $user,$user_id) {
$sessions = WP_Session_Tokens::get_instance( get_current_user_id() );
$token = wp_get_session_token();
$sessions->destroy_others( $token );
}
add_action('wp_login', 'your_function',10,2);
You could try to hook into the wp_login action. Could be done in the plugin or in your functions.php
<?php
function your_function() {
// your code
}
add_action('wp_login', 'your_function');
?>
https://codex.wordpress.org/Plugin_API/Action_Reference/wp_login

Trigger woocommerce_payment_complete when creating order manually

I have a hook to woocommerce_payment_complete, in which I send the order to the distributor. This is working fine.
Now, since I'm also selling through 3rd party marketplace, sometimes I want to create an order form the admin panel, and I expect the woocommerce_payment_complete hook to be triggered by setting the order status to 'Processing' but it's not.
Is there any way to trigger this hook by creating an order manually?
Thanks
You can use the following to set 'processing' for admin orders. action_woocommerce_process_shop_order_meta is used to detect the order update.
// define the woocommerce_admin_order_actions_end callback
function action_woocommerce_admin_order_actions_end( $order_id ) {
global $woocommerce;
if (!$order_id)
return;
$order = new WC_Order($order_id);
$order_status = $order->get_status();
if ($order_status != "failed") {
$order->update_status('processing');
}
};
// add the action
add_action( 'action_woocommerce_process_shop_order_meta', 'action_woocommerce_admin_order_actions_end', 10, 1 );

How to get Pay Now URL with custom order status in WooCommerce?

I want to get the URL from where the customer can directly pay for their Invoice and also it should work with wc-cancelled and wc-transaction-declined (custom order status).
My Solution
What I'm doing now is created a custom page with my custom get parameters and processing the whole Payment Process as Documentation in Gateway provider Website.
My Problem
But the problem is whenever they update their doc file and plugin I also have to update my code; but if I get the Pay Now URL then WooCommerce and Gateway Plugin will take care of it.
Is there a better solution?
I got the solution in WooCommerce templates/emails/customer-invoice.php file. The function that I was looking for is get_checkout_payment_url().
Usage
$order = wc_get_order($order_id);
$pay_now_url = esc_url( $order->get_checkout_payment_url() );
echo $pay_now_url; //http://example.com/checkout/order-pay/{order_id}?pay_for_order=true&key={order_key}
//http://example.com will be site_url and protocol will depending upon SSL checkout WooCommerce setting.
But this url only works with pending, failed order status; So I used filter woocommerce_valid_order_statuses_for_payment
if (!function_exists('filter_woocommerce_valid_order_statuses_for_payment')) {
//http://woocommerce.wp-a2z.org/oik_api/wc_abstract_orderneeds_payment/
//http://hookr.io/filters/woocommerce_valid_order_statuses_for_payment/
// define the woocommerce_valid_order_statuses_for_payment callback 
function filter_woocommerce_valid_order_statuses_for_payment( $array, $instance ) {
$my_order_status = array('cancelled', 'transaction-declined');
return array_merge($array, $my_order_status);
}
// add the filter 
add_filter('woocommerce_valid_order_statuses_for_payment', 'filter_woocommerce_valid_order_statuses_for_payment', 10, 2);
}
^^ I added this in my active theme's functions.php file.
Reference:
get_checkout_payment_url()
wc_abstract_orderneeds_payment
woocommerce_valid_order_statuses_for_payment
You can get url with below code but it will work for wc-pending status order only, with the help of order_id or post_id
$order = wc_get_order($order_id);
echo $pay_now_url = $order->get_checkout_payment_url();

Change current user role with form selection on update (not entry creation)

I'm using Formidable forms in Wordpress and have a form that registers users. I can use a radio button in the registration form to determine what their role will be. I have a hook for that. What I need, however, is a hook that will change the user role based on radio selection on form entry UPDATE. My current code only works on entry creation. Here is the code that assigns roles on registration:
add_filter('frmreg_new_role', 'frmreg_new_role', 10, 2);
function frmreg_new_role($role, $atts){
extract($atts);
if($form->id == 8){
if($_POST['item_meta'][280] == 'Job Applicant')
$role = 'applicant';
}
return $role;
}
"8" is the id of the form itself. "280" is the id of the radio button field where "Job Applicant" is one of the values. And "applicant" is one of our site's user roles.
I need an adaptation of this that will change the role after the entry has already been created, on update. The closest thing I can find is a hook that changes user role after a successful PayPal payment. I tried to combine the two but I couldn't get it to work. Here is the PayPal generated user role changer:
add_action('frm_payment_paypal_ipn', 'change_paid_user_role');
function change_paid_user_role($args){
$new_role = 'contributor'; //change this to the role paid users should have
if(!$args['pay_vars']['completed'])
return; //don't continue if the payment was not completed
if(!$args['entry']->user_id or !is_numeric($args['entry']->user_id))
return; //don't continue if not linked to a user
$user = get_userdata($args['entry']->user_id);
if(!$user)
return; //don't continue if user doesn't exist
$updated_user = (array)$user;
// Get the highest/primary role for this user
$user_roles = $user->roles;
$user_role = array_shift($user_roles);
if ( $user_role == 'administrator' )
return; //make sure we don't downgrade any admins
$updated_user['role'] = $new_role;
wp_update_user($updated_user);
}
UPDATE: the action hook should probably be: frm_after_create_entry according to Formidable forums.
Many times, researching the core files is more productive than any Google or Manual. Dropping the whole plugin directory in a code editor and researching for the string frm_after_create_entry takes us to the create() method where this hook happens.
After that, there's the update() method and it provides the action hook: frm_after_update_entry.
This hook passes two parameters: $id and $new_values['form_id']. I cannot reproduce your setup, so testing the hook is up to you.
Reference: Actions and filters are NOT the same thing…
In this example:
add_action( 'frm_after_update_entry', 'change_role_to_staff', 10, 2);
function change_role_to_staff( $form_id, $values ){
var_dump($values);
die();
}
As this is an action hook, nothing has to be returned.
There's no $roles or $atts, the parameters are the form ID and Values.
What you're looking for is inside $values.
var_dump() and die() are for debugging purposes and must be removed at once after testing.
Do your wp_update_user with this values and adapting your previous code.

Resources