ElixirMpesa.Session (ElixirMpesa v0.2.0)
View SourceCaches encrypted M-Pesa session keys, one per market.
Before any transaction, the M-Pesa OpenAPI requires a session key: encrypt the API
key, exchange it at getSession for a session ID, then encrypt that session ID. The
result is valid for about an hour.
Doing that dance on every payment costs a full network round trip plus two RSA operations. This process does it once per market and reuses the result until it is close to expiring.
What it does for you
- Caches the encrypted session key per
{api_type, url_context}, so one application can serve several markets at once. - Refreshes early, at 80% of the TTL, so a request never races the expiry boundary.
- Collapses concurrent misses — a hundred simultaneous callers on a cold cache
produce exactly one
getSessioncall, not a hundred. - Re-authenticates once when M-Pesa reports the session is no longer valid.
Opting out
The cache is started automatically. To manage sessions yourself, call
fetch/2 with cache: false, or use ElixirMpesa.Crypto directly.
If this process is not running — for instance when the library is used without its application started — every call transparently falls back to an uncached fetch rather than failing.
Summary
Functions
Returns a specification to start this module under a supervisor.
Returns a valid encrypted session key for config, fetching one if needed.
Drops the cached session for config, forcing the next call to re-authenticate.
Runs fun with a session key, retrying once with a fresh session if M-Pesa reports
the current one has expired.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec fetch( ElixirMpesa.Config.t(), keyword() ) :: {:ok, String.t()} | {:error, ElixirMpesa.Error.t()}
Returns a valid encrypted session key for config, fetching one if needed.
Options
:cache- set tofalseto bypass the cache and always fetch a fresh session.
@spec invalidate(ElixirMpesa.Config.t()) :: :ok
Drops the cached session for config, forcing the next call to re-authenticate.
@spec with_session(ElixirMpesa.Config.t(), (String.t() -> result), keyword()) :: result | {:error, ElixirMpesa.Error.t()} when result: {:ok, term()} | {:error, ElixirMpesa.Error.t()}
Runs fun with a session key, retrying once with a fresh session if M-Pesa reports
the current one has expired.
This is what every ElixirMpesa transaction function goes through.