PHPackages                             hamoi1/laravel-fib-payment - 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. hamoi1/laravel-fib-payment

ActiveLibrary[Payment Processing](/categories/payments)

hamoi1/laravel-fib-payment
==========================

A Laravel package for integrating with the First Iraqi Bank (FIB) payment gateway, providing seamless payment processing and management.

v1.0.0(3mo ago)31↓90%MITPHPPHP ^8.2

Since Apr 1Pushed 2mo agoCompare

[ Source](https://github.com/Hamoi1/laravel-fib-payment)[ Packagist](https://packagist.org/packages/hamoi1/laravel-fib-payment)[ RSS](/packages/hamoi1-laravel-fib-payment/feed)WikiDiscussions main Synced 4w ago

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

Laravel FIB Payment (First Iraqi Bank)
======================================

[](#laravel-fib-payment-first-iraqi-bank)

 [![Latest Version on Packagist](https://camo.githubusercontent.com/fe07408146b89e5bb70d704dc19e5d8f945c59d46481fb198c528a7895c033b9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f68616d6f69312f6c61726176656c2d6669622d7061796d656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hamoi1/laravel-fib-payment) [![Supported PHP Version](https://camo.githubusercontent.com/60a65f13c0247537655132cf12a5cca1e74280ec463e550e1c210460c9b839f6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f68616d6f69312f6c61726176656c2d6669622d7061796d656e742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hamoi1/laravel-fib-payment) [![Laravel Versions](https://camo.githubusercontent.com/9b1609f7a699cfe29a7786d394a7dad665317cbe79344f994ab975b86fecf9a4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31312e782532307c25323031322e782532307c25323031332e782d6f72616e67653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/hamoi1/laravel-fib-payment) [![License](https://camo.githubusercontent.com/d1e23d5c2738b507c5fd969eb0b743b8316c5fc67b6c354f243f740086521c6a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f68616d6f69312f6c61726176656c2d6669622d7061796d656e742e7376673f7374796c653d666c61742d737175617265)](LICENSE)

A modern, type-safe Laravel SDK for First Iraqi Bank (FIB) payment integration. This package provides a fluent API for payment creation, status tracking, cancellations, refunds, and webhook protection with full dependency injection support.

---

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

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Architecture Overview](#architecture-overview)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Error Handling](#error-handling)
- [Webhook Protection](#webhook-protection)
- [Testing](#testing)
- [Advanced Usage](#advanced-usage)
- [Troubleshooting](#troubleshooting)
- [License](#license)

---

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

[](#requirements)

- PHP 8.2+
- Laravel 11.x, 12.x, or 13.x
- FIB Payment Gateway credentials (client\_id and client\_secret)

---

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

[](#installation)

Install via Composer:

```
composer require hamoi1/laravel-fib-payment
```

The package will auto-register via Laravel's discovery. Publish the configuration file:

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

---

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

[](#configuration)

Add the following to your `.env` file:

```
# Required
FIB_CLIENT_ID=your-fib-client-id
FIB_CLIENT_SECRET=your-fib-client-secret
FIB_ENVIRONMENT=stage

# Optional
FIB_CALLBACK_URL=https://your-app.test/fib/webhook
FIB_CURRENCY=IQD
FIB_TIMEOUT=15
FIB_CONNECT_TIMEOUT=5
FIB_RETRY_TIMES=3
FIB_RETRY_DELAY=200
FIB_CACHE_DRIVER=
FIB_REFUNDABLE_FOR=P7D
FIB_ALLOWED_CALLBACK_IPS=
```

### Environment Variables Reference

[](#environment-variables-reference)

VariableRequiredDefaultDescription`FIB_CLIENT_ID`Yes-OAuth2 client ID from FIB`FIB_CLIENT_SECRET`Yes-OAuth2 client secret from FIB`FIB_ENVIRONMENT`Yes`stage`Environment: `stage`, or `prod``FIB_CALLBACK_URL`No`http://127.0.0.1:8000/fib/callback`Webhook endpoint for status updates`FIB_CURRENCY`No`IQD`Default currency: `IQD` or `USD``FIB_TIMEOUT`No`15`HTTP request timeout in seconds`FIB_CONNECT_TIMEOUT`No`5`Connection timeout in seconds`FIB_RETRY_TIMES`No`3`Number of retry attempts for failed requests`FIB_RETRY_DELAY`No`200`Delay between retries in milliseconds`FIB_CACHE_DRIVER`No-Cache driver for OAuth tokens (null = default)`FIB_REFUNDABLE_FOR`No`P7D`ISO 8601 duration for refund window`FIB_ALLOWED_CALLBACK_IPS`No-Comma-separated IPs for webhook security### Environments

[](#environments)

EnvironmentBase URLUse Case`stage``https://fib.stage.fib.iq`Testing with FIB staging apps`prod``https://fib.prod.fib.iq`Production transactions---

Architecture Overview
---------------------

[](#architecture-overview)

### Design Principles

[](#design-principles)

- **Dependency Injection**: No static methods - everything is injectable
- **Type Safety**: PHP 8.2+ features with `readonly` classes and strict types
- **DTO Pattern**: Data Transfer Objects for all API inputs/outputs
- **Enum Safety**: Enums for currencies, environments, statuses, and error reasons
- **Exception Hierarchy**: Specific exceptions for different error types
- **Token Caching**: Smart OAuth2 token caching with configurable drivers

Usage
-----

[](#usage)

### 1. Quick Start with Facade

[](#1-quick-start-with-facade)

The simplest way to use the package:

```
use Hamoi1\FibPayment\Facades\Fib;
use Hamoi1\FibPayment\Data\PaymentRequest;
use Hamoi1\FibPayment\Enums\Currency;

// Create a payment
$response = Fib::createPayment(new PaymentRequest(
    amount: 25000,
    currency: Currency::IQD,
    description: 'Order #1024',
    callbackUrl: route('fib.webhook'),
));

// Access response data
$paymentId = $response->paymentId;
$readableCode = $response->readableCode;
$qrCode = $response->qrCode;
```

### 2. Check Payment Status

[](#2-check-payment-status)

```
use Hamoi1\FibPayment\Facades\Fib;

$status = Fib::getPaymentStatus($paymentId);

// Helper methods
if ($status->isPaid()) {
    // Payment completed successfully
    $payerName = $status->paidBy?->name;
    $payerIban = $status->paidBy?->iban;
}

if ($status->isUnpaid()) {
    // Payment still pending
    $expiresAt = $status->validUntil;
}

if ($status->isDeclined()) {
    // Payment declined
    $reason = $status->decliningReason?->value;
}
```

### 3. Cancel or Refund Payments

[](#3-cancel-or-refund-payments)

```
// Cancel an unpaid payment
$cancelled = Fib::cancelPayment($paymentId); // bool

// Refund a paid payment (within refundable window)
$refunded = Fib::refundPayment($paymentId); // bool
```

### 4. Dependency Injection (Recommended)

[](#4-dependency-injection-recommended)

For better testability and cleaner architecture:

```
use Hamoi1\FibPayment\Contracts\FibClientInterface;
use Hamoi1\FibPayment\Data\PaymentRequest;

final class CheckoutController
{
    public function __construct(
        private readonly FibClientInterface $fib
    ) {}

    public function store(Request $request): JsonResponse
    {
        $payment = $this->fib->createPayment(new PaymentRequest(
            amount: $request->input('amount'),
            description: "Order #{$request->input('order_id')}",
        ));

        return response()->json([
            'payment_id' => $payment->paymentId,
            'code' => $payment->readableCode,
        ]);
    }
}
```

---

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

[](#error-handling)

The package throws specific exceptions for different error scenarios:

### Exception Hierarchy

[](#exception-hierarchy)

```
FibException (abstract base)
├── AuthenticationException (401/403)
├── RateLimitException (429)
└── PaymentFailedException (other HTTP errors)

```

### Handling Examples

[](#handling-examples)

```
use Hamoi1\FibPayment\Exceptions\AuthenticationException;
use Hamoi1\FibPayment\Exceptions\RateLimitException;
use Hamoi1\FibPayment\Exceptions\PaymentFailedException;
use Hamoi1\FibPayment\Exceptions\FibException;

try {
    $response = Fib::createPayment($request);
} catch (AuthenticationException $e) {
    // Invalid credentials or token expired
    // HTTP 401 or 403
    Log::error('FIB auth failed: ' . $e->getMessage());
} catch (RateLimitException $e) {
    // Too many requests
    // HTTP 429
    Log::warning('FIB rate limit hit');
    // Retry after delay
} catch (PaymentFailedException $e) {
    // Other API errors (500, 400, etc.)
    Log::error('FIB payment error: ' . $e->getMessage());
} catch (FibException $e) {
    // Catch-all for any package exception
    Log::error('FIB error: ' . $e->getMessage());
}
```

---

Webhook Protection
------------------

[](#webhook-protection)

### Using the Middleware

[](#using-the-middleware)

Protect your webhook endpoint from invalid requests:

```
use Hamoi1\FibPayment\Http\Middleware\VerifyFibWebhook;
use Illuminate\Support\Facades\Route;

Route::post('/fib/webhook', [PaymentController::class, 'handleWebhook'])
    ->middleware(VerifyFibWebhook::class)
    ->name('fib.webhook');
```

### Middleware Validation

[](#middleware-validation)

The `VerifyFibWebhook` middleware validates:

1. **Required Fields**: Ensures `paymentId` and `status` are present
2. **Valid Status**: Checks status is one of `PAID`, `UNPAID`, or `DECLINED`
3. **IP Allowlist**: If `FIB_ALLOWED_CALLBACK_IPS` is set, validates request IP

### Webhook Controller Example

[](#webhook-controller-example)

```
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Hamoi1\FibPayment\Enums\PaymentStatus;

final class PaymentController extends Controller
{
    public function handleWebhook(Request $request): JsonResponse
    {
        $paymentId = $request->input('paymentId');
        $status = PaymentStatus::from($request->input('status'));

        match ($status) {
            PaymentStatus::PAID => $this->markOrderAsPaid($paymentId),
            PaymentStatus::DECLINED => $this->markOrderAsDeclined($paymentId),
            PaymentStatus::UNPAID => null, // No action needed
        };

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

    private function markOrderAsPaid(string $paymentId): void
    {
        // Update your database
        Order::where('fib_payment_id', $paymentId)
            ->update(['status' => 'paid']);
    }

    private function markOrderAsDeclined(string $paymentId): void
    {
        Order::where('fib_payment_id', $paymentId)
            ->update(['status' => 'declined']);
    }
}
```

### IP Allowlist Configuration

[](#ip-allowlist-configuration)

Restrict webhooks to specific FIB server IPs:

```
FIB_ALLOWED_CALLBACK_IPS=203.0.113.10,203.0.113.11
```

---

Testing
-------

[](#testing)

### Mocking the Service

[](#mocking-the-service)

In your application tests, mock the interface:

```
use Hamoi1\FibPayment\Contracts\FibClientInterface;
use Hamoi1\FibPayment\Data\PaymentResponse;
use Hamoi1\FibPayment\Data\PaymentStatusInfo;
use Hamoi1\FibPayment\Enums\PaymentStatus;
use Illuminate\Support\Facades\App;
use Mockery;

it('processes successful payment', function () {
    // Create mock
    $mock = Mockery::mock(FibClientInterface::class);

    // Define expected behavior
    $mock->shouldReceive('createPayment')
        ->once()
        ->andReturn(new PaymentResponse(
            paymentId: 'pay-test-123',
            readableCode: 'ABC123',
            qrCode: 'base64-encoded-qr-data',
            validUntil: now()->addHour()->toIso8601String(),
            personalAppLink: 'https://fib.iq/personal/pay-test-123',
            businessAppLink: 'https://fib.iq/business/pay-test-123',
            corporateAppLink: 'https://fib.iq/corporate/pay-test-123',
        ));

    // Bind mock to container
    App::instance(FibClientInterface::class, $mock);

    // Test your controller/service
    $response = $this->postJson('/api/checkout', [
        'amount' => 1000,
    ]);

    $response->assertOk()
        ->assertJsonPath('payment_id', 'pay-test-123');
});

it('handles paid webhook', function () {
    $mock = Mockery::mock(FibClientInterface::class);

    $mock->shouldReceive('getPaymentStatus')
        ->with('pay-test-456')
        ->andReturn(new PaymentStatusInfo(
            paymentId: 'pay-test-456',
            status: PaymentStatus::PAID,
            validUntil: now()->addHour()->toIso8601String(),
            amount: new \Hamoi1\FibPayment\Data\MonetaryValue(1000, \Hamoi1\FibPayment\Enums\Currency::IQD),
        ));

    App::instance(FibClientInterface::class, $mock);

    $response = $this->postJson('/fib/webhook', [
        'paymentId' => 'pay-test-456',
        'status' => 'PAID',
    ]);

    $response->assertOk();
});
```

### Package Quality Commands

[](#package-quality-commands)

Run these commands to ensure code quality:

```
# Run all checks
composer check

# Individual commands
composer lint      # Laravel Pint code style check
composer lint:fix  # Auto-fix code style
composer analyse   # PHPStan static analysis
composer test      # Pest tests
```

---

Troubleshooting
---------------

[](#troubleshooting)

### Common Issues

[](#common-issues)

IssueSolution`Jwt issuer is not configured`Your client\_id isn't activated by FIB. Contact FIB support.`401 Unauthorized`Check client\_id and client\_secret in .env`403 Forbidden`Credentials may be valid but lack permissions`429 Too Many Requests`You're hitting rate limits. Implement exponential backoff.Token cache issuesRun `php artisan cache:clear`Config not loadingRun `php artisan config:clear`### Debug Endpoints

[](#debug-endpoints)

Add this to your routes for debugging:

```
Route::get('/fib/debug', function () {
    return [
        'environment' => config('fib.environment'),
        'client_id' => config('fib.client_id') ? '***' . substr(config('fib.client_id'), -4) : 'NOT SET',
        'client_secret_set' => ! empty(config('fib.client_secret')),
        'callback_url' => config('fib.callback_url'),
        'base_url' => \Hamoi1\FibPayment\Enums\FibEnvironment::from(config('fib.environment'))->baseUrl(),
    ];
});
```

---

License
-------

[](#license)

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

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance83

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

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

91d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/92602172?v=4)[Muhammad Esmael](/maintainers/Hamoi1)[@Hamoi1](https://github.com/Hamoi1)

---

Top Contributors

[![Hamoi1](https://avatars.githubusercontent.com/u/92602172?v=4)](https://github.com/Hamoi1 "Hamoi1 (7 commits)")

---

Tags

fibfirst-iraqi-bankgatewayintegrationiqdiraqlaravelpackagepaymentpayment-gatewaypayment-integrationphplaravelpackagepaymentgatewayintegrationFIBiraqfirst-iraqi-bankiqd

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/hamoi1-laravel-fib-payment/health.svg)

```
[![Health](https://phpackages.com/badges/hamoi1-laravel-fib-payment/health.svg)](https://phpackages.com/packages/hamoi1-laravel-fib-payment)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M341](/packages/psalm-plugin-laravel)[laravel/pulse

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

1.7k15.1M128](/packages/laravel-pulse)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k55.4M7.9k](/packages/larastan-larastan)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M125](/packages/roots-acorn)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77022.3M133](/packages/laravel-mcp)[propaganistas/laravel-disposable-email

Disposable email validator

6023.0M7](/packages/propaganistas-laravel-disposable-email)

PHPackages © 2026

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