PHPackages                             yehia-tarek/salla-toolkit - 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. yehia-tarek/salla-toolkit

ActiveLibrary[API Development](/categories/api)

yehia-tarek/salla-toolkit
=========================

Laravel package for integrating with the Salla e-commerce platform: Merchant API, OAuth 2.0 (Easy &amp; Custom mode), and Webhooks.

v1.0.0(1mo ago)11MITPHPPHP ^8.1

Since Jul 10Pushed 1mo agoCompare

[ Source](https://github.com/yehia-tarek/salla-toolkit)[ Packagist](https://packagist.org/packages/yehia-tarek/salla-toolkit)[ Docs](https://docs.salla.dev/)[ RSS](/packages/yehia-tarek-salla-toolkit/feed)WikiDiscussions main Synced 2w ago

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

Salla Laravel SDK
=================

[](#salla-laravel-sdk)

An unofficial Laravel package for building apps on the [Salla](https://salla.sa) e-commerce platform: Merchant API resources, OAuth 2.0 (Easy Mode &amp; Custom Mode), and secure webhook handling. Built against [docs.salla.dev](https://docs.salla.dev/).

> This is a community package, not published or maintained by Salla. Endpoint paths mirror the [Merchant API docs](https://docs.salla.dev/426392m0) as of this writing — please verify against the docs for anything mission critical, and open an issue/PR if something drifted.

Features
--------

[](#features)

- Fluent, resource-based client: `Salla::orders()->all()`, `Salla::products()->create([...])`
- OAuth 2.0 helpers for both Easy Mode and Custom Mode
- Per-store token storage (Eloquent model + migration) for multi-tenant apps, with automatic refresh-token exchange on expiry
- A secured webhook endpoint, auto-registered, that verifies Salla's signature and dispatches Laravel events per store event (`order.created`, `product.created`, etc.)
- Typed exceptions for auth failures, rate limits, and validation errors

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

[](#installation)

```
composer require yehia-tarek/salla-toolkit
php artisan salla:install
php artisan migrate
```

`salla:install` publishes `config/salla.php` and the `salla_authorizations` migration, and prints your webhook URL.

Add your app's credentials (from the [Salla Partners Portal](https://salla.partners)) to `.env`:

```
SALLA_CLIENT_ID=
SALLA_CLIENT_SECRET=
SALLA_REDIRECT_URI=https://your-app.com/salla/callback
SALLA_WEBHOOK_SECRET=
SALLA_SCOPES="offline_access"

# Only needed for private, single-store apps (skips OAuth entirely):
# SALLA_ACCESS_TOKEN=
```

Usage
-----

[](#usage)

### Single-store / private apps

[](#single-store--private-apps)

If you're building a private app for one store, drop a long-lived token in `SALLA_ACCESS_TOKEN` and skip straight to calling resources:

```
use YehiaTarek\SallaToolkit\Facades\Salla;

$orders = Salla::orders()->all(['status' => 'pending']);
$order  = Salla::orders()->find($orderId);

$product = Salla::products()->create([
    'name' => 'T-Shirt',
    'price' => 100,
    'product_type' => 'product',
]);

Salla::customers()->ban($customerId);
```

### Public / multi-store apps (OAuth)

[](#public--multi-store-apps-oauth)

**Easy Mode** (recommended by Salla): send merchants straight to the install URL. Salla handles the authorization code exchange for you and delivers the resulting tokens via the `app.store.authorize` webhook event, which this package catches and persists automatically.

```
// Redirect a merchant to install your app:
return redirect(Salla::oauth()->installationUrl($appId));
```

Nothing else required — as long as your webhook route is reachable and `SALLA_WEBHOOK_SECRET` matches the secret configured on the Partners Portal, tokens land in the `salla_authorizations` table on their own.

**Custom Mode**: build your own authorize URL and handle the callback:

```
// routes/web.php
Route::get('/salla/connect', function () {
    return redirect(Salla::oauth()->authorizationUrl());
});

Route::get('/salla/callback', function (Illuminate\Http\Request $request) {
    $tokens = Salla::oauth()->exchangeCodeForToken($request->query('code'));
    $me = Salla::oauth()->userInfo($tokens['access_token']);

    app(\YehiaTarek\SallaToolkit\Contracts\SallaTokenRepository::class)->store(
        storeId: $me['data']['merchant']['id'] ?? $me['data']['id'],
        accessToken: $tokens['access_token'],
        refreshToken: $tokens['refresh_token'] ?? null,
        expiresAt: time() + ($tokens['expires_in'] ?? 0),
        scope: $tokens['scope'] ?? null,
    );

    return redirect('/dashboard');
});
```

Once a store's tokens are stored, scope every call to that store:

```
Salla::forStore($storeId)->orders()->all();
Salla::forStore($storeId)->products()->find($productId);
```

`forStore()` automatically refreshes the access token (and re-persists the new refresh token — Salla's are single-use) if a request comes back with a 401.

### Ad-hoc token

[](#ad-hoc-token)

```
Salla::withToken($accessToken)->orders()->all();
```

### Pagination

[](#pagination)

Salla list endpoints return `data` + `pagination`:

```
$response = Salla::orders()->all(['page' => 2]);
$orders = $response['data'];
$pagination = $response['pagination']; // count, total, perPage, currentPage, totalPages, links
```

Or fetch every page at once (careful on large stores):

```
$allOrders = Salla::orders()->allPages();
```

Available resources
-------------------

[](#available-resources)

`orders`, `products`, `customers`, `categories`, `brands`, `coupons`, `specialOffers`, `shipments`, `shippingCompanies`, `shippingZones`, `taxes`, `countries`, `cities`, `currencies`, `affiliates`, `reviews`, `webhooks`, `settings`, `store`, `exports`.

Every resource supports `all()`, `find($id)`, `create($data)`, `update($id, $data)`, and `delete($id)` (where Salla's API supports the corresponding verb), plus resource-specific helpers — e.g. `Salla::products()->findBySku($sku)`, `Salla::orders()->updateStatus(...)`, `Salla::customers()->ban($id)`. See each class under `src/Resources` for the full list.

Webhooks
--------

[](#webhooks)

Point your app's Webhook URL (Partners Portal) at:

```
https://your-app.com/salla/webhook

```

(configurable via `SALLA_WEBHOOK_PATH`). Incoming requests are verified against `X-Salla-Signature` using `SALLA_WEBHOOK_SECRET`, then dispatched as Laravel events:

```
use YehiaTarek\SallaToolkit\Webhooks\Events\SallaWebhookReceived;

// Catch-all listener
Event::listen(SallaWebhookReceived::class, function (SallaWebhookReceived $event) {
    logger("Salla event: {$event->event}", $event->data());
});

// Or listen for one specific event by name
Event::listen('salla.order.created', function (array $payload) {
    // $payload['data'] is the created order
});
```

See the full event list at [docs.salla.dev/421119m0](https://docs.salla.dev/421119m0#list-of-salla-store-events).

If you'd rather not use the auto-registered route, set `SALLA_WEBHOOK_ROUTE_ENABLED=false`and wire up your own controller with the `VerifySallaWebhook` middleware:

```
Route::post('/my-webhook', MyWebhookController::class)
    ->middleware(\YehiaTarek\SallaToolkit\Middleware\VerifySallaWebhook::class);
```

Error handling
--------------

[](#error-handling)

```
use YehiaTarek\SallaToolkit\Exceptions\{
    SallaAuthenticationException,
    SallaRateLimitException,
    SallaRequestException,
};

try {
    Salla::forStore($storeId)->orders()->create($data);
} catch (SallaRequestException $e) {
    // $e->statusCode(), $e->errors() (422 field errors), $e->getMessage()
} catch (SallaRateLimitException $e) {
    // $e->retryAfter() in seconds, if provided
} catch (SallaAuthenticationException $e) {
    // token missing/expired and could not be refreshed — merchant likely
    // needs to reinstall the app
}
```

Custom token storage
--------------------

[](#custom-token-storage)

Swap the Eloquent-backed repository for your own by binding the contract in your own service provider:

```
$this->app->bind(
    \YehiaTarek\SallaToolkit\Contracts\SallaTokenRepository::class,
    \App\Services\RedisSallaTokenRepository::class
);
```

Your class just needs to implement `store()`, `find()`, and `forget()` — see `src/Contracts/SallaTokenRepository.php`.

Configuration reference
-----------------------

[](#configuration-reference)

See [`config/salla.php`](config/salla.php) for every option (API base URL, OAuth endpoints, HTTP timeouts/retries, token table name/connection, webhook path &amp; middleware).

License
-------

[](#license)

MIT

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance91

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

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

49d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/92787505?v=4)[Yehia Tarek](/maintainers/yehia-tarek)[@yehia-tarek](https://github.com/yehia-tarek)

---

Top Contributors

[![yehia-tarek](https://avatars.githubusercontent.com/u/92787505?v=4)](https://github.com/yehia-tarek "yehia-tarek (4 commits)")

---

Tags

apilaravelsdkoauth2webhooksecommercesallasaudi-arabia

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/yehia-tarek-salla-toolkit/health.svg)

```
[![Health](https://phpackages.com/badges/yehia-tarek-salla-toolkit/health.svg)](https://phpackages.com/packages/yehia-tarek-salla-toolkit)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58190.1k21](/packages/api-platform-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5226.7k](/packages/simplestats-io-laravel-client)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k161.4k2](/packages/mike-bronner-laravel-model-caching)[forjedio/inertia-table

Backend-driven dynamic tables for Laravel + Inertia.js

272.0k](/packages/forjedio-inertia-table)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45844.8k1](/packages/pressbooks-pressbooks)

PHPackages © 2026

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