## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require kyon147/laravel-shopify
php artisan vendor:publish --tag=shopify-config
.env with your Shopify API credentials:
SHOPIFY_API_KEY=your_api_key
SHOPIFY_API_SECRET=your_api_secret
SHOPIFY_API_SCOPES=write_products,read_orders
SHOPIFY_API_HOSTNAME=your-shop.myshopify.com
First Use Case: OAuth Flow
routes/web.php:
Route::get('/shopify/auth', [ShopifyController::class, 'install']);
Route::get('/shopify/auth/callback', [ShopifyController::class, 'callback']);
Shopify facade to handle authentication:
use Kyon147\Shopify\Facades\Shopify;
// Redirect to Shopify OAuth
return Shopify::redirectToShopifyAuth();
// Handle callback
$shop = Shopify::getShopFromRequest();
Verify Installation
/shopify/auth to test the OAuth flow.shopify_shops table for installed shops.// Install a shop (redirects to OAuth)
return Shopify::installShop();
// Uninstall programmatically
Shopify::uninstallShop($shopDomain);
$shops = Shopify::getAllShops();
foreach ($shops as $shop) {
echo $shop->name . ' (' . $shop->domain . ')';
}
$products = Shopify::call('GET', 'products', ['limit' => 10]);
Shopify::registerWebhook('orders/create', 'https://your-app.com/webhooks/orders');
public function handleWebhook(Request $request) {
$topic = $request->input('topic');
$payload = $request->input('payload');
Shopify::handleWebhook($topic, $payload);
}
$shop = Shopify::getCurrentShop();
$session = Shopify::getSession($shop->domain);
Shopify::setSessionData($shop->domain, 'user_id', 123);
$userId = Shopify::getSessionData($shop->domain, 'user_id');
$token = Shopify::generateOnlineAccessToken($shop->domain);
fetch('https://your-shop.myshopify.com/admin/api/2023-04/products.json', {
headers: {
'X-Shopify-Access-Token': 'your_token_here'
}
});
Shopify::recordUsage($shop->domain, 'api_calls', 5);
$report = Shopify::generateUsageReport($shop->domain);
Service Providers:
Extend the package’s ShopifyServiceProvider to add custom logic:
public function register() {
$this->app->extend('shopify', function ($app) {
return new CustomShopifyManager($app['shopify']);
});
}
Events:
Listen to Shopify events (e.g., shop.installed):
Shopify::on('shop.installed', function ($shop) {
// Send welcome email
});
Middleware: Protect routes with shop-specific middleware:
Route::middleware(['shopify.auth'])->group(function () {
// Routes requiring Shopify auth
});
Mocking Shopify: Use the package’s mocking utilities:
Shopify::shouldReceive('call')
->once()
->with('GET', 'products')
->andReturn(['products' => []]);
Test Webhooks:
$this->post('/webhooks/orders', [
'topic' => 'orders/create',
'payload' => json_encode(['order_id' => 123])
]);
Session Expiry:
try {
$token = Shopify::getOnlineAccessToken($shop->domain);
} catch (\Exception $e) {
if ($e->getCode() === 401) {
$token = Shopify::refreshOnlineAccessToken($shop->domain);
}
}
Webhook Verification:
$isValid = Shopify::verifyWebhook($request);
if (!$isValid) {
abort(403, 'Invalid webhook signature');
}
Rate Limiting:
try {
$response = Shopify::call('GET', 'products', ['limit' => 250]);
} catch (\Kyon147\Shopify\Exceptions\RateLimitException $e) {
sleep($e->getRetryAfter());
retry();
}
Shop Context:
Shopify::setShop($shopDomain);
$products = Shopify::call('GET', 'products');
Config Overrides:
config(['shopify.api_key' => env('SHOPIFY_API_KEY')]);
Enable Logging:
config/shopify.php:
'log' => [
'enabled' => true,
'channel' => 'single',
],
tail -f storage/logs/laravel.log | grep shopify
API Response Inspection:
debug method to inspect raw responses:
$response = Shopify::call('GET', 'products', ['limit' => 1]);
Shopify::debug($response);
Common Errors:
InvalidShopDomain: Ensure the shop domain matches the installed shops.MissingScope: Verify your SHOPIFY_API_SCOPES include all required permissions.InvalidAccessToken: Regenerate tokens or check for typos in the shop domain.Custom API Endpoints:
ShopifyManager to add custom API routes:
public function extendApiRoutes() {
Route::get('/custom-endpoint', [CustomController::class, 'handle'])
->middleware(['shopify.auth']);
}
Webhook Handlers:
Shopify::onWebhook('orders/create', function ($payload) {
// Custom logic for order creation
});
Session Drivers:
Shopify::setSessionDriver(new RedisSessionDriver());
Billing Integration:
usage.recorded event to sync with a billing system:
Shopify::on('usage.recorded', function ($shop, $metric, $value) {
// Sync with Stripe/Paddle
});
Blade Directives:
Blade::directive('shopifyShop', function ($expression) {
return "<?php echo Shopify::getCurrentShop()->{$expression}; ?>";
});
Usage:
@shopifyShop('name')
SHOPIFY_API_HOSTNAME is set to the **How can I help you explore Laravel packages today?