For Ingenico and Adyen, we include their hosted checkout page in an iframe. They redirect the donor back to us in the iframe. We first serve the donor a page with javascript that breaks out of the frame and loads the same URL in the outer form, but with parameter liberated=1. Only on the second request do we actually process the donation and redirect donors to an error page or the thank you page.
We should tighten this up. When the iframe is redirected back to us, we should immediately process the donation (if we can show a spinner or the like while we work, so much the better!). Then when we decide whether to send the user to the thank you page or the error page, we should use the framebusting javascript to send them to that URL in the top frame.