PHPackages                             cashdash-pro/zaar - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. cashdash-pro/zaar

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

cashdash-pro/zaar
=================

A robust Laravel package for Shopify authentication handling both embedded and external app flows. Features JWT session management, seamless online/offline token handling, and automatic re-authentication for embedded apps. Built for Laravel 10+ and PHP 8.2+.

1.2.3(1y ago)21.8kMITPHPPHP ^8.2CI failing

Since Dec 16Pushed 1y ago1 watchersCompare

[ Source](https://github.com/cashdash-pro/zaar)[ Packagist](https://packagist.org/packages/cashdash-pro/zaar)[ Docs](https://github.com/nick-potts/laravel-shopify)[ GitHub Sponsors](https://github.com/CashDash)[ RSS](/packages/cashdash-pro-zaar/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (10)Dependencies (14)Versions (46)Used By (0)

Zaar - Laravel Shopify Authentication Made Easy
===============================================

[](#zaar---laravel-shopify-authentication-made-easy)

[![Latest Version on Packagist](https://camo.githubusercontent.com/8c8c11c639f1d10d7578224b5c2c33bb9ed45de78c8de3e8d4710a7dab468fc3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e69636b2d706f7474732f6c61726176656c2d73686f706966792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nick-potts/laravel-shopify)[![GitHub Tests Action Status](https://camo.githubusercontent.com/408ddf06165ff5a934b004e4a87b4b42f07135e06d43ea81f9b8d732108d35df/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6e69636b2d706f7474732f6c61726176656c2d73686f706966792f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/nick-potts/laravel-shopify/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/370a3ee6edf2fcb56c9d970e636b4ed8f2c741421fc8fc099f7c921ccecc939f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6e69636b2d706f7474732f6c61726176656c2d73686f706966792f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/nick-potts/laravel-shopify/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/f6f6f07f463d8abc3444fb4f40e634c01d329db04b63eea206009e871efbb8e1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e69636b2d706f7474732f6c61726176656c2d73686f706966792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nick-potts/laravel-shopify)

Overview
--------

[](#overview)

Zaar is a Laravel package that simplifies Shopify authentication for your Laravel applications. It provides seamless integration for both embedded and external Shopify apps, handling session management, authentication flows, and user management.

Features
--------

[](#features)

- 🔒 Secure authentication for embedded and external Shopify apps
- 🔄 Session management with online/offline token support
- 🛡️ Built-in CSRF protection configuration
- 🔌 Easy integration with Laravel's authentication system
- 📱 Support for both web and API authentication
- 🎯 Public app endpoints support
- ⚡ Automatic Axios interceptor setup for session tokens

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

[](#installation)

```
composer require cashdash-pro/zaar

php artisan zaar:install
```

The install command will:

1. Publish the configuration file
2. Create necessary migrations
3. Set up Axios interceptors (optional)
4. Add the `@zaarHead` directive to your Blade layout (optional)

Core Concepts
-------------

[](#core-concepts)

### Authentication Flow and Events

[](#authentication-flow-and-events)

Zaar implements different authentication strategies but follows a consistent flow through the `run()` method. Here's how it works:

```
// From HasAuthEvents trait
public function run(?Authenticatable $user): ?Authenticatable
{
    return $this
        ->withOnlineSession($user)    // Step 1
        ->withUser()                  // Step 2
        ->withDomain()                // Step 3
        ->when(                       // Step 4 (Conditional)
            Zaar::sessionType() === SessionType::OFFLINE,
            fn (AuthFlow $auth) => $auth->withOfflineSession()
        )
        ->mergeSessions()             // Step 5
        ->bindData()                  // Step 6
        ->withShopifyModel()          // Step 7
        ->dispatchEvents()            // Step 8
        ->getUser();                  // Final Result
}
```

#### Embedded Apps (Admin Panel)

[](#embedded-apps-admin-panel)

1. **Online Session** (`withOnlineSession`)

    - Validates Shopify's session token
    - Extracts user and shop information
    - Fires `OnlineSessionLoaded`
2. **User Resolution** (`withUser`)

    - Uses session data to find/create user
    - Can be customized via `findUserUsing`/`createUserUsing`
3. **Domain Resolution** (`withDomain`)

    - Uses domain from session token by default
    - Can be overridden via `setShopifyDomain` (good for store switching)
4. **Offline Session** (Conditional)

    - Only if configured for offline tokens
    - Fires `OfflineSessionLoaded`

#### External Apps (API/Standalone)

[](#external-apps-apistandalone)

The same flow is followed, but with key differences:

1. **Online Session** (`withOnlineSession`)

    - Tries to load the online session from the authenticated user
    - Fires `OnlineSessionLoaded` if successful
2. **User Resolution** (`withUser`)

    - Uses your existing authenticated user (configured via 'guards' in zaar.php)
3. **Domain Resolution** (`withDomain`)

    - Must be explicitly provided via `setShopifyDomain`
    - Critical for determining which store to use
4. **Offline Session** (Conditional)

    - Required for external apps
    - Fires `OfflineSessionLoaded`

#### Common Steps (Both Types)

[](#common-steps-both-types)

After strategy-specific steps:

1. **Session Merging** (`mergeSessions`)

    - Combines available session data
    - Creates unified access token available via `Zaar::session()`
2. **Data Binding** (`bindData`)

    - Makes sessions available via container
    - Enables `Zaar::session()`, `Zaar::onlineSession()`, `Zaar::offlineSession()` helpers
3. **Store Loading** (`withShopifyModel`)

    - Loads/creates Shopify store record
    - Fires `ShopifyTenantLoaded`
4. **Event Dispatch** (`dispatchEvents`)

    - Fires all accumulated events
    - Ends with `SessionAuthenticated`

This flow ensures consistent behavior while accommodating the different requirements of embedded and external apps.

### Event Flow and Importance

[](#event-flow-and-importance)

The events in Zaar are fired in a specific order through `dispatchEvents()`, each serving a crucial purpose:

1. **`OnlineSessionLoaded`**

    - Fired when an online session token is validated
    - Contains user identity from Shopify
    - Perfect for tracking user activity or session starts
    - Only fires for embedded apps or when online token exists
2. **`OfflineSessionLoaded`**

    - Fired when offline token is available
    - Critical for setting up API access
    - Use this to initialize API clients or background job configurations
    - Contains the permanent access token
3. **`ShopifyTenantLoaded`**

    - **Most important event for multi-tenant apps**
    - Fired when the Shopify store model is loaded
    - This is your chance to:
        - Set up database connections
        - Initialize tenant-specific services
        - Configure API settings
        - Load store preferences
    - Always fires regardless of authentication type
4. **`SessionAuthenticated`**

    - Final event with complete context
    - Provides access to:
        - Session data (merged online/offline)
        - Shopify store model
        - Authenticated user
    - Perfect for:
        - Logging successful authentications
        - Starting background processes
        - Initializing store-specific features

### Additional Critical Events

[](#additional-critical-events)

These events fire during specific operations:

- **`ShopifyFoundEvent`**

    - Fires when an existing store is found
    - Critical for:
        - Updating store metadata
        - Syncing store settings
        - Checking for plan changes
        - Validating store status
- **`ShopifyCreated`**

    - Fires for new store installations
    - Use for:
        - Initial store setup
        - Creating default settings
        - Welcome notifications
        - First-time configurations
- **`ShopifyUserCreated`**

    - Fires when a new user is created
    - Perfect for:
        - Setting up user preferences
        - Sending welcome emails
        - Initial role assignment
- **`ShopifyOnlineSessionCreated`/`ShopifyOfflineSessionCreated`**

    - Fire when new sessions are created
    - Use for:
        - Token storage
        - Session monitoring
        - Access logging

The event system is designed to give you complete control over the authentication and initialization process. Each event provides specific context and timing for different aspects of your application's setup.

### Domain Resolution

[](#domain-resolution)

The most important configuration in Zaar is setting up how shop domains are resolved. This controls which store is loaded for both embedded and external apps:

```
use CashDash\Zaar\Facades\Zaar;

Zaar::setShopifyDomain(function (Request $request, User $user, ?string $current_domain) {
    // For external apps (outside Shopify Admin), you MUST return the shop domain
    if (!Zaar::isEmbedded()) {
        return $request->header('X-Shopify-Shop-Domain');
        // or from query params: return $request->get('shop');
        // or from route parameters: return $request->route('shop');
    }

    // For embedded apps, you can override the domain to switch stores
    // The $user parameter lets you check permissions
    if ($user->can('access', $otherStore)) {
        return 'other-store.myshopify.com';
    }

    // Return null to use the domain from the session token
    return null;
});
```

This resolver is called during the authentication flow and determines which store's data and sessions are loaded. For external apps, you must return a domain. For embedded apps, returning `null` will use the domain from Shopify's session token.

Usage
-----

[](#usage)

### Middleware Types

[](#middleware-types)

1. **Embedded Apps** (`shopify.web`)

    - For apps within Shopify Admin iframe
    - Handles session token exchange
    - Includes necessary headers
    - Example:

    ```
    Route::middleware('shopify.web')->group(function () {
        Route::get('/app', function () {
            // Your embedded app's main entry point
        });
    });
    ```
2. **External Apps** (`shopify`)

    - For standalone/API applications
    - Uses offline tokens
    - No iframe handling
    - Example:

    ```
    Route::middleware('shopify')->group(function () {
        Route::get('/api/products', function () {
            $session = Zaar::offlineSession();
        });
    });
    ```
3. **Public Endpoints** (`shopify.public`)

    - For public-facing endpoints
    - Limited shop context
    - Example:

    ```
    Route::middleware('shopify.public')->group(function () {
        Route::get('/public/products', function () {
            // Public endpoint logic
        });
    });
    ```

### Session Management

[](#session-management)

1. **Accessing Sessions**

    ```
    // Get current session
    $session = Zaar::session();
    $accessToken = $session->accessToken;
    $shop = $session->shop;

    // Check session type
    if (Zaar::sessionType() === SessionType::ONLINE) {
        // Online session logic
    }
    ```
2. **Manual Session Control**

    ```
    // Start session for different store
    Zaar::startSessionManually($newShop, $user);

    // Handle expired sessions
    if (!Zaar::sessionStarted()) {
        Zaar::clearExpiredSessionsAndReauthenticate($domain);
    }
    ```

### User Management

[](#user-management)

```
use CashDash\Zaar\Dtos\OnlineSessionData;

// Custom user lookup
Zaar::findUserUsing(function (OnlineSessionData $session) {
    return User::where('email', $session->email)
              ->orWhere('shopify_id', $session->sub)
              ->first();
});

// Custom user creation
Zaar::createUserUsing(function (OnlineSessionData $session) {
    return User::create([
        'name' => $session->name,
        'email' => $session->email,
        'shopify_id' => $session->sub
    ]);
});
```

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

[](#configuration)

### Environment Setup

[](#environment-setup)

```
SHOPIFY_CLIENT_ID=your_client_id
SHOPIFY_CLIENT_SECRET=your_client_secret
SHOPIFY_API_VERSION=2024-01
SHOPIFY_SESSION_TYPE=offline # or online
SHOPIFY_SCOPES=read_products,write_products
SHOPIFY_REDIRECT_URI=https://your-app.com/auth/callback
```

### Package Configuration

[](#package-configuration)

```
// config/zaar.php
return [
    'shopify_app' => [
        'client_id' => env('SHOPIFY_CLIENT_ID'),
        'client_secret' => env('SHOPIFY_CLIENT_SECRET'),
        'scopes' => env('SHOPIFY_SCOPES'),
        'redirect' => env('SHOPIFY_REDIRECT_URI'),
        'api_version' => env('SHOPIFY_API_VERSION', '2024-01'),
        'session_type' => env('SHOPIFY_SESSION_TYPE', 'OFFLINE'),
    ],
    'guards' => 'web',
    'force_embedded_https' => true,
    'disabled_csrf_routes' => ['*'],
    'default_session_repository' => 'database',
];
```

### Frontend Integration

[](#frontend-integration)

The package automatically sets up Axios interceptors:

```
window.axios.interceptors.request.use(async function (config) {
    if (!window.shopify) {
        return config;
    }

    const token = await window.shopify.idToken();
    config.headers['Authorization'] = `Bearer ${token}`;
    config.headers['X-Referrer'] = window.location.href;

    return config;
});
```

Advanced Usage
--------------

[](#advanced-usage)

### Repository Configuration

[](#repository-configuration)

```
'repositories' => [
    'user' => [
        'type' => YourUserRepository::class,
        'model' => User::class,
        'email_column' => 'email',
    ],
    'shopify' => [
        'type' => YourShopifyRepository::class,
        'model' => Shopify::class,
        'shop_domain_column' => 'domain',
    ],
    'sessions' => [
        'database' => [
            'type' => YourSessionRepository::class,
            'model' => ShopifySession::class,
        ],
    ],
],
```

Testing
-------

[](#testing)

```
composer test
```

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)

- [CashDash](https://github.com/nick-potts)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance46

Moderate activity, may be stable

Popularity19

Limited adoption so far

Community20

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 52.4% 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 ~3 days

Total

45

Last Release

413d ago

Major Versions

v0.6.1 → 1.02024-12-23

### Community

Maintainers

![](https://www.gravatar.com/avatar/1050207b143d5cd9d862e9a6d474fd48df9003786bfadd34b7a09262ed0f5ee9?d=identicon)[nick-potts](/maintainers/nick-potts)

---

Top Contributors

[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (362 commits)")[![nick-potts](https://avatars.githubusercontent.com/u/1109914?v=4)](https://github.com/nick-potts "nick-potts (102 commits)")[![mvdnbrk](https://avatars.githubusercontent.com/u/802681?v=4)](https://github.com/mvdnbrk "mvdnbrk (46 commits)")[![Nielsvanpach](https://avatars.githubusercontent.com/u/10651054?v=4)](https://github.com/Nielsvanpach "Nielsvanpach (23 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (21 commits)")[![pforret](https://avatars.githubusercontent.com/u/474312?v=4)](https://github.com/pforret "pforret (16 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (15 commits)")[![sebastiandedeyne](https://avatars.githubusercontent.com/u/1561079?v=4)](https://github.com/sebastiandedeyne "sebastiandedeyne (14 commits)")[![patinthehat](https://avatars.githubusercontent.com/u/5508707?v=4)](https://github.com/patinthehat "patinthehat (10 commits)")[![riasvdv](https://avatars.githubusercontent.com/u/3626559?v=4)](https://github.com/riasvdv "riasvdv (9 commits)")[![crynobone](https://avatars.githubusercontent.com/u/172966?v=4)](https://github.com/crynobone "crynobone (8 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (8 commits)")[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (7 commits)")[![thecaliskan](https://avatars.githubusercontent.com/u/13554944?v=4)](https://github.com/thecaliskan "thecaliskan (5 commits)")[![irfanm96](https://avatars.githubusercontent.com/u/42065936?v=4)](https://github.com/irfanm96 "irfanm96 (5 commits)")[![IGedeon](https://avatars.githubusercontent.com/u/694313?v=4)](https://github.com/IGedeon "IGedeon (4 commits)")[![yaroslawww](https://avatars.githubusercontent.com/u/23663794?v=4)](https://github.com/yaroslawww "yaroslawww (3 commits)")[![jessarcher](https://avatars.githubusercontent.com/u/4977161?v=4)](https://github.com/jessarcher "jessarcher (3 commits)")[![koossaayy](https://avatars.githubusercontent.com/u/6431084?v=4)](https://github.com/koossaayy "koossaayy (3 commits)")[![lloricode](https://avatars.githubusercontent.com/u/8251344?v=4)](https://github.com/lloricode "lloricode (3 commits)")

---

Tags

laravelphp8jwt-authlaravel-shopifyshopify-appsession-managementCashDashshopify-authenticationshopify-embedded-appsshopify-oauth

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/cashdash-pro-zaar/health.svg)

```
[![Health](https://phpackages.com/badges/cashdash-pro-zaar/health.svg)](https://phpackages.com/packages/cashdash-pro-zaar)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k98.0M1.3k](/packages/spatie-laravel-permission)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.3M42](/packages/spatie-laravel-pdf)[laravel/ai

The official AI SDK for Laravel.

9782.1M161](/packages/laravel-ai)[spatie/laravel-passkeys

Use passkeys in your Laravel app

470755.5k32](/packages/spatie-laravel-passkeys)[wnx/laravel-backup-restore

A package to restore database backups made with spatie/laravel-backup.

213389.8k2](/packages/wnx-laravel-backup-restore)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)

PHPackages © 2026

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