Woocommerce returns Product post_status as published even tho it is in status draft

The solution is simple, delete the if check you’re having problems and add the post_status parameter to get_posts.

For example:

$args = [
    'post_status' => 'publish',
];
$only_published_posts = get_posts( $args );

Likewise we can pass an array of the statuses we do want, e.g.

$args = [
    'post_status' => [ 'publish', 'pending' ],
];
$only_published_and_pending_posts = get_posts( $args );

Or everything except published posts:

$args = [
    'post_status' => [ 'future', 'draft', 'pending' ],
];
$not_published = get_posts( $args );

Or private posts:

$args = [
    'post_status' => [ 'private' ],
];
$private_posts = get_posts( $args );

Or all post statuses, including revisions and auto drafts:

$args = [
    'post_status' => 'any',
];
$all_posts = get_posts( $args );

There are a limited number of post statuses that come with core, and they’re hard coded, so you can just list the ones you want, and ommit the ones you don’t.

More information at: https://developer.wordpress.org/reference/classes/wp_query/#status-parameters

Note that while this is the canonical standard WordPress method, plugins may employ custom post statuses, or ignore statuses altogether if they are poorly built. In these situations you will need to contact their dev support routes.