Have you considered using the resource identifier as an idempotency key? Basically, have the client generate the ID (UUID, but namespaced on the server side [client+date]). This eliminates the need for the client to generate the idempotency key as well as the eliminates the need for the server to maintain an idempotency repository?
I think that would be a fine alternative to the system we have.
I don't have a perfect history of events, but I suspect that our current design is basically the result of two things:
1. Idempotency keys as a concept were introduced quite a bit later than the API was originally conceived, so it made sense to make them an optional augmentation to existing integrations.
2. Our resource IDs have a fairly specific formats including a prefix (i.e. `acct_` for an account or a `ch_`). It would still be possible to generate this client-side, but it's a little extra trouble.
Idempotency keys are a simple enough concept, that I think that they're mostly okay as is (we could have done a few smarter things on the server side implementation, but luckily that can still be fixed).
There are certainly a few things around HTTP semantics that Stripe got wrong. e.g. Most updates should probably be `PATCH` instead of `POST`, but it's probably not worth changing at this point.