Skip to content

Python SDK ​

The official Cashfin SDK for Python applications.

Installation ​

bash
pip install cashfin-business-sdk

Requirements ​

  • Python 3.8 or later

Quick Start ​

python
import os
from cashfin_sdk.main import CashfinSDK

os.environ["CASHFIN_CLIENT_SECRET"] = "cs_your_client_secret"
os.environ["CASHFIN_BASE_URL"] = "https://api.cashfin.africa"

sdk = CashfinSDK()

Authentication ​

Authentication is handled via environment variables. Set them before initialising the SDK:

python
import os
from cashfin_sdk.main import CashfinSDK

os.environ["CASHFIN_CLIENT_SECRET"] = "cs_your_client_secret"
os.environ["CASHFIN_BASE_URL"] = "https://api.cashfin.africa"  # optional, this is the default

sdk = CashfinSDK()

TIP

Find your client secret under Settings → API Keys in the Cashfin Dashboard.

Environment Variables ​

VariableDescription
CASHFIN_CLIENT_SECRETYour API client secret (from Cashfin Dashboard)
CASHFIN_BASE_URLAPI base URL (default: https://api.cashfin.africa)

Products ​

List Products ​

python
products = sdk.business.products.list(status="published", type="product")

for product in products.data:
    print(product.title)

Get Product ​

python
product = sdk.business.products.get("507f1f77bcf86cd799439011")

print(product.title)
print(product.price)

Create Product ​

python
product = sdk.business.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 = sdk.business.products.update(
    '507f1f77bcf86cd799439011',
    price=2499.99,
    stock=75
)

Categories ​

List Categories ​

python
categories = sdk.business.categories.list()

Create Category ​

python
category = sdk.business.categories.create(
    title='Electronics',
    description='Electronic devices and accessories',
    status='active'
)

Update Category ​

python
category = sdk.business.categories.update(
    '507f191e810c19729de860ea',
    status='archived'
)

Orders ​

Create Checkout ​

python
order = sdk.business.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}")

List Orders ​

python
orders = sdk.business.orders.list(status="processing")

Get Order ​

python
order = sdk.business.orders.get("order_id")

Payments ​

M-Pesa STK Push ​

python
payment = sdk.business.payment.request_stk_push(
    phone_number='+254712345678',
    ref_id='ORDER-001',
    amount=1500
)

print(f"Checkout ID: {payment.checkoutrequestid}")

Transactions ​

python
# List transactions
transactions = sdk.business.transactions.list(page=1, limit=20, status="completed")

# Get a transaction
transaction = sdk.business.transactions.get("transaction_id")

Receipts ​

python
receipts = sdk.business.receipts.list()
receipt = sdk.business.receipts.get("receipt_id")
python
# Create a payment link
link = sdk.business.payment_links.create(title="Website Payment", amount=1000)

# List payment links
links = sdk.business.payment_links.list()

# Get a payment link
link = sdk.business.payment_links.get("link_id")

Invoices ​

python
# Create an invoice
invoice = sdk.business.invoices.create(
    customerid='customer_id',
    items=[{'itemid': 'prod_id', 'quantity': 1, 'rate': 1000}],
    duedate='2025-12-31'
)

# List invoices
invoices = sdk.business.invoices.list()

# Get an invoice
invoice = sdk.business.invoices.get("invoice_id")

# Update an invoice
sdk.business.invoices.update("invoice_id", status="paid")

Customers ​

Create Customer ​

python
customer = sdk.business.customers.create(
    name='John Doe',
    email='[email protected]',
    phone='254712345678',
    country='Kenya',
    currency='KES',
    type='individual'
)

print(f"Customer ID: {customer.id}")

List & Search Customers ​

python
# List all customers
customers = sdk.business.customers.list()

# Search customers
results = sdk.business.customers.list(search="jane")

Get Customer ​

python
customer = sdk.business.customers.get("customer_id")

Update Customer ​

python
sdk.business.customers.update("customer_id", company="Acme Ltd")

Subscriptions ​

Create Subscription ​

python
subscription = sdk.business.subscriptions.create(
    customerid='507f1f77bcf86cd799439011',
    items=[
        {
            'itemid': '507f191e810c19729de860ea',
            'quantity': 1,
            'rate': 2999.00
        }
    ],
    billingcycle='monthly',
    autorenew=True
)

print(f"Subscription: {subscription.subscriptionno}")

Get Subscription ​

python
subscription = sdk.business.subscriptions.get('507f1f77bcf86cd799439020')

print(f"Status: {subscription.status}")
print(f"Next Billing: {subscription.nextbillingdate}")

Manage Subscriptions ​

python
# Cancel
sdk.business.subscriptions.cancel("sub_id")

# Pause
sdk.business.subscriptions.pause("sub_id")

# Resume
sdk.business.subscriptions.resume("sub_id")

# Generate invoice for the current billing cycle
sdk.business.subscriptions.generate_invoice("sub_id")

CRM ​

Contacts ​

python
sdk.business.contacts.create(name="John Smith", email="[email protected]")
sdk.business.contacts.list()
sdk.business.contacts.get("contact_id")

Leads ​

python
sdk.business.leads.create(name="Alice", source="website", budget=50000)
sdk.business.leads.list(status="new")

Quotes ​

python
# Read-only
sdk.business.quotes.list(status="sent")
sdk.business.quotes.get("quote_id")

Contracts ​

python
# Read-only
sdk.business.contracts.list(status="active")
sdk.business.contracts.get("contract_id")

Bookings ​

python
# Read-only
sdk.business.bookings.list(status="scheduled")
sdk.business.bookings.get("booking_id")

Appointments ​

python
# Read-only
sdk.business.appointments.list(status="active")
sdk.business.appointments.get("appointment_id")

Purchases ​

Vendors ​

python
sdk.business.vendors.create(name="Office Supplies Co", type="business", phone="254700000000")
sdk.business.vendors.list()
sdk.business.vendors.get("vendor_id")
sdk.business.vendors.update("vendor_id", city="Nairobi")

Expenses ​

python
sdk.business.expenses.create(title="Office rent", amount=30000, expensedate="2025-01-01")
sdk.business.expenses.list(status="approved")
sdk.business.expenses.get("expense_id")

Bills ​

python
sdk.business.bills.create(
    title="Electricity bill",
    amount=5000,
    billdate="2025-01-01",
    duedate="2025-01-15"
)
sdk.business.bills.list()
sdk.business.bills.get("bill_id")

Purchase Orders ​

python
sdk.business.purchase_orders.create(
    title="Q1 stock order",
    orderdate="2025-01-01",
    deliverydate="2025-01-20"
)
sdk.business.purchase_orders.list()
sdk.business.purchase_orders.get("po_id")

Marketing ​

Campaigns ​

python
# Read-only
sdk.business.campaigns.list(medium="email", status="sent")
sdk.business.campaigns.get("campaign_id")

Marketing Lists ​

python
# Create a list
sdk.business.marketing_lists.create(name="Newsletter", type="email")

# List all
sdk.business.marketing_lists.list()

# Get a list
sdk.business.marketing_lists.get("list_id")

# Add a contact to a list
sdk.business.marketing_lists.add_contact(
    list_id="list_id",
    email="[email protected]",
    firstname="Bob"
)

Error Handling ​

python
from cashfin_sdk.error import (
    CashfinError,
    ValidationError,
    AuthenticationError,
    NotFoundError,
    RateLimitError
)

try:
    product = sdk.business.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 os
from cashfin_sdk.main import CashfinSDK
from cashfin_sdk.webhook import Webhook

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 = Webhook.construct_event(
            payload, signature, secret
        )
    except ValueError:
        # Invalid payload
        return 'Invalid payload', 400
    except Exception:
        # 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 = sdk.business.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 sdk.business.products.list().auto_paging_iter():
    print(product.title)

Django Integration ​

Settings ​

python
# settings.py
CASHFIN_CLIENT_SECRET = os.environ.get('CASHFIN_CLIENT_SECRET')
CASHFIN_WEBHOOK_SECRET = os.environ.get('CASHFIN_WEBHOOK_SECRET')
CASHFIN_BASE_URL = os.environ.get('CASHFIN_BASE_URL', 'https://api.cashfin.africa')

Service Class ​

python
# services/cashfin_service.py
import os
from cashfin_sdk.main import CashfinSDK
from django.conf import settings

class CashfinService:
    def __init__(self):
        os.environ["CASHFIN_CLIENT_SECRET"] = settings.CASHFIN_CLIENT_SECRET
        os.environ["CASHFIN_BASE_URL"] = settings.CASHFIN_BASE_URL
        self.sdk = CashfinSDK()

    def create_product(self, **kwargs):
        return self.sdk.business.products.create(**kwargs)

    def initiate_payment(self, amount, phone, reference):
        return self.sdk.business.payment.request_stk_push(
            amount=amount,
            phone_number=phone,
            ref_id=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
from cashfin_sdk.webhook import Webhook
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 = 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 os
from cashfin_sdk.main import CashfinSDK

app = Flask(__name__)

os.environ["CASHFIN_CLIENT_SECRET"] = os.environ.get('CASHFIN_CLIENT_SECRET')
sdk = CashfinSDK()

@app.route('/api/checkout', methods=['POST'])
def checkout():
    data = request.json

    order = sdk.business.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 = sdk.business.payment.request_stk_push(
        amount=data['amount'],
        phone_number=data['phone'],
        ref_id=data['reference']
    )

    return jsonify({
        'checkout_id': payment.checkoutrequestid,
        'message': 'Check your phone for M-Pesa prompt'
    })

Development ​

bash
# Install UV
pip install uv

# Install dependencies
uv sync

# Run tests
uv run python -m pytest

Contributing ​

Want to contribute to the Python SDK?

  1. Check our GitLab repository or PyPI package
  2. Review open issues
  3. Submit pull requests

Getting Help ​

Cashfin Business API Documentation