Skip to main content

Official X-Pay Python SDK for payment processing

Project description

X-Pay Python SDK

PyPI version Python Support License: MIT

The official Python SDK for X-Pay payment processing API. Support for Django, Flask, FastAPI, and standalone applications.

Features

  • 🔐 Secure Authentication: API key-based authentication with automatic environment detection
  • 💰 Payment Processing: Support for Stripe, Mobile Money (Ghana, Liberia, Nigeria, Uganda, Rwanda), and X-Pay Wallet
  • 🌍 Multi-Currency: USD, GHS, EUR, GBP with automatic currency conversion utilities
  • 🪝 Webhooks: Complete webhook management with signature verification
  • 👥 Customer Management: Full CRUD operations for customer data
  • 🔄 Async Support: Optional async HTTP client with httpx
  • 🏗️ Framework Integration: Native support for Django, Flask, and FastAPI
  • Type Safety: Full type hints and Pydantic models
  • 📊 Testing: Comprehensive test suite with 90%+ coverage

Installation

# Basic installation
pip install xpay-python-sdk

# With async support
pip install xpay-python-sdk[async]

# With Django integration
pip install xpay-python-sdk[django]

# With Flask integration  
pip install xpay-python-sdk[flask]

# With FastAPI integration
pip install xpay-python-sdk[fastapi]

# All optional dependencies
pip install xpay-python-sdk[all]

Quick Start

from xpay import XPayClient
from decimal import Decimal

# Initialize the client
client = XPayClient(
    api_key="sk_sandbox_your_secret_key_here",
    environment="sandbox"  # Optional: auto-detected from API key
)

# Create a payment
payment = client.payments.create({
    "amount": "10.00",
    "currency": "USD",
    "payment_method": "stripe",
    "description": "Test payment",
    "payment_method_data": {
        "payment_method_types": ["card"]
    }
})

print(f"Payment created: {payment.id}")
print(f"Status: {payment.status}")

Supported Payment Methods

Method Code Supported Currencies Description
Stripe stripe USD, EUR, GBP, GHS Credit/debit cards via Stripe
Ghana Mobile Money momo GHS MTN, Vodafone, AirtelTigo
Liberia Mobile Money momo_liberia USD Orange Money, MTN
Nigeria Mobile Money momo_nigeria NGN Various providers
Uganda Mobile Money momo_uganda UGX MTN, Airtel
Rwanda Mobile Money momo_rwanda RWF MTN, Airtel
X-Pay Wallet xpay_wallet USD, GHS, EUR Internal wallet system

Framework Integrations

Django Integration

# settings.py
INSTALLED_APPS = [
    # ...
    'xpay.integrations.django',
]

XPAY = {
    'API_KEY': 'sk_sandbox_your_key_here',
    'ENVIRONMENT': 'sandbox',
    'WEBHOOK_SECRET': 'whsec_your_webhook_secret',
}

# views.py  
from xpay.integrations.django import XPayDjangoClient

def create_payment(request):
    client = XPayDjangoClient()  # Uses settings automatically
    payment = client.payments.create({
        "amount": "25.00",
        "payment_method": "momo",
        "payment_method_data": {
            "phone_number": "+233501234567"
        }
    })
    return JsonResponse({"payment_id": payment.id})

Flask Integration

from flask import Flask
from xpay.integrations.flask import XPayBlueprint

app = Flask(__name__)
app.config['XPAY_API_KEY'] = 'sk_sandbox_your_key_here'
app.config['XPAY_ENVIRONMENT'] = 'sandbox'

# Register X-Pay blueprint
xpay_bp = XPayBlueprint(api_key=app.config['XPAY_API_KEY'])
app.register_blueprint(xpay_bp, url_prefix='/xpay')

@app.route('/payments', methods=['POST'])
def create_payment():
    client = xpay_bp.get_client()
    payment = client.payments.create(request.json)
    return {"payment_id": payment.id}

FastAPI Integration

from fastapi import FastAPI, Depends
from xpay.integrations.fastapi import get_xpay_client, XPayClientDep

app = FastAPI()

@app.post("/payments")
async def create_payment(
    payment_data: dict,
    client: XPayClientDep = Depends(get_xpay_client)
):
    payment = await client.payments.create_async(payment_data)
    return {"payment_id": payment.id}

API Reference

Payments

# Create a payment
payment = client.payments.create({
    "amount": "50.00",
    "currency": "GHS", 
    "payment_method": "momo",
    "description": "Mobile money payment",
    "customer_id": "cust_123",
    "payment_method_data": {
        "phone_number": "+233501234567"
    },
    "metadata": {"order_id": "ord_456"}
})

# Retrieve a payment
payment = client.payments.retrieve("pay_12345")

# List payments
payments = client.payments.list(
    limit=10,
    status="completed",
    customer_id="cust_123"
)

# Cancel a payment
cancelled_payment = client.payments.cancel("pay_12345")

