Ok. So thanks to @Milo I figure out it how it should be done. First of all in archive should be a standard loop. Then in functions.php I just add a pre_get_posts function directly for archive pages and it’s look like this:
archive-cpt.php loop:
<div class="center">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php include 'product.php' ?>
<?php endwhile ?>
<nav class="pagination">
<?php
$big = 999999999; // need an unlikely integer
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => __(' « '),
'next_text' => __(' » '),
) );
?>
</nav>
<?php else : ?>
<p>
<?php esc_html_e( 'Sorry, no posts matched your criteria.' ); ?>
</p>
<?php endif; ?>
</div>
and in functions.php:
function archive($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_archive) {
$query->set('post_status', 'publish');
$query->set('meta_key', 'order');
$query->set('orderby', 'meta_value_num');
$query->set('order', 'asc');
}
}
}
add_action('pre_get_posts','archive');
The point is do not create a new WP_Query but modifying existing. Then pagination and others functionality works fine. In pre_get_posts we can also add additional parameters to loop like ‘order’ etc using
$query->set('order', 'asc');
now everything is working.
Here’s a usefull links about:
https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts