Skip to main content

Python client for the eDahab payment API

Project description

edahab — Python client

Lightweight Python client for the official eDahab API. Uses only the standard library (no required third-party packages).

Install

pip install .

Official API docs

Topic URL
Request format & hash API introduction
Customer payment (push/pop-up) Purchase / Issueinvoice
Merchant credit payment Credit payment / agentPayment
Verify invoice CheckInvoiceStatus
Numeric status codes Status codes

Configuration (set credentials once)

configure

Save api_key and api_secret for the process. After this, pay, verify_invoice, and send_credit can omit credentials.

Parameters (summary): api_key, api_secret, optional base_url, timeout, open_url (tests / custom HTTP).

Returns: EdahabClient (the shared default client).

from edahab import configure, pay

configure("your-api-key", "your-api-secret")

result = pay(customer="65", amount=1, agent="5555")

Custom base URL and timeout:

from edahab import configure

configure(
    "your-api-key",
    "your-api-secret",
    base_url="https://edahab.net/api/api/",
    timeout=60.0,
)

configure_from_env

Same as configure, but reads credentials from environment variables (default names below).

Parameters (summary): optional api_key_env, api_secret_env, base_url, timeout, open_url.

Returns: EdahabClient.

export EDAHAB_API_KEY="your-api-key"
export EDAHAB_API_SECRET="your-api-secret"
from edahab import configure_from_env, pay

configure_from_env()
pay(customer="65", amount=1, agent="5555")

Custom env var names:

configure_from_env(api_key_env="MY_EDAHAB_KEY", api_secret_env="MY_EDAHAB_SECRET")

get_client

Return the client created by configure or configure_from_env.

Raises: RuntimeError if nothing was configured yet.

from edahab import configure, get_client

configure("your-api-key", "your-api-secret")

client = get_client()
same = client.pay(customer="65", amount=1, agent="5555")

clear_configuration

Remove the shared default client (useful in tests).

from edahab import clear_configuration

clear_configuration()

Module functions

pay

Create a purchase invoice (Issueinvoice). Customer confirms on their phone (push/pop-up).

  • With configured credentials:
from edahab import configure, pay, is_invoice_paid

configure("your-api-key", "your-api-secret")
invoice = pay(customer="65", amount=1, agent="5555", currency="USD")
print(is_invoice_paid(invoice.invoice_status), invoice.invoice_id)
  • One-call with explicit credentials (no configure):
from edahab import pay

invoice = pay(
    "your-api-key",
    "your-api-secret",
    customer="65",
    amount=1,
    agent="5555",
)

verify_invoice

Double-check invoice status (CheckInvoiceStatus). Works with configured client or explicit api_key / api_secret (same rules as pay).

from edahab import configure, pay, verify_invoice, is_invoice_paid

configure("your-api-key", "your-api-secret")
issued = pay(customer="65", amount=1, agent="5555")

if issued.invoice_id:
    confirmed = verify_invoice(invoice_id=issued.invoice_id)
    print(confirmed.invoice_status, is_invoice_paid(confirmed.invoice_status))

With explicit credentials:

verify_invoice(
    "your-api-key",
    "your-api-secret",
    invoice_id="INV123456789",
)

send_credit

Send money from your merchant balance (agentPayment). Uses configured client or pass keys like pay.

from edahab import configure, send_credit

configure("your-api-key", "your-api-secret")
credit = send_credit(
    to="252612345678",
    amount=100,
    reference="order-999",
    currency="SLSH",
)
print(credit.transaction_status, credit.transaction_message)

is_invoice_paid

Return True only when InvoiceStatus == "Paid" (per purchase docs).

from edahab import is_invoice_paid

assert is_invoice_paid("Paid") is True
assert is_invoice_paid("Unpaid") is False

generate_request_hash

Build the hash query string: SHA-256 hex of (JSON body string + api_secret). Use the exact same body string you POST.

from edahab import generate_request_hash, serialize_body

body = serialize_body({"apiKey": "123", "invoiceId": "ABC"})
h = generate_request_hash(body, "secretapikey")

serialize_body

Turn a dict into compact JSON with sorted keys (stable for signing and posting).

from edahab import serialize_body

s = serialize_body({"apiKey": "x", "amount": 1})

describe_status_code

Map an invoice StatusCode integer (or None) to a short description string.

from edahab import describe_status_code, StatusCode

print(describe_status_code(0))
print(describe_status_code(StatusCode.INSUFFICIENT_CUSTOMER_BALANCE))
print(describe_status_code(None))  # None

EdahabClient

Low-level control: one instance holds your key pair and options.

Constructor EdahabClient(api_key, api_secret, *, base_url=..., timeout=..., open_url=...)

from edahab import EdahabClient, DEFAULT_BASE_URL

client = EdahabClient(
    "your-api-key",
    "your-api-secret",
    base_url=DEFAULT_BASE_URL,
    timeout=30.0,
)

EdahabClient.from_env

Build a client from environment variables (same defaults as configure_from_env).

client = EdahabClient.from_env()

client.api_key (property)

Read-only API key used in JSON bodies.

print(client.api_key)

issue_invoice

Official parameter names: edahab_number, amount, agent_code, optional currency, raise_on_api_error.