Customers

# Create a customer
customer = client.customers.create({
    "name": "John Doe",
    "email": "john@example.com", 
    "phone": "+233501234567",
    "metadata": {"source": "website"}
})

# Retrieve a customer
customer = client.customers.retrieve("cust_12345")

# Update a customer
updated_customer = client.customers.update("cust_12345", {
    "name": "John Smith",
    "phone": "+233509876543"
})

# List customers
customers = client.customers.list(
    limit=50,
    email="john@example.com"
)

# Delete a customer
result = client.customers.delete("cust_12345")

Webhooks

# Create a webhook endpoint
webhook = client.webhooks.create({
    "url": "https://your-site.com/webhooks/xpay",
    "events": ["payment.succeeded", "payment.failed"],
    "description": "Payment notifications"
})

# List webhook endpoints  
webhooks = client.webhooks.list()

# Update a webhook
updated_webhook = client.webhooks.update("whk_12345", {
    "events": ["payment.succeeded", "payment.failed", "refund.created"]
})

# Test a webhook
test_result = client.webhooks.test("whk_12345")

# Verify webhook signature
from xpay.utils.webhook import verify_signature

is_valid = verify_signature(
    payload=request.body,
    signature=request.headers.get("X-XPay-Signature"),  
    secret="whsec_your_webhook_secret"
)

Currency Utilities

from xpay.utils.currency import CurrencyUtils
from decimal import Decimal

# Convert to smallest unit (cents, pesewas, etc.)
amount_cents = CurrencyUtils.to_smallest_unit(Decimal("10.50"), "USD")  # 1050

# Convert from smallest unit  
amount_dollars = CurrencyUtils.from_smallest_unit(1050, "USD")  # Decimal("10.50")

# Format currency for display
formatted = CurrencyUtils.format_amount(Decimal("10.50"), "GHS")  # "₵10.50"

# Get currency info
info = CurrencyUtils.get_currency_info("GHS")
# {"code": "GHS", "name": "Ghanaian Cedi", "symbol": "₵", "decimal_places": 2}

Error Handling

from xpay.exceptions import (
    XPayError,
    AuthenticationError, 
    ValidationError,
    PaymentError,
    NetworkError
)

try:
    payment = client.payments.create(invalid_data)
except ValidationError as e:
    print(f"Validation failed: {e.message}")
    print(f"Error code: {e.code}")
    print(f"Field errors: {e.details}")
    
except AuthenticationError as e:
    print(f"Authentication failed: {e.message}")
    
except PaymentError as e:
    print(f"Payment processing failed: {e.message}")
    print(f"Payment ID: {e.payment_id}")
    
except NetworkError as e:
    print(f"Network error: {e.message}")
    
except XPayError as e:
    print(f"General X-Pay error: {e.message}")
    print(f"Status code: {e.status_code}")

Async Support

from xpay import XPayAsyncClient

# Initialize async client
async_client = XPayAsyncClient(
    api_key="sk_sandbox_your_key_here",
    timeout=30.0
)

# Async payment creation
async def create_payment_async():
    payment = await async_client.payments.create_async({
        "amount": "15.00",
        "payment_method": "stripe"
    })
    return payment

# Use in async context
import asyncio
payment = asyncio.run(create_payment_async())

Testing

# Unit tests
pytest tests/unit/

# Integration tests (requires valid API keys)
pytest tests/integration/ 

# All tests with coverage
pytest --cov=xpay tests/

# Type checking
mypy src/xpay

# Linting
flake8 src/xpay
black --check src/xpay
isort --check-only src/xpay

Configuration

Environment Variables

export XPAY_API_KEY="sk_sandbox_your_key_here"
export XPAY_ENVIRONMENT="sandbox"
export XPAY_BASE_URL="https://api.xpay-bits.com" 
export XPAY_TIMEOUT="30"
export XPAY_WEBHOOK_SECRET="whsec_your_secret"

Configuration File

# config.py
XPAY_CONFIG = {
    "api_key": "sk_sandbox_your_key_here",
    "environment": "sandbox",
    "timeout": 30,
    "retry_attempts": 3,
    "base_url": "https://api.xpay-bits.com"
}

# Usage
from xpay import XPayClient
client = XPayClient(**XPAY_CONFIG)

Security Best Practices

  1. API Key Management: Never commit API keys to version control
  2. Environment Separation: Use sandbox for development, live for production
  3. Webhook Verification: Always verify webhook signatures
  4. HTTPS Only: Use HTTPS for all webhook endpoints
  5. Error Handling: Don't expose sensitive error details to end users

Requirements

  • Python 3.8+
  • requests >= 2.28.0
  • pydantic >= 1.10.0, < 3.0.0

Development

# Clone the repository
git clone https://github.com/x-pay/python-sdk.git
cd python-sdk

# Install development dependencies
pip install -e ".[dev]"

