PHPackages                             hadimazalan/n9pay-laravel - 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. hadimazalan/n9pay-laravel

ActiveLibrary[Payment Processing](/categories/payments)

hadimazalan/n9pay-laravel
=========================

Laravel SDK and webhook integration for the N9Pay Payment Gateway API (v1.3).

v1.0.0(yesterday)00MITPHPPHP ^8.2

Since Jun 8Pushed yesterdayCompare

[ Source](https://github.com/hadimazalan/n9pay-laravel)[ Packagist](https://packagist.org/packages/hadimazalan/n9pay-laravel)[ RSS](/packages/hadimazalan-n9pay-laravel/feed)WikiDiscussions main Synced yesterday

READMEChangelogDependencies (5)Versions (2)Used By (0)

N9Pay Laravel
=============

[](#n9pay-laravel)

Laravel SDK and webhook integration for the [N9Pay Payment Gateway](https://apigate.n9pay.ns.gov.my) API (v1.3).

This package provides:

- HTTP client to create payment links and requery payment status
- Webhook signature verification (documented HMAC + legacy fallback)
- Optional webhook route that dispatches Laravel events
- DTOs for requests, responses, and normalized payment data

Your application owns order/payment persistence — listen to events and update your models.

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

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, or 12

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

[](#installation)

```
composer require hadimazalan/n9pay-laravel
```

Publish the configuration:

```
php artisan vendor:publish --tag=n9pay-config
```

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

[](#configuration)

Add these variables to your `.env`:

```
N9PAY_API_KEY=your-bearer-token
N9PAY_SIGNATURE_KEY=your-webhook-hmac-key
N9PAY_MODE=live
N9PAY_URL=https://apigate.n9pay.ns.gov.my/api
N9PAY_TEST_URL=https://stg-apigate.n9pay.ns.gov.my/api
N9PAY_WEBHOOK_ENABLED=true
N9PAY_WEBHOOK_ROUTE=webhook/n9pay
```

VariableDescription`N9PAY_API_KEY`Bearer token for outbound API requests`N9PAY_SIGNATURE_KEY`HMAC key for verifying inbound webhooks`N9PAY_MODE``live` or `test` — selects API base URL`N9PAY_URL`Live API base URL`N9PAY_TEST_URL`Sandbox API base URL`N9PAY_WEBHOOK_ENABLED`Register the webhook route (default: `true`)`N9PAY_WEBHOOK_ROUTE`Webhook path (default: `webhook/n9pay`)Disable the built-in webhook route and handle verification yourself:

```
// config/n9pay.php
'webhook' => [
    'enabled' => false,
],
```

Payment Flow
------------

[](#payment-flow)

 ```
sequenceDiagram
    participant App as Your App
    participant Pkg as n9pay-laravel
    participant N9 as N9Pay API
    participant Payer

    App->>Pkg: createPaymentLink()
    Pkg->>N9: POST /payment-links
    N9-->>Pkg: payment_url, _id
    Pkg-->>App: PaymentLinkResult
    App->>Payer: Redirect to payment_url
    Payer->>N9: Complete payment
    N9->>Pkg: POST /webhook/n9pay
    Pkg->>App: PaymentSucceeded event
    App->>App: Mark order paid
```

      Loading ### 1. Create a payment link

[](#1-create-a-payment-link)

```
use Hadimazalan\N9Pay\Data\CreatePaymentLinkData;
use Hadimazalan\N9Pay\Facades\N9Pay;

$result = N9Pay::createPaymentLink(new CreatePaymentLinkData(
    amount: 10.00,
    reference: $order->id,           // echoed back as payment_link_reference in webhook
    redirectUrl: route('orders.return', $order),
    eventUrl: route('n9pay.webhook'), // or url('/webhook/n9pay')
    email: $order->customer_email,
    title: 'Order #'.$order->number,
    description: 'Payment for order #'.$order->number,
    reference2: $order->invoice_number,
));

// Store the N9Pay payment link ID for requery
$order->update(['n9pay_payment_link_id' => $result->paymentLinkId]);

return redirect()->away($result->paymentUrl);
```

**Reference field mapping:** Pass your order/attempt ID as `reference`. N9Pay returns it in webhooks as `data.payment_link_reference`.

Amounts are in **MYR decimal** (e.g. `10.00` for RM 10.00), not cents.

### 2. Handle the payer return URL

[](#2-handle-the-payer-return-url)

After payment, N9Pay redirects the payer to your `redirect_url`. Optionally requery status:

```
use Hadimazalan\N9Pay\Facades\N9Pay;

$result = N9Pay::getPaymentLinkStatus($order->n9pay_payment_link_id);

if ($result->success && $result->status->value === 1) {
    $order->markAsPaid($result->data);
}
```

### 3. Listen to webhook events

[](#3-listen-to-webhook-events)

When `N9PAY_WEBHOOK_ENABLED=true`, the package registers:

```
POST /webhook/n9pay

```

Register listeners in your `EventServiceProvider` or `bootstrap/app.php`:

```
use Hadimazalan\N9Pay\Events\PaymentSucceeded;
use Hadimazalan\N9Pay\Events\PaymentFailed;
use Hadimazalan\N9Pay\Events\PaymentPending;

Event::listen(PaymentSucceeded::class, function (PaymentSucceeded $event) {
    $order = Order::find($event->payment->reference);
    $order?->markAsPaid($event->payment);
});

Event::listen(PaymentFailed::class, function (PaymentFailed $event) {
    $order = Order::find($event->payment->reference);
    $order?->markAsFailed($event->payment->message);
});

Event::listen(PaymentPending::class, function (PaymentPending $event) {
    $order = Order::find($event->payment->reference);
    $order?->markAsPending();
});
```

Each event carries:

- `$event->payload` — raw `WebhookPayload` DTO
- `$event->payment` — normalized `NormalizedPayment` DTO with `reference`, `status`, `message`, etc.

### 4. Manual webhook verification

[](#4-manual-webhook-verification)

If you disable the built-in route:

```
use Hadimazalan\N9Pay\Webhook\WebhookSignatureVerifier;
use Hadimazalan\N9Pay\Data\WebhookPayload;
use Hadimazalan\N9Pay\Data\NormalizedPayment;

public function handleWebhook(Request $request, WebhookSignatureVerifier $verifier)
{
    if (! $verifier->verify($request)) {
        abort(403);
    }

    $payload = WebhookPayload::fromArray($request->all());
    $payment = NormalizedPayment::fromWebhook($payload);

    // Handle $payment->status, $payment->reference, etc.
}
```

Sandbox Mode
------------

[](#sandbox-mode)

Set `N9PAY_MODE=test` to use the sandbox API base URL (`N9PAY_TEST_URL`).

API Reference
-------------

[](#api-reference)

Based on **Dokumentasi Payment Gateway N9PAY v1.3**.

OperationMethodEndpointCreate payment link`POST``{base_url}/payment-links`Requery status`GET``{base_url}/payment-links/{id}`Webhook notification`POST`Your `event_url`Authentication: `Authorization: Bearer {N9PAY_API_KEY}`

Webhook signature: HMAC-SHA256 verified against `N9PAY_SIGNATURE_KEY` (see `WebhookSignatureVerifier` for field order).

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

MIT

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

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

1d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/11846272?v=4)[Hadi Mazalan](/maintainers/hadimazalan)[@hadimazalan](https://github.com/hadimazalan)

---

Top Contributors

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

---

Tags

laravelpayment gatewayMalaysiafpxn9pay

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hadimazalan-n9pay-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/hadimazalan-n9pay-laravel/health.svg)](https://phpackages.com/packages/hadimazalan-n9pay-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[api-platform/laravel

API Platform support for Laravel

59156.3k10](/packages/api-platform-laravel)

PHPackages © 2026

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