PHPackages                             achetibi/laravel-satim - 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. achetibi/laravel-satim

ActiveLibrary[Payment Processing](/categories/payments)

achetibi/laravel-satim
======================

Laravel package for integrating SATIM online payments.

v2.1.1(1w ago)15945MITPHPPHP ^8.3CI passing

Since Jun 28Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/achetibi/laravel-satim)[ Packagist](https://packagist.org/packages/achetibi/laravel-satim)[ Docs](https://github.com/achetibi/laravel-satim)[ RSS](/packages/achetibi-laravel-satim/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (8)Dependencies (70)Versions (11)Used By (0)

Laravel Satim
=============

[](#laravel-satim)

[![Latest Version on Packagist](https://camo.githubusercontent.com/6ac74a44aef559eff5a866a9a0fdd4aa6b80dc458596683a4e495115415e9ea5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f61636865746962692f6c61726176656c2d736174696d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/achetibi/laravel-satim)[![Total Downloads](https://camo.githubusercontent.com/2b11a6be2a6e59cb51dff5ad1e7205991c992a53f256e65582dc3a26137cf956/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f61636865746962692f6c61726176656c2d736174696d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/achetibi/laravel-satim)[![Tests](https://camo.githubusercontent.com/832023cac9cede76bc5d9585bedc7da7b5c460ab1db1de544c26cbe771b59c60/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f61636865746962692f6c61726176656c2d736174696d2f74657374732e796d6c3f6c6162656c3d7465737473)](https://github.com/achetibi/laravel-satim/actions)[![PHPStan](https://camo.githubusercontent.com/65c9bbcae389e4ca189f0239aa80ea655e986c4d7d4d586a15927056765c173f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](phpstan.neon)[![License](https://camo.githubusercontent.com/61cd402d3bcec4e94e1812def774a0284e7cacd7a585748d9b5c6cf1e03d64fb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f61636865746962692f6c61726176656c2d736174696d)](LICENSE.md)

**Laravel Satim** is a clean, strongly-typed Laravel package for **SATIM online payments in Algeria** — the interbank e-payment gateway behind **CIB** and **Edahabia** card payments (paiement en ligne / الدفع الإلكتروني). It covers the full transaction lifecycle — registration, confirmation, status and refund — behind pure request DTOs, immutable response objects, typed value objects and a real exception hierarchy.

> Keywords: SATIM Laravel, CIB Laravel, e-paiement Algérie, Algerian payment gateway, carte CIB / Edahabia, DZ.

---

🚀 Features
----------

[](#-features)

- Simple configuration via `.env`
- Register / Confirm / **Status** / Refund operations
- **Immutable, typed responses** — each response owns its own data
- **Typed value objects** for nested response structures (card auth info, merchant params…)
- **Real exception hierarchy** driven by the official SATIM error codes
- **Config-driven HTTP method** — POST by default, as recommended by SATIM
- Automatic retries for transport failures and 5xx responses
- Credentials injected into the HTTP client (requests stay pure data-transfer objects)
- Translations in **Arabic, English and French** with automatic fallback
- Analysed at **PHPStan level 10** and formatted with **Pint (PSR-12)**

---

📦 Requirements
--------------

[](#-requirements)

- PHP 8.3+
- Laravel 11, 12 or 13

📦 Installation
--------------

[](#-installation)

```
composer require achetibi/laravel-satim
```

---

⚙️ Configuration
----------------

[](#️-configuration)

Publish the config file:

```
php artisan vendor:publish --provider="LaravelSatim\SatimServiceProvider" --tag="satim-config"
```

Optionally publish the translations:

```
php artisan vendor:publish --provider="LaravelSatim\SatimServiceProvider" --tag="satim-lang"
```

Add the following variables to your `.env`:

```
SATIM_ENV=test
SATIM_USERNAME=your_username
SATIM_PASSWORD=your_password
SATIM_TERMINAL=your_terminal
SATIM_CURRENCY=DZD
SATIM_LANGUAGE=fr
```

Optional HTTP client settings (defaults shown):

```
# SATIM strongly recommends POST so credentials are never exposed in URLs/logs.
SATIM_HTTP_METHOD=POST
SATIM_TIMEOUT=30
SATIM_CONNECT_TIMEOUT=10
SATIM_RETRIES=2
SATIM_RETRY_DELAY=300
SATIM_SSL_VERIFY=true

# Optional request logging (endpoint/method/status only, never credentials)
SATIM_LOG=false
SATIM_LOG_CHANNEL=stack
```

Disable SSL verification in local development only. `SATIM_RETRIES` / `SATIM_RETRY_DELAY` control the number of automatic retries and the linear back-off delay (in milliseconds) for transport failures and 5xx responses.

Every configuration option is documented inline in [`config/satim.php`](config/satim.php).

---

🧠 Usage
-------

[](#-usage)

Resolve the gateway from the container via `SatimGatewayInterface`, or use the `Satim` facade — both share the same singleton instance.

### 1. Register a transaction

[](#1-register-a-transaction)

```
use LaravelSatim\Contracts\SatimGatewayInterface;
use LaravelSatim\Http\Requests\SatimRegisterRequest;

$response = app(SatimGatewayInterface::class)->register(new SatimRegisterRequest(
    orderNumber: 'ORD123456',    // alphanumeric, max 10 chars, unique per transaction
    amount: 1500.00,             // amount in DZD (dinars); converted to centimes internally
    returnUrl: route('payment.success'),
    udf1: 'ORD123456',           // required user-defined field
));

// Redirect the customer to the hosted payment page:
return redirect()->away($response->formUrl());

// Keep $response->orderId() to confirm the order later.
```

For merchants enabled for **bill payment**, pass the funding type indicator (sent by SATIM inside `jsonParams` as `fundingTypeIndicator`):

```
use LaravelSatim\Enums\FundingType;

new SatimRegisterRequest(
    orderNumber: 'ORD123456',
    amount: 1500.00,
    returnUrl: route('payment.success'),
    udf1: 'ORD123456',
    fundingType: FundingType::BILL_PAYMENT, // "CP" (or FundingType::BILL_PAYMENT_698 for "698")
);
```

`SatimRegisterRequest` also accepts the optional `udf2`–`udf5`, `failUrl`, `description`, `currency` and `language`arguments. `SatimRegisterResponse` exposes `successful()`, `errorCode()`, `errorMessage()`, `orderId()`, `formUrl()`and `raw()`.

### 2. Confirm a transaction

[](#2-confirm-a-transaction)

After the customer pays and is redirected back to your `returnUrl`, confirm the order. `mdOrder` is the gateway order identifier returned by `register()` as `$response->orderId()`:

```
use LaravelSatim\Contracts\SatimGatewayInterface;
use LaravelSatim\Http\Requests\SatimConfirmRequest;

$response = app(SatimGatewayInterface::class)->confirm(new SatimConfirmRequest(
    mdOrder: 'BnTjnFDzZSP97QXu8FXq',
));

if ($response->successful()) {
    // Payment captured (OrderStatus::DEPOSITED).
} else {
    // Inspect the outcome — $response->orderStatus(), $response->message().
}
```

`SatimConfirmResponse` exposes rich accessors: `successful()`, `orderStatus()` (a `LaravelSatim\Enums\OrderStatus`enum), `message()`, `amount()`, `depositAmount()`, `currency()`, `approvalCode()`, `authorizationResponseId()`, `pan()`, `errorCode()`, `errorMessage()`, `raw()`, plus `params()` — a typed `LaravelSatim\ValueObjects\ConfirmResponse\Params` value object (`respCode`, `respCodeDesc`, `udf1`–`udf5`, `extra`).

### 3. Refund a transaction

[](#3-refund-a-transaction)

```
use LaravelSatim\Contracts\SatimGatewayInterface;
use LaravelSatim\Http\Requests\SatimRefundRequest;

$response = app(SatimGatewayInterface::class)->refund(new SatimRefundRequest(
    orderId: 'BnTjnFDzZSP97QXu8FXq',
    amount: 1500.00,
));
```

### 4. Check a transaction status

[](#4-check-a-transaction-status)

Fetch the full, **extended** status of an order at any time (reconciliation, webhooks, retries…) using its gateway `orderId` (the value returned by `register()` as `$response->orderId()`):

```
use LaravelSatim\Contracts\SatimGatewayInterface;
use LaravelSatim\Http\Requests\SatimStatusRequest;

$response = app(SatimGatewayInterface::class)->status(new SatimStatusRequest(
    orderId: 'ehf9z2yvvThwQ4AACW2G',
));

if ($response->successful()) {
    // Payment captured (OrderStatus::DEPOSITED).
}
```

`SatimStatusResponse` exposes `successful()`, `orderStatus()`, `message()`, `amount()`, `currency()`, `date()` and `authDateTime()` (both `?DateTimeImmutable`), `ip()`, `fraudLevel()`, `terminalId()`, `authRefNum()`, `orderNumber()`, `orderDescription()`, `errorCode()`, `errorMessage()`, `raw()`, plus three **typed value objects**:

```
$response->merchantOrderParams()->disablePhone;      // ?bool
$response->merchantOrderParams()->transmissionDate;  // ?DateTimeImmutable
$response->merchantOrderParams()->udf1;              // ?string  (also udf2–udf5, forceTerminalId, extra)

$response->cardAuthInfo()->pan;                      // '628058**7215'
$response->cardAuthInfo()->expiration;               // '202701'  (also cardholderName, approvalCode, …)

$response->attributes()->mdOrder;                    // gateway order id  (+ ->extra)
```

They live under `LaravelSatim\ValueObjects\StatusResponse\{MerchantOrderParams, CardAuthInfo, Attributes}`. Each keeps any unmodelled field in an `extra` array, so nothing is ever lost.

### Using the facade

[](#using-the-facade)

```
use LaravelSatim\Facades\Satim;
use LaravelSatim\Http\Requests\SatimRegisterRequest;

// register(), confirm(), status() and refund() are all available on the facade.
$response = Satim::register(new SatimRegisterRequest(/* ... */));
```

### Overriding language and currency

[](#overriding-language-and-currency)

Language and currency default to your configuration. Override them **per request** directly on the request DTO:

```
use LaravelSatim\Enums\Currency;
use LaravelSatim\Enums\Language;
use LaravelSatim\Http\Requests\SatimRegisterRequest;

new SatimRegisterRequest(
    orderNumber: 'ORD123456',
    amount: 1500.00,
    returnUrl: route('payment.success'),
    udf1: 'ORD123456',
    currency: Currency::DZD,
    language: Language::ARABIC,
);
```

---

🌍 Translations
--------------

[](#-translations)

The package ships translations for **Arabic (`ar`)**, **English (`en`)** and **French (`fr`)**. Package texts (error messages and validation messages) follow the active Laravel locale. When the active locale is not one of the three supported locales, the package falls back to the locale configured in `satim.defaults.language` (and ultimately to English), so end users never see raw translation keys.

---

⚠️ Error handling
-----------------

[](#️-error-handling)

API-level errors (invalid credentials, unknown order, system errors…) raise **typed exceptions**. A declined card during confirmation is a **business outcome**, not an exception: `confirm()` returns a `SatimConfirmResponse` you inspect with `successful()` / `orderStatus()` / `message()`.

```
use LaravelSatim\Exceptions\SatimAbstractException;
use LaravelSatim\Exceptions\SatimConnectionException;
use LaravelSatim\Exceptions\SatimResponseException;
use LaravelSatim\Exceptions\SatimValidationException;

try {
    $response = app(SatimGatewayInterface::class)->register($request);
} catch (SatimValidationException $e) {
    // Invalid request data (thrown before the request is sent) — $e->errors(), $e->first()
} catch (SatimResponseException $e) {
    // SATIM returned an error code — $e->errorCode, $e->errorMessage
} catch (SatimConnectionException $e) {
    // Network / transport failure — $e->getPrevious()
} catch (SatimAbstractException $e) {
    // Base type: catch-all for any SATIM error
}
```

Exception hierarchy:

```
SatimAbstractException (base)
├── SatimConfigurationException   // missing credentials / invalid config
├── SatimValidationException      // request DTO validation (->errors(), ->first(), ->messages())
├── SatimConnectionException      // transport / HTTP failure
├── SatimEncodingException        // failed to JSON-encode jsonParams
└── SatimResponseException        // SATIM returned an error code (->errorCode, ->errorMessage)

```

---

✅ Testing
---------

[](#-testing)

```
composer test
```

Runs Pint (PSR-12), PHPStan (level 10) and the Pest unit suite. The suite mirrors the `src` directory structure under `tests/Unit`. Continuous integration runs the full matrix of PHP 8.3/8.4 against Laravel 11, 12 and 13, on both the lowest and the latest resolvable dependencies.

---

📌 Roadmap
---------

[](#-roadmap)

- Register / Confirm / Refund operations
- Native request validation layer
- Typed exception mapping from SATIM error codes
- Config-driven HTTP method and automatic retries
- Full unit test suite mirroring `src`
- Status operation (extended order status)
- Webhook support

---

🔒 Security
----------

[](#-security)

If you discover any security-related issues, please email **** instead of using the issue tracker.

---

🙏 Credits
---------

[](#-credits)

- [Abderrahim CHETIBI](https://github.com/achetibi)
- [All Contributors](../../contributors)

---

📄 License
---------

[](#-license)

The MIT License (MIT). See [LICENSE.md](LICENSE.md) for full license text.

###  Health Score

49

—

FairBetter than 94% of packages

Maintenance94

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

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

Every ~44 days

Recently: every ~8 days

Total

10

Last Release

13d ago

Major Versions

v1.1.2 → v2.0.02026-07-03

PHP version history (2 changes)v1.0.0PHP ^8.2

v1.1.2PHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/30299188?v=4)[Abderrahim CHETIBI](/maintainers/achetibi)[@achetibi](https://github.com/achetibi)

---

Top Contributors

[![achetibi](https://avatars.githubusercontent.com/u/30299188?v=4)](https://github.com/achetibi "achetibi (50 commits)")

---

Tags

algeriacarte-cibcibdze-paymentecommerceedahabialaravellaravel-satimpaimentpaymentpayment-gatewaysatimlaravelpaymentecommercee-commercepayment gatewaypaiementAlgeriasatimcibe-paymentedahabiaDzlaravel-satimcarte-cib

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/achetibi-laravel-satim/health.svg)

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

###  Alternatives

[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

265.2k](/packages/aedart-athenaeum)[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.2k555.0M2.8k](/packages/aws-aws-sdk-php)[tempest/framework

The PHP framework that gets out of your way.

2.3k37.6k21](/packages/tempest-framework)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

353.6k](/packages/eslazarev-wildberries-sdk)

PHPackages © 2026

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