Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Basic Shopify Api Laravel Package

osiset/basic-shopify-api

A lightweight PHP library for Shopify’s REST and GraphQL Admin APIs. Provides a clean client, request/response handling, pagination helpers, rate limit awareness, and easy authentication setup. Ideal for building Shopify apps or integrating stores in any PHP project.

View on GitHub
Deep Wiki
Context7
## Getting Started

### **First Steps**
1. **Installation**
   ```bash
   composer require osiset/basic-shopify-api:^10.0

Register the service provider in config/app.php:

'providers' => [
    // ...
    Osiset\BasicShopifyApi\ShopifyServiceProvider::class,
],
  1. Configuration Publish the config file:

    php artisan vendor:publish --provider="Osiset\BasicShopifyApi\ShopifyServiceProvider" --tag="config"
    

    Update .env with your Shopify API credentials:

    SHOPIFY_API_KEY=your_api_key
    SHOPIFY_API_SECRET=your_api_secret
    SHOPIFY_STORE_DOMAIN=your-store.myshopify.com
    
  2. First API Call (REST Example)

    use Osiset\BasicShopifyApi\Facades\Shopify;
    
    // PHP 8.1+ iterable support
    foreach (Shopify::get('/admin/api/2023-07/products.json') as $product) {
        // Process each product
    }
    
    // Or with a model:
    $product = Shopify::product()->find(123456789);
    
  3. GraphQL Example (Private Calls)

    $query = '
        query {
            privateMetafields {
                edges {
                    node {
                        key
                        value
                    }
                }
            }
        }
    ';
    $result = Shopify::graphql()->query($query);
    

Implementation Patterns

Common Workflows

  1. CRUD Operations with PHP 8.1 Iterables

    // Create
    $product = Shopify::product()->create([
        'title' => 'New Product',
        'body_html' => '<p>Description</p>',
    ]);
    
    // Read (PHP 8.1 iterable support)
    foreach (Shopify::product()->all() as $product) {
        echo $product->title;
    }
    
    // Update
    $product->update(['title' => 'Updated Title']);
    
    // Delete
    $product->delete();
    
  2. Bulk Operations

    // Bulk create (REST)
    $products = Shopify::post('/admin/api/2023-07/products.json', [
        'products' => [
            ['title' => 'Product 1'],
            ['title' => 'Product 2'],
        ],
    ]);
    
    // GraphQL bulk operations
    $query = '
        mutation {
            bulkOperationRunQuery(
                query: "mutation { productCreate(input: {title: \"Bulk Product\"}) { product { id } } }"
            ) {
                bulkOperation { id }
            }
        }
    ';
    Shopify::graphql()->query($query);
    
  3. Webhook Handling Configure webhooks in config/shopify.php:

    'webhooks' => [
        'topics' => ['orders/create', 'products/update'],
        'handlers' => [
            'orders/create' => \App\Http\Controllers\ShopifyWebhookController::class . '@handleOrderCreate',
            'products/update' => \App\Http\Controllers\ShopifyWebhookController::class . '@handleProductUpdate',
        ],
    ],
    
  4. Pagination with PHP 8.1 Iterables

    // REST pagination
    foreach (Shopify::product()->all(['limit' => 50]) as $product) {
        // Process each product
    }
    
    // GraphQL cursor-based pagination
    $query = '
        query {
            products(first: 25, after: "cursor") {
                edges { cursor }
                pageInfo { hasNextPage }
            }
        }
    ';
    $result = Shopify::graphql()->query($query);
    
  5. Error Handling

    try {
        $product = Shopify::product()->find(999999999); // Non-existent product
    } catch (\Osiset\BasicShopifyApi\Exceptions\ShopifyException $e) {
        logger()->error($e->getMessage());
    }
    

Integration Tips

  • Laravel Eloquent Models Extend the package’s models to add custom logic:

    use Osiset\BasicShopifyApi\Models\Product;
    
    class CustomProduct extends Product {
        public function getFormattedTitle(): string {
            return strtoupper($this->title);
        }
    }
    
  • Caching Responses Cache API responses to reduce calls:

    $products = Cache::remember('shopify_products', now()->addHours(1), function () {
        return Shopify::product()->all();
    });
    
  • Rate Limiting Use Laravel’s rate limiter middleware for Shopify API endpoints:

    Route::middleware(['throttle:10,1'])->group(function () {
        Route::get('/shopify/products', [ShopifyController::class, 'index']);
    });
    
  • Testing with PHP 8.1 Types Use the ShopifyMock facade for unit tests:

    use Osiset\BasicShopifyApi\Facades\ShopifyMock;
    
    public function test_product_creation(): void {
        ShopifyMock::shouldReceive('post')
                   ->once()
                   ->with('/admin/api/2023-07/products.json', ['title' => 'Test'])
                   ->andReturn(['product' => ['id' => 123]]);
    
        $product = Shopify::product()->create(['title' => 'Test']);
        $this->assertEquals(123, $product->id);
    }
    

Gotchas and Tips

Pitfalls

  1. PHP 8.1 Type Changes

    • The package now enforces stricter iterable return types. Ensure your code handles iterables properly:
      // Old way (may not work in PHP 8.1)
      $products = Shopify::product()->all();
      foreach ($products as $product) { ... }
      
      // New way (explicit iterable handling)
      foreach (Shopify::product()->all() as $product) { ... }
      
  2. GraphQL Private Calls

    • Private GraphQL calls (e.g., privateMetafields) require explicit permission scopes. Ensure your API key has the correct access:
      // Example of accessing private data
      $query = '
          query {
              privateMetafields(first: 10) {
                  edges {
                      node {
                          namespace
                          key
                      }
                  }
              }
          }
      ';
      
  3. API Versioning

    • The package defaults to 2023-07. Update if needed:
      Shopify::setApiVersion('2023-10'); // Update if required
      
  4. Webhook Verification

    • Always verify webhook signatures to prevent spoofing:
      use Osiset\BasicShopifyApi\Facades\Shopify;
      
      $isValid = Shopify::verifyWebhook($request->header('X-Shopify-Hmac-Sha256'), $request->getContent());
      
  5. Rate Limits

    • Shopify enforces rate limits (e.g., 2 calls/second for REST). Use exponential backoff:
      use Osiset\BasicShopifyApi\Exceptions\RateLimitExceededException;
      
      try {
          $response = Shopify::get('/admin/api/2023-07/products.json');
      } catch (RateLimitExceededException $e) {
          sleep($e->getRetryAfter());
          retry();
      }
      

Debugging Tips

  1. Enable Debugging Set debug to true in config/shopify.php to log raw responses:

    'debug' => env('SHOPIFY_DEBUG', false),
    
  2. Log Raw Responses Use a middleware to log requests/responses:

    Shopify::extend(function ($client) {
        $client->getEmitter()->attach(
            Subscriber::fromCallable(function ($request, $options, $context) {
                logger()->debug('Shopify Request:', [
                    'url' => (string) $request->getUri(),
                    'method' => $request->getMethod(),
                    'body' => $request->getBody() ? $request->getBody()->getContents() : null,
                ]);
            })
        );
    });
    
  3. Common Errors

    • 404 Not Found: Verify endpoint URLs (e.g., /products vs. /products.json).
    • 422 Unprocessable Entity: Validate input data against Shopify’s schema.
    • 401 Unauthorized: Regenerate API credentials or check scopes.

Extension Points

  1. Custom Endpoints Extend the client to add non-standard endpoints:
    Shopify::extend(function ($client) {
        $client->customEndpoint = function ($method, $uri, $data = []) {
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle