Skip to content

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 cashfin

Requirements

  • Python 3.8 or later
  • requests library

Quick Start

python
import cashfin
import os

client = cashfin.Client(api_key=os.environ.get('CASHFIN_API_KEY'))

# Your code here

Configuration 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 += 1

Auto-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?

  1. Check our GitHub repository
  2. Review open issues
  3. Submit pull requests

Getting Help

Cashfin Business API Documentation