Daraja.B2B.PaymentRequest (daraja v0.1.0)

Copy Markdown View Source

Input struct for a B2B payment request.

Required fields:

  • initiator
  • security_credential
  • command_id
  • sender_identifier_type
  • receiver_identifier_type
  • amount
  • party_a
  • party_b
  • remarks
  • queue_timeout_url
  • result_url

Optional fields:

  • account_reference

security_credential

security_credential accepts either a pre-encrypted Base64 string or a {initiator_password, pem} tuple. When a tuple is provided, encryption is handled internally via Daraja.SecurityCredential.encrypt/2:

# Pre-encrypted (useful when you encrypt once at deploy time):
%{security_credential: "base64-encoded-credential", ...}

# Auto-encrypt (convenient for sandbox/dev):
%{security_credential: {"my-initiator-password", File.read!("sandbox.cer")}, ...}

The tuple form is sugar over calling Daraja.SecurityCredential.encrypt/2 inside PaymentRequest.new/1. In production, prefer pre-encrypting with Daraja.SecurityCredential.encrypt/2 and storing only the resulting Base64 string — so plaintext passwords never live in application state at runtime. When a tuple is supplied via application env, it is encrypted as soon as the env fallback is read; the tuple nevertheless remains in Application env until you replace it with a pre-encrypted string.

Application env fallbacks

initiator, security_credential, queue_timeout_url, and result_url fall back to the :daraja application env when not supplied in params. security_credential can be a pre-encrypted string or a {password, pem} tuple in config; per-call params always take precedence:

config :daraja,
  b2b_initiator: "testapi",
  b2b_security_credential: "base64-credential",
  b2b_queue_timeout_url: "https://example.com/b2b/timeout",
  b2b_result_url: "https://example.com/b2b/result"

# Or in runtime.exs to read the cert file at boot:
config :daraja,
  b2b_security_credential: {"my-initiator-password", File.read!("priv/sandbox.cer")}

Per-call params always take precedence over env values, which is handy for multi-tenant callers that need to override defaults per request.

Summary

Types

command_id()

@type command_id() :: String.t()

identifier_type()

@type identifier_type() :: 2 | 4

security_credential_input()

@type security_credential_input() :: String.t() | {String.t(), String.t()}

t()

@type t() :: %Daraja.B2B.PaymentRequest{
  account_reference: String.t() | nil,
  amount: pos_integer(),
  command_id: command_id(),
  initiator: String.t(),
  party_a: String.t(),
  party_b: String.t(),
  queue_timeout_url: String.t(),
  receiver_identifier_type: identifier_type(),
  remarks: String.t(),
  result_url: String.t(),
  security_credential: String.t(),
  sender_identifier_type: identifier_type()
}

Functions

new(params)

@spec new(map()) ::
  {:ok, t()}
  | {:error, :invalid_request,
     [
       atom()
       | {:command_id, String.t()}
       | {:sender_identifier_type, String.t()}
       | {:receiver_identifier_type, String.t()}
       | {:security_credential,
          Daraja.SecurityCredential.encrypt_error() | :invalid_format}
     ]}