The order of operations here is this:
- You create a payment on the backend.
- Previously you were capturing immediately, resulting in a completed payment.
- When a completed payment is saved, its
postSave() function requests an update to the order via the PaymentOrderUpdater service, which recalculates the related order's total_paid field at the end of the page request via its destructor (the destruct() function).
- The
total_paid is calculated afresh. If it doesn't match the current total_paid value on the order, the order will be saved.
- (Note: the first time a draft order is saved, its
paid_event_dispatched boolean gets initialized to FALSE in its data array. This is important to the next step.)
- When the order is saved by the
PaymentOrderUpdater at the end of its updateOrder() function, the OrderStorage checks in the presave process to see if the total_paid is less than order equal to the order total. If so, it dispatches the OrderEvents::ORDER_PAID event you're depending on.
- After all order paid subscribers execute, including to apply a state transition, the order is saved.
I don't see why changing from an authorization + capture workflow to an authorization only + capture later workflow would change this process. At the end of the day, steps 3 - 7 only activate when a completed payment is saved, and the process should be no different.
If the PaymentOrderUpdater service is somehow not getting a chance to function, I suppose that would create the instance you're seeing ... but if removing your subscriber solves things, then it sounds more like your subscriber is failing. However, if it is failing, I'd expect you'd see some sort of error. The most common failure I can imagine would be the transition failing to apply because the order is not in a draft state any longer. Since your logic wouldn't get activated until destruction, I suppose the HTTP response has already been streamed, but the save ultimately fails.
You can check your PHP error logs are add debugging to your subscriber, but my hunch is these orders you want to see the balance reduced to $0 on are already placed - i.e. no longer in the draft state.