PHPackages                             pralhadstha/nepal-can-php-sdk - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. pralhadstha/nepal-can-php-sdk

ActiveLibrary[HTTP &amp; Networking](/categories/http)

pralhadstha/nepal-can-php-sdk
=============================

PHP SDK for Nepal Can Move (NCM) shipping and courier API - order creation, tracking, webhooks, COD, and delivery management for Nepal

v1.0.0(2mo ago)171MITPHPPHP ^8.1

Since Apr 1Pushed 2mo agoCompare

[ Source](https://github.com/pralhadstha/nepalcan-php-sdk)[ Packagist](https://packagist.org/packages/pralhadstha/nepal-can-php-sdk)[ Docs](https://github.com/pralhadstha/nepal-can-php-sdk)[ RSS](/packages/pralhadstha-nepal-can-php-sdk/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (1)Dependencies (3)Versions (2)Used By (1)

Nepal Can Move (NCM) PHP SDK
============================

[](#nepal-can-move-ncm-php-sdk)

[![PHP Version](https://camo.githubusercontent.com/2e2594698ad60142b9234d2658819cf6bd3491f5d4b6e17ddc8e9acb76edf166/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f7072616c686164737468612f6e6570616c2d63616e2d7068702d73646b)](https://packagist.org/packages/pralhadstha/nepal-can-php-sdk)[![Latest Version](https://camo.githubusercontent.com/5198fb8e9bb3adea48f2996443b658192f9371629e96c588c27cfa2e028a88ab/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7072616c686164737468612f6e6570616c2d63616e2d7068702d73646b)](https://packagist.org/packages/pralhadstha/nepal-can-php-sdk)[![License](https://camo.githubusercontent.com/7b861a76bb480aaa9f1047004af78e0935d8c02dd3e31d33ecdcd5fa7d05422d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7072616c686164737468612f6e6570616c2d63616e2d7068702d73646b)](https://packagist.org/packages/pralhadstha/nepal-can-php-sdk)

A PHP SDK for integrating with the [Nepal Can Move (NCM)](https://nepalcanmove.com) shipping and courier API. Manage shipments, track orders, calculate delivery rates, handle COD (Cash on Delivery) payments, and receive real-time webhook notifications for your e-commerce platform in Nepal.

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
    - [Branches](#branches)
    - [Shipping Rates](#shipping-rates)
    - [Create Order](#create-order)
    - [Get Order Details](#get-order-details)
    - [Order Comments](#order-comments)
    - [Tracking](#tracking)
    - [Returns &amp; Exchanges](#returns--exchanges)
    - [Tickets](#tickets)
    - [Staff](#staff)
- [Webhooks](#webhooks)
    - [Event Dispatcher](#event-dispatcher)
    - [Laravel](#laravel)
    - [Idempotency](#idempotency)
- [Error Handling](#error-handling)
- [API Limits](#api-limits)
- [Testing](#testing)
- [Code Style](#code-style)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Credits](#credits)
- [License](#license)

Features
--------

[](#features)

- **Shipment Management** - Create, find, return, exchange, and redirect orders
- **Order Tracking** - Status history and bulk status checks
- **Rate Calculation** - Delivery charges for 4 delivery types (Door2Door, Branch2Door, Door2Branch, Branch2Branch)
- **Branch Listing** - Get all NCM branches with contact details and covered areas
- **COD Support** - Cash on delivery charge management and COD transfer tickets
- **Webhook Integration** - Parse incoming webhooks with typed resources and event dispatcher
- **Support Tickets** - Create and manage vendor support tickets
- **Staff Management** - List and search vendor staff members
- **Type-Safe** - Immutable resource objects with readonly properties
- **Well Tested** - Comprehensive test suite with mocked HTTP responses
- **PSR-12 Compliant** - Enforced via PHP-CS-Fixer

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

[](#requirements)

- PHP 8.1+
- Guzzle 7.0+

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

[](#installation)

```
composer require pralhadstha/nepal-can-php-sdk
```

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

[](#configuration)

```
use OmniCargo\NepalCan\Client;
use OmniCargo\NepalCan\Config;

// Sandbox environment (default)
$client = new Client('your-api-token');

// Production environment
$client = new Client('your-api-token', Config::BASE_URL_PRODUCTION);
```

> **Note:** Request your API token from NCM's IT Admin. Sandbox and production environments use separate tokens.

Usage
-----

[](#usage)

### Branches

[](#branches)

```
$branches = $client->branches->list();

foreach ($branches as $branch) {
    echo $branch->name;
    echo $branch->district;
}
```

### Shipping Rates

[](#shipping-rates)

```
use OmniCargo\NepalCan\Services\RateService;

$rate = $client->rates->calculate('TINKUNE', 'BIRATNAGAR', RateService::TYPE_PICKUP_COLLECT);

echo $rate->charge;
```

Available delivery types:

- `RateService::TYPE_PICKUP_COLLECT` - Door2Door (NCM pickup &amp; delivery)
- `RateService::TYPE_SEND` - Branch2Door (Sender drops at branch, NCM delivers)
- `RateService::TYPE_D2B` - Door2Branch (NCM picks, customer collects at branch)
- `RateService::TYPE_B2B` - Branch2Branch (Sender drops at branch, customer collects)

### Create Order

[](#create-order)

```
$order = $client->shipments->create([
    'name' => 'John Doe',
    'phone' => '9847023226',
    'cod_charge' => '2200',
    'address' => 'Byas Pokhari',
    'fbranch' => 'TINKUNE',
    'branch' => 'BIRATNAGAR',
    'package' => 'Jeans Pant',
    'vref_id' => 'VREF234',
    'instruction' => 'Handle with care',
    'delivery_type' => 'Branch2Door',
    'weight' => '2',
]);

echo $order->orderId;
```

### Get Order Details

[](#get-order-details)

```
$order = $client->shipments->find(134);

echo $order->codCharge;
echo $order->deliveryCharge;
echo $order->lastDeliveryStatus;
echo $order->paymentStatus;
```

### Order Comments

[](#order-comments)

```
// Get comments for an order
$comments = $client->shipments->getComments(134);

foreach ($comments as $comment) {
    echo $comment->comments;
    echo $comment->addedBy;
}

// Get last 25 bulk comments
$comments = $client->shipments->getBulkComments();

// Add a comment
$client->shipments->addComment(1234567, 'Test comment from api');
```

### Tracking

[](#tracking)

```
// Get status history for an order
$statuses = $client->tracking->getStatusHistory(134);

foreach ($statuses as $status) {
    echo $status->status;
    echo $status->addedTime;
}

// Track by tracking ID
$tracking = $client->tracking->track('8D634706B3394C3');

echo $tracking->trackId;
echo $tracking->lastDeliveryStatus;
echo $tracking->receiver;
echo $tracking->destination;

foreach ($tracking->statusHistory as $status) {
    echo $status; // "Pickup Order Created - 2026-03-23 04:43 AM"
}

// Bulk status check
$result = $client->tracking->getBulkStatuses([4041, 3855, 4032]);

// $result['result'] => ['4041' => 'Pickup Order Created', ...]
// $result['errors'] => [4042, ...] (invalid order IDs)
```

### Returns &amp; Exchanges

[](#returns--exchanges)

```
// Return an order
$client->shipments->returnOrder(4041, 'Customer refused the delivery');

// Create exchange order
$response = $client->shipments->createExchange(4041);
// $response['cust_order'] => new delivery order ID
// $response['ven_order'] => return order ID

// Redirect an order
$client->shipments->redirect(4041, [
    'name' => 'Jane Doe',
    'phone' => '9800000000',
    'address' => 'New Address',
]);
```

### Tickets

[](#tickets)

```
use OmniCargo\NepalCan\Services\TicketService;

// Create a general ticket
$ticket = $client->tickets->create(TicketService::TYPE_GENERAL, 'Please arrange delivery at the earliest');

echo $ticket->ticketId;

// Create COD transfer ticket
$ticket = $client->tickets->createCodTransfer('Nepal Bank Limited', 'John Doe', '1234567890');

// Close a ticket
$client->tickets->close(123);
```

Available ticket types: `General`, `Order Processing`, `Return`, `Pickup`

### Staff

[](#staff)

```
$result = $client->staff->list(search: 'Ram', page: 1, pageSize: 20);

echo $result['count'];

foreach ($result['results'] as $staff) {
    echo $staff->name;
    echo $staff->email;
    echo $staff->phone;
}
```

Webhooks
--------

[](#webhooks)

NCM sends HTTP POST requests to your configured webhook URL when order status changes occur. This SDK provides typed parsing via `$client->webhooks->parse()`, User-Agent validation via `$client->webhooks->isValidUserAgent()`, and an event dispatcher for clean webhook handling.

### Event Dispatcher

[](#event-dispatcher)

Use the `EventDispatcher` to route webhook events to handler classes instead of if/else chains:

```
use OmniCargo\NepalCan\Webhooks\EventDispatcher;
use OmniCargo\NepalCan\Webhooks\WebhookEvent;
use OmniCargo\NepalCan\Webhooks\WebhookHandlerInterface;
use OmniCargo\NepalCan\Resources\Webhook;

// Create a handler
class DeliveryCompletedHandler implements WebhookHandlerInterface
{
    public function handle(Webhook $webhook): void
    {
        // Update order status in your system
    }
}

// Register handlers and dispatch
$dispatcher = new EventDispatcher();
$dispatcher
    ->subscribe(WebhookEvent::DELIVERY_COMPLETED, new DeliveryCompletedHandler())
    ->subscribe(WebhookEvent::ORDER_DISPATCHED, new OrderDispatchedHandler());

$webhook = $client->webhooks->parse($payload);
$dispatcher->dispatch($webhook);
```

### Laravel

[](#laravel)

For Laravel applications, use the official Laravel wrapper which provides service provider, facade, config publishing, and artisan commands out of the box:

**[pralhadstha/nepalcan-laravel](https://github.com/pralhadstha/nepalcan-laravel)** - Official Laravel wrapper for Nepal Can Move SDK

```
composer require pralhadstha/nepalcan-laravel
```

If you prefer using the SDK directly without the Laravel wrapper, you can still use this package in any PHP application including Laravel.

Supported webhook events:

- `WebhookEvent::PICKUP_COMPLETED` - Order picked up
- `WebhookEvent::SENT_FOR_DELIVERY` - Order sent for delivery
- `WebhookEvent::ORDER_DISPATCHED` - Order dispatched from origin branch
- `WebhookEvent::ORDER_ARRIVED` - Order arrived at destination branch
- `WebhookEvent::DELIVERY_COMPLETED` - Order delivered

### Idempotency

[](#idempotency)

NCM may send duplicate webhook notifications. Your application should handle this by tracking processed webhooks to avoid processing the same event twice:

```
class DeliveryCompletedHandler implements WebhookHandlerInterface
{
    public function handle(Webhook $webhook): void
    {
        // Create a unique key from the webhook data
        $idempotencyKey = $webhook->orderId . ':' . $webhook->event . ':' . $webhook->timestamp;

        // Skip if already processed
        if (ProcessedWebhook::where('idempotency_key', $idempotencyKey)->exists()) {
            return;
        }

        // Process the webhook
        Order::where('ncm_order_id', $webhook->orderId)
            ->update(['status' => $webhook->status]);

        // Mark as processed
        ProcessedWebhook::create(['idempotency_key' => $idempotencyKey]);
    }
}
```

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

[](#error-handling)

```
use OmniCargo\NepalCan\Exceptions\ApiException;
use OmniCargo\NepalCan\Exceptions\AuthenticationException;
use OmniCargo\NepalCan\Exceptions\ValidationException;
use OmniCargo\NepalCan\Exceptions\NotFoundException;

try {
    $order = $client->shipments->find(99999);
} catch (AuthenticationException $e) {
    // Invalid or missing API token (401)
} catch (ValidationException $e) {
    // Invalid parameters (400)
    $errors = $e->getErrors();
} catch (NotFoundException $e) {
    // Order not found (404)
} catch (ApiException $e) {
    // Other API errors
    $statusCode = $e->getStatusCode();
    $errorBody = $e->getErrorBody();
}
```

API Limits
----------

[](#api-limits)

- Order Creation: 1,000 per day
- Order View (Detail, Comments, Status): 20,000 per day

Testing
-------

[](#testing)

Run the test suite:

```
vendor/bin/phpunit
```

Code Style
----------

[](#code-style)

This project follows PSR-12 coding standards enforced via [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer).

```
# Check for style violations
composer cs-check

# Auto-fix style violations
composer cs-fix
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

Credits
-------

[](#credits)

- [Pralhad Kumar Shrestha](https://github.com/pralhadstha)
- [Nepal Can Move (NCM)](https://nepalcanmove.com) - Shipping &amp; Courier API Provider

License
-------

[](#license)

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

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance83

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity42

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

87d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2d46fb8b473d604d2f5eb4e27451ef88b44e10a430c0a0ce89b4e501fcfe95b2?d=identicon)[pralhad](/maintainers/pralhad)

---

Top Contributors

[![pralhadstha](https://avatars.githubusercontent.com/u/6309194?v=4)](https://github.com/pralhadstha "pralhadstha (8 commits)")

---

Tags

courier-apiecommercelogisticsncmnepal-can-movephp-librarysdk-phpshippingtrackingwebhooksGuzzletrackingwebhookecommerceapi clientphp-sdkshippingdeliverycourierlogisticsnepalnepal can movecodncmcash-on-delivery

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/pralhadstha-nepal-can-php-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/pralhadstha-nepal-can-php-sdk/health.svg)](https://phpackages.com/packages/pralhadstha-nepal-can-php-sdk)
```

###  Alternatives

[jlevers/selling-partner-api

PHP client for Amazon's Selling Partner API

4335.4M2](/packages/jlevers-selling-partner-api)[sunchayn/nimbus

A Laravel package providing an in-browser API client with automatic schema generation, live validation, and built-in authentication with a touch of Laravel-tailored magic for effortless API testing.

32837.0k](/packages/sunchayn-nimbus)

PHPackages © 2026

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