Skip to main content

A modern Python SDK for the ZenoPay payment API

Project description

ZenoPay Python SDK

Modern Python SDK for ZenoPay payment API with async/sync support, order management, and disbursements.

Installation

pip install zenopay-sdk

Quick Start

from elusion.zenopay import ZenoPay
from elusion.zenopay.models.order import NewOrder
from elusion.zenopay.utils import generate_order_id

# Initialize client (uses environment variables)
client = ZenoPay()

# Create order (sync)
with client:
    order = NewOrder(
        order_id=generate_order_id(),
        buyer_email="customer@example.com",
        buyer_name="John Doe",
        buyer_phone="07XXXXXXXX",
        amount=1000
    )
    response = client.orders.sync.create(order)
    print(f"Order ID: {response.results.order_id}")

Configuration

Environment Variables

export ZENOPAY_API_KEY="your_api_key"

Code Configuration

client = ZenoPay(
    api_key="your_api_key",
    timeout=30.0
)

Orders API

Synchronous Operations

from elusion.zenopay import ZenoPay
from elusion.zenopay.models.order import NewOrder
from elusion.zenopay.utils import generate_order_id

client = ZenoPay()

# Create order
def create_order():
    with client:
        order = NewOrder(
            order_id=generate_order_id(),
            buyer_email="test@example.com",
            buyer_name="Test User",
            buyer_phone="07XXXXXXXX",
            amount=1000,
        )
        response = client.orders.sync.create(order)
        return response.results.order_id

# Check status
def check_status(order_id: str):
    with client:
        response = client.orders.sync.check_status(order_id)
        return response.results

# Check if paid
def check_payment(order_id: str):
    with client:
        return client.orders.sync.check_payment(order_id)

# Wait for payment completion
def wait_for_payment(order_id: str):
    with client:
        return client.orders.sync.wait_for_payment(order_id)

# Usage example
if __name__ == "__main__":
    order_id = create_order()
    status = check_status(order_id)
    is_paid = check_payment(order_id)

    print(f"Order: {order_id}")
    print(f"Status: {status.data[0].payment_status}")
    print(f"Paid: {is_paid}")

    order_content = wait_for_payment(order_id)
    print(f"Order completed: {order_content}")

Asynchronous Operations

import asyncio
from elusion.zenopay import ZenoPay
from elusion.zenopay.models.order import NewOrder
from elusion.zenopay.utils import generate_order_id

client = ZenoPay()

# Create order (async)
async def create_order_async():
    async with client:
        order = NewOrder(
            order_id=generate_order_id(),
            buyer_email="test@example.com",
            buyer_name="Test User",
            buyer_phone="07XXXXXXXX",
            amount=1000,
            webhook_url="https://example.com/webhook",
            metadata={"key": "value"},
        )
        response = await client.orders.create(order)
        return response.results.order_id

# Check status (async)
async def check_status_async(order_id: str):
    async with client:
        response = await client.orders.check_status(order_id)
        return response.results.data[0].payment_status

# Check payment (async)
async def check_payment_async(order_id: str):
    async with client:
        return await client.orders.check_payment(order_id)

# Usage example
async def async_example():
    order_id = await create_order_async()
    status = await check_status_async(order_id)
    is_paid = await check_payment_async(order_id)

    print(f"Async Order: {order_id}")
    print(f"Async Status: {status}")
    print(f"Async Paid: {is_paid}")

asyncio.run(async_example())

Disbursements API

Mobile Money Disbursements

from elusion.zenopay import ZenoPay
from elusion.zenopay.models.disbursement import NewDisbursement, UtilityCodes
from elusion.zenopay.utils import generate_order_id

client = ZenoPay()

def disburse():
    response = client.disbursements.sync.disburse(
        disbursement_data=NewDisbursement(
            amount=5000,
            pin=0000,  # Your ZenoPay PIN
            transid=generate_order_id(),
            utilitycode=UtilityCodes.CASHIN,
            utilityref="07XXXXXXXX"  # Phone number
        )
    )
    return response.results.zenopay_response.result

# Usage
if __name__ == "__main__":
    result = disburse()
    print(f"Disbursement result: {result}")

Available Utility Codes

from elusion.zenopay.models.disbursement import UtilityCodes

# Available disbursement types
UtilityCodes.CASHIN      # Mobile money cash-in
# Add other available codes as needed

Webhook Handling

Basic Setup

# Setup handlers
def payment_completed(event):
    order_id = event.payload.order_id
    reference = event.payload.reference
    print(f"Payment completed: {order_id} - {reference}")

def payment_failed(event):
    order_id = event.payload.order_id
    print(f"Payment failed: {order_id}")

# Register handlers
client.webhooks.on_payment_completed(payment_completed)
client.webhooks.on_payment_failed(payment_failed)

# Process webhook
webhook_data = '{"order_id":"123","payment_status":"COMPLETED","reference":"REF123"}'
response = client.webhooks.process_webhook_request(webhook_data)

Flask Integration

from flask import Flask, request, jsonify
from elusion.zenopay import ZenoPay

app = Flask(__name__)
client = ZenoPay()

def handle_completed_payment(event):
    order_id = event.payload.order_id
    # Update database, send emails, etc.
    print(f"Order {order_id} completed")

client.webhooks.on_payment_completed(handle_completed_payment)

@app.route('/zenopay/webhook', methods=['POST'])
def webhook():
    raw_data = request.data.decode('utf-8')
    response = client.webhooks.process_webhook_request(raw_data)
    return jsonify({'status': response.status})

if __name__ == '__main__':
    app.run()

FastAPI Integration

from fastapi import FastAPI, Request
from elusion.zenopay import ZenoPay

app = FastAPI()
client = ZenoPay()

