Quick Start β’ Features β’ Installation β’ Filament β’ Changelog
π OAuth Β· πͺ Webhooks Β· β‘ GraphQL & REST Β· π Data Sync Β· πͺ Multi-Store Β· ποΈ Filament v5
| Property | Value |
|---|---|
| Composer Name | giorgigrdzelidze/laravel-shopify-sdk |
| PHP Namespace | LaravelShopifySdk\ |
| Shopify API | 2026-01 |
| GitHub | https://github.com/GiorgiGrdzelidze/laravel-shopify-sdk |
OAuth Authorization Code Grant β Standard Shopify OAuth flow for public/custom apps
Client Credentials Grant (2026+) β Server-to-server auth for modern Shopify apps
Secure Token Encryption β Encrypted access tokens with automatic refresh
GraphQL API β Recommended for optimal performance and flexibility
REST API β Full support for legacy endpoints
Rate Limiting β Intelligent throttling respects Shopify limits
Retry Logic β Exponential backoff for transient failures
Entity Sync Push Update Delete Products & Variants β β β β Product Types β β β β Product Tags β β β β Orders & Line Items β β β β Customers β β β β Collections β β β β Discounts β β β β Draft Orders β β β β Fulfillments β β β β Metafields β β β β Inventory Levels β β β β
HMAC-SHA256 Verification β Cryptographic verification of webhook authenticity
Idempotent Processing β Safe handling of duplicate webhook deliveries
Event Storage β Full audit trail of all received webhooks
Multi-Store Support β Manage unlimited Shopify stores from one app
Single-Store Mode β Simplified setup for single-store applications
Access Control β Restrict users to specific stores
17+ Resources β Full CRUD for all Shopify entities
Dashboard Widgets β Real-time stats, top products, inventory alerts
Sync Actions β One-click sync buttons with confirmation dialogs
RBAC β 7 roles, 55+ permissions out of the box
Activity Logging β Complete audit trail of all actions
PHP 8.3 Strict Types β Full type safety across entire codebase
Comprehensive Tests β PHPUnit/Pest test suite included
PHPDoc Coverage β Complete documentation for IDE support
# Create store from .env credentials (supports OAuth2 Client Credentials) php artisan shopify:setup php artisan shopify:setup --oauth --custom-domain=your-domain.com --currency=USD # Assign Super Admin role to a user (required for first-time setup) php artisan shopify:assign-admin your-email@example.com
# Sync individual entities php artisan shopify:sync:products # Products & variants php artisan shopify:sync:orders # Orders & line items php artisan shopify:sync:customers # Customer data php artisan shopify:sync:collections # Smart & custom collections php artisan shopify:sync:inventory # Inventory levels php artisan shopify:sync:discounts # Discount codes & rules php artisan shopify:sync:draft-orders # Draft orders php artisan shopify:sync:fulfillments # Fulfillment data php artisan shopify:sync:metafields # Product/collection metafields # Sync everything at once php artisan shopify:sync:all # With options php artisan shopify:sync:products --store=your-store.myshopify.com php artisan shopify:sync:orders --date-from=2026-01-01 --date-to=2026-03-20 php artisan shopify:sync:products --dry-run # Preview without syncing
# Install the package composer require giorgigrdzelidze/laravel-shopify-sdk # Publish config and migrations php artisan vendor:publish --tag=shopify-config php artisan vendor:publish --tag=shopify-migrations php artisan migrate
Add to your
.envfile:# For Single Store (simplest setup) SHOPIFY_SINGLE_STORE_ENABLED=true SHOPIFY_SHOP_DOMAIN=your-store.myshopify.com SHOPIFY_ACCESS_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxxx # For OAuth / Multi-Store SHOPIFY_CLIENT_ID=your-client-id SHOPIFY_CLIENT_SECRET=your-client-secret SHOPIFY_API_VERSION=2026-01
# Create your store in the database php artisan shopify:setup # For 2026+ apps using OAuth2 Client Credentials: php artisan shopify:setup --oauth --custom-domain=your-domain.com --currency=USD # Seed roles and permissions php artisan db:seed --class="LaravelShopifySdk\\Database\\Seeders\\ShopifyRolesAndPermissionsSeeder" # π IMPORTANT: Assign yourself as Super Admin php artisan shopify:assign-admin your-email@example.com
# Install Filament if not already installed composer require filament/filament:"^5.0"Update
config/shopify.php:'filament' => [ 'enabled' => true, ],Add the trait to your User model:
use LaravelShopifySdk\Traits\HasShopifyRoles; class User extends Authenticatable { use HasShopifyRoles; }
# Sync your products php artisan shopify:sync:products # Sync everything php artisan shopify:sync:all # Visit the admin panel open http://your-app.test/admin
Your Shopify data is now synced and you have full admin access.
Visit/adminto see your dashboard with products, orders, customers, and more.
- Requirements
- Quick Start
- Installation
- Configuration
- Usage
- Filament v5 Integration
- Testing
- Security
- Troubleshooting
- Contributing
| Requirement | Version |
|---|---|
| PHP | 8.3+ |
| Laravel | 12.0+ |
| Database | MySQL / PostgreSQL / SQLite |
| Filament (optional) | 5.0+ |
| Component | Version | Status |
|---|---|---|
| PHP | 8.3+ | β Required |
| Laravel | 12.x | β Required |
| Filament | v5 | β‘ Optional |
| Shopify API | 2026-01 | β Default |
# 1οΈβ£ Install the package
composer require giorgigrdzelidze/laravel-shopify-sdk
# 2οΈβ£ Publish config and migrations
php artisan vendor:publish --tag=shopify-config
php artisan vendor:publish --tag=shopify-migrations
# 3οΈβ£ Run migrations
php artisan migrate
# 4οΈβ£ Configure your .env
SHOPIFY_CLIENT_ID=your-client-id
SHOPIFY_CLIENT_SECRET=your-client-secret
SHOPIFY_API_VERSION=2026-01
# 5οΈβ£ Start syncing!
php artisan shopify:sync:productsThat's it! π You're ready to integrate with Shopify.
Install the package via Composer:
composer require giorgigrdzelidze/laravel-shopify-sdkPublish the configuration file:
php artisan vendor:publish --tag=shopify-configPublish and run migrations:
php artisan vendor:publish --tag=shopify-migrations
php artisan migrateThis package uses the root namespace LaravelShopifySdk\ for all classes. After installing or updating the package, ensure you regenerate the autoloader:
composer dump-autoloadPackage Structure:
| Namespace | Purpose |
|---|---|
LaravelShopifySdk\Auth\* |
π Authentication and OAuth |
LaravelShopifySdk\Clients\* |
β‘ API clients (GraphQL, REST) |
LaravelShopifySdk\Models\* |
π¦ Eloquent models |
LaravelShopifySdk\Sync\* |
π Sync engine |
LaravelShopifySdk\Commands\* |
π― Artisan commands |
LaravelShopifySdk\Webhooks\* |
πͺ Webhook handling |
LaravelShopifySdk\Exceptions\* |
Add these to your .env file:
# Shopify API Version
SHOPIFY_API_VERSION=2026-01
# Webhook Secret (required for webhooks)
SHOPIFY_WEBHOOK_SECRET=your-webhook-secret
# Optional: Filament Integration
SHOPIFY_FILAMENT_ENABLED=falseChoose one of the following configurations:
Use this if you're managing a single Shopify store. No database required for store credentials.
# Enable Single Store Mode
SHOPIFY_SINGLE_STORE_ENABLED=true
SHOPIFY_SHOP_DOMAIN=your-store.myshopify.com
SHOPIFY_ACCESS_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxxxHow to get your access token (Legacy - before Jan 2026):
- Go to your Shopify Admin
- Settings β Apps and sales channels β Develop apps
- Create a custom app with required scopes
- Install the app and copy the Admin API access token
How to get your access token (2026+ - Client Credentials Grant):
β οΈ Important: Starting January 1, 2026, Shopify no longer allows creating legacy custom apps in the store admin. New apps must be created via the Developer Dashboard and use OAuth2 Client Credentials Grant.
- Create your app in the Shopify Developer Dashboard
- Get your Client ID and Client Secret
- Install the app to your store
- Use the setup command with
--oauthflag to obtain access token:
php artisan shopify:setup --oauth --custom-domain=your-domain.com --currency=USDUse this if you're building a public app or managing multiple stores.
# Disable Single Store Mode
SHOPIFY_SINGLE_STORE_ENABLED=false
# OAuth Credentials (required for multi-store)
SHOPIFY_CLIENT_ID=your-client-id
SHOPIFY_CLIENT_SECRET=your-client-secret
SHOPIFY_SCOPES=read_products,write_products,read_orders,write_orders,read_customers,write_customers,read_inventory,write_inventory
SHOPIFY_REDIRECT_URI=https://your-app.com/shopify/callbackImportant: In multi-store mode, stores must be installed via OAuth flow before syncing. The package will store credentials in the shopify_stores table.
To install a store manually in multi-store mode:
use LaravelShopifySdk\Auth\StoreRepository;
$repository = app(StoreRepository::class);
$repository->createOrUpdate(
shopDomain: 'your-store.myshopify.com',
accessToken: 'shpat_xxxxxxxxxxxxxxxxxxxxx',
scopes: 'read_products,write_products,read_orders'
);The config/shopify.php file provides extensive customization options:
- API version and endpoints
- OAuth settings
- Route configuration
- Webhook handling
- Rate limiting parameters
- Sync behavior
- Filament integration
- Logging preferences
Create a Shopify app in your Partner Dashboard and configure:
- App URL:
https://your-app.com - Allowed redirection URL(s):
https://your-app.com/shopify/callback
Direct merchants to your install route:
https://your-app.com/shopify/install?shop=store-name.myshopify.com
The package handles the OAuth flow automatically:
- Redirects to Shopify for authorization
- Validates the callback HMAC
- Exchanges code for access token
- Stores encrypted credentials in database
After successful installation, the store is marked as active and ready for API calls.
use LaravelShopifySdk\Clients\ShopifyClient;
$client = app(ShopifyClient::class);
// Get store instance
$store = $client->getStore('store-name.myshopify.com');
// Execute GraphQL query
$query = <<<GQL
{
products(first: 10) {
edges {
node {
id
title
status
}
}
}
}
GQL;
$response = $client->graphql($store)->query($store, $query);// GET request
$products = $client->rest($store)->get($store, 'products.json', [
'limit' => 50,
'status' => 'active',
]);
// POST request
$product = $client->rest($store)->post($store, 'products.json', [
'product' => [
'title' => 'New Product',
'vendor' => 'My Store',
],
]);
// PUT request
$updated = $client->rest($store)->put($store, 'products/123.json', [
'product' => ['status' => 'draft'],
]);
// DELETE request
$client->rest($store)->delete($store, 'products/123.json');Register webhooks in your Shopify admin or via API:
POST /admin/api/2026-01/webhooks.json
{
"webhook": {
"topic": "products/create",
"address": "https://your-app.com/shopify/webhooks",
"format": "json"
}
}
Webhooks are automatically verified using HMAC-SHA256. Invalid webhooks are rejected with a 401 response.
The package stores all webhook events in the shopify_webhook_events table for:
- Idempotency (prevents duplicate processing)
- Audit trail
- Retry capability
Webhooks are processed asynchronously by default. The app/uninstalled webhook automatically marks stores as inactive.
The shopify:setup command creates or updates a store from environment credentials:
# Basic setup (uses SHOPIFY_SHOP_DOMAIN and SHOPIFY_ACCESS_TOKEN from .env)
php artisan shopify:setup
# With custom domain and currency
php artisan shopify:setup --custom-domain=lumino.ge --currency=GEL
# Using OAuth2 Client Credentials Grant (2026+ method)
php artisan shopify:setup --oauth --custom-domain=lumino.ge --currency=GEL
# With explicit options
php artisan shopify:setup --domain=your-store.myshopify.com --token=shpat_xxxOptions:
| Option | Description |
|---|---|
--domain |
Shop domain (defaults to SHOPIFY_SHOP_DOMAIN) |
--token |
Access token (defaults to SHOPIFY_ACCESS_TOKEN) |
--custom-domain |
Custom domain (e.g., lumino.ge) |
--currency |
Store currency (e.g., GEL, USD) |
--oauth |
Use OAuth2 Client Credentials Grant to obtain token |
The --oauth flag uses SHOPIFY_CLIENT_ID and SHOPIFY_CLIENT_SECRET to programmatically obtain an access token via the Client Credentials Grant flow.
# Sync products
php artisan shopify:sync:products --store=store-name.myshopify.com
# Sync orders (with date range)
php artisan shopify:sync:orders --date-from=2026-01-01 --date-to=2026-03-16
# Sync customers (incremental since last sync)
php artisan shopify:sync:customers --since=2026-03-01
# Sync inventory
php artisan shopify:sync:inventory
# Sync all entities
php artisan shopify:sync:all
# Dry run (preview without syncing)
php artisan shopify:sync:products --dry-run
# Sync all active stores
php artisan shopify:sync:productsAdd to routes/console.php (Laravel 12+):
use Illuminate\Support\Facades\Schedule;
// Sync products daily at 2 AM
Schedule::command('shopify:sync:products')->dailyAt('02:00');
// Sync orders every hour
Schedule::command('shopify:sync:orders')->hourly();
// Sync customers daily at 3 AM
Schedule::command('shopify:sync:customers')->dailyAt('03:00');
// Sync inventory every 15 minutes
Schedule::command('shopify:sync:inventory')->everyFifteenMinutes();
// Sync everything daily at 1 AM
Schedule::command('shopify:sync:all')->dailyAt('01:00');use LaravelShopifySdk\Sync\SyncRunner;
use LaravelShopifySdk\Auth\StoreRepository;
$runner = app(SyncRunner::class);
$repository = app(StoreRepository::class);
$store = $repository->findByDomain('store-name.myshopify.com');
// Sync products
$syncRun = $runner->syncProducts($store, [
'since' => '2026-03-01',
]);
echo "Synced {$syncRun->counts['products']} products in {$syncRun->duration_ms}ms";
// Sync orders with date range
$syncRun = $runner->syncOrders($store, [
'date_from' => '2026-01-01',
'date_to' => '2026-03-16',
]);All synced data is stored with:
- Full JSON payload in
payloadcolumn - Searchable columns for common queries
- Relationships between entities
use LaravelShopifySdk\Models\Product;
use LaravelShopifySdk\Models\Order;
use LaravelShopifySdk\Models\Customer;
// Query products
$products = Product::where('store_id', $store->id)
->where('status', 'active')
->where('vendor', 'Nike')
->get();
// Access full payload
$productData = $product->payload;
// Relationships
$variants = $product->variants;
$store = $product->store;
// Query orders
$orders = Order::where('store_id', $store->id)
->where('financial_status', 'paid')
->whereBetween('processed_at', [$from, $to])
->with('lineItems')
->get();The package automatically handles rate limiting for both REST and GraphQL APIs:
- Bucket-based rate limiting (40 requests per second)
- Automatic throttling when approaching limits
- Respects
X-Shopify-Shop-Api-Call-Limitheader
- Cost-based throttling (1000 points maximum)
- Monitors
extensions.costin responses - Throttles when available points drop below threshold
- Restores at 50 points per second
- Automatic retries on 429 (rate limit) responses
- Exponential backoff for 5xx server errors
- Configurable retry attempts and delays
Shopify guarantees stable API versions for minimum 12 months. The package defaults to 2026-01.
- Update
SHOPIFY_API_VERSIONin.env - Review Shopify's changelog
- Test thoroughly in development
- Deploy to production
The package supports per-store API versions if needed.
Note: Filament is completely optional and not a hard dependency. Install only if you need admin panel features.
composer require filament/filament:"^5.0"// config/shopify.php
'filament' => [
'enabled' => true,
],- π± Mobile-first design - Responsive tables and forms
- π Resources - Stores, Products, Variants, Orders, Customers, Locations, Inventory, Webhooks, Sync Runs
- π Widgets - Sync health dashboard, order statistics, product counts, top selling products, inventory alerts
- β‘ Sync Actions - One-click sync buttons on Products, Orders, Customers pages
- π Filtered Order Summary - Real-time statistics when filters are applied
- π Filters - Store, status, date ranges
- β‘ Cached queries - Widget data cached for 5 minutes
- π¨ Auto-discovery - Resources and widgets auto-register when enabled
This package is built for Filament v5 with:
- Modern panel API
- Auto-discovery support
- Mobile-first responsive design
- Enhanced widget system
Full CRUD operations for managing Shopify stores directly from Filament:
Features:
- Create stores manually with token mode (shop_domain, access_token, scopes)
- Edit stores - rotate tokens, update scopes, activate/deactivate
- Delete stores - with confirmation and cascade delete
- Test Connection - verify store credentials with a lightweight API call
- Sync Actions - trigger sync for products, orders, customers, or all data
Token Security:
- Access tokens are encrypted at rest using Laravel's encryption
- Tokens are hidden in forms with reveal option
- Masked token display in views (e.g.,
shpaβ’β’β’β’β’β’cdef)
Store Modes:
oauth- Store installed via Shopify OAuth flowtoken- Store added manually with access token
For testing UI flows, filtering, and relationships, enable Sandbox CRUD mode:
SHOPIFY_TESTING_CRUD_ENABLED=trueOr in config:
// config/shopify.php
'filament' => [
'testing_crud_enabled' => env('SHOPIFY_TESTING_CRUD_ENABLED', false),
],When enabled:
- Create/Edit/Delete actions appear for Products, Orders, Customers
β οΈ Sandbox Mode warning badge displayed in forms- JSON payload editor available for raw data manipulation
- Changes are LOCAL ONLY - they do NOT sync back to Shopify
Use cases:
- Testing Filament UI components
- Developing custom filters and actions
- Populating test data for demos
- Debugging relationship queries
Each resource page includes sync action buttons in the header:
Products Page:
- Sync Products - Sync all products and variants
- Sync Inventory - Sync inventory levels for all locations
- Sync All - Sync both products and inventory
Orders Page:
- Sync Orders - Sync all orders from Shopify
Customers Page:
- Sync Customers - Sync all customers from Shopify
All sync actions show a confirmation modal and display the count of synced items upon completion.
Full CRUD for Shopify collections with bi-directional sync:
Features:
- β Sync from Shopify - Import all Smart and Custom collections
- β Create Collections - Create new custom collections locally
- β Edit Collections - Update title, description, handle, image
- β Manage Products - Add/remove products from collections
- β Push to Shopify - Sync local changes to Shopify (with confirmation)
- β Image Upload - Upload local images or use external URLs
- β Smart Rules Display - Human-readable rule formatting (e.g., "Tag equals paintglow")
- β Product Previews - Visual grid of products in collection
Sync Command:
# Sync all collections from Shopify
php artisan shopify:sync:collections
# Sync for specific store
php artisan shopify:sync:collections --store=your-store.myshopify.comCollection Types:
- Smart Collections - Auto-populated based on rules (read-only, synced from Shopify)
- Custom Collections - Manually curated product lists (full CRUD)
Push to Shopify:
When editing a collection, use the "Push to Shopify" button to:
- Create new collection in Shopify (if not yet synced)
- Update existing collection details
- Sync products to the Shopify collection
Image Requirements for Shopify:
- Must be a publicly accessible URL (https://)
- Local uploads work locally but won't sync to Shopify
- Supported formats: PNG, JPG, WEBP, GIF
Filament Resource Features:
- Collection list with images, type badges, product counts
- View page with product grid and smart rules
- Edit page with product multi-select
- Products relation manager for add/remove
Built-in role-based access control for multi-user environments:
Default Roles:
| Role | Description |
|---|---|
| Super Admin | Full access to all features and settings |
| Store Manager | Full access to assigned stores |
| Product Manager | Manage products and inventory |
| Order Manager | Manage orders and customers |
| Viewer | Read-only access (default for new users) |
Permission Groups:
stores.*- View, create, edit, delete storesproducts.*- View, create, edit, delete, push, pull productsorders.*- View, edit, delete orderscustomers.*- View, edit, delete customersinventory.*- View, edit inventorysync.*- Run sync, view logssettings.*- Manage roles, permissions, users
Setup:
# Run the roles migration
php artisan migrate
# Seed default roles and permissions (optional)
php artisan db:seed --class="LaravelShopifySdk\\Database\\Seeders\\ShopifyRolesAndPermissionsSeeder"
# Assign Super Admin role to a user
php artisan shopify:assign-admin your-email@example.comAdd to your User model:
use LaravelShopifySdk\Traits\HasShopifyRoles;
class User extends Authenticatable
{
use HasShopifyRoles;
}Usage in code:
// Check permissions
if ($user->hasShopifyPermission('products.edit')) {
// Can edit products
}
// Check roles
if ($user->hasShopifyRole('super-admin')) {
// Is super admin
}
// Assign role
$user->assignShopifyRole('product-manager');
// Check store access (for multi-store)
if ($user->canAccessStore($store)) {
// Can access this store
}Filament Resources:
- Roles - Create/edit roles with permission checkboxes
- Permissions - Manage individual permissions by group
For testing UI flows, filtering, and relationships, enable Sandbox CRUD mode:
SHOPIFY_TESTING_CRUD_ENABLED=trueOr in config:
// config/shopify.php
'filament' => [
'testing_crud_enabled' => env('SHOPIFY_TESTING_CRUD_ENABLED', false),
],When enabled:
- Create/Edit/Delete actions appear for Products, Orders, Customers
β οΈ Sandbox Mode warning badge displayed in forms- JSON payload editor available for raw data manipulation
- Changes are LOCAL ONLY - they do NOT sync back to Shopify
Use cases:
- Testing Filament UI components
- Developing custom filters and actions
- Populating test data for demos
- Debugging relationship queries
Each resource page includes sync action buttons in the header:
Products Page:
- Sync Products - Sync all products and variants
- Sync Inventory - Sync inventory levels for all locations
- Sync All - Sync both products and inventory
Orders Page:
- Sync Orders - Sync all orders from Shopify
Customers Page:
- Sync Customers - Sync all customers from Shopify
All sync actions show a confirmation modal and display the count of synced items upon completion.
When filters are applied on the Orders page, a summary bar appears showing:
| Metric | Description |
|---|---|
| Filtered Orders | Count of orders matching filters |
| Total Revenue | Sum of filtered order totals |
| Average Order | Average order value |
| % of Total | Percentage of all orders |
The summary bar uses color-coded cards with icons and only appears when filters are active.
Monitor sync status across all stores and entities:
| Column | Description |
|---|---|
| Store | Shop domain |
| Entity | products, orders, customers, inventory |
| Status | running, completed, failed |
| Records | Count of synced items |
| Duration | Time taken (ms/s/m) |
| Errors | Error count or β |
| Last Sync | Timestamp with relative time |
The widget shows the latest sync run per entity per store and auto-refreshes every 60 seconds.
Run the test suite:
cd packages/giorgigrdzelidze/laravel-shopify-sdk
composer install
vendor/bin/pestOr with PHPUnit:
vendor/bin/phpunitThe package includes tests for:
- HMAC validation (OAuth and webhooks)
- Store repository operations
- Token encryption
- OAuth callback verification
- Rate limiting behavior
- Access tokens are encrypted at rest using Laravel's encryption
- Never log or expose access tokens
- Webhook secrets are stored in configuration
- OAuth callbacks verified with timing-safe comparison
- Webhooks verified using
X-Shopify-Hmac-SHA256header - Raw request body used for webhook verification
- Use HTTPS for all endpoints
- Rotate webhook secrets periodically
- Monitor failed webhook verifications
- Implement IP whitelisting if needed
Issue: "Invalid HMAC signature"
Solution:
- Verify
SHOPIFY_CLIENT_SECRETmatches your app settings - Ensure callback URL is exactly as configured in Shopify
- Check for URL encoding issues
Issue: Webhooks return 401
Solution:
- Verify
SHOPIFY_WEBHOOK_SECRETis correct - Ensure raw request body is used (disable middleware that reads body)
- Check webhook is registered with correct URL
Issue: 429 responses despite throttling
Solution:
- Reduce
SHOPIFY_SYNC_CHUNK_SIZE - Increase delays between sync runs
- Use incremental syncs (
--sinceflag) - Sync during off-peak hours
Issue: Syncs are slow
Solution:
- Use GraphQL instead of REST where possible
- Enable queue processing (
--queueflag) - Optimize chunk sizes
- Add database indexes for common queries
cp .env.example .envAdd your Shopify app credentials:
SHOPIFY_CLIENT_ID=your-actual-client-id
SHOPIFY_CLIENT_SECRET=your-actual-client-secret
SHOPIFY_WEBHOOK_SECRET=your-actual-webhook-secretVisit:
http://localhost:8000/shopify/install?shop=your-dev-store.myshopify.com
Use ngrok to expose your local server:
ngrok http 8000Register webhook with ngrok URL:
https://your-ngrok-url.ngrok.io/shopify/webhooks
Send test webhook from Shopify admin or use:
curl -X POST http://localhost:8000/shopify/webhooks \
-H "X-Shopify-Topic: products/create" \
-H "X-Shopify-Shop-Domain: your-store.myshopify.com" \
-H "X-Shopify-Hmac-SHA256: $(echo -n '{"id":123}' | openssl dgst -sha256 -hmac 'your-webhook-secret' -binary | base64)" \
-d '{"id":123}'# Sync products from your test store
php artisan shopify:sync:products --store=your-dev-store.myshopify.com
# View sync results
php artisan shopify:sync:storesContributions are welcome! Please ensure:
- All tests pass
- Code follows PSR-12 standards
- PHPDoc is complete
- README is updated for new features
MIT License. See LICENSE file for details.
For issues, questions, or feature requests, please open an issue on GitHub.
New Features π
- β Product Types CRUD - Manage product types with Shopify sync
- β Product Tags CRUD - Manage product tags with Shopify sync
- β Assign to Products - Select products and assign types/tags directly to Shopify
- β Rename on Shopify - Rename types/tags across all products with one click
- β Sync from Products - Extract unique types/tags from existing products
- β Sync Confirmation Dialogs - All sync actions now require confirmation
- β Immediate Variant Sync - Variant sync now executes immediately
- β Model Organization - Models organized into Core, Commerce, Marketing subdirectories
New Filament Resources:
- ProductTypeResource - Manage product types with assign/rename actions
- ProductTagResource - Manage product tags with assign/rename actions
New Models:
- ProductType - Store-aware product type management
- ProductTag - Store-aware product tag management
New Services:
- ProductTypeService - Push types to Shopify, assign to products
- ProductTagService - Push tags to Shopify, assign to products
Improvements:
- All sync actions now show confirmation dialogs
- Variant sync executes immediately instead of waiting for product sync
- Fixed Store type hints in VariantService
- Auto-fill store_id when only one store exists
New Features π
- β Metafields Support - Sync and manage product/collection/customer metafields
- β Discounts & Price Rules - Full CRUD for discount codes and automatic discounts
- β Draft Orders - Create, edit, send invoices, complete draft orders
- β Fulfillments - Track shipments, carriers, tracking numbers
- β Push to Shopify - Push discounts, draft orders, metafields to Shopify
- β Enhanced Activity Logging - All actions logged to ShopifyLog
- β 7 New Roles - Marketing Manager, Fulfillment Staff added
- β 55+ Permissions - Granular access control across all features
- β New Navigation Groups - Marketing, Operations, Reports
- β
4 New Sync Commands -
shopify:sync:discounts,shopify:sync:draft-orders,shopify:sync:fulfillments,shopify:sync:metafields
New Filament Resources:
- MetafieldResource - View/edit metafields by owner type
- DiscountResource - Manage discount codes and price rules
- DraftOrderResource - Create and manage draft orders
- FulfillmentResource - Track order fulfillments
New Models:
- Metafield, MetafieldDefinition
- Discount, DiscountCode
- DraftOrder
- Fulfillment, FulfillmentOrder, FulfillmentEvent
New Features π
- β Collections Full CRUD - Create, edit, delete collections with Shopify sync
- β Collection Products - Add/remove products from collections via relation manager
- β Push to Shopify - Sync local collections to Shopify with confirmation
- β Collection Images - Upload local images or use external URLs
- β Smart Rules Display - Human-readable formatting (e.g., "Tag equals paintglow")
- β
Product Images Sync - Sync
featured_image_urlandimagesarray from Shopify - β Roles & Permissions - Built-in RBAC with 5 default roles and 27 permissions
- β Role CRUD - Filament resource for managing roles with permission checkboxes
- β Permission CRUD - Filament resource for managing permissions by group
- β User Management - Assign roles and store access to users
- β HasShopifyRoles Trait - Easy integration with your User model
- β Store-level Access Control - Restrict users to specific stores
- β
Super Admin Command -
shopify:assign-adminto assign admin role - β Product Image Lightbox - Click to view full-size images in popup
- β Checkbox Image Removal - Visual selection for removing product images
- β Pull from Shopify - Sync individual products from edit page
- β Variant Creation - Create products with multiple variants
New Features π
- β
shopify:setupcommand for easy store creation from .env - β OAuth2 Client Credentials Grant support (2026+ Shopify apps)
- β Custom domain and currency fields for stores
- β Sync action buttons on Products, Orders, Customers pages
- β Filtered order summary cards with real-time statistics
- β Top Selling Products widget with star ratings
- β Inventory Alert widget for low stock items
- β Improved GraphQL query cost optimization
Initial Release π
- β OAuth Authorization Code Grant flow
- β Webhook verification and processing
- β GraphQL and REST API clients
- β Rate limiting and retry logic
- β Data mirroring for products, orders, customers, inventory
- β Artisan sync commands
- β Optional Filament v5 integration
- β Comprehensive test suite
- β Strict types across entire codebase
- β Complete PHPDoc coverage
Built with β€οΈ for the Laravel and Shopify communities.
Powered by:
- Laravel 12
- Shopify Admin API
- Filament v5 (optional)