From your description, I assume Magento is creating the Order (including triggering the email) then referring the customer to a 3rd party site for payment, which refers them back to your site when payment is complete. I also assume that you have not turned on the asynchronous message sending for the server.
Magento will create the order as part of the checkout process, which is necessary for how it handles orders. Rather than try to prevent that, you would be better off trying to change the behaviours that happen in response.
For the email, these changes are things that I would normally expect to be be handled by the module responsible for integrating the payment method. That said, to change when the customer has an email sent to them will require two parts:
- A means of preventing the email being sent initially, which means overriding Magento's default behaviour.
- Something that responds to payment being completed that then triggers the email being sent.
Magento\Sales\Model\Order\Email\Sender\OrderSender class is the one that actually sends the email to the customer (unless async sending is turned on). The simplest method to prevent that would simply be to implement a Plugin for
OrderSender that implements an
aroundSend method and doesn't trigger the default behaviour (i.e. doesn't execute the callable object/function provided as a parameter) if the criteria are not met (e.g. status of the order).
Important caveat: Implementing a plugin in this manner may prevent other plugins from operating. It likely won't be an issue, but will depend on things like what 3rd party modules you have installed, etc.
The second part will depend largely on how the payment methods used will return data to Magento (I'm not personally familiar with either payment provider). At the very least there will likely be an event that is dispatched, which can be monitored for via an Observer.
Regardless of the communication mechanism, triggering the email would then just be a case of making certain the criteria now matches your requirements, then just use the
OrderSender class to
send the email.
With reference to hiding the order in the admin panel, you could implement a filter mechanism to prevent orders with a certain status from being visible, but I would strongly advise against that.
Preventing your admin users from being able to see the order, even in a partially complete state will also prevent them from being able to fix the order. For instance, if a glitch in payment processing prevents the order status being updated after the customer was charged, without admin users being able to see the order the only way to fix this would be updating the database manually (not something I would ever recommend).