PHPackages                             aiarmada/jnt - 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. [API Development](/categories/api)
4. /
5. aiarmada/jnt

ActiveLibrary[API Development](/categories/api)

aiarmada/jnt
============

J&amp;T Express Malaysia API Integration Package

v0.1.34(1mo ago)01012MITPHPPHP ^8.4

Since May 21Pushed 3w agoCompare

[ Source](https://github.com/AIArmada/jnt)[ Packagist](https://packagist.org/packages/aiarmada/jnt)[ Docs](https://github.com/aiarmada/commerce)[ RSS](/packages/aiarmada-jnt/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (50)Versions (69)Used By (2)

J&amp;T Express for Laravel
===========================

[](#jt-express-for-laravel)

> Laravel 12 integration for [J&amp;T Express Malaysia](https://www.jtexpress.my/) Open API – orders, tracking, waybills, and real-time webhooks.

Why this package?
-----------------

[](#why-this-package)

- **Complete API coverage** – create orders, track parcels, print waybills, cancel orders, batch operations.
- **Clean API naming** – use `orderId` instead of `txlogisticId`, `trackingNumber` instead of `billCode`.
- **Type-safe enums** – `ExpressType::DOMESTIC` instead of magic strings like `'EZ'`.
- **First-class Laravel DX** – facades, fluent builders, data objects, events, Artisan commands.
- **Production ready** – PHP 8.4 / Laravel 12, PHPStan level 6, Pest test suite.
- **Webhooks included** – automatic signature verification and event dispatching.

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

[](#installation)

```
composer require aiarmada/jnt
```

Publish configuration and migrations:

```
php artisan vendor:publish --tag="jnt-config"
php artisan vendor:publish --tag="jnt-migrations"
php artisan migrate
```

### Environment Variables

[](#environment-variables)

```
JNT_ENVIRONMENT=testing  # or 'production'
JNT_CUSTOMER_CODE=your_customer_code
JNT_PASSWORD=your_password

# Production only (testing uses J&T's public sandbox credentials):
JNT_API_ACCOUNT=your_api_account
JNT_PRIVATE_KEY=your_private_key

# Optional
JNT_LOGGING_ENABLED=true
JNT_WEBHOOKS_ENABLED=true
```

> **Note:** When `JNT_ENVIRONMENT=testing`, the package automatically uses J&amp;T's official sandbox credentials. You only need `JNT_CUSTOMER_CODE` and `JNT_PASSWORD`.

---

Usage
-----

[](#usage)

### Create an Order

[](#create-an-order)

```
use AIArmada\Jnt\Facades\JntExpress;
use AIArmada\Jnt\Data\{AddressData, ItemData, PackageInfoData};
use AIArmada\Jnt\Enums\{ExpressType, ServiceType, PaymentType, GoodsType};

$sender = new AddressData(
    name: 'John Sender',
    phone: '60123456789',
    address: 'No 32, Jalan Kempas 4',
    postCode: '81930',
    countryCode: 'MYS',
    state: 'Johor',
    city: 'Johor Bahru',
);

$receiver = new AddressData(
    name: 'Jane Receiver',
    phone: '60987654321',
    address: '4678, Laluan Sentang 35',
    postCode: '31000',
    countryCode: 'MYS',
    state: 'Perak',
    city: 'Batu Gajah',
);

$item = new ItemData(
    itemName: 'Basketball',
    quantity: 2,
    weight: 10,
    unitPrice: 50.00,
);

$packageInfo = new PackageInfoData(
    quantity: 1,
    weight: 10,
    declaredValue: 50,
    goodsType: GoodsType::PACKAGE,
);

$order = JntExpress::createOrderBuilder()
    ->orderId('ORDER-' . time())
    ->expressType(ExpressType::DOMESTIC)
    ->serviceType(ServiceType::DOOR_TO_DOOR)
    ->paymentType(PaymentType::PREPAID_POSTPAID)
    ->sender($sender)
    ->receiver($receiver)
    ->addItem($item)
    ->packageInfo($packageInfo)
    ->build();

$result = JntExpress::createOrderFromArray($order);

echo "Tracking: " . $result->trackingNumber;
```

### Track a Parcel

[](#track-a-parcel)

```
// By your order ID
$tracking = JntExpress::trackParcel(orderId: 'ORDER-123');

// Or by J&T tracking number
$tracking = JntExpress::trackParcel(trackingNumber: 'JT630002864925');

foreach ($tracking->details as $detail) {
    echo "{$detail->scanTime}: {$detail->description}\n";
}
```

### Cancel an Order

[](#cancel-an-order)

```
JntExpress::cancelOrder(
    orderId: 'ORDER-123',
    reason: 'Customer requested cancellation',
    trackingNumber: 'JT630002864925',
);
```

### Print Waybill

[](#print-waybill)

```
$label = JntExpress::printOrder(
    orderId: 'ORDER-123',
    trackingNumber: 'JT630002864925',
);

$pdfUrl = $label['urlContent'];
```

---

Enums
-----

[](#enums)

Type-safe enums prevent invalid values:

```
// Express Type
ExpressType::DOMESTIC   // Standard delivery
ExpressType::NEXT_DAY   // Express next day
ExpressType::FRESH      // Cold chain delivery

// Service Type
ServiceType::DOOR_TO_DOOR  // Pickup from sender
ServiceType::WALK_IN       // Drop-off at counter

// Payment Type
PaymentType::PREPAID_POSTPAID  // Prepaid by merchant
PaymentType::COLLECT_CASH      // Cash on delivery

// Goods Type
GoodsType::DOCUMENT  // Documents
GoodsType::PACKAGE   // Parcels
```

---

Webhooks
--------

[](#webhooks)

Receive real-time tracking updates from J&amp;T.

### Setup

[](#setup)

1. **Enable webhooks** in `.env`:

    ```
    JNT_WEBHOOKS_ENABLED=true
    ```
2. **Create a listener**:

    ```
    namespace App\Listeners;

    use AIArmada\Jnt\Events\TrackingStatusReceived;

    class UpdateOrderTracking
    {
        public function handle(TrackingStatusReceived $event): void
        {
            $order = Order::where('tracking_number', $event->trackingNumber)->first();

            $order?->update([
                'tracking_status' => $event->lastStatus,
                'tracking_time' => $event->scanTime,
            ]);
        }
    }
    ```
3. **Register the listener**:

    ```
    // EventServiceProvider.php
    protected $listen = [
        \AIArmada\Jnt\Events\TrackingStatusReceived::class => [
            \App\Listeners\UpdateOrderTracking::class,
        ],
    ];
    ```
4. **Configure J&amp;T Dashboard** with your webhook URL:

    ```
    https://yourdomain.com/webhooks/jnt/status

    ```

---

Artisan Commands
----------------

[](#artisan-commands)

```
# Check configuration
php artisan jnt:config:check

# Health check
php artisan jnt:health

# Track parcel
php artisan jnt:order:track ORDER-123

# Cancel order
php artisan jnt:order:cancel ORDER-123 --reason=out_of_stock

# Print waybill
php artisan jnt:order:print ORDER-123 --tracking-number=JT123456
```

---

Documentation
-------------

[](#documentation)

- [API Reference](docs/api-reference.md) – Complete method reference
- [Batch Operations](docs/batch-operations.md) – Process multiple orders efficiently
- [Webhooks](docs/webhooks.md) – Webhook integration guide
- [Testing Credentials](docs/testing-credentials.md) – Auto-configuration for sandbox

---

Property Name Mapping
---------------------

[](#property-name-mapping)

The package translates clean names to J&amp;T's API format automatically:

Your CodeJ&amp;T APIDescription`orderId``txlogisticId`Your order reference`trackingNumber``billCode`J&amp;T tracking number`state``prov`State/province`quantity``number`Item quantity`chargeableWeight``packageChargeWeight`Billable weight---

Testing
-------

[](#testing)

```
vendor/bin/pest tests/src/Jnt
```

---

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

[](#contributing)

1. Fork &amp; clone the repository
2. Install dependencies: `composer install`
3. Run tests: `vendor/bin/pest`
4. Format code: `vendor/bin/pint`

---

License
-------

[](#license)

Released under the MIT License. See [LICENSE](LICENSE) for details.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance94

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

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

Every ~3 days

Total

68

Last Release

36d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1634949?v=4)[Saiffil Fariz](/maintainers/sairiz)[@sairiz](https://github.com/sairiz)

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/aiarmada-jnt/health.svg)

```
[![Health](https://phpackages.com/badges/aiarmada-jnt/health.svg)](https://phpackages.com/packages/aiarmada-jnt)
```

###  Alternatives

[symfony/symfony

The Symfony PHP framework

31.4k87.2M2.2k](/packages/symfony-symfony)[symfony/framework-bundle

Provides a tight integration between Symfony components and the Symfony full-stack framework

3.6k251.7M11.6k](/packages/symfony-framework-bundle)[symfony/security-bundle

Provides a tight integration of the Security component into the Symfony full-stack framework

2.5k185.6M2.4k](/packages/symfony-security-bundle)[symfony/web-profiler-bundle

Provides a development tool that gives detailed information about the execution of any request

2.3k160.5M1.2k](/packages/symfony-web-profiler-bundle)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[wikimedia/parsoid

Parsoid, a bidirectional parser between wikitext and HTML5

187557.3k3](/packages/wikimedia-parsoid)

PHPackages © 2026

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