Skip to content

PHP SDK

The official Cashfin SDK for PHP applications.

Installation

bash
composer require cashfin/cashfin-php

Requirements

  • PHP 8.0 or later
  • Composer

Quick Start

php
<?php
require 'vendor/autoload.php';

use Cashfin\CashfinClient;

$cashfin = new CashfinClient([
    'api_key' => getenv('CASHFIN_API_KEY')
]);

// Your code here

Configuration Options

php
$cashfin = new CashfinClient([
    // 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

php
// List all products
$products = $cashfin->products->all();

// With pagination
$products = $cashfin->products->all([
    'page' => 1,
    'limit' => 20,
    'status' => 'published'
]);

foreach ($products->data as $product) {
    echo $product->title . "\n";
}

Get Product

php
$product = $cashfin->products->retrieve('507f1f77bcf86cd799439011');

echo $product->title;
echo $product->price;

Create Product

php
$product = $cashfin->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
        ]
    ]
]);

echo "Created: " . $product->id;

Update Product

php
$product = $cashfin->products->update('507f1f77bcf86cd799439011', [
    'price' => 2499.99,
    'stock' => 75
]);

Categories

List Categories

php
$categories = $cashfin->categories->all();

Create Category

php
$category = $cashfin->categories->create([
    'title' => 'Electronics',
    'description' => 'Electronic devices and accessories',
    'status' => 'active'
]);

Update Category

php
$category = $cashfin->categories->update('507f191e810c19729de860ea', [
    'description' => 'Updated description'
]);

Orders

Create Checkout

php
$order = $cashfin->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'
    ]
]);

echo "Order: " . $order->orderno;
echo "Payment: " . $order->paymentlink->shorturl;

Payments

M-Pesa Payment

php
$payment = $cashfin->payments->mpesa([
    'amount' => 1500,
    'phone' => '254712345678',
    'referenceid' => 'ORDER-001',
    'description' => 'Payment for Order #001'
]);

echo "Checkout ID: " . $payment->checkoutrequestid;

Customers

Create Customer

php
$customer = $cashfin->customers->create([
    'name' => 'John Doe',
    'email' => '[email protected]',
    'phone' => '+254712345678',
    'country' => 'Kenya',
    'currency' => 'KES',
    'type' => 'individual'
]);

echo "Customer ID: " . $customer->id;

Subscriptions

Create Subscription

php
$subscription = $cashfin->subscriptions->create([
    'customerid' => '507f1f77bcf86cd799439011',
    'items' => [
        [
            'itemid' => '507f191e810c19729de860ea',
            'quantity' => 1,
            'rate' => 2999.00
        ]
    ],
    'billingcycle' => 'monthly',
    'autorenew' => true,
    'trial' => [
        'startdate' => date('c'),
        'enddate' => date('c', strtotime('+14 days'))
    ]
]);

echo "Subscription: " . $subscription->subscriptionno;

Get Subscription

php
$subscription = $cashfin->subscriptions->retrieve('507f1f77bcf86cd799439020');

echo "Status: " . $subscription->status;
echo "Next Billing: " . $subscription->nextbillingdate;

Error Handling

php
<?php
use Cashfin\Exception\ValidationException;
use Cashfin\Exception\AuthenticationException;
use Cashfin\Exception\NotFoundException;
use Cashfin\Exception\RateLimitException;
use Cashfin\Exception\CashfinException;

try {
    $product = $cashfin->products->create([
        'title' => 'Widget'
        // Missing required fields
    ]);
} catch (ValidationException $e) {
    echo 'Validation errors: ' . json_encode($e->getErrors());
    // { "price": "Price is required" }
} catch (AuthenticationException $e) {
    echo 'Check your API key';
} catch (NotFoundException $e) {
    echo 'Resource not found';
} catch (RateLimitException $e) {
    echo 'Rate limited. Retry after ' . $e->getRetryAfter() . ' seconds';
} catch (CashfinException $e) {
    echo 'API Error: ' . $e->getMessage();
    echo 'Status: ' . $e->getHttpStatus();
}

Webhooks

Verify Signature

php
<?php
use Cashfin\Webhook;
use Cashfin\Exception\SignatureVerificationException;

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_CASHFIN_SIGNATURE'];
$secret = getenv('CASHFIN_WEBHOOK_SECRET');

try {
    $event = Webhook::constructEvent($payload, $signature, $secret);
} catch (\UnexpectedValueException $e) {
    // Invalid payload
    http_response_code(400);
    exit();
} catch (SignatureVerificationException $e) {
    // Invalid signature
    http_response_code(401);
    exit();
}

