### Implement After-Authenticate Job Source: https://context7.com/kyon147/laravel-shopify/llms.txt Define the logic for the job that runs after shop authentication. This example skips setup if already finished and optionally grandfather's affiliate/staff stores. ```php shop = $shop; } public function handle(): void { // Run only once — skip if already finished setup if ($this->shop->finished_setup) { return; } // Example: auto-grandfather affiliate/staff stores so they skip billing $planName = $this->shop->api() ->rest('GET', '/admin/shop.json')['body']['shop']['plan_name']; if (in_array($planName, ['affiliate', 'staff_business', 'shopify_plus'])) { $this->shop->shopify_grandfathered = true; } $this->shop->finished_setup = true; $this->shop->save(); } } ``` -------------------------------- ### Create Recurring Plan with Usage Charges Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App SQL statement to insert a new recurring plan. This example creates a plan named 'Test Plan' for $5.00 per 30 days, with 7 trial days, presented on install, and capable of issuing usage charges up to $10.00 with specified terms. ```sql INSERT INTO plans (`type`,`name`,`price`,`interval`,`capped_amount`,`terms`,`trial_days`,`test`,`on_install`,`created_at`,`updated_at`) VALUES ('RECURRING','Test Plan',5.00,'EVERY_30_DAYS',10.00,'Test terms',7,FALSE,1,NULL,NULL); ``` -------------------------------- ### Install Laravel Shopify Package Source: https://context7.com/kyon147/laravel-shopify/llms.txt Install the package using Composer and publish its configuration file. Run migrations to set up necessary database tables. ```bash composer remove osiset/laravel-shopify composer require kyon147/laravel-shopify php artisan vendor:publish --tag=shopify-config php artisan migrate ``` -------------------------------- ### Shop Install/Login Route Source: https://context7.com/kyon147/laravel-shopify/llms.txt Handles the initial shop installation or login process for the Shopify app. ```APIDOC ## GET /login ### Description This route serves as the entry point for shops to install or log in to the application. It typically redirects to Shopify's authorization flow. ### Method GET ### Endpoint /login ### Parameters None explicitly mentioned for this route. ### Request Example None provided. ### Response Typically a redirect to Shopify's authorization URL. ``` -------------------------------- ### Configure After-Authenticate Job Source: https://context7.com/kyon147/laravel-shopify/llms.txt Set up a job to run immediately after a shop installs or re-authenticates. Configure whether the job runs synchronously or is queued. ```php // config/shopify-app.php 'after_authenticate_job' => [ 'job' => \App\Jobs\AfterAuthenticateJob::class, 'inline' => true, // true = run synchronously before home loads; false = queue ] ``` -------------------------------- ### Run All Tests Source: https://github.com/kyon147/laravel-shopify/blob/master/CONTRIBUTING.md Execute all tests using PHPUnit after installing dependencies with Composer. ```bash composer install vendor/bin/phpunit ``` -------------------------------- ### Example of Setting App Bridge CDN URL Source: https://github.com/kyon147/laravel-shopify/wiki/Upgrading Examples of how to set the SHOPIFY_APPBRIDGE_CDN_URL environment variable to change the App Bridge CDN. ```bash SHOPIFY_APPBRIDGE_CDN_URL="https://cdn.jsdelivr.net/npm" SHOPIFY_APPBRIDGE_CDN_URL="https://unpkg.com" ``` -------------------------------- ### Making a REST API Call to Get Shop Information Source: https://github.com/kyon147/laravel-shopify/wiki/Usage Example of making a GET request to the '/admin/shop.json' endpoint to retrieve shop details and accessing the shop name. ```php $shop = Auth::user(); $request = $shop->api()->rest('GET', '/admin/shop.json'); // $request = $shop->api()->graph('{ shop { name } }'); echo $request['body']['shop']['name']; ``` -------------------------------- ### Enable Freemium Mode Configuration Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App Set this environment variable to 1 to allow freemium usage, skipping the billing section on install. Defaults to 0. ```env SHOPIFY_BILLING_FREEMIUM_ENABLED=1 ``` -------------------------------- ### Install Laravel Shopify Package Source: https://github.com/kyon147/laravel-shopify/blob/master/README.md Use Composer to add the package to your Laravel project. This command fetches and installs the latest version of the library. ```bash composer require kyon147/laravel-shopify ``` -------------------------------- ### Controller Example for Accessing Current Shop Source: https://github.com/kyon147/laravel-shopify/wiki/Usage This controller demonstrates how to access the authenticated shop's domain and retrieve shop information using the API. Ensure the route is protected by the 'verify.shopify' middleware. ```php getDomain()->toNative(); $shopApi = $shop->api()->rest('GET', '/admin/shop.json')['body']['shop']; Log::info("Shop {$domain}'s object:" . json_encode($shop)); Log::info("Shop {$domain}'s API objct:" . json_encode($shopApi)); return; } } ?> ``` -------------------------------- ### Modify AfterAuthenticateJob to set finished_setup Source: https://github.com/kyon147/laravel-shopify/wiki/Free-Access-Based-on-Shopify-Plan This modification to the 'handle' method in 'App\Jobs\AfterAuthenticateJob' checks if setup is already finished. If not, it determines the shop's plan and sets 'finished_setup' to true for 'affiliate' or 'staff_business' plans. ```php # Modify handle in App\Jobs\AfterAuthenticateJob public function handle() { if ($this->shop->finished_setup) { // Setup has finished, this should've ran by now, kill it return; } if (!$this->shop->isGrandfathered()) { $planName = $this->shop->api()->rest('GET', '/admin/shop.json')->body->shop->plan_name; if ($planName === 'affiliate' || $planName === 'staff_business') { $this->shop->shopify_grandfathered = true; $this->shop->finished_setup = true; $this->shop->save(); } } } ``` -------------------------------- ### Generate URL for New Page with Host Param Source: https://github.com/kyon147/laravel-shopify/wiki/Authentication-Process This example demonstrates using the `tokenRoute` helper to navigate to a new page, ensuring the 'host' parameter is passed along, which is crucial for Shopify requests. ```html New page ``` -------------------------------- ### Apply Billable Middleware to MPA Route Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App This example shows how to apply the 'billable' middleware to a specific route in a Multi-Page Application (MPA). This ensures that only shops with valid billing arrangements can access the route. ```php Route::get( '/settings', 'App\Controllers\SettingsController@index' ) ->middleware(['auth.shopify', 'billable']) // <--- ->name('settings'); ``` -------------------------------- ### Making a POST REST API Call with Payload Source: https://github.com/kyon147/laravel-shopify/wiki/Usage Example of making a POST request to create or update a customer, including sending a JSON payload. ```php $shop = Auth::user(); $request = $shop->api()->rest('POST', '/admin/api/customers/customer.json', ['customer' => "phone:{$phone}"]); echo $request['body']['customers']; ``` -------------------------------- ### Retrieve All Shop Instances Source: https://github.com/kyon147/laravel-shopify/wiki/Namespacing-Your-App Remove the global scope to query for all shop instances across all namespaces for a specific shop. This is useful when a shop is installed multiple times. ```php use App\User; use Osiset\ShopifyApp\Storage\Scopes\Namespacing; // ... $shopInstances = User::withoutGlobalScope(Namespacing::class)->where('name', 'example.myshopify.com')->get(); ``` -------------------------------- ### Setup Customer Data Request Webhook Job Source: https://github.com/kyon147/laravel-shopify/wiki/GDPR Artisan command to generate a job for handling the customers/data_request webhook. This job is used to gather and provide customer data to the shop owner. ```bash php artisan shopify-app:make:webhook CustomersDataRequestJob customers/data_request ``` -------------------------------- ### Shop Redact Job Implementation Source: https://github.com/kyon147/laravel-shopify/wiki/GDPR Example PHP job implementation for the shop/redact webhook. It finds the shop by domain and deletes the corresponding user record. ```php shopDomain = $shopDomain; $this->data = $data; } /** * Execute the job. * * @return void */ public function handle() { try { $shop = User::where('name', $this->shopDomain->toNative())->first(); $shop->delete(); return; } catch(\Exception $e) { Log::error($e->getMessage()); } } } ``` -------------------------------- ### Implementing a Plan Activated Email Listener Source: https://context7.com/kyon147/laravel-shopify/llms.txt Create a listener class that implements `ShouldQueue` to send an email when a Shopify plan is activated. This example demonstrates accessing event properties like shop details, plan information, and charge ID, and sending a custom `PlanActivatedMail`. ```php onQueue('default'); } // Available event properties: // PlanActivatedEvent -> $event->shop, $event->plan, $event->chargeId // AppInstalledEvent -> $event->shopId // ShopAuthenticatedEvent -> $event->shopId // ShopDeletedEvent -> $event->shop // AppUninstalledEvent -> $event->shop public function handle(PlanActivatedEvent $event): void { Mail::to($event->shop->email) ->send(new PlanActivatedMail($event->plan, $event->chargeId)); } } ``` -------------------------------- ### Seed Recurring Plan Source: https://context7.com/kyon147/laravel-shopify/llms.txt Insert a new recurring plan into the database. This plan will be automatically presented on install if `on_install` is set to 1. ```sql -- Seed a recurring plan (presented automatically on install when on_install = 1) INSERT INTO plans (type, name, price, `interval`, capped_amount, terms, trial_days, test, on_install, created_at, updated_at) VALUES ('RECURRING', 'Pro Plan', 9.99, 'EVERY_30_DAYS', 50.00, 'Usage billed per API call', 7, FALSE, 1, NOW(), NOW()); ``` -------------------------------- ### Configure Script Tags for Storefronts Source: https://context7.com/kyon147/laravel-shopify/llms.txt Configure the 'scripttags' array in shopify-app.php to automatically inject a JavaScript file into installed stores' storefronts. Ensure storefront.js is placed in public/js/. ```php // config/shopify-app.php 'api_scopes' => env('SHOPIFY_API_SCOPES', 'read_products,write_script_tags'), 'scripttags' => [ [ 'src' => env('SHOPIFY_SCRIPTTAG_1_SRC', env('APP_URL') . '/js/storefront.js'), 'event' => env('SHOPIFY_SCRIPTTAG_1_EVENT', 'onload'), 'display_scope' => env('SHOPIFY_SCRIPTTAG_1_DISPLAY_SCOPE', 'online_store'), ], ], // Place storefront.js in public/js/ // The package dispatches CreateScripts job on install/re-auth automatically. ``` -------------------------------- ### Define Proxy Route with Controller Source: https://github.com/kyon147/laravel-shopify/wiki/App-Proxies Define a GET route for your proxy that points to a controller method. Ensure you use the `auth.proxy` middleware to validate incoming proxy requests. ```php Route::get('/proxy', 'AppProxyController@index')->middleware('auth.proxy'); ``` -------------------------------- ### Remove Old Shopify Package Source: https://github.com/kyon147/laravel-shopify/wiki/Installation Before installing the new package, remove any existing osiset/laravel-shopify installations using Composer. ```bash composer remove osiset/laravel-shopify ``` -------------------------------- ### Set up package.json for Shopify App Extension Source: https://github.com/kyon147/laravel-shopify/wiki/How-to-create-App-Extension This JSON file defines the project's name, private status, license, and essential scripts for building, developing, and deploying your Shopify app extension. Ensure dependencies like `@shopify/app` and `@shopify/cli` are included. ```json { "name": "APP NAME HERE WITHOUT SPACE, REPLACE SPACE WITH hyphen ", // my-app "private": true, "license": "UNLICENSED", "scripts": { "shopify": "shopify", "build": "shopify app build", "dev": "shopify app dev", "info": "shopify app info", "scaffold": "shopify app scaffold", "deploy": "shopify app deploy" }, "dependencies": { "@shopify/app": "^3", "@shopify/cli": "^3" } } ``` -------------------------------- ### Implementing a Custom App Proxy Controller Source: https://context7.com/kyon147/laravel-shopify/llms.txt Create an `AppProxyController` to handle incoming proxy requests. This controller can access the shop domain from the request and return data in JSON or Liquid format. Ensure the `Content-Type` header is set appropriately for the response. ```php input('shop') contains the proxying shop's domain $shopDomain = $request->input('shop'); $data = ['message' => "Hello from {$shopDomain}!", 'items' => [1, 2, 3]]; return response(json_encode($data)) ->withHeaders(['Content-Type' => 'application/json']); // For Liquid responses: // return response('{{ shop.name }} has {{ cart.item_count }} items') // ->withHeaders(['Content-Type' => 'application/liquid']); } } // Shopify Partner dashboard: Extensions → Online Store → handle = apps/my-app // Proxy URL = https://your-domain.com/proxy ``` -------------------------------- ### Create SQLite Database File Source: https://github.com/kyon147/laravel-shopify/wiki/Developing-Locally Creates an empty SQLite database file. This command should be run in your project's root directory. After creation, update your `.env` file to use SQLite. ```bash touch databases/database.sqlite ``` -------------------------------- ### Run Package Test Suite Source: https://context7.com/kyon147/laravel-shopify/llms.txt Execute the package's own test suite. No .env file is required for this command. ```bash composer install composer run test ``` ```bash composer run test-html-cov ``` ```bash composer run test-no-cov ``` -------------------------------- ### Setup Customer Redact Webhook Job Source: https://github.com/kyon147/laravel-shopify/wiki/GDPR Artisan command to generate a job for handling the customers/redact webhook. This job is used to delete customer-specific information. ```bash php artisan shopify-app:make:webhook CustomersRedactJob customers/redact ``` -------------------------------- ### Publish Shopify Migrations Source: https://github.com/kyon147/laravel-shopify/wiki/Installation Execute this command to publish the package's migration files to your application's migration directory. ```bash php artisan vendor:publish --tag=shopify-migrations ``` -------------------------------- ### Add Billable Middleware for v2.0.0 Upgrade Source: https://github.com/kyon147/laravel-shopify/wiki/Upgrading Add the 'billable' middleware to your `app/Http/Kernel.php` file's `routeMiddleware` array to enable the billing feature on existing installs. ```php 'billable' => \OhMyBrew\ShopifyApp\Middleware\Billable::class, ``` -------------------------------- ### Simple Proxy Route Definition Source: https://github.com/kyon147/laravel-shopify/wiki/App-Proxies Create a basic proxy route that returns a simple 'Hello, world!' response with the `application/liquid` content type. This is useful for quick testing or simple embedded content. ```php Route::get('/proxy', function () { return response('Hello, world!')->withHeaders(['Content-Type' => 'application/liquid']); })->middleware('auth.proxy'); ``` -------------------------------- ### Setup Shop Redact Webhook Job Source: https://github.com/kyon147/laravel-shopify/wiki/GDPR Artisan command to generate a job for handling the shop/redact webhook. This job will be responsible for deleting shop-specific data from your database. ```bash php artisan shopify-app:make:webhook ShopRedactJob shop/redact ``` -------------------------------- ### Configure Billing Redirect Path Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App Set this environment variable to specify the URL path for handling application charge acceptance or decline. The default is /billing/process. ```env SHOPIFY_BILLING_REDIRECT="/url/path" ``` -------------------------------- ### Enable Billing Configuration Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App Set this environment variable to 1 to enable billing for your application. Defaults to 0. ```env SHOPIFY_BILLING_ENABLED=1 ``` -------------------------------- ### Making a REST API Call with Parameters Source: https://github.com/kyon147/laravel-shopify/wiki/Usage Demonstrates how to pass parameters to a REST API endpoint, such as searching for customers by phone number. ```php $shop = Auth::user(); $request = $shop->api()->rest('GET', '/admin/api/customers/search.json', ['query' => "phone:{$phone}"]); echo $request['body']['customers']; ``` -------------------------------- ### Run Migrations and Update Billing Configuration Source: https://github.com/kyon147/laravel-shopify/wiki/Upgrading When upgrading to v4.0.0, run the provided migrations to add new tables and columns for billing. Remove old billing environment values and add 'billing_freemium_enabled' to `config/shopify-app.php`. ```bash php artisan vendor:publish --tag=migrations php artisan migrate ``` -------------------------------- ### Accessing Authenticated Shop & Shopify API Source: https://context7.com/kyon147/laravel-shopify/llms.txt Use Auth::user() to get the current shop object and make REST or GraphQL API calls. Ensure the user is authenticated before accessing these methods. ```php getDomain()->toNative(); // e.g. "example.myshopify.com" // REST call $shopData = $shop->api()->rest('GET', '/admin/shop.json')['body']['shop']; // REST call with query params $customers = $shop->api()->rest( 'GET', '/admin/api/customers/search.json', ['query' => 'phone:+15551234567'] )['body']['customers']; // REST POST with payload $newProduct = $shop->api()->rest('POST', '/admin/api/products.json', [ 'product' => ['title' => 'New Widget', 'vendor' => 'Acme'] ])['body']['product']; // GraphQL call $result = $shop->api()->graph('{ shop { name currencyCode } }'); $name = $result['body']['data']['shop']['name']; return response()->json([ 'domain' => $domain, 'currency' => $result['body']['data']['shop']['currencyCode'], 'product' => $newProduct['id'] ?? null, ]); } } ``` -------------------------------- ### Configure Shopify App Environment Variables Source: https://context7.com/kyon147/laravel-shopify/llms.txt Set up required Shopify API credentials, redirect URIs, and other settings in your .env file. Ensure SHOPIFY_API_KEY and SHOPIFY_API_SECRET are correctly set. ```dotenv SHOPIFY_APP_NAME="My App" SHOPIFY_API_KEY=your_api_key SHOPIFY_API_SECRET=your_api_secret SHOPIFY_API_SCOPES=read_products,write_products SHOPIFY_API_REDIRECT=/authenticate SHOPIFY_FRONTEND_ENGINE=MPA SHOPIFY_APP_PREFIX=app SHOPIFY_BILLING_ENABLED=1 SHOPIFY_BILLING_FREEMIUM_ENABLED=0 SHOPIFY_BILLING_REDIRECT=/billing/process SHOPIFY_EXPIRING_OFFLINE_TOKENS=true SHOPIFY_MANUAL_MIGRATIONS=0 ``` -------------------------------- ### Registering Event Listeners in Laravel Shopify Source: https://context7.com/kyon147/laravel-shopify/llms.txt Configure event listeners in `config/shopify-app.php` to react to internal package events like app installation or uninstallation. Note that in Laravel 11+, listeners in `App\Listeners` are auto-discovered, so avoid duplicate registrations. ```php [ \Osiset\ShopifyApp\Messaging\Events\AppInstalledEvent::class => [ \App\Listeners\OnAppInstalled::class, ], \Osiset\ShopifyApp\Messaging\Events\ShopAuthenticatedEvent::class => [], \Osiset\ShopifyApp\Messaging\Events\ShopDeletedEvent::class => [], \Osiset\ShopifyApp\Messaging\Events\AppUninstalledEvent::class => [ \App\Listeners\OnAppUninstalled::class, ], \Osiset\ShopifyApp\Messaging\Events\PlanActivatedEvent::class => [ \App\Listeners\SendPlanActivatedEmail::class, ], ], // Note: In Laravel 11+ listeners in App\Listeners are auto-discovered; // adding them here too will cause them to fire twice. ``` -------------------------------- ### Publish Shopify Configuration File Source: https://github.com/kyon147/laravel-shopify/blob/master/README.md Run this Artisan command to publish the package's configuration file to your application's config directory. This allows for customization of package settings. ```bash php artisan vendor:publish --tag=shopify-config ``` -------------------------------- ### Configure Shopify App Callback and Redirect URIs Source: https://github.com/kyon147/laravel-shopify/wiki/Installation Set the callback and redirect URIs in your Shopify Partner dashboard. The callback URL points to your app's home route, and the redirect_uri points to the authentication route. Both must start with https. ```bash https://(your-domain).com/ ``` ```bash https://(your-domain).com/authenticate ``` -------------------------------- ### Configure App Uninstalled Webhook Source: https://github.com/kyon147/laravel-shopify/wiki/Installation Set up the `APP_UNINSTALLED` webhook in `config/shopify-app.php` to trigger the `AppUninstalledJob` when the application is uninstalled. ```php 'webhooks' => [ [ 'topic' => env('SHOPIFY_WEBHOOK_1_TOPIC', 'APP_UNINSTALLED'), 'address' => env('SHOPIFY_WEBHOOK_1_ADDRESS', 'https://(your-domain).com/webhook/app-uninstalled') ], ], ``` -------------------------------- ### Defining App Proxy Routes in Laravel Source: https://context7.com/kyon147/laravel-shopify/llms.txt Register routes for app proxies in `routes/web.php` using the `auth.proxy` middleware for HMAC verification. This allows serving Liquid-compatible content directly from a Shopify storefront URL. Examples include a general proxy route and a minimal inline proxy for status checks. ```php // routes/web.php — protected by auth.proxy (HMAC verification) Route::get('/proxy', App\Http\Controllers\AppProxyController::class) ->middleware('auth.proxy'); // Minimal inline proxy Route::get('/proxy/status', function () { return response('All systems go!') ->withHeaders(['Content-Type' => 'application/liquid']); })->middleware('auth.proxy'); ``` -------------------------------- ### Implement AfterAuthenticateJob for Free Access Source: https://github.com/kyon147/laravel-shopify/wiki/Free-Access-Based-on-Shopify-Plan Replace the contents of `App\Jobs\AfterAuthenticateJob` to check the shop's plan and grant grandfathered access if it matches. ```php shop = $shop; } /** * Execute the job. * * @return void */ public function handle() { if (!$this->shop->isGrandfathered()) { $planName = $this->shop->api()->rest('GET', '/admin/shop.json')->body->shop->plan_name; if ($planName === 'affiliate' || $planName === 'staff_business') { $this->shop->shopify_grandfathered = true; $this->shop->save(); } } } } ``` -------------------------------- ### Update Config Helper Usage Source: https://github.com/kyon147/laravel-shopify/wiki/Upgrading After removing the ConfigAccessible trait and ConfigHelper service, use the global helper function `getShopifyConfig` instead of `$this->getConfig`. Import the function using `use function Osiset\ShopifyApp\getShopifyConfig;`. ```php use function Osiset\ShopifyApp\getShopifyConfig; // ... // Instead of $this->getConfig('some_key') getShopifyConfig('some_key'); ``` -------------------------------- ### Create Usage Charge in Controller Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App This PHP code demonstrates how to define and create a usage charge. It includes the description, price, and an optional redirect URL. A signature is created to prevent tampering before generating the usage charge route. ```php # App/Http/Controllers/Example # ... public function index() { // Description and price of usage charge (the only two parameters required) $charge = [ 'description' => 'Five e-mails', 'price' => 1.00, 'redirect' => route('example.success') // Optional, if not supplied redirect goes back to previous page with flash `success`=`true` ]; // Create a signature to prevent tampering $signature = Util::createHmac(['data' => $charge, 'buildQuery' => true], Config::get('shopify-app.api_secret')); // Create the route $usageChargeRoute = route('billing.usage_charge', array_merge($charge, ['signature' => $signature->toNative()])); return view('example.index', compact('usageChargeRoute')); } ``` -------------------------------- ### Create After Authenticate Job Source: https://github.com/kyon147/laravel-shopify/wiki/After-Authentication-Job Use the Artisan command to generate a new job class for handling post-authentication tasks. ```bash php artisan make:job {YourJobName} ``` ```bash php artisan make:job AfterAuthenticateJob ``` -------------------------------- ### Configure Billing Settings Source: https://context7.com/kyon147/laravel-shopify/llms.txt Enable or disable various billing features and set the redirect URL for billing processes in the `shopify-app.php` configuration file. ```php // config/shopify-app.php — billing config 'billing_enabled' => env('SHOPIFY_BILLING_ENABLED', false), 'billing_freemium_enabled' => env('SHOPIFY_BILLING_FREEMIUM_ENABLED', false), 'billing_redirect' => env('SHOPIFY_BILLING_REDIRECT', '/billing/process'), ``` -------------------------------- ### Accessing Shop Plan Charges Source: https://github.com/kyon147/laravel-shopify/wiki/Usage This snippet shows how to retrieve a shop's plan charge using the ChargeHelper service, which is useful for managing subscriptions and payments. ```php use Osiset\ShopifyApp\Services\ChargeHelper; $shop = Auth::user(); $chargeHelper = app()->make(ChargeHelper::class); $charge = $chargeHelper->chargeForPlan($shop->plan->getId(), $shop); $chargeApi = $chargeHelper->useCharge($charge->getReference())->retrieve($shop); ``` -------------------------------- ### Registering Webhook Topics in Configuration Source: https://context7.com/kyon147/laravel-shopify/llms.txt Define webhook topics and their corresponding callback URLs in the shopify-app.php configuration file. Use the GraphQL enum format for topics. ```php // config/shopify-app.php — register webhook topics (GraphQL enum format) 'webhooks' => [ [ 'topic' => 'ORDERS_CREATE', 'address' => 'https://your-domain.com/webhook/orders-create', ], [ 'topic' => 'APP_UNINSTALLED', 'address' => 'https://your-domain.com/webhook/app-uninstalled', ], ], ``` -------------------------------- ### Configure App Namespace Source: https://github.com/kyon147/laravel-shopify/wiki/Namespacing-Your-App Modify the configuration file to set a namespace for your app. This is useful for running multiple apps on the same database instance. ```php /* |-------------------------------------------------------------------------- | Namespace |-------------------------------------------------------------------------- | | This option allows you to set a namespace. | Useful for multiple apps using the same database instance. | Meaning, one shop can be part of many apps on the same database. | */ 'namespace' => env('SHOPIFY_APP_NAMESPACE', null), ``` -------------------------------- ### Configure shopify.app.toml for App Extension Source: https://github.com/kyon147/laravel-shopify/wiki/How-to-create-App-Extension Add this TOML file to your new app extension directory to configure essential app details like name, scopes, API keys, and URLs. ```toml NAME = "YOUR APP NAME HERE" SCOPES = "YOUR SCOPES HERE" SHOPIFY_API_KEY = "YOUR SHOPIFY APP API KEY HERE" SHOPIFY_API_SECRET = "YOUR SHOPIFY APP SECRET HERE" APP_URL = "YOUR APP URL" HOS T = "YOUR APP HOST" PORT = "YOUR APP URL PORT" ``` -------------------------------- ### Link to Billing Screen with Host Parameter Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App When using a normal route link for billing, ensure you pass the 'host' parameter along with 'shop' to correctly direct the user to the billing screen for a specific plan. ```html

