The times things will get out of order are on retries, and on changes to the number of subscribers.
Even when doing a completely custom approach getting duplicate delivery and exact ordering is very difficult to get provably correct without significant locking and/or other convolutions.
However, as it seems that you are looking for a consumer to process by stream, this can all be made very simple for either the built in or a custom approach.
You can leverage the incrementing Event Position in the stream as a checkpoint for idempotency, missing message detection, and out of order detection.
Give the consumer the capacity to request missing messages and an idempotency check based on the highest position processed and all of you ordering problems are sorted.