A modern, easy-to-use Python SDK for integrating with ToyyibPay payment gateway. Inspired by Stripe's SDK design principles.
- 🚀 Simple, intuitive API
- đź”’ Full type hints support
- ⚡ Async/await support
- 🛡️ Comprehensive error handling
- đź”§ Easy integration with Flask and FastAPI
- 📊 Built-in webhook handling
- 🗄️ Optional database integration (PostgreSQL first, MySQL/MongoDB coming soon)
- đź§Ş Well-tested
and production-ready(nvm not production-ready yet till v1.0.0)
pip install toyyibpay# For PostgreSQL support
pip install toyyibpay[postgres]
# For Flask integration
pip install toyyibpay[flask]
# For FastAPI integration
pip install toyyibpay[fastapi]
# For everything
pip install toyyibpay[all]For development with tests and documentation:
# Clone the repository
git clone https://github.com/waizwafiq/toyyibpay-python.git
cd toyyibpay-python
# Install in editable mode with dev dependencies
pip install -e ".[dev]"import toyyibpay
# Initialize client
client = toyyibpay.Client(api_key="your-api-key")
# Create a payment
bill = client.create_bill(
name="John Doe",
email="john@example.com",
phone="0123456789",
amount=100.00, # MYR 100.00
order_id="ORD-12345",
description="Purchase of Product X"
)
print(f"Payment URL: {bill.payment_url}")
print(f"Bill Code: {bill.bill_code}")import asyncio
import toyyibpay
async def create_payment():
async with toyyibpay.AsyncClient(api_key="your-api-key") as client:
bill = await client.create_bill(
name="John Doe",
email="john@example.com",
phone="0123456789",
amount=100.00,
order_id="ORD-12345"
)
return bill
# Run async function
bill = asyncio.run(create_payment())import os
import toyyibpay
# Set environment variables
os.environ['TOYYIBPAY_API_KEY'] = 'your-api-key'
os.environ['TOYYIBPAY_CATEGORY_ID'] = 'your-category-id'
os.environ['TOYYIBPAY_ENVIRONMENT'] = 'production' # or 'dev'
# Create client from environment
config = toyyibpay.ToyyibPayConfig.from_env()
client = toyyibpay.Client(config=config)from flask import Flask, request, jsonify
import toyyibpay
app = Flask(__name__)
client = toyyibpay.Client(api_key="your-api-key")
@app.route('/create-payment', methods=['POST'])
def create_payment():
data = request.get_json()
try:
bill = client.create_bill(
name=data['name'],
email=data['email'],
phone=data['phone'],
amount=data['amount'],
order_id=data.get('order_id')
)
return jsonify({
'success': True,
'payment_url': bill.payment_url,
'bill_code': bill.bill_code
})
except toyyibpay.ToyyibPayError as e:
return jsonify({
'success': False,
'error': str(e)
}), 400from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import toyyibpay
app = FastAPI()
client = toyyibpay.Client(api_key="your-api-key")
class PaymentRequest(BaseModel):
name: str
email: str
phone: str
amount: float
@app.post("/create-payment")
async def create_payment(payment: PaymentRequest):
try:
bill = client.create_bill(
name=payment.name,
email=payment.email,
phone=payment.phone,
amount=payment.amount,
order_id=toyyibpay.utils.generate_order_id()
)
return {
"payment_url": bill.payment_url,
"bill_code": bill.bill_code
}
except toyyibpay.ToyyibPayError as e:
raise HTTPException(status_code=400, detail=str(e))import toyyibpay
from toyyibpay.webhooks import WebhookHandler
# Create webhook handler
webhook_handler = WebhookHandler()
# Register event handlers
@webhook_handler.on_payment_success
def handle_success(data: toyyibpay.CallbackData):
print(f"Payment {data.order_id} successful!")
# Update order status, send email, etc.
@webhook_handler.on_payment_failed
def handle_failure(data: toyyibpay.CallbackData):
print(f"Payment {data.order_id} failed: {data.reason}")
# Handle failed payment
# Process webhook (in your webhook endpoint)
def process_webhook(request_body, headers):
try:
callback_data = webhook_handler.process(request_body, headers)
return {"success": True}
except toyyibpay.WebhookError as e:
return {"success": False, "error": str(e)}from sqlalchemy import create_engine
import toyyibpay
from toyyibpay.db import PostgresPaymentStore
# Setup database
engine = create_engine("postgresql://user:pass@localhost/mydb")
payment_store = PostgresPaymentStore(engine)
payment_store.create_tables()
# Create payment with database tracking
def create_payment_with_tracking(customer_data):
# Create bill with ToyyibPay
bill = client.create_bill(**customer_data)
# Store in database
with payment_store.session() as session:
payment = payment_store.create_payment(
session,
order_id=customer_data['order_id'],
amount=customer_data['amount'],
bill_code=bill.bill_code,
customer_name=customer_data['name'],
customer_email=customer_data['email']
)
return billCreate a new payment bill.
bill = client.create_bill(
name="Waiz Wafiq", # Customer name (required)
email="waiz@gmail.com", # Customer email (required)
phone="0123456789", # Customer phone (required)
amount=100.00, # Amount in MYR (required)
order_id="ORD-12345", # Your reference ID (required)
description="bayar hutang", # Description (optional)
return_url="https://...", # Return URL (optional)
callback_url="https://...", # Callback URL (optional)
)Get transaction history for a bill.
# Get all transactions
transactions = client.get_bill_transactions("bill_code")
# Get only successful transactions
successful = client.get_bill_transactions(
"bill_code",
status=toyyibpay.PaymentStatus.SUCCESS
)Check payment status for a bill.
status = client.check_payment_status("bill_code")
if status == toyyibpay.PaymentStatus.SUCCESS:
print("Payment successful!")Create a new payment category.
category = client.create_category(
name="Online Store",
description="Payments for online store"
)PaymentStatus: SUCCESS, PENDING, FAILED, PENDING_TRANSACTIONPaymentChannel: FPX, CREDIT_CARD, FPX_AND_CREDIT_CARDEnvironment: DEV, STAGING, PRODUCTION
ToyyibPayError: Base exceptionAuthenticationError: Invalid API keyValidationError: Invalid request dataNetworkError: Network-related errorsAPIError: ToyyibPay API errors
TOYYIBPAY_API_KEY: Your ToyyibPay API keyTOYYIBPAY_CATEGORY_ID: Default category IDTOYYIBPAY_ENVIRONMENT: Environment (dev/staging/production)TOYYIBPAY_RETURN_URL: Default return URLTOYYIBPAY_CALLBACK_URL: Default callback URLDATABASE_URL: PostgreSQL connection string (optional)
# Install dev dependencies
pip install -e .[dev]
# Run tests
pytest
# Run with coverage
pytest --cov=toyyibpay# Format code
black toyyibpay tests
# Sort imports
isort toyyibpay tests
# Type checking
mypy toyyibpayTests are not included in the PyPI package but are available in the GitHub repository.
# Clone the repository
git clone https://github.com/mwaizwafiq/toyyibpay-python.git
cd toyyibpay-python
# Install with development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=toyyibpay- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
pytest) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Inspired by Stripe's excellent Python SDK
- Thanks to the ToyyibPay team for their payment gateway service