Update: Can etags + If-Match work? Yes, I'm sure it can be made to work. Your client will have to interpret the 412 error as an optimistic concurrency failure. As far as using it with POST, the spec does not restrict which methods it is allowed on.
The If-Match request-header field is used with a method to make it conditional.
I would also return 412 (with a different message) if there is no entity (and therefore no etag) found in the database. In other words, they are requesting modification for an entity that was never created.
The question remains as to whether you should use If-Match for optimistic concurrency. The main problem with it is that semantically, it allows the client to specify whether or not the resource should be updated. It is very possible that the business will want some optimistic concurrency failures to be allowed to continue anyway. F.ex. if CancelOrder is received, regardless of version mismatch, it should be processed. (It could be that the order is already shipped and cancellation fails, but at least we can respond with that information instead of just a version mismatch error!) This is not a decision you usually want on the client. However, you could subvert the spec and just use If-Match to send your version (e-tag), and ultimately let the business rules decide whether the operation should continue if the tags don't match and return the 412 otherwise.
Should you send the etag to the reified URI? Yes. In fact as part of modeling what is essentially messaging over HTTP, there should be no POST URI for an "original order resource". What you are really doing with that order URI is sending the "create order" command message. If you changed its name to fit that, then that would make it much more clear that POSTing to an Order resource doesn't make sense. In this type of API the POST URIs are message types, not resources.
By the way, I wholeheartedly disagree with the linked article at making these nouns instead of verbs. REST tries to represent operations (actions) as HTTP verbs, which fits fine for the 4 CRUD operations, but is far too limited for domain operations. Realizing this, the article's author moves the domain operation to be part of the URI, but tries to retain the REST principle of noun URIs (I assume) to stick to the REST spec in letter, even though it is not followed in spirit. Sometimes you just have to acknowledge that something doesn't fit and don't force it. Verbs definitionally include actions, and actions more closely represent business operations. Therefore, use POST /create-customer
instead of POST /create-customer-req
. Do you really want to add a superfluous -req
on the end of every URI?
The read side
It makes complete sense to have a GET URI for Order. Actually, it makes sense to have multiple GET URIs for Order, one for each different perspective (view) on the order. F.ex. a customer is likely to want different information when looking at their orders than the sales manager. (This may actually lead to different bounded contexts, but that is a different discussion.)
Update
I see your edit changed the URIs to the form POST order/123/action
instead of including the ID in the JSON body. Either way, this does not make sense in the context of REST. The URI is supposed to represent a resource, but here is a message type. The fact that you are communicating an ID via URI doesn't make it a resource. The same way that changing an action to a noun form doesn't make it a resource. Sticking to REST naming conventions without actually implementing a uniform interface is in no way helpful. The idea of following REST is to use HTTP in a standard and consistent way so that clients have a reasonable expectation for how it works.
In the case of a CRUD resource conforming to REST, if you gave the client a URI and object shape, it would already know how to perform all operations. In your case, the clients don't have knowledge of your custom operations until you tell them (via hypermedia perhaps, or hard-coding in the client).
Let me re-emphasize: It's okay that your use case doesn't fit in the REST box! It's okay to use HTTP in a different way that makes sense for your system!