Upgrade

``` -------------------------------- ### Publish Shopify Jobs Source: https://github.com/kyon147/laravel-shopify/wiki/Installation Run this Artisan command to publish the `AppUninstalledJob` to your application's `App/Jobs` directory. ```bash php artisan vendor:publish --tag=shopify-jobs ``` -------------------------------- ### Environment Variables for Shop API Keys Source: https://github.com/kyon147/laravel-shopify/wiki/Multiple-Custom-Apps-on-Same-Codebase Define environment variables for each shop's API key and secret, prefixed with the shop's processed domain. This enables the dynamic key swapping mechanism. ```env API_KEY_CHARLESSTORE="66d7f69b713b201e06805db4d6f9bcefa" API_SECRET_CHARLESSTORE="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" ``` -------------------------------- ### Add finished_setup column to users table Source: https://github.com/kyon147/laravel-shopify/wiki/Free-Access-Based-on-Shopify-Plan This migration adds a boolean column 'finished_setup' with a default value of false to the users table. Run this migration using 'php artisan migrate'. ```php boolean('finished_setup')->default(false); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('finished_setup'); }); } } ``` -------------------------------- ### Redirect with Token (Controller) Source: https://github.com/kyon147/laravel-shopify/wiki/Authentication-Process Use this helper in a controller to perform a redirect that ensures a valid session token is obtained first. ```php Redirect::tokenRedirect('orders.view', ['id' => 1]); ``` -------------------------------- ### Dynamic API Key Configuration Source: https://github.com/kyon147/laravel-shopify/wiki/Multiple-Custom-Apps-on-Same-Codebase Configure the `config_api_callback` in `config/shopify-app.php` to dynamically fetch API keys from environment variables based on the shop domain. This allows a single codebase to be used for multiple custom apps. ```php use Osiset\ShopifyApp\Contracts\Objects\Values\ShopDomain as ShopDomainValue; use Illuminate\Support\Facades\Config; // ... 'config_api_callback' => function (string $key, $shop) { $fullKey = "shopify-app.{$key}"; if (! $shop) { // No shop passed, return default return Config::get($fullKey); } // Clean the shop domain $shopDomain = $shop instanceof ShopDomainValue ? $shop->toNative() : $shop; $shopDomain = preg_replace('/[^A-Z0-9]/', '', strtoupper(explode('.', $shopDomain)[0])); // Try to get env defined for shop, fallback to config value return env( strtoupper($key)."_" . $shopDomain, Config::get($fullKey) ); }, ``` -------------------------------- ### Create a Plan Activated Email Listener Source: https://github.com/kyon147/laravel-shopify/wiki/Event-Listener-System Implement a listener that sends an email to the store owner when a new plan is activated. This listener implements `ShouldQueue` for background processing and uses Laravel's Mail facade to send a custom `PlanActivatedMail`. ```php onQueue('default'); } /** * Handle the event. * * @param object $event * @return void */ public function handle(PlanActivatedEvent $event) { Mail::to($event->shop->email) ->send(new PlanActivatedMail($event->plan, $event->chargeId)); } } ``` -------------------------------- ### Set Redirect URI for Authentication Source: https://github.com/kyon147/laravel-shopify/wiki/Becoming-a-Shopify-App-Developer Specify this URI for handling authentication redirects during app development. Ensure it matches your local development server configuration. ```bash https://localhost:8000/authenticate ``` -------------------------------- ### Docker Compose Configuration Source: https://github.com/kyon147/laravel-shopify/wiki/Developing-Locally Defines the Nginx and PHP-FPM services for local development. Mounts project code and SSL certificates. Ensure your `.env` file is configured for SQLite or other database credentials. ```yaml nginx: image: nginx:latest ports: - '8000:443' volumes: - $PWD/default.conf:/etc/nginx/conf.d/default.conf - $PWD:/var/www/html - $PWD/ssl:/etc/nginx/ssl links: - php restart: always php: image: php:7-fpm volumes: - $PWD:/var/www/html ``` -------------------------------- ### Generating Webhook Jobs and Publishing Source: https://context7.com/kyon147/laravel-shopify/llms.txt Use Artisan commands to generate webhook handler jobs and publish pre-built jobs like AppUninstalledJob. The generated job file will be located in App/Jobs. ```bash # Generate a webhook job (creates App/Jobs/OrdersCreateJob.php) php artisan shopify-app:make:webhook OrdersCreateJob orders/create # Publish the built-in AppUninstalledJob php artisan vendor:publish --tag=shopify-jobs ``` -------------------------------- ### Link to New Plan Billing Screen Source: https://github.com/kyon147/laravel-shopify/wiki/Creating-a-Billable-App Use this method to direct a shop to the billing screen to accept a new charge for a specific plan. It utilizes the tokenRoute helper for convenience. ```html Move to plan 1 ``` -------------------------------- ### Define Custom Home Route Source: https://context7.com/kyon147/laravel-shopify/llms.txt After setting SHOPIFY_MANUAL_ROUTES=home in your environment file, define your custom home route in routes/web.php. ```php // routes/web.php — define your own home route after setting SHOPIFY_MANUAL_ROUTES=home Route::get('/app', App\Http\Controllers\HomeController::class) ->middleware(['verify.shopify']) ->name('home'); ``` -------------------------------- ### Create Usage Charge Source: https://context7.com/kyon147/laravel-shopify/llms.txt Programmatically create a usage charge for shops on recurring plans with a capped amount. This involves constructing charge details, creating a signature, and redirecting to the billing URL. ```php // Creating a usage charge (for shops on recurring plans with a capped_amount) use Osiset\ShopifyApp\Util; use Illuminate\Support\Facades\Config; public function addEmailCharge() { $charge = [ 'description' => '10 transactional emails', 'price' => 0.50, 'redirect' => route('dashboard'), ]; $signature = Util::createHmac( ['data' => $charge, 'buildQuery' => true], Config::get('shopify-app.api_secret') ); $url = route('billing.usage_charge', array_merge($charge, [ 'signature' => $signature->toNative(), ])); return redirect($url); } ``` -------------------------------- ### Set Home Route with Shopify Middleware Source: https://github.com/kyon147/laravel-shopify/wiki/Installation Modify your `routes/web.php` file to use the `verify.shopify` middleware and name the route 'home'. This ensures proper authentication for the home page. ```php Route::get('/', function () { return view('welcome'); })->middleware(['verify.shopify'])->name('home'); ``` -------------------------------- ### Configure Route Prefixes and Overrides Source: https://context7.com/kyon147/laravel-shopify/llms.txt Set environment variables to add a URL prefix to all package routes or override specific routes like 'home' and 'billing'. ```dotenv # Add /app prefix to all package routes SHOPIFY_APP_PREFIX=app SHOPIFY_API_REDIRECT=app/authenticate SHOPIFY_BILLING_REDIRECT=app/billing/process # Override specific routes so you can define your own controllers SHOPIFY_MANUAL_ROUTES=home,billing ```