PHPackages                             keenops/laravel-tcb-cms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. keenops/laravel-tcb-cms

ActiveLibrary[Payment Processing](/categories/payments)

keenops/laravel-tcb-cms
=======================

Laravel package for integrating with Tanzania Commercial Bank's Cash Management System (CMS) API

1.0(1mo ago)00MITPHPPHP ^8.4

Since Mar 19Pushed 1mo agoCompare

[ Source](https://github.com/keenops/laravel-tcb-cms)[ Packagist](https://packagist.org/packages/keenops/laravel-tcb-cms)[ RSS](/packages/keenops-laravel-tcb-cms/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (10)Versions (2)Used By (0)

Laravel TCB CMS
===============

[](#laravel-tcb-cms)

A Laravel package for integrating with Tanzania Commercial Bank's Cash Management System (CMS) API. This package enables payment reference creation, IPN (Instant Payment Notification) handling, reconciliation, and reference cancellation.

Requirements
------------

[](#requirements)

- PHP 8.4+
- Laravel 12.x or 13.x

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require keenops/laravel-tcb-cms
```

The package will auto-register its service provider and facade.

### Publish Configuration

[](#publish-configuration)

```
php artisan vendor:publish --tag=tcb-cms-config
```

### Run Migrations

[](#run-migrations)

```
php artisan migrate
```

This creates the `tcb_cms_transactions` table for transaction logging.

Configuration
-------------

[](#configuration)

Add the following environment variables to your `.env` file:

```
TCB_CMS_API_KEY=your-api-key
TCB_CMS_PARTNER_CODE=PART-YOURCODE
TCB_CMS_PROFILE_ID=1234567890
TCB_CMS_BASE_URL=https://partners.tcbbank.co.tz
TCB_CMS_RECONCILIATION_BASE_URL=https://partners.tcbbank.co.tz:8444
TCB_CMS_IPN_ROUTE=/tcb-cms/ipn
TCB_CMS_VERIFY_IP=false
TCB_CMS_ALLOWED_IPS=
TCB_CMS_TIMEOUT=30
TCB_CMS_RETRY_TIMES=3
TCB_CMS_LOGGING_ENABLED=true
```

### Configuration Options

[](#configuration-options)

OptionDescriptionDefault`api_key`Your TCB CMS API key-`partner_code`Your partner code assigned by TCB-`profile_id`Your profile ID-`base_url`TCB CMS API base URL`https://partners.tcbbank.co.tz``reconciliation_base_url`Reconciliation API base URL`https://partners.tcbbank.co.tz:8444``ipn.route`IPN callback route`/tcb-cms/ipn``ipn.middleware`Middleware for IPN route`['api']``verify_ip`Enable IP verification for IPN`false``allowed_ips`Comma-separated allowed IPs-`timeout`HTTP request timeout (seconds)`30``retry_times`Number of retry attempts`3``logging.enabled`Enable transaction logging`true`Usage
-----

[](#usage)

### Using the Facade

[](#using-the-facade)

```
use Keenops\LaravelTcbCms\Facades\TcbCms;
```

### Create a Payment Reference

[](#create-a-payment-reference)

Create a payment reference for a customer to make payments:

```
$response = TcbCms::createReference(
    reference: '999MYREF001',
    name: 'John Doe',
    mobile: '0712345678',
    message: 'Invoice #12345',
);

if ($response->isSuccessful()) {
    echo "Account No: " . $response->accountNo;
    echo "Reference No: " . $response->referenceNo;
} else {
    echo "Error: " . $response->message;
}
```

With optional amount and expiry date:

```
$response = TcbCms::createReference(
    reference: '999MYREF001',
    name: 'John Doe',
    mobile: '0712345678',
    message: 'Invoice #12345',
    amount: 50000.00,
    expiryDate: '2024-12-31',
);
```

### Cancel a Payment Reference

[](#cancel-a-payment-reference)

```
$response = TcbCms::cancelReference(
    accountNo: '240123456789',
    referenceNo: '999MYREF001',
);

if ($response->isSuccessful()) {
    echo "Reference cancelled successfully";
}
```

### Reconciliation

[](#reconciliation)

Fetch all transactions within a date range:

```
use Carbon\Carbon;

$response = TcbCms::reconcile(
    startDate: Carbon::now()->subDays(7),
    endDate: Carbon::now(),
);

if ($response->isSuccessful()) {
    echo "Total Transactions: " . $response->totalCount;
    echo "Total Amount: " . $response->totalAmount;

    foreach ($response->transactions as $transaction) {
        echo $transaction->transactionId;
        echo $transaction->reference;
        echo $transaction->amount;
        echo $transaction->payerName;
        echo $transaction->transactionDate->format('Y-m-d H:i:s');
    }
}
```

Handling Payment Notifications (IPN)
------------------------------------

[](#handling-payment-notifications-ipn)

The package automatically registers an IPN route at `/tcb-cms/ipn` (configurable). When TCB Bank sends a payment notification, the package dispatches a `PaymentReceived` event.

### Create an Event Listener

[](#create-an-event-listener)

```
// app/Listeners/HandleTcbPayment.php

namespace App\Listeners;

use Keenops\LaravelTcbCms\Events\PaymentReceived;

class HandleTcbPayment
{
    public function handle(PaymentReceived $event): void
    {
        $payload = $event->payload;

        // Access payment details
        $transactionId = $payload->transactionId;
        $reference = $payload->reference;
        $amount = $payload->amount;
        $payerName = $payload->payerName;
        $payerMobile = $payload->payerMobile;
        $transactionDate = $payload->transactionDate;

        // Update your order/invoice
        $order = Order::where('payment_reference', $reference)->first();

        if ($order) {
            $order->markAsPaid($transactionId, $amount);
        }
    }
}
```

### Register the Listener

[](#register-the-listener)

```
// app/Providers/EventServiceProvider.php

use Keenops\LaravelTcbCms\Events\PaymentReceived;
use App\Listeners\HandleTcbPayment;

protected $listen = [
    PaymentReceived::class => [
        HandleTcbPayment::class,
    ],
];
```

Or using Laravel 11+ event discovery, the listener will be auto-registered.

Available Events
----------------

[](#available-events)

EventDescriptionPayload`PaymentReceived`Dispatched when IPN callback is received`IpnPayload $payload``ReferenceCreated`Dispatched on successful reference creation`CreateReferenceRequest $request`, `CreateReferenceResponse $response``ReferenceCancelled`Dispatched on successful reference cancellation`CancelReferenceRequest $request`, `CancelReferenceResponse $response``ReconciliationCompleted`Dispatched after successful reconciliation`ReconciliationRequest $request`, `ReconciliationResponse $response`Payment Channel Helper
----------------------

[](#payment-channel-helper)

Get payment instructions for different channels:

```
use Keenops\LaravelTcbCms\Enums\PaymentChannel;

// Get instructions for a specific channel
$instructions = PaymentChannel::TcbMobile->getPaymentInstructions('999MYREF001');
// "Open TCB Mobile App > Payments > Bill Payments > Enter Reference: 999MYREF001"

// Get all channels with instructions
$channels = PaymentChannel::allWithInstructions('999MYREF001');

foreach ($channels as $value => $channel) {
    echo $channel['label'];        // "TCB Mobile Banking"
    echo $channel['instructions']; // Payment instructions
}
```

Available channels:

- `TCB_MOBILE` - TCB Mobile Banking
- `TCB_BRANCH` - TCB Branch
- `TCB_ATM` - TCB ATM
- `USSD` - USSD Banking
- `INTERNET_BANKING` - Internet Banking
- `AGENT_BANKING` - Agent Banking
- `PESALINK` - PesaLink

Transaction Logging
-------------------

[](#transaction-logging)

All API requests and IPN callbacks are logged to the `tcb_cms_transactions` table when logging is enabled.

### Query Transaction Logs

[](#query-transaction-logs)

```
use Keenops\LaravelTcbCms\Models\TcbTransaction;

// Get all transactions for a reference
$transactions = TcbTransaction::forReference('999MYREF001')->get();

// Get all successful transactions
$successful = TcbTransaction::successful()->get();

// Get all failed transactions
$failed = TcbTransaction::failed()->get();

// Get transactions by type
$ipnLogs = TcbTransaction::ofType('ipn')->get();
$createLogs = TcbTransaction::ofType('create_reference')->get();
$cancelLogs = TcbTransaction::ofType('cancel_reference')->get();
$reconcileLogs = TcbTransaction::ofType('reconciliation')->get();
```

### Disable Logging

[](#disable-logging)

Set `TCB_CMS_LOGGING_ENABLED=false` in your `.env` file or update the config:

```
// config/tcb-cms.php
'logging' => [
    'enabled' => false,
],
```

IP Verification for IPN
-----------------------

[](#ip-verification-for-ipn)

For additional security, enable IP verification to only accept IPN callbacks from TCB Bank's servers:

```
TCB_CMS_VERIFY_IP=true
TCB_CMS_ALLOWED_IPS=192.168.1.1,192.168.1.2
```

Error Handling
--------------

[](#error-handling)

The package throws specific exceptions for different error scenarios:

```
use Keenops\LaravelTcbCms\Exceptions\TcbCmsException;
use Keenops\LaravelTcbCms\Exceptions\ApiConnectionException;
use Keenops\LaravelTcbCms\Exceptions\InvalidApiKeyException;
use Keenops\LaravelTcbCms\Exceptions\InvalidReferenceException;

try {
    $response = TcbCms::createReference(...);
} catch (InvalidApiKeyException $e) {
    // Invalid API key
} catch (ApiConnectionException $e) {
    // Connection failed
} catch (TcbCmsException $e) {
    // General API error
    $context = $e->context(); // Additional error context
}
```

Response Status Codes
---------------------

[](#response-status-codes)

```
use Keenops\LaravelTcbCms\Enums\ResponseStatus;

ResponseStatus::Success;         // 0 - Successful operation
ResponseStatus::Failure;         // 1 - Operation failed
ResponseStatus::ConnectionError; // 2 - Connection error
ResponseStatus::ApiKeyError;     // 4 - Invalid API key
```

Testing
-------

[](#testing)

Run the package tests:

```
composer test
```

Or using Pest directly:

```
vendor/bin/pest
```

### Mocking in Your Application Tests

[](#mocking-in-your-application-tests)

```
use Illuminate\Support\Facades\Http;
use Keenops\LaravelTcbCms\Facades\TcbCms;

it('creates an order with payment reference', function () {
    Http::fake([
        '*/api/v1/cms/reference/create' => Http::response([
            'status' => 0,
            'message' => 'Reference created successfully',
            'accountNo' => '240123456789',
            'referenceNo' => '999MYREF001',
            'partnerCode' => 'TEST-PARTNER',
        ], 200),
    ]);

    $response = TcbCms::createReference(
        reference: '999MYREF001',
        name: 'John Doe',
        mobile: '0712345678',
        message: 'Test Order',
    );

    expect($response->isSuccessful())->toBeTrue();
});
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

Credits
-------

[](#credits)

- [Kimwalu](https://github.com/kimwalu)

Support
-------

[](#support)

For issues and feature requests, please use the [GitHub issue tracker](https://github.com/keenops/laravel-tcb-cms/issues).

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance89

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

54d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/979e7b5ad115c575c452f36f2316011ad49f9bb01cf45c5eb68d069af01ed64e?d=identicon)[kimwalu](/maintainers/kimwalu)

---

Top Contributors

[![keenops](https://avatars.githubusercontent.com/u/37520787?v=4)](https://github.com/keenops "keenops (1 commits)")

---

Tags

laravelcmspaymentBanktanzaniaTCB

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/keenops-laravel-tcb-cms/health.svg)

```
[![Health](https://phpackages.com/badges/keenops-laravel-tcb-cms/health.svg)](https://phpackages.com/packages/keenops-laravel-tcb-cms)
```

###  Alternatives

[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[psalm/plugin-laravel

Psalm plugin for Laravel

3274.9M308](/packages/psalm-plugin-laravel)[asciisd/knet

Knet package is provides an expressive, fluent interface to KNet's payment services.

141.1k](/packages/asciisd-knet)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)[api-platform/laravel

API Platform support for Laravel

59126.4k6](/packages/api-platform-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
