creating new table partition with values already existing in the default partition
The non-hack would be to not get into this situation in the first place, by not using a default partition when you are not really sure that that is permanently what you want.  When we fail to correctly foresee the future, sometimes we have to resort to hacks.

You could make it slightly less hack by populating a permanent table, then attaching it as the new partition, rather than juggling the data out and in with a temp table.

begin;
CREATE TABLE orders_foo (like orders); 
INSERT into orders_foo SELECT * FROM orders where country_code = 'foo';
DELETE FROM orders where country_code = 'foo';
ALTER TABLE orders ATTACH PARTITION orders_foo FOR VALUES IN ('foo');
commit;


You could also combine the INSERT and DELETE into a single statement, but I don't know that that really gets you anything worthwhile, other than avoiding one opportunity to misspell 'foo'.

with t as (delete from orders where country_code='foo' returning *) 
   insert into  orders_bar select * from t;