// Handle the event
switch ($event->type) {
    case 'payment.completed':
        $payment = $event->data;
        handlePaymentCompleted($payment);
        break;
    case 'order.created':
        $order = $event->data;
        handleOrderCreated($order);
        break;
    case 'subscription.renewed':
        $subscription = $event->data;
        handleSubscriptionRenewed($subscription);
        break;
    default:
        echo 'Unhandled event type: ' . $event->type;
}

http_response_code(200);
echo json_encode(['received' => true]);

Pagination

Manual Pagination

php
$page = 1;
$hasMore = true;

while ($hasMore) {
    $response = $cashfin->products->all(['page' => $page, 'limit' => 100]);

    foreach ($response->data as $product) {
        echo $product->title . "\n";
    }

    $hasMore = $page < $response->meta->pages;
    $page++;
}

Auto-Pagination

php
// Automatically handles pagination
$allProducts = $cashfin->products->all()->autoPagingIterator();

foreach ($allProducts as $product) {
    echo $product->title . "\n";
}

Laravel Integration

Service Provider

php
// config/services.php
return [
    // ...
    'cashfin' => [
        'key' => env('CASHFIN_API_KEY'),
        'secret' => env('CASHFIN_WEBHOOK_SECRET'),
        'environment' => env('CASHFIN_ENVIRONMENT', 'sandbox'),
    ],
];

Service Class

php
<?php
// app/Services/CashfinService.php

namespace App\Services;

use Cashfin\CashfinClient;

class CashfinService
{
    private CashfinClient $client;

    public function __construct()
    {
        $this->client = new CashfinClient([
            'api_key' => config('services.cashfin.key'),
            'environment' => config('services.cashfin.environment')
        ]);
    }

    public function createProduct(array $data)
    {
        return $this->client->products->create($data);
    }

    public function initiatePayment(float $amount, string $phone, string $reference)
    {
        return $this->client->payments->mpesa([
            'amount' => $amount,
            'phone' => $phone,
            'referenceid' => $reference
        ]);
    }
}

Controller Example

php
<?php
// app/Http/Controllers/PaymentController.php

namespace App\Http\Controllers;

use App\Services\CashfinService;
use Illuminate\Http\Request;

class PaymentController extends Controller
{
    public function __construct(
        private CashfinService $cashfin
    ) {}

    public function initiatePayment(Request $request)
    {
        $validated = $request->validate([
            'amount' => 'required|numeric|min:10',
            'phone' => 'required|string',
            'order_id' => 'required|string'
        ]);

        $payment = $this->cashfin->initiatePayment(
            $validated['amount'],
            $validated['phone'],
            $validated['order_id']
        );

        return response()->json([
            'success' => true,
            'checkout_id' => $payment->checkoutrequestid
        ]);
    }
}

Webhook Controller

php
<?php
// app/Http/Controllers/WebhookController.php

namespace App\Http\Controllers;

use Cashfin\Webhook;
use Illuminate\Http\Request;

class WebhookController extends Controller
{
    public function handle(Request $request)
    {
        $payload = $request->getContent();
        $signature = $request->header('X-Cashfin-Signature');
        $secret = config('services.cashfin.secret');

        try {
            $event = Webhook::constructEvent($payload, $signature, $secret);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid webhook'], 400);
        }

        match ($event->type) {
            'payment.completed' => $this->handlePaymentCompleted($event->data),
            'order.created' => $this->handleOrderCreated($event->data),
            default => null
        };

        return response()->json(['received' => true]);
    }

    private function handlePaymentCompleted($payment)
    {
        // Update order status, send confirmation email, etc.
    }

    private function handleOrderCreated($order)
    {
        // Process new order
    }
}

Examples

WooCommerce Integration

php
<?php
// Process WooCommerce order with Cashfin

use Cashfin\CashfinClient;

add_action('woocommerce_thankyou', 'sync_order_to_cashfin');

function sync_order_to_cashfin($order_id) {
    $order = wc_get_order($order_id);

    $cashfin = new CashfinClient([
        'api_key' => get_option('cashfin_api_key')
    ]);

    $items = [];
    foreach ($order->get_items() as $item) {
        $items[] = [
            'itemid' => $item->get_product_id(),
            'quantity' => $item->get_quantity(),
            'rate' => $item->get_total() / $item->get_quantity()
        ];
    }

    $cashfinOrder = $cashfin->orders->checkout([
        'customeremail' => $order->get_billing_email(),
        'items' => $items,
        'shippingaddress' => [
            'name' => $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name(),
            'address' => $order->get_shipping_address_1(),
            'city' => $order->get_shipping_city(),
            'country' => $order->get_shipping_country()
        ]
    ]);

    // Store Cashfin order ID
    update_post_meta($order_id, '_cashfin_order_id', $cashfinOrder->id);
}

Cashfin Business API Documentation