I tried the solution with JavaScript by @MrCarrot first and it didn't work, but later found another working one. I thought that, instead of just a comment, I mention a few bits about the response and error handling.
MERCHANT_RESPONSE_URL needs to be a public (and I assume HTTPS) address where your script waits for a POST from Realex servers. The POST looks like this:
[RESULT] => 00
[AUTHCODE] => 12345
[MESSAGE] => [ test system ] AUTHORISED
[PASREF] => 16542926167123558
[MERCHANT_ID] => merchantid
[ORDER_ID] => INV-223665
[TIMESTAMP] => 20220603224317
[AMOUNT] => 9480
[SHA1HASH] => 934138a1157dead529806e9ed5578f538e1a68c8
Now you really should check the SHA1HASH as described at Card Payments: Check hash. You will need the original TIMESTAMP your request was from, MERCHANT_ID, ORDER_ID, RESULT number, the MESSAGE, PASREF, and AUTHCODE. Implode these with a full stop, so you'll get something like
20220603224317.merchantid.INV-223665.00.[ test system ] AUTHORISED.16542926167123558.12345
and run sha1() on it. Then, add your secret
ea4dcce506c6e5ee3fbaeae212477be838733694.mySecr3t
and run sha1() again, then compare it with the SHA1HASH response. Only if it equals, you should mark the payment as valid and send header("HTTP/1.0 200 OK").
Then you can redirect back with the above JavaScript, and maybe instead of the whole message, you can just send this error id. What I do is to go back to my payment page with either /thanks or /error111 to show a possible error message.
<script language='javascript' type='text/javascript'>
window.location.replace('https://pay.example.com/{orderId}/error{result}');
</script>