PHPackages                             ht3aa/zain-cash - 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. ht3aa/zain-cash

ActiveLibrary[Payment Processing](/categories/payments)

ht3aa/zain-cash
===============

This is a laravel package that provide all the functionality that you need to integrate your app with zain cash gateway api

v0.0.1(4mo ago)00[4 PRs](https://github.com/ht3aa/zain-cash/pulls)MITPHPPHP ^8.4CI passing

Since Jan 6Pushed 1mo agoCompare

[ Source](https://github.com/ht3aa/zain-cash)[ Packagist](https://packagist.org/packages/ht3aa/zain-cash)[ Docs](https://github.com/ht3aa/zain-cash)[ GitHub Sponsors](https://github.com/ht3aa)[ RSS](/packages/ht3aa-zain-cash/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (14)Versions (6)Used By (0)

ZainCash Integration For Laravel
================================

[](#zaincash-integration-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/000f54958246e9e0421ab4143d6a040fecfa021f6ef8d2157f0490aa64906482/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f68743361612f7a61696e2d636173682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ht3aa/zain-cash)[![Total Downloads](https://camo.githubusercontent.com/20a7f9151d0a970bc6736712e5b23fead4a7b73082793d7459f5f2dd9ca8bc3c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f68743361612f7a61696e2d636173682e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ht3aa/zain-cash)

A comprehensive Laravel package for integrating ZainCash payment gateway into your application. This package provides a simple and elegant way to handle payment transactions, webhooks, and transaction tracking with ZainCash.

[![ZainCash Delivery Integration For Laravel](image.png)](image.png)

Features
--------

[](#features)

- ✅ Easy integration with ZainCash payment gateway
- ✅ Automatic transaction tracking and management
- ✅ Polymorphic relationships - link transactions to any order model
- ✅ Webhook handling for payment status updates
- ✅ Check transaction status with ZainCash API
- ✅ Support for both production and test environments
- ✅ JWT token generation and validation
- ✅ Database transaction logging
- ✅ Custom webhook URL support
- ✅ Built-in error handling and logging

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

[](#installation)

You can install the package via composer:

```
composer require ht3aa/zain-cash
```

Publish the configuration file:

```
php artisan vendor:publish --tag="zain-cash-config"
```

Publish and run the migrations:

```
php artisan vendor:publish --tag="zain-cash-migrations"
php artisan migrate
```

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

[](#configuration)

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

```
ZAIN_CASH_IS_PRODUCTION=false
ZAIN_CASH_MERCHANT_ID=your_merchant_id
ZAIN_CASH_MERCHANT_SECRET=your_merchant_secret
ZAIN_CASH_MSISDN=your_msisdn
ZAIN_CASH_WEBHOOK_URL="${APP_URL}/api/zain-cash/webhook"
ZAIN_CASH_CUSTOM_WEBHOOK_URL=
```

### Configuration Options

[](#configuration-options)

- `ZAIN_CASH_IS_PRODUCTION`: Set to `true` for production environment, `false` for testing
- `ZAIN_CASH_MERCHANT_ID`: Your ZainCash merchant ID
- `ZAIN_CASH_MERCHANT_SECRET`: Your ZainCash merchant secret key
- `ZAIN_CASH_MSISDN`: Your registered mobile number with ZainCash
- `ZAIN_CASH_WEBHOOK_URL`: The URL where ZainCash will send payment status updates
- `ZAIN_CASH_CUSTOM_WEBHOOK_URL`: (Optional) Custom URL to receive payment notifications in your app

Usage
-----

[](#usage)

### Creating a Payment Transaction

[](#creating-a-payment-transaction)

To initiate a payment transaction, create a new `ZainCashTransaction` instance and pass it to the `initiateTransaction` method.

#### Basic Usage (Simple Order ID)

[](#basic-usage-simple-order-id)

```
use Ht3aa\ZainCash\Models\ZainCashTransaction;
use Ht3aa\ZainCash\Facades\ZainCash;

// Create a new transaction with simple order ID
$transaction = ZainCashTransaction::create([
    'amount' => 10000, // Amount in IQD (e.g., 10000 IQD)
    'service_type' => 'Product Purchase',
    'order_id' => 'ORDER-' . uniqid(),
    'redirect_url' => route('payment.callback'),
]);

// Initiate the transaction with ZainCash
$transaction = ZainCash::initiateTransaction($transaction);
$transaction->save();

// Redirect user to payment page
return redirect($transaction->payment_redirect_url);
```

#### Advanced Usage (Polymorphic Relationship)

[](#advanced-usage-polymorphic-relationship)

Link the transaction directly to your Order model using polymorphic relationships:

```
use App\Models\Order;
use Ht3aa\ZainCash\Models\ZainCashTransaction;
use Ht3aa\ZainCash\Facades\ZainCash;

// Create an order first
$order = Order::create([
    'user_id' => auth()->id(),
    'total' => 10000,
    // ... other order fields
]);

// Create a transaction linked to the order
$transaction = ZainCashTransaction::create([
    'amount' => $order->total,
    'service_type' => 'Product Purchase',
    'order_id' => $order->id,
    'order_type' => Order::class,
    'redirect_url' => route('payment.callback'),
]);

// Initiate the transaction with ZainCash
$transaction = ZainCash::initiateTransaction($transaction);
$transaction->save();

// Redirect user to payment page
return redirect($transaction->payment_redirect_url);
```

Now you can access the order from the transaction:

```
$transaction = ZainCashTransaction::find(1);
$order = $transaction->order; // Returns the Order model instance
```

### Transaction Model

[](#transaction-model)

The `ZainCashTransaction` model includes the following attributes:

- `amount`: Payment amount in IQD
- `service_type`: Description of the service/product
- `order_id`: Unique order identifier (can be string or model ID for polymorphic relationship)
- `order_type`: Model class name for polymorphic relationship (e.g., `App\Models\Order`)
- `redirect_url`: URL to redirect after payment
- `token`: JWT token for the transaction
- `iat`: Token issued at timestamp
- `exp`: Token expiration timestamp
- `zain_cash_response`: Full response from ZainCash API
- `status`: Transaction status (pending, completed, failed, etc.)
- `payment_redirect_url`: URL to redirect user for payment
- `transaction_id`: ZainCash transaction ID

#### Polymorphic Relationship

[](#polymorphic-relationship)

The model includes a polymorphic `order()` relationship that allows you to link transactions to any order model:

```
// Access the related order
$transaction = ZainCashTransaction::find(1);
$order = $transaction->order;

// Define inverse relationship in your Order model
class Order extends Model
{
    public function zainCashTransactions()
    {
        return $this->morphMany(ZainCashTransaction::class, 'order');
    }
}
```

### Webhook Handling

[](#webhook-handling)

The package automatically registers a webhook route at `/api/zain-cash/webhook` to handle payment status updates from ZainCash.

When a payment is completed, ZainCash will send a callback to this URL with the transaction status. The webhook controller will:

1. Decode the JWT token from ZainCash
2. Update the transaction status in your database
3. (Optional) Forward the notification to your custom webhook URL

### Custom Webhook Notifications

[](#custom-webhook-notifications)

If you want to receive notifications in your own application when a payment status is updated, set the `ZAIN_CASH_CUSTOM_WEBHOOK_URL` in your `.env` file:

```
ZAIN_CASH_CUSTOM_WEBHOOK_URL=https://yourapp.com/api/payment-notification
```

The package will POST to this URL with the following payload:

```
{
    "zain_cash_transaction_id": 123
}
```

You can then create your own controller to handle this:

```
use Ht3aa\ZainCash\Models\ZainCashTransaction;

public function handlePaymentNotification(Request $request)
{
    $transaction = ZainCashTransaction::find($request->zain_cash_transaction_id);

    if ($transaction->status === 'success') {
        // Payment successful - update your order, send confirmation email, etc.
    } else {
        // Payment failed - handle accordingly
    }
}
```

### Checking Transaction Status

[](#checking-transaction-status)

#### From Local Database

[](#from-local-database)

You can check the status of a transaction from your local database:

```
use Ht3aa\ZainCash\Models\ZainCashTransaction;

$transaction = ZainCashTransaction::where('transaction_id', 'TRANS-123')->first();

if ($transaction->status === 'success') {
    // Payment completed
} elseif ($transaction->status === 'pending') {
    // Payment still pending
} else {
    // Payment failed or cancelled
}
```

#### From ZainCash API

[](#from-zaincash-api)

You can also verify the transaction status directly from ZainCash API:

```
use Ht3aa\ZainCash\Facades\ZainCash;

// Check transaction status from ZainCash
$response = ZainCash::checkTransaction('TRANS-123');

// Response includes:
// - id: Transaction ID
// - status: Current status
// - amount: Transaction amount
// - orderId: Your order ID
// ... other transaction details
```

This is useful for:

- Verifying payment status before fulfilling orders
- Reconciling payments with ZainCash
- Handling edge cases where webhook might have failed

### Using the Facade

[](#using-the-facade)

The package provides a facade for easy access to all methods:

```
use Ht3aa\ZainCash\Facades\ZainCash;

// Initiate a transaction
$transaction = ZainCash::initiateTransaction($zainCashTransaction);

// Check transaction status
$response = ZainCash::checkTransaction('transaction_id');
```

Complete Example Flow
---------------------

[](#complete-example-flow)

Here's a complete example of a payment flow with polymorphic relationships:

```
use App\Models\Order;
use Ht3aa\ZainCash\Models\ZainCashTransaction;
use Ht3aa\ZainCash\Facades\ZainCash;
use Illuminate\Support\Facades\Mail;

// 1. Create order and initiate payment
public function initiatePayment(Request $request)
{
    // Create the order
    $order = Order::create([
        'user_id' => auth()->id(),
        'total' => $request->amount,
        'status' => 'pending',
    ]);

    // Create transaction linked to order
    $transaction = ZainCashTransaction::create([
        'amount' => $order->total,
        'service_type' => 'Product Purchase',
        'order_id' => $order->id,
        'order_type' => Order::class,
        'redirect_url' => route('payment.callback'),
    ]);

    // Initiate with ZainCash
    $transaction = ZainCash::initiateTransaction($transaction);
    $transaction->save();

    // Redirect user to payment page
    return redirect($transaction->payment_redirect_url);
}

// 2. Handle callback (optional - webhook handles status updates automatically)
public function paymentCallback(Request $request)
{
    return view('payment.processing', [
        'message' => 'Processing your payment...'
    ]);
}

// 3. Handle custom webhook notification
public function handlePaymentNotification(Request $request)
{
    $transaction = ZainCashTransaction::with('order')
        ->find($request->zain_cash_transaction_id);

    if ($transaction->status === 'success') {
        // Update order status using the polymorphic relationship
        $order = $transaction->order;
        $order->update([
            'status' => 'paid',
            'payment_status' => 'completed'
        ]);

        // Send confirmation email
        Mail::to($order->user)->send(new PaymentConfirmation($transaction));

        // Optional: Verify with ZainCash API
        $verification = ZainCash::checkTransaction($transaction->transaction_id);

        if ($verification['status'] === 'success') {
            // Process order fulfillment
        }
    } else {
        // Handle failed payment
        $transaction->order->update(['status' => 'payment_failed']);
    }

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

// 4. Check payment status (e.g., from admin panel)
public function checkPaymentStatus($transactionId)
{
    $transaction = ZainCashTransaction::where('transaction_id', $transactionId)->first();

    // Verify with ZainCash API
    $response = ZainCash::checkTransaction($transactionId);

    // Update local status if different
    if ($response['status'] !== $transaction->status) {
        $transaction->update(['status' => $response['status']]);
    }

    return response()->json([
        'local_status' => $transaction->status,
        'zaincash_status' => $response['status'],
        'order' => $transaction->order
    ]);
}
```

### Setting Up Your Order Model

[](#setting-up-your-order-model)

To use polymorphic relationships, add the inverse relationship to your Order model:

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Ht3aa\ZainCash\Models\ZainCashTransaction;

class Order extends Model
{
    protected $fillable = ['user_id', 'total', 'status', 'payment_status'];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function zainCashTransactions()
    {
        return $this->morphMany(ZainCashTransaction::class, 'order');
    }

    public function latestZainCashTransaction()
    {
        return $this->morphOne(ZainCashTransaction::class, 'order')->latestOfMany();
    }
}
```

Now you can easily access transactions from orders:

```
$order = Order::find(1);

// Get all ZainCash transactions for this order
$transactions = $order->zainCashTransactions;

// Get the latest transaction
$latestTransaction = $order->latestZainCashTransaction;

// Check payment status
if ($latestTransaction->status === 'success') {
    // Order is paid
}
```

Testing
-------

[](#testing)

The package includes test credentials for the ZainCash sandbox environment. Make sure `ZAIN_CASH_IS_PRODUCTION` is set to `false` when testing.

Changelog
---------

[](#changelog)

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

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

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Hasan Tahseen](https://github.com/ht3aa)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance85

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 84.6% 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

125d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5960d0e04603296e1d859501a366241098d1a46c95f0bfc47f0541871b08cfbb?d=identicon)[ht3aa](/maintainers/ht3aa)

---

Top Contributors

[![ht3aa](https://avatars.githubusercontent.com/u/96876427?v=4)](https://github.com/ht3aa "ht3aa (11 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

laravelZain Cashht3aa

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ht3aa-zain-cash/health.svg)

```
[![Health](https://phpackages.com/badges/ht3aa-zain-cash/health.svg)](https://phpackages.com/packages/ht3aa-zain-cash)
```

###  Alternatives

[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[danestves/laravel-polar

A package to easily integrate your Laravel application with Polar.sh

7812.3k](/packages/danestves-laravel-polar)[musahmusah/laravel-multipayment-gateways

A Laravel Package that makes implementation of multiple payment Gateways endpoints and webhooks seamless

852.2k1](/packages/musahmusah-laravel-multipayment-gateways)[creagia/laravel-redsys

Laravel Redsys Payments Gateway

2013.6k](/packages/creagia-laravel-redsys)

PHPackages © 2026

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