1

First of all, Thanks to a guys who helped me write a script which changes order status to completed(script below).

Unfortunately it doesn't trigger subscription to go active. When I manually change order status in WooCommerce it does. So my idea was to activate a subscription based on given order_id.

How to change subscription status from "Pending" to "Active" based on order_id in WooCommerce?

Here is a code which changes the order status when I use 100% coupon and it works: in functions.php

<?php

add_action('woocommerce_checkout_order_processed', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order($order_id)
{
    if (!$order_id) {
        return;
    }

      $order = wc_get_order($order_id);
    if ($order->get_total() == 0) {
        $order->update_status('processing');
        $order->update_status('completed');
    }
}
 

I have found smth like this to activate those subscriptions, but I cannot implement this, maybe somebody can help me solve this? Here is the code I have found on github

/**
     * Activates all the subscriptions created by a given order.
     *
     * @param WC_Order|int $order The order or ID of the order for which subscriptions should be marked as activated.
     * @since 1.0
     */
    public static function activate_subscriptions_for_order( $order ) {

        $subscriptions = wcs_get_subscriptions_for_order( $order );

        if ( ! empty( $subscriptions ) ) {

            foreach ( $subscriptions as $subscription ) {

                try {
                    $subscription->update_status( 'active' );
                } catch ( Exception $e ) {
                    // translators: $1: order number, $2: error message
                    $subscription->add_order_note( sprintf( __( 'Failed to activate subscription status for order #%1$s: %2$s', 'woocommerce-subscriptions' ), is_object( $order ) ? $order->get_order_number() : $order, $e->getMessage() ) );
                }
            }

            do_action( 'subscriptions_activated_for_order', $order );
        }
    } 

I tried this but it doesn't work:

add_action('woocommerce_checkout_order_processed', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order($order_id)
{
    if (!$order_id) {
        return;
    }

      $order = wc_get_order($order_id);
    if ($order->get_total() == 0) {
        $order->update_status('processing');
        $order->update_status('completed');
    }
}


do_action('woocommerce_checkout_order_processed', 'subscriptions_activated_for_order', $order_id );
function activate_subscriptions_for_order( $order_id ) {

  $subscriptions = wcs_get_subscriptions_for_order( $order_id );

  if ( ! empty( $subscriptions ) ) {

    foreach ( $subscriptions as $subscription ) {

      try {
        $subscription->update_status( 'active' );
      } catch ( Exception $e ) {
        // translators: $1: order number, $2: error message
        $subscription->add_order_note( sprintf( __( 'Failed to activate subscription status for order #%1$s: %2$s', 'woocommerce-subscriptions' ), is_object( $order_id ) ? $order->get_order_number() : $order_id, $e->getMessage() ) );
      }
    }

  }
}

Best Regards

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
ShantiAum
  • 11
  • 2

1 Answers1

2

There are errors and mistakes in your code. You could try to merge everything together like:

add_action('woocommerce_checkout_order_processed', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order($order_id)
{
    if (!$order_id) {
        return;
    }

    $order = wc_get_order($order_id);

    if ($order->get_total() == 0) {
        // $order->update_status('processing'); // Unneeded as you complete the order
        $order->update_status('completed');
    }

    $subscriptions = wcs_get_subscriptions_for_order( $order );
    
    if ( ! empty( $subscriptions ) ) {
        activate_subscriptions_for_order( $order );
    }
}

Code goes in functions.php file of the active child theme (or active theme). It could work.


Or you could keep:

add_action('woocommerce_checkout_order_processed', 'custom_woocommerce_auto_complete_order');
function custom_woocommerce_auto_complete_order($order_id)
{
    if (!$order_id) {
        return;
    }

    $order = wc_get_order($order_id);

    if ($order->get_total() == 0) {
        // $order->update_status('processing'); // Unneeded as you complete the order
        $order->update_status('completed');
    }
}

and use the hook woocommerce_order_status_completed triggered when order status is "completed" as follows to activate the subscription related to the order:

add_action( 'woocommerce_order_status_completed', 'order_complete_activate_subscription', 10, 2 );
function order_complete_activate_subscription( $order_id, $order ) {
    $subscriptions = wcs_get_subscriptions_for_order( $order );
    
    if ( ! empty( $subscriptions ) ) {
        activate_subscriptions_for_order( $order );
    }
}

Code goes in functions.php file of the active child theme (or active theme). It could work.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • thank you for answering me, The thing is the first one works as before, nothing changed, just added the session timeout, the second solution doesn't make subscription status from pending to active either. – ShantiAum Apr 23 '21 at 00:35