result = client.issue_invoice("65", 1, "5555", currency="USD")

Allow non-success StatusCode without raising:

result = client.issue_invoice(
    "65", 1, "5555", raise_on_api_error=False
)
print(result.status_code, result.validation_errors)

pay

Alias for issue_invoice with keyword names: customer, amount, agent, currency, raise_on_api_error.

result = client.pay(customer="65", amount=1, agent="5555")

agent_payment

Credit payment: phone_number, transaction_amount, transaction_id, optional currency.

out = client.agent_payment(
    "252612345678",
    100,
    "order-999",
    currency="SLSH",
)

send_credit

Alias: to, amount, reference, currency.

out = client.send_credit(to="252612345678", amount=100, reference="order-999")

check_invoice_status

invoice_id, optional raise_on_api_error.

status = client.check_invoice_status("INV123456789")

verify

Alias for check_invoice_status.

status = client.verify("INV123456789")

Result types

Dataclasses returned by the client. Each includes raw (dict) with the full API payload.

IssueInvoiceResult

Fields: invoice_status, transaction_id, invoice_id, status_code, request_id, status_description, validation_errors, raw.

CheckInvoiceStatusResult

Same fields as IssueInvoiceResult (verify endpoint matches purchase response shape in the docs).

AgentPaymentResult

Fields: transaction_status, transaction_message, phone_number, transaction_id, currency, raw.

from edahab import EdahabClient

client = EdahabClient("k", "s")
r = client.pay(customer="65", amount=1, agent="5555")
print(r.invoice_id, r.raw)

Status codes

StatusCode (enum)

SUCCESS, API_ERROR, INVALID_JSON, VALIDATION_ERROR, INVALID_API_CREDENTIALS, INSUFFICIENT_CUSTOMER_BALANCE, INVOICE_NOT_FOUND, INVALID (int values 0–7; see status docs).

from edahab import StatusCode

assert StatusCode.SUCCESS == 0

STATUS_DESCRIPTIONS

dict[int, str] — human-readable lines for each code. Also used internally by describe_status_code.

from edahab import STATUS_DESCRIPTIONS, StatusCode

print(STATUS_DESCRIPTIONS[StatusCode.SUCCESS.value])

Errors (exceptions)

Class When
EdahabError Base type for all package errors
EdahabHTTPError HTTP/network failure; may set status_code, url, body
EdahabDecodeError Response is not JSON or not a JSON object
EdahabCredentialError API StatusCode 4 (bad key/hash)
EdahabValidationError API StatusCode 3; check validation_errors
EdahabAPIStatusError Other non-zero invoice StatusCode; check raw_response
from edahab import (
    EdahabClient,
    EdahabCredentialError,
    EdahabValidationError,
    EdahabAPIStatusError,
    EdahabHTTPError,
)

client = EdahabClient("your-api-key", "your-api-secret")
try:
    client.issue_invoice("65", 1, "5555")
except EdahabCredentialError as e:
    print("Fix key/secret or hash", e)
except EdahabValidationError as e:
    print(e.validation_errors)
except EdahabAPIStatusError as e:
    print(e.status_code, e.raw_response)
except EdahabHTTPError as e:
    print(e.status_code, e.body)

Constants

DEFAULT_BASE_URL

"https://edahab.net/api/api/" — default POST base for all endpoints.

from edahab import DEFAULT_BASE_URL
print(DEFAULT_BASE_URL)

Default environment variable names

Used by configure_from_env and EdahabClient.from_env:

  • EDAHAB_API_KEY
  • EDAHAB_API_SECRET

Package version

import edahab

print(edahab.__version__)

Quick reference — everything exported from edahab

configure, configure_from_env, get_client, clear_configuration, pay, verify_invoice, send_credit, is_invoice_paid, generate_request_hash, serialize_body, describe_status_code, EdahabClient, DEFAULT_BASE_URL, StatusCode, STATUS_DESCRIPTIONS, IssueInvoiceResult, CheckInvoiceStatusResult, AgentPaymentResult, EdahabError, EdahabHTTPError, EdahabDecodeError, EdahabCredentialError, EdahabValidationError, EdahabAPIStatusError.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

edahab-1.1.0.tar.gz (15.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

edahab-1.1.0-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file edahab-1.1.0.tar.gz.

File metadata

  • Download URL: edahab-1.1.0.tar.gz
  • Upload date:
  • Size: 15.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for edahab-1.1.0.tar.gz
Algorithm Hash digest
SHA256 b96aad6ae6a86b4844c936bfdf794075559cc73f8888d3bd972344fb75ae4a1a
MD5 859a92c169612cacc8958bad92ddfd03
BLAKE2b-256 567e72fab5d6d849d68d6eb5eb89bc905abcad4af26c5175e6649b6f6bd6764d

See more details on using hashes here.

File details

Details for the file edahab-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: edahab-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for edahab-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 57673f474fa8e8e33041725aa23d235a053afafb3a210632447f5355ec9a843f
MD5 160da20ce776ee44b885d325d322d765
BLAKE2b-256 0acc784e7426f1cce3f08fa3523e1d5eba170a8fbd37963dd03b430037bf8fc6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page