Update 1:
You can't use json_encode() on $order->get_items() as you will always get something like "257":{} (where 257 is the item ID) for each order item. So json_encode() fails encoding each order item data located in the array of items, as order items are protected.
Now the only way to JSON encode order items is to unprotect each order item using the WC_Data method get_data() and set it back in the order items array.
This can be done in a compact way using array_map() with a custom function like:
add_action( 'woocommerce_order_status_completed', 'send_order', 10, 2 );
function send_order( $order_id, $order ) {
// Unprotect each order item in the array of order items
$order_items_data = array_map( function($item){ return $item->get_data(); }, $order->get_items() );
$logger = wc_get_logger();
$logger->add("send-order-debug", json_encode($order_items_data));
}
Now it works.
Original answer:
The WC_Order Object is already an included argument in woocommerce_order_status_completed hook, so in your code it should be:
add_action( 'woocommerce_order_status_completed', 'send_order', 10, 2 );
function send_order( $order_id, $order ) {
$order_items = $order->get_items();
}
That works… see this related answers threads…
So the problem is maybe related in the way you try to send the order items using:
$logger->add($TAG, json_encode($order->get_items()));
But it's not possible to help as your code is not testable: the $logger and $TAG variables are not defined in your code.
Now to target subscription products you will use something like:
// Loop through order items
foreach( $order->get_items() as $item ) {
$product = $item->get_product(); // get the WC_Product Object
// Targeting subscription products only
if ( in_array( $product->get_type(), ['subscription', 'subscription_variation'] ) ) {
// Do something
}
}