# Set up pre-commit hooks
pre-commit install

# Run tests
pytest

# Check code quality
black src/ tests/
flake8 src/ tests/  
isort src/ tests/
mypy src/

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support


Made with ❤️ by the X-Pay team# X-Pay Python SDK

Python License: MIT

The official Python SDK for X-Pay payment processing platform. Accept payments from multiple providers including Stripe, Mobile Money, and X-Pay Wallets with a unified API.

Features

  • 🚀 Multiple Payment Methods: Stripe, Mobile Money (MoMo), X-Pay Wallets
  • 🔒 Type Safety: Full type hints and Pydantic models
  • 💰 Decimal Precision: Proper currency handling with Python Decimal
  • 🌍 Environment Detection: Auto-detect sandbox/live from API keys
  • 📱 Framework Integration: Django, Flask, FastAPI support
  • 👥 Customer Management: Complete customer lifecycle management
  • 🔗 Webhook Management: Easy webhook setup and verification
  • Async Support: Optional async HTTP client with httpx

Installation

pip install xpay-python-sdk

Optional Dependencies

# For async support
pip install xpay-python-sdk[async]

# For Django integration
pip install xpay-python-sdk[django]

# For Flask integration  
pip install xpay-python-sdk[flask]

# For FastAPI integration
pip install xpay-python-sdk[fastapi]

# For development
pip install xpay-python-sdk[dev]

Quick Start

from xpay import XPayClient, PaymentRequest

# Initialize client
client = XPayClient(
    api_key="sk_sandbox_your_secret_key_here",
    merchant_id="your_merchant_id_here", 
    environment="sandbox",
    base_url="http://localhost:8000"  # For local development
)

# Create a payment
payment_request = PaymentRequest(
    amount="29.99",
    currency="USD",
    payment_method="stripe",
    description="Python SDK test payment"
)

payment = client.payments.create(payment_request)
print(f"Payment created: {payment.id}")

Working Credentials (for testing)

client = XPayClient(
    api_key="sk_sandbox_7c845adf-f658-4f29-9857-7e8a8708",
    merchant_id="548d8033-fbe9-411b-991f-f159cdee7745",
    environment="sandbox",
    base_url="http://localhost:8000"
)

Testing

Run the test script to verify functionality:

cd integrations/sdks/python
python test_sdk.py

Type Safety

The Python SDK is fully typed with Pydantic models:

from xpay import XPayClient, PaymentRequest, Payment
from decimal import Decimal

# Type-safe payment creation
payment_request = PaymentRequest(
    amount="25.99",
    currency="USD", 
    payment_method="stripe",
    metadata={"order_id": "123", "user_id": "456"}
)

# Response is properly typed
payment: Payment = client.payments.create(payment_request)
print(payment.client_secret)  # Type checker knows this exists for Stripe

Currency Handling

from xpay.utils import CurrencyUtils
from decimal import Decimal

# Convert to smallest unit (cents)
cents = CurrencyUtils.to_smallest_unit(Decimal("25.99"), "USD")
print(cents)  # 2599

# Format for display
formatted = CurrencyUtils.format_amount(cents, "USD")
print(formatted)  # $25.99

Payment Methods

All payment methods from the JavaScript SDK are supported:

  • stripe - Credit/debit cards
  • momo_liberia - MTN Mobile Money Liberia
  • xpay_wallet - X-Pay wallet transfers
  • More coming soon...

Error Handling

from xpay import XPayClient
from xpay.exceptions import XPayError, AuthenticationError, ValidationError

try:
    payment = client.payments.create(payment_request)
except AuthenticationError as e:
    print(f"Auth failed: {e.message}")
except ValidationError as e:
    print(f"Validation error: {e.message}")
    print(f"Details: {e.details}")
except XPayError as e:
    print(f"X-Pay error [{e.code}]: {e.message}")

Contributing

  1. Fork the repository
  2. Create feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open Pull Request

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

xpay_python_sdk-1.0.0.tar.gz (23.0 kB view details)

Uploaded Source

Built Distribution

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

xpay_python_sdk-1.0.0-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file xpay_python_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: xpay_python_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 23.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xpay_python_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 e1b7e9f070e436e5208349455f3d5ca5ef5a825eed38731d240f6668128ebb36
MD5 0de89f9eed61ff2509d826e4b0e83c50
BLAKE2b-256 87a7678c9acf3b34ac1ec58c676a2cf63e1d48a5318caa95bf36d3b213facb66

See more details on using hashes here.

File details

Details for the file xpay_python_sdk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for xpay_python_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a9422e5b91d9fcc1111c16a9747dbac1b2d6b96bfe085392ea33b0a5b2b6c23a
MD5 8ccd0688dc5a9cea7620f4d867916d48
BLAKE2b-256 6d40bc81d7845ec17315ed9989043ee6f2c4245534762b25e09b98f88f45b03a

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