def handle_completed_payment(event):
    order_id = event.payload.order_id
    print(f"Order {order_id} completed")

client.webhooks.on_payment_completed(handle_completed_payment)

@app.post("/zenopay/webhook")
async def webhook(request: Request):
    raw_data = await request.body()
    raw_data_str = raw_data.decode('utf-8')
    response = client.webhooks.process_webhook_request(raw_data_str)
    return {'status': response.status}

Error Handling

from elusion.zenopay.exceptions import (
    ZenoPayError,
    ZenoPayValidationError,
    ZenoPayNetworkError,
    ZenoPayAuthenticationError
)

try:
    with client:
        response = client.orders.sync.create(order)
except ZenoPayValidationError as e:
    print(f"Validation error: {e.message}")
    print(f"Details: {e.validation_errors}")
except ZenoPayAuthenticationError as e:
    print(f"Authentication error: {e.message}")
except ZenoPayNetworkError as e:
    print(f"Network error: {e.message}")
except ZenoPayError as e:
    print(f"General error: {e.message}")

Models

Order Models

from elusion.zenopay.models.order import NewOrder
from elusion.zenopay.utils import generate_order_id

# Create order with all fields
order = NewOrder(
    order_id=generate_order_id(),
    buyer_email="customer@example.com",
    buyer_name="John Doe",
    buyer_phone="07XXXXXXXX",
    amount=1000,
    webhook_url="https://yoursite.com/webhook",
    metadata={
        "product_id": "12345",
        "campaign": "summer_sale"
    }
)

# Minimal order
order = NewOrder(
    order_id=generate_order_id(),
    buyer_email="customer@example.com",
    buyer_name="John Doe",
    buyer_phone="07XXXXXXXX",
    amount=1000
)

Disbursement Models

from elusion.zenopay.models.disbursement import NewDisbursement, UtilityCodes
from elusion.zenopay.utils import generate_order_id

# Mobile money disbursement
disbursement = NewDisbursement(
    amount=5000,
    pin=0000,  # Your ZenoPay PIN
    transid=generate_order_id(),
    utilitycode=UtilityCodes.CASHIN,
    utilityref="07XXXXXXXX"  # Phone number
)

Response Models

# Order creation response
response = client.orders.sync.create(order)
print(f"Order ID: {response.results.order_id}")

# Status check response
status = client.orders.sync.check_status(order_id)
print(f"Payment Status: {status.results.data[0].payment_status}")

# Disbursement response
response = client.disbursements.sync.disburse(disbursement_data)
print(f"Result: {response.results.zenopay_response.result}")

API Reference

Order Operations

Method Sync Async Description
Create Order client.orders.sync.create() await client.orders.create() Create new payment order
Check Status client.orders.sync.check_status() await client.orders.check_status() Check order payment status
Check Payment client.orders.sync.check_payment() await client.orders.check_payment() Returns boolean if paid
Wait for Payment client.orders.sync.wait_for_payment() await client.orders.wait_for_payment() Poll until completed

Disbursement Operations

Method Sync Async Description
Disburse client.disbursements.sync.disburse() await client.disbursements.disburse() Send money disbursement

Webhook Events

Event Handler Method Description
COMPLETED client.webhooks.on_payment_completed() Payment successful
FAILED client.webhooks.on_payment_failed() Payment failed
PENDING client.webhooks.on_payment_pending() Payment initiated
CANCELLED client.webhooks.on_payment_cancelled() Payment cancelled

Best Practices

Context Managers

Always use context managers for proper resource cleanup:

# Sync
with client:
    response = client.orders.sync.create(order)

# Async
async with client:
    response = await client.orders.create(order)

Error Handling

Handle specific exceptions for better error management:

try:
    with client:
        response = client.orders.sync.create(order)
except ZenoPayValidationError:
    # Handle validation errors
    pass
except ZenoPayNetworkError:
    # Handle network issues
    pass

Environment Configuration

Use environment variables for sensitive configuration:

# Don't hardcode credentials
client = ZenoPay(api_key=os.getenv('ZENOPAY_API_KEY'))

Generate Unique Order IDs

Always use the built-in utility to generate unique order IDs:

from elusion.zenopay.utils import generate_order_id

order_id = generate_order_id()  # Generates UUID-based unique ID

Support

License

MIT License - see LICENSE file for details.

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

zenopay_sdk-0.2.0.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

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

zenopay_sdk-0.2.0-py3-none-any.whl (29.3 kB view details)

Uploaded Python 3

File details

Details for the file zenopay_sdk-0.2.0.tar.gz.

File metadata

  • Download URL: zenopay_sdk-0.2.0.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for zenopay_sdk-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fac381cd4df621602c0e35523128058cc5102d9f28a7c8276e97cf538874d034
MD5 eb72da912fc09ab8b266f2f59494a93a
BLAKE2b-256 72d7d6321e9f09db9e2cb58e8a1e09e83159e83bdd69e40626d67d04d2a8345c

See more details on using hashes here.

Provenance

The following attestation bundles were made for zenopay_sdk-0.2.0.tar.gz:

Publisher: release.yaml on elusionhub/zenopay-python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file zenopay_sdk-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: zenopay_sdk-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 29.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for zenopay_sdk-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ba024526ecb13b4d42aa238a57150b5b41e0812933e504222ba91b94840c27e
MD5 f0606f78cd35074d36e87fc03e8a903d
BLAKE2b-256 e4470e13c5110f3b645b84ebc9f8f8313106da198e73b28ae1e89e77b2684cd0

See more details on using hashes here.

Provenance

The following attestation bundles were made for zenopay_sdk-0.2.0-py3-none-any.whl:

Publisher: release.yaml on elusionhub/zenopay-python-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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