Search code examples
phpwoocommercemethodsorderswoocommerce-subscriptions

Set the shipping method in WooCommerce Subscriptions renewal orders


When a user buys a product with the recurrent option which create an order each month, there is no shipping methods set. Only the parent order has the shipping method, and all child orders doesn't have shipping.

I would like to add the parent shipping method to all child orders while a recurrent order is created.

Here the code I tried but not working, I would like to add the shipping method of the parent when the child order is created.

add_action('woocommerce_new_order', 'add_colissimo_method', 10, 1);

function add_colissimo_method($order_id) {
    $order = wc_get_order($order_id);

  
    if ($order->get_shipping_method()) {
        return; 
    }


        $subscriptions = wcs_get_subscriptions_for_order($renewal_order_id);

        if (!empty($subscriptions)) {
    
            $parent_order_id = $subscriptions[0]->get_parent_id();

            if (!empty($parent_order_id)) {
                $parent_order = wc_get_order($parent_order_id);
                $parent_shipping_method = $parent_order->get_shipping_method();
                update_post_meta($renewal_order_id, '_shipping_method', $parent_shipping_method);
            }
     }

    $order->save();
    
}

Solution

  • You are not doing this in the right way, and you need to use WC Subscriptions filter hooks.

    Try the following instead (code is commented):

    add_filter( 'wcs_new_order_created', 'add_shipping_items_to_renewal_orders', 10, 3 );
    function add_shipping_items_to_renewal_orders( $order, $subscription, $type ) {
        // Targeting renewal orders only
        if ( $type === 'renewal_order' ) {
            // Get the parent order (initial order)
            $parent_order = $subscription->get_related_orders('all', 'parent');
            $parent_order = reset($parent_order);
    
            // Set the array for tax calculations
            $calculate_tax_for = array(
                'country'   => $parent_order->get_shipping_country(),
                'state'     => $parent_order->get_shipping_state(),
                'postcode'  => $parent_order->get_shipping_postcode(),
                'city'      => $parent_order->get_shipping_city(),
            );
    
            // Loop through parent order "shipping" items
            foreach( $parent_order->get_items('shipping') as $parent_item ) {
                $item  = new WC_Order_Item_Shipping(); // create a new empty order item "shipping"
                $item->set_method_title( $parent_item->get_method_title() ); // set the existing Shipping method title
                $item->set_method_id( $parent_item->get_method_id() ); // set an existing Shipping method rate ID
                $item->set_total( $parent_item->get_total() );  // set an existing Shipping method total
                $item->calculate_taxes( $calculate_tax_for );  // Calculate taxes for the item
    
                $order->add_item( $item ); // Add the shipping item to the renewal order
            }
            $order->calculate_totals(); // recalculate totals and save
        }
        return $order;
    }
    

    It should work.

    Related: Add update or remove WooCommerce shipping order items