Skip to main content

Python client for the eDahab payment API

Project description

eDahab logo

edahab (Python SDK)

Full Python SDK for the official eDahab API.

PyPIn8n Node DocsStatus Codes


Table of Contents


1) Product separation

This repository has two separate deliverables:

  • Python SDK (this package): edahab (published on PyPI)
  • n8n node package: see n8n-nodes-edahab/README.md (published on npm)

They are independent in packaging and release process.


2) Install

Install from PyPI:

pip install edahab

Install from local source:

pip install .

Editable install for development:

pip install -e .

3) Quick start

from edahab import configure, pay, verify_invoice, is_invoice_paid

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

invoice = pay(
    customer="65",
    amount=1,
    agent="5555",
    currency="USD",  # required
)

print(invoice.invoice_id, invoice.invoice_status)
print("paid?", is_invoice_paid(invoice.invoice_status))

if invoice.invoice_id:
    status = verify_invoice(invoice_id=invoice.invoice_id)
    print("verified:", status.invoice_status)

Every payment call requires currency and only accepts USD or SLSH.


4) Credentials and configuration

Environment variables

  • EDAHAB_API_KEY
  • EDAHAB_API_SECRET

configure(api_key, api_secret, *, base_url=..., timeout=..., open_url=...)

Sets a shared default client used by pay, verify_invoice, and send_credit.

configure_from_env(...)

Same as configure, but reads from env vars.

get_client()

Returns configured client or raises RuntimeError if not configured.

clear_configuration()

Clears configured default client (mostly useful in tests).


5) API reference (module-level functions)

pay(api_key=None, api_secret=None, *, customer, amount, agent, currency) -> IssueInvoiceResult

Creates purchase invoice (Issueinvoice).

  • If api_key and api_secret are omitted, uses configured default client.
  • If either key is provided alone, raises ValueError.

Example:

from edahab import pay

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

verify_invoice(api_key=None, api_secret=None, *, invoice_id) -> CheckInvoiceStatusResult

Checks status via CheckInvoiceStatus.

send_credit(api_key=None, api_secret=None, *, to, amount, reference, currency) -> AgentPaymentResult

Sends merchant-balance credit (agentPayment).

is_invoice_paid(invoice_status) -> bool

Returns True only for "Paid".

normalize_currency(currency) -> str

Normalizes and validates currency:

  • accepts case-insensitive input
  • returns canonical "USD" / "SLSH"
  • raises ValueError on invalid input

generate_request_hash(serialized_body, api_secret) -> str

Computes SHA-256 hex of serialized_body + api_secret.

serialize_body(payload: dict) -> str

Compacts JSON with stable sorting:

  • separators=(",", ":")
  • sort_keys=True

describe_status_code(code) -> str | None

Human description for invoice StatusCode.


6) API reference (EdahabClient)

Constructor

EdahabClient(api_key, api_secret, *, base_url="https://edahab.net/api/api/", timeout=30.0, open_url=None)

Alternate constructor

EdahabClient.from_env(...)

Property

client.api_key

Methods

issue_invoice(edahab_number, amount, agent_code, *, currency, raise_on_api_error=True)

  • endpoint: Issueinvoice
  • returns: IssueInvoiceResult

pay(*, customer, amount, agent, currency, raise_on_api_error=True)

Alias for issue_invoice.

agent_payment(phone_number, transaction_amount, transaction_id, *, currency)

  • endpoint: agentPayment
  • returns: AgentPaymentResult

send_credit(*, to, amount, reference, currency)

Alias for agent_payment.

check_invoice_status(invoice_id, *, raise_on_api_error=True)

  • endpoint: CheckInvoiceStatus
  • returns: CheckInvoiceStatusResult

verify(invoice_id, *, raise_on_api_error=True)

Alias for check_invoice_status.

Error behavior

  • invoice endpoints can raise based on StatusCode if raise_on_api_error=True
  • credit endpoint currently returns parsed payload without status-code raising

7) Result objects

IssueInvoiceResult

  • invoice_status
  • transaction_id
  • invoice_id
  • status_code
  • request_id
  • status_description
  • validation_errors
  • raw

CheckInvoiceStatusResult

Same field shape as IssueInvoiceResult.

AgentPaymentResult

  • transaction_status
  • transaction_message (handles API typo TransactionMesage)
  • phone_number
  • transaction_id
  • currency
  • raw

8) Exceptions

  • EdahabError (base)
  • EdahabHTTPError (status_code, url, body)
  • EdahabDecodeError
  • EdahabCredentialError
  • EdahabValidationError (validation_errors)
  • EdahabAPIStatusError (status_code, status_description, raw_response)

Example:

from edahab import (
    EdahabClient,
    EdahabCredentialError,
    EdahabValidationError,
    EdahabAPIStatusError,
    EdahabHTTPError,
)

client = EdahabClient("your-api-key", "your-api-secret")

try:
    client.issue_invoice("65", 1, "5555", currency="USD")
except EdahabCredentialError:
    print("invalid key/secret/hash")
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)

9) Status codes

StatusCode enum:

  • SUCCESS = 0
  • API_ERROR = 1
  • INVALID_JSON = 2
  • VALIDATION_ERROR = 3
  • INVALID_API_CREDENTIALS = 4
  • INSUFFICIENT_CUSTOMER_BALANCE = 5
  • INVOICE_NOT_FOUND = 6
  • INVALID = 7

Use STATUS_DESCRIPTIONS or describe_status_code() for labels.


10) Hashing and serialization rules

The API hash must use the exact body string sent on POST:

  1. Build body string via serialize_body(payload)
  2. Compute hash = sha256(body + api_secret).hexdigest()
  3. Send request to: https://edahab.net/api/api/{Endpoint}?hash={hash}

If this does not match exactly, credentials can be rejected with StatusCode=4.


11) Publish and release workflow

PyPI

rm -rf dist build src/*.egg-info *.egg-info
python3 -m build
python3 -m twine check dist/*
twine upload dist/*

Versioning

Keep in sync:

  • pyproject.toml -> [project].version
  • src/edahab/__init__.py -> __version__

12) Troubleshooting

  • RuntimeError: No default client configured Call configure(...) or configure_from_env() first.

  • ValueError: currency must be 'USD' or 'SLSH' Pass valid currency; use normalize_currency().

  • HTTP 400 at upload to PyPI You are likely re-uploading an existing release file; bump version.

  • StatusCode=4 from API Check key/secret pair and hash generation body consistency.


13) Exports

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


14) Official docs links

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-2.0.1.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

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

edahab-2.0.1-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for edahab-2.0.1.tar.gz
Algorithm Hash digest
SHA256 3ab2dcd7dd9bec4f2b32c202616b454d87347a11807af9926e9ada15f2040106
MD5 abf3de29a29c89e17abfa093797c3aa1
BLAKE2b-256 1eb984a134d3a48339863e03453d67e632438091b210b3986ad733bdbabafd0b

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for edahab-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 30d39f89140525efc2221e4268dbd0584c6e8ee21bf9c261b50536ce60594fe3
MD5 680656a35af3603f195fdcb5aa7e98c0
BLAKE2b-256 a55fd112466f0e2e9a7f396b150309e100c1b6ca0ce59d6f80d4b32dc51b4b6c

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