ElixirMpesa.Session (ElixirMpesa v0.2.0)

View Source

Caches 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 getSession call, 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

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

fetch(config, opts \\ [])

@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 to false to bypass the cache and always fetch a fresh session.

invalidate(config)

@spec invalidate(ElixirMpesa.Config.t()) :: :ok

Drops the cached session for config, forcing the next call to re-authenticate.

with_session(config, fun, opts \\ [])

@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.