Search filter between promo and exact price

In order to use two or more different meta fields that need to have a relationship bewteen them, you have to provide a value for the relation key. This way you can establish the relationship that must be met for your meta fields.

In your specific case, you would use the relation AND to make sure that the value of $price is greater or equal than the promotion price but also (read AND) lower or equal than the exact price.

So according to your question “Search filter between promo and exact price” your meta_query array will look something like:

'meta_query' => array(
    'relation' => 'AND',
    array(
        'key'     => 'promotion_price',
        'value'   => $price,
        'compare' => '>=',
        'type'    => 'NUMERIC'
    ),
    array(
        'key'     => 'exact_price',
        'value'   => $price,
        'compare' => '<=',
        'type'    => 'NUMERIC'
    )
),

Extract from the WP Meta Query docs:

You can optionally pass the relation key and set it to either OR or AND. It defines the relation, when there is more than one meta query (whether all of the conditions should be met, or at least one of them needs to be met)

Using multiple nested meta queries

You can also nest multiple meta queries having multiple relation keys. So you can create different conditional blocks. For example, to ignore the promotion_price key if it does not exist, but use it if it exists:

'meta_query'  => array(
    'relation' => 'OR',
    array(
        'relation' => 'AND',
        array(
            'key'     => 'promotion_price',
            'compare' => 'NOT EXISTS'
        ),
        array(
            'key'     => 'exact_price',
            'value'   => $price,
            'compare' => '<=',
            'type'    => 'NUMERIC',
        ),
    ),
    array(
        'relation' => 'AND',
        array(
            'key'     => 'promotion_price',
            'value'   => $price,
            'compare' => '>=',
            'type'    => 'NUMERIC'
        ),
        array(
            'key'     => 'exact_price',
            'value'   => $price,
            'compare' => '<=',
            'type'    => 'NUMERIC'
        ),
    )
),

And if you have more conditionals, you can keep on nesting them following the same structure. At each level you will have one 'relation' => 'OR/AND' with two or more arrays.