Python SDK
The official Cashfin SDK for Python applications.
Coming Soon
The Python SDK is currently in development. This documentation previews the planned API.
Installation
bash
pip install cashfinRequirements
- Python 3.8 or later
requestslibrary
Quick Start
python
import cashfin
import os
client = cashfin.Client(api_key=os.environ.get('CASHFIN_API_KEY'))
# Your code hereConfiguration Options
python
client = cashfin.Client(
# Required
api_key='cs_your_client_secret',
# Optional
environment='live', # 'live' or 'sandbox'
timeout=30, # Request timeout in seconds
max_retries=3, # Number of retries on failure
debug=False # Enable debug logging
)Products
List Products
python
# List all products
products = client.products.list()
# With pagination
products = client.products.list(
page=1,
limit=20,
status='published'
)
for product in products.data:
print(product.title)Get Product
python
product = client.products.retrieve('507f1f77bcf86cd799439011')
print(product.title)
print(product.price)Create Product
python
product = client.products.create(
title='Premium Widget',
description='A high-quality widget',
price=1999.99,
stock=100,
type='product',
status='published',
featured=True,
variants=[
{
'attributetitle': 'Color',
'valuetitle': 'Blue',
'valueprice': 1999.99,
'valuestock': 50
}
]
)
print(f"Created: {product.id}")Update Product
python
product = client.products.update(
'507f1f77bcf86cd799439011',
price=2499.99,
stock=75
)Categories
List Categories
python
categories = client.categories.list()Create Category
python
category = client.categories.create(
title='Electronics',
description='Electronic devices and accessories',
status='active'
)Update Category
python
category = client.categories.update(
'507f191e810c19729de860ea',
description='Updated description'
)Orders
Create Checkout
python
order = client.orders.checkout(
customeremail='[email protected]',
items=[
{
'itemid': '507f1f77bcf86cd799439011',
'quantity': 2,
'rate': 1999.99
}
],
shippingaddress={
'name': 'John Doe',
'address': '123 Main St',
'city': 'Nairobi',
'country': 'Kenya',
'phone': '+254712345678'
}
)
print(f"Order: {order.orderno}")
print(f"Payment: {order.paymentlink.shorturl}")Payments
M-Pesa Payment
python
payment = client.payments.mpesa(
amount=1500,
phone='254712345678',
referenceid='ORDER-001',
description='Payment for Order #001'
)
print(f"Checkout ID: {payment.checkoutrequestid}")Customers
Create Customer
python
customer = client.customers.create(
name='John Doe',
email='[email protected]',
phone='+254712345678',
country='Kenya',
currency='KES',
type='individual'
)
print(f"Customer ID: {customer.id}")Subscriptions
Create Subscription
python
from datetime import datetime, timedelta
subscription = client.subscriptions.create(
customerid='507f1f77bcf86cd799439011',
items=[
{
'itemid': '507f191e810c19729de860ea',
'quantity': 1,
'rate': 2999.00
}
],
billingcycle='monthly',
autorenew=True,
trial={
'startdate': datetime.now().isoformat(),
'enddate': (datetime.now() + timedelta(days=14)).isoformat()
}
)
print(f"Subscription: {subscription.subscriptionno}")Get Subscription
python
subscription = client.subscriptions.retrieve('507f1f77bcf86cd799439020')
print(f"Status: {subscription.status}")
print(f"Next Billing: {subscription.nextbillingdate}")Error Handling
python
from cashfin.error import (
CashfinError,
ValidationError,
AuthenticationError,
NotFoundError,
RateLimitError
)
try:
product = client.products.create(
title='Widget'
# Missing required fields
)
except ValidationError as e:
print(f'Validation errors: {e.errors}')
# {'price': 'Price is required'}
except AuthenticationError as e:
print('Check your API key')
except NotFoundError as e:
print('Resource not found')
except RateLimitError as e:
print(f'Rate limited. Retry after {e.retry_after} seconds')
except CashfinError as e:
print(f'API Error: {e.message}')
print(f'Status: {e.http_status}')Webhooks
Verify Signature
python
from flask import Flask, request
import cashfin
app = Flask(__name__)
@app.route('/webhooks/cashfin', methods=['POST'])
def webhook():
payload = request.data.decode('utf-8')
signature = request.headers.get('X-Cashfin-Signature')
secret = os.environ.get('CASHFIN_WEBHOOK_SECRET')
try:
event = cashfin.Webhook.construct_event(
payload, signature, secret
)
except ValueError:
# Invalid payload
return 'Invalid payload', 400
except cashfin.error.SignatureVerificationError:
# Invalid signature
return 'Invalid signature', 401
# Handle the event
if event.type == 'payment.completed':
handle_payment_completed(event.data)
elif event.type == 'order.created':
handle_order_created(event.data)
elif event.type == 'subscription.renewed':
handle_subscription_renewed(event.data)
return {'received': True}Pagination
Manual Pagination
python
page = 1
has_more = True
while has_more:
response = client.products.list(page=page, limit=100)
for product in response.data:
print(product.title)
has_more = page < response.meta.pages
page += 1Auto-Pagination
python
# Automatically handles pagination
for product in client.products.list().auto_paging_iter():
print(product.title)Async Support
python
import asyncio
import cashfin
async def main():
client = cashfin.AsyncClient(api_key=os.environ.get('CASHFIN_API_KEY'))
# All methods work with async/await
products = await client.products.list()
product = await client.products.create(
title='Async Widget',
price=999.99
)
print(f"Created: {product.id}")
asyncio.run(main())Django Integration
Settings
python
# settings.py
CASHFIN_API_KEY = os.environ.get('CASHFIN_API_KEY')
CASHFIN_WEBHOOK_SECRET = os.environ.get('CASHFIN_WEBHOOK_SECRET')
CASHFIN_ENVIRONMENT = os.environ.get('CASHFIN_ENVIRONMENT', 'sandbox')Service Class
python
# services/cashfin_service.py
import cashfin
from django.conf import settings
class CashfinService:
def __init__(self):
self.client = cashfin.Client(
api_key=settings.CASHFIN_API_KEY,
environment=settings.CASHFIN_ENVIRONMENT
)
def create_product(self, **kwargs):
return self.client.products.create(**kwargs)
def initiate_payment(self, amount, phone, reference):
return self.client.payments.mpesa(
amount=amount,
phone=phone,
referenceid=reference
)View Example
python
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .services.cashfin_service import CashfinService
class PaymentView(APIView):
def __init__(self):
self.cashfin = CashfinService()
def post(self, request):
amount = request.data.get('amount')
phone = request.data.get('phone')
order_id = request.data.get('order_id')
payment = self.cashfin.initiate_payment(
amount=amount,
phone=phone,
reference=order_id
)
return Response({
'success': True,
'checkout_id': payment.checkoutrequestid
})Webhook View
python
# views.py
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
import cashfin
from django.conf import settings
@csrf_exempt
def cashfin_webhook(request):
payload = request.body.decode('utf-8')
signature = request.headers.get('X-Cashfin-Signature')
try:
event = cashfin.Webhook.construct_event(
payload, signature, settings.CASHFIN_WEBHOOK_SECRET
)
except Exception:
return JsonResponse({'error': 'Invalid webhook'}, status=400)
if event.type == 'payment.completed':
handle_payment_completed(event.data)
return JsonResponse({'received': True})Examples
Flask E-commerce
python
from flask import Flask, request, jsonify
import cashfin
import os
app = Flask(__name__)
client = cashfin.Client(api_key=os.environ.get('CASHFIN_API_KEY'))
@app.route('/api/checkout', methods=['POST'])
def checkout():
data = request.json
order = client.orders.checkout(
customeremail=data['email'],
items=[
{
'itemid': item['id'],
'quantity': item['quantity'],
'rate': item['price']
}
for item in data['items']
]
)
return jsonify({
'order_id': order.id,
'order_number': order.orderno,
'payment_url': order.paymentlink.shorturl
})
@app.route('/api/payment/mpesa', methods=['POST'])
def mpesa_payment():
data = request.json
payment = client.payments.mpesa(
amount=data['amount'],
phone=data['phone'],
referenceid=data['reference']
)
return jsonify({
'checkout_id': payment.checkoutrequestid,
'message': 'Check your phone for M-Pesa prompt'
})Contributing
The Python SDK is under development. Want to contribute?
- Check our GitHub repository
- Review open issues
- Submit pull requests