In the end I solved this by defining a trigger which prevents UPDATE queries on the table from succeeding if the owner_id does not match.
It's dead simple and looks something like this:
CREATE OR REPLACE FUNCTION order_update_check()
RETURNS trigger
AS $$
BEGIN
IF NEW.owner_id != OLD.owner_id THEN
RAISE EXCEPTION 'User % cannot modify order %', NEW.owning_user, OLD.order_id;
END IF;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER order_update_trigger BEFORE UPDATE ON orders
FOR EACH ROW EXECUTE PROCEDURE order_update_check();
Having defined this, I then defined an upsert procedure much the same as described in the PG docs.
Thanks to @Noran for giving me the idea.