## Getting Started
### Minimal Setup
1. **Installation**
```bash
composer require kyon147/laravel-shopify
php artisan vendor:publish --tag=shopify-config
config/shopify-app.php and migrations for Shopify integration.Run Migrations
php artisan migrate
shops table with required fields (e.g., shopify_offline_access_token, shopify_offline_refresh_token).Configure .env
SHOPIFY_API_KEY=your_api_key
SHOPIFY_API_SECRET=your_api_secret
SHOPIFY_APP_URL=https://your-app-url.com
SHOPIFY_EXPIRING_OFFLINE_TOKENS=true # Required for new public apps (post-April 2026)
First Use Case: OAuth Flow
routes/web.php:
Route::shopify();
/shopify/auth in your browser to trigger the OAuth flow. The package now throws an exception if the API route is accessed directly in a browser (e.g., /shopify/api/products), preventing accidental exposure.Access Shopify API
use Osiset\ShopifyApp\Facades\Shopify;
$shop = Shopify::getCurrentShop();
$apiHelper = Shopify::apiHelper();
$products = $apiHelper->call('GET', '/products');
Auth Flow:
Route::shopify() to auto-register OAuth routes (/shopify/auth, /shopify/auth/callback).config/shopify-app.php:
'scopes' => ['write_products', 'read_orders'],
Session Tokens:
SHOPIFY_EXPIRING_OFFLINE_TOKENS=true to handle expiring tokens.OfflineAccessTokenRefresher before API calls.Managed App Installations:
SessionToken for Checkout UI Extensions or Section Blocks:
$sessionToken = Shopify::getSessionToken();
AppServiceProvider:
public function boot()
{
Shopify::subscribe('orders/create', 'App\Http\Controllers\WebhookController@handleOrder');
}
public function handleOrder(Request $request)
{
$topic = $request->input('topic');
$payload = $request->input('payload');
// Process payload...
}
Route::middleware(['shopify.billable'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
Shopify::appBridge() to generate scripts for Vue/React:
{!! Shopify::appBridge() !!}
ShopModel for custom shop data:
use Osiset\ShopifyApp\Models\ShopModel;
class MyShop extends ShopModel
{
protected $table = 'shops';
}
$shop = MyShop::find($shopDomain);
$shop->shopify_access_token; // Auto-decrypted
apiHelper() for REST/GraphQL calls:
$apiHelper = Shopify::apiHelper();
$response = $apiHelper->call('GET', '/products', ['limit' => 10]);
$response = $apiHelper->graphql([
'query' => '{ products(first: 10) { edges { node { title } } } }'
]);
$sessionToken = Shopify::getSessionToken();
session_token field.BillableMiddleware to enforce subscriptions:
Route::middleware(['shopify.billable'])->group(function () {
// Protected routes
});
app/Http/Middleware/ShopifyBillableMiddleware.php.$this->mockShopifyApi('GET', '/products', ['products' => []]);
php artisan shopify:refresh-offline-tokens
php artisan shopify:refresh-offline-tokens --queue=shopify_queue --connection=database
Issue: Public apps require expiring offline tokens (post-April 2026). If SHOPIFY_EXPIRING_OFFLINE_TOKENS=false, tokens won’t refresh.
Fix:
SHOPIFY_EXPIRING_OFFLINE_TOKENS=true in .env.shopify_offline_* columns.shopify:refresh-offline-tokens command to preemptively refresh tokens before expiration.Debugging:
OfflineAccessTokenRefresher logs for refresh failures.shopify_offline_access_token_expires_at is set correctly.SHOPIFY_API_SECRET is incorrect or HMAC headers are missing..env for SHOPIFY_API_SECRET.session_token, but Shopify::getSessionToken() may return null if not properly configured.SHOPIFY_SESSION_TOKEN_ENABLED=true in config/shopify-app.php.Shopify::getSessionTokenForBlock().'app_bridge_exclude_routes' => ['shopify.auth', 'shopify.callback'],
Shopify::appBridge(['exclude' => true]) conditionally.APP_KEY changes, encrypted tokens (e.g., shopify_access_token) become unreadable.APP_KEY consistent across environments.php artisan key:generate sparingly./shopify/api/*) are accessed directly in a browser.Shopify::apiHelper() in controllers or services, not directly in Blade templates.config/shopify-app.php:
'debug' => env('SHOPIFY_DEBUG', false),
| Error | Cause | Solution |
|---|---|---|
Invalid OAuth token |
Expired or invalid token | Refresh token or re-authenticate. |
Webhook signature mismatch |
Incorrect SHOPIFY_API_SECRET |
Verify .env and Shopify app settings. |
Session token not found |
Missing shopify_session_token |
Enable SHOPIFY_SESSION_TOKEN_ENABLED. |
AppBridge script missing |
Route excluded or JS not loaded | Check app_bridge_exclude_routes. |
How can I help you explore Laravel packages today?