KopoKopo (KopoKopo v0.1.0)

Copy Markdown View Source

Client helpers for Kopo Kopo payments.

The client supports OAuth client credentials, M-PESA STK Push incoming payments, status verification, and callback signature validation.

Configuration

config :kopokopo,
  base_url: "https://api.kopokopo.com",
  client_id: System.fetch_env!("KOPOKOPO_CLIENT_ID"),
  client_secret: System.fetch_env!("KOPOKOPO_CLIENT_SECRET"),
  api_key: System.fetch_env!("KOPOKOPO_API_KEY"),
  till_number: System.fetch_env!("KOPOKOPO_TILL_NUMBER"),
  callback_url: "https://example.com/payments/kopokopo/callback",
  user_agent: "my_app/1.0"

For local sandbox work, set base_url to https://sandbox.kopokopo.com.

Summary

Functions

Checks whether configured credentials can obtain an OAuth access token.

Checks credentials against a temporary base URL.

Returns the configured callback URL.

Returns the outgoing STK Push payload without making a network request.

Converts an error reason returned by this client into displayable text.

Initiates an M-PESA STK Push payment.

Normalizes Kopo Kopo payment status response data into :ok, :pending, or :error tuples.

Sends a small STK Push test prompt.

Sends a test prompt against a temporary base URL.

Validates a callback body against the x-kopokopo-signature header.

Verifies a payment status URL returned by initiate_payment/1.

Types

payment_result()

@type payment_result() :: {:ok, map()} | {:pending, map()} | {:error, term()}

t()

@type t() :: %KopoKopo{
  body: term(),
  status: pos_integer() | nil,
  url: String.t() | nil
}

Functions

auth_check()

@spec auth_check() :: {:ok, String.t()} | {:error, term()}

Checks whether configured credentials can obtain an OAuth access token.

auth_check(base_url)

@spec auth_check(String.t()) :: {:ok, String.t()} | {:error, term()}

Checks credentials against a temporary base URL.

callback_url()

@spec callback_url() :: String.t()

Returns the configured callback URL.

If :callback_url is configured, it is used directly. Otherwise the URL is built from :site_url and :callback_path.

debug_prompt_payload(phone \\ "0740769596", amount \\ "1")

@spec debug_prompt_payload(String.t(), String.t() | number()) :: map()

Returns the outgoing STK Push payload without making a network request.

error_text(reason)

Converts an error reason returned by this client into displayable text.

initiate_payment(map)

@spec initiate_payment(map()) :: {:ok, map()} | {:error, term()}

Initiates an M-PESA STK Push payment.

Expected fields are:

  • :reference
  • :amount
  • :phone
  • :email
  • :name

Returns {:ok, %{location: location, reference: reference}} when Kopo Kopo accepts the payment request.

payment_result(data)

@spec payment_result(map()) :: payment_result()

Normalizes Kopo Kopo payment status response data into :ok, :pending, or :error tuples.

test_prompt(phone \\ "0740769596", amount \\ "1")

@spec test_prompt(String.t(), String.t() | number()) ::
  {:ok, map()} | {:error, term()}

Sends a small STK Push test prompt.

This uses configured credentials and till details, so it can trigger a real M-PESA prompt when pointed at production.

test_prompt(base_url, phone, amount)

@spec test_prompt(String.t(), String.t(), String.t() | number()) ::
  {:ok, map()} | {:error, term()}

Sends a test prompt against a temporary base URL.

valid_signature?(body, signature)

@spec valid_signature?(binary(), binary()) :: boolean()

Validates a callback body against the x-kopokopo-signature header.

verify(location)

@spec verify(String.t()) :: payment_result()

Verifies a payment status URL returned by initiate_payment/1.