We use a third-party shipping website that gets notifications from our WooCommerce store via webhooks that they installed. The webhooks fire on any WooCommerce order create/update/delete activity. However, we don't want these webhooks to fire on subscription orders, since these are purely digital, and don't require shipping. So we have some of our own code hooked in via woocommerce_webhook_should_deliver to weed out subscription orders.
Specifically, we can use wcs_order_contains_subscription() to determine if an order is a "parent" order to a subscription. And we can use wcs_order_contains_renewal() to determine if an order is a "renewal" order for a subscription. But if the order ID represents the subscription itself, neither one of these works, and there doesn't appear to be any built-in alternative.
One solution is to try to get a subscription with the order ID. However, this is ambiguous because it appears to succeed as long as an order ID is a valid Woo order. So we additionally test to see if the subscription has a parent. If so, then it's a subscription. So far, this seems to work.
My question: Is this a reliable test for whether an order ID represents a subscription? Or is there a better / more direct test?
Code:
if($order = wc_get_order($order_id)) //validate order id
{
$sub = new WC_Subscription($order_id);
if($parent_id = $sub->get_parent_id())
{
//it's a subscription
}
else
{
//it's not a subscription
}
}
else
{
//ignore, order id doesn't exist
}
Edit:
My question was closed for being the same as this question here, about determining the subscription id from the order id.
However, this is not exactly the situation I'm in. I don't need the subscription id — I potentially already have it. I just need a way of testing the id to determine if it is a subscription, or just another type of order.
I understand that Woocommerce is a little confusing on this subject because subscriptions also have ids, and Woocommerce hooks like woocommerce_webhook_should_deliver supply subscription ids and order ids interchangaebly, so you don't know which type you're getting. That's the problem in this case.
The linked question is a good example of why this is problematic. If you already have the subscription id, and you supply it as $order_id, the solution fails to find any related subscriptions, and the loop never breaks. This in itself could be used a kind of test, but you'd be relying on the code to fail to find a subscription, which seems a little backwards to me.
What I'm asking is if there is an accepted way to positively identify an Woo order id as a "subscription" id, and not one of the other two subscription "order" types, i.e. a parent order (used to purchase a subscription) or a renewal order (used to keep the subscription going).
If I'm misunderstanding how this works (and I might be!), apologies from me.
Second Edit:
Solved. This is the actual answer to the question, not the linked question.
wcs_get_subscription($order_id) will return a subscription object or FALSE if the order is not a subscription.
Note that wcs_get_subscriptions_for_order($order_id) will return an empty array if the order is a subscription, so that's ambiguous.