1
votes

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

1

1 Answers

2
votes

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.