Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.digifist.com/llms.txt

Use this file to discover all available pages before exploring further.

Galantis interacts with Shopify exclusively through the Shopify Admin GraphQL API, using ShopifySdkService as the internal client. The API is used for four categories of operations: fetching initial and on-demand data, managing webhook subscriptions, polling for abandoned checkouts, and managing app subscriptions through Shopify’s billing system.

What this covers

  • How ShopifySdkService works
  • The four categories of Shopify Admin API usage
  • Specific GraphQL operations per category
  • Authentication and per-tenant token management

ShopifySdkService

ShopifySdkService is Galantis’s abstraction layer over the Shopify Admin GraphQL API. All Shopify API calls are routed through this service — application code never constructs raw GraphQL queries or manages access tokens directly. ShopifySdkService handles:
  • Resolving the correct tenant’s encrypted Shopify access token per request
  • Constructing authenticated GraphQL requests to https://{shop}.myshopify.com/admin/api/graphql.json
  • Handling response parsing and GraphQL error mapping
  • Managing pagination for queries that return large result sets

Data fetching

Initial customer and product import

At app installation, Galantis runs a full import of the store’s existing data via paginated GraphQL queries. This populates the Galantis database with all customers, orders, products, and collections that exist at the time of installation. Queries used:
  • customers — fetches all customer records with phone, email, name, tags, marketing consent, and locale
  • orders — fetches order history per customer for segment rule evaluation and Inbox context
  • products — fetches the full product catalog with variants, pricing, images, tags, and collection memberships
  • collections — fetches all collections and their product associations
These are paginated queries using Shopify’s cursor-based pagination (after / pageInfo.hasNextPage). Large stores with thousands of customers or products are fetched in batches across multiple queries.

On-demand data fetching

Beyond the initial import, ShopifySdkService is used for targeted data fetches when specific records are needed:
  • Fetching a specific customer record when a webhook payload contains only an ID and the full record is needed for context
  • Fetching order details for automation condition evaluation when order data is incomplete from the webhook payload
  • Re-fetching a product record when a sync error has left a Galantis record inconsistent with Shopify

Webhook management

Galantis registers its webhook subscriptions with Shopify via the Admin GraphQL API during installation and manages them through the same API throughout the app lifecycle. Relevant GraphQL mutations:
mutation webhookSubscriptionCreate($topic: WebhookSubscriptionTopic!, $webhookSubscription: WebhookSubscriptionInput!) {
  webhookSubscriptionCreate(topic: $topic, webhookSubscription: $webhookSubscription) {
    webhookSubscription {
      id
      topic
      endpoint {
        ... on WebhookHttpEndpoint {
          callbackUrl
        }
      }
    }
    userErrors {
      field
      message
    }
  }
}
Webhook subscriptions are created once at installation and persist for the lifetime of the app installation. Galantis does not need to re-register webhooks on each request — they remain registered until the app is uninstalled or the webhook subscription is explicitly deleted. Webhook topics registered: All webhook topics registered by Galantis are documented in the complete reference in Webhooks Reference. The registration covers customers, orders, products, collections, consent, billing, app lifecycle, and GDPR compliance topics.

Abandoned checkout polling

The read_checkouts permission grants Galantis access to query for incomplete checkout records. Unlike other data types, abandoned checkouts have no real-time webhook — detection requires polling. GraphQL query pattern:
query {
  checkouts(first: 250, query: "created_at:>'{recency_threshold}' AND completed_at:null") {
    edges {
      node {
        id
        createdAt
        updatedAt
        lineItems(first: 10) {
          edges {
            node {
              title
              quantity
              variant {
                id
                price
              }
            }
          }
        }
        email
        phone
        totalPriceV2 {
          amount
          currencyCode
        }
      }
    }
  }
}
This query runs every 10 minutes per active tenant. Results are filtered to identify checkouts that:
  • Were created within the qualifying recency window
  • Have not been completed (completed_at:null)
  • Have an associated customer with a WhatsApp phone number
Matching checkouts fire the ABANDONED_CHECKOUT automation trigger for the associated customer, subject to frequency cap and consent checks. See Integrations — Abandoned Checkout for the timing implications and edge cases.

Billing

Galantis uses Shopify’s app billing system for subscription management. All billing operations — creating subscriptions, processing plan changes, handling trial periods — go through the Shopify Admin GraphQL API’s billing mutations and are surfaced to merchants through Shopify’s native billing UI. Relevant billing operations:
# Create a recurring app subscription
mutation appSubscriptionCreate {
  appSubscriptionCreate(
    name: "{plan_name}"
    lineItems: [{
      plan: {
        appRecurringPricingDetails: {
          price: { amount: "{price}", currencyCode: USD }
          interval: EVERY_30_DAYS
        }
      }
    }]
    returnUrl: "{return_url}"
    test: false
  ) {
    appSubscription { id status }
    confirmationUrl
    userErrors { field message }
  }
}
Plan changes and upgrades are handled via UpdateSubscriptionController, which calls the appropriate Shopify billing mutation for the new plan configuration. Free trial activation is handled via BillingStartFreeTrialController. Subscription status changes from Shopify — approvals, cancellations, billing failures — arrive via the app_subscriptions/update webhook and are processed by MonitorBillingSubscriptionsJob.

Error handling

ShopifySdkService maps Shopify GraphQL errors to application-level exceptions with structured error details. Common error categories:
Error typeCauseHandling
Authentication errorAccess token expired or revokedJob fails; surfaces as integration error requiring reinstallation
Rate limit error (THROTTLED)Too many API calls in a short periodExponential backoff retry via queue
Resource not foundRecord deleted in Shopify before the fetch completedRecord marked as deleted in Galantis
userErrors in mutation responseInvalid input dataLogged with details; surfaced as a job failure
All errors are logged to Laravel Nightwatch with the tenant context, job payload, and full GraphQL response for diagnostic review.