Here is how i do it: I use a service user in zitadel, and use its clientId and secret to be able to hit the endpoints in zitadel.
i route the customer creation through my backend app, i create a customer in my backend i create an organization with the customer as an org manager viewer (i believe this is read only he can't update anything, if not you can create custom role in defaults.yaml file with read only permission) , and then i create the user and org in my internal tables (just the id, external id, and name), also the user creation is the same, i use the api, i check the seats and license first in my backend app and then let the customer invite the users to his organization. (everything is done by the user service in zitadel by calling from my backend)