Skip to content

Integrations

Location: dg_smart_pos_api/modules/Integrations. The stub for this page previously flagged that the module’s name suggested broader scope than the single model (PlatformProductMapping) found in an earlier scan. That model count is still accurate (Models/ really does hold only one class), but the module itself is broader than that: it owns storefront marketing/tag settings (Meta Pixel, Google Ads, GA4, GTM, Search Console verification), OAuth connect/disconnect for platform accounts, an inbound webhook receiver, and the per-variant sync-state tracking (PlatformProductMapping) between a store’s catalog and Meta Catalog / Google Merchant Center feeds. It leans on Ecommerce for the storefront/website/domain it configures and on Inventory for the stock/variant being mapped.

  • PlatformProductMapping - the only model in modules/Integrations/Models. Tracks one internal stock variant’s (internal_variant_id, belongs to Modules\Inventory\Models\NewStock) sync state against one external platform (platform, external_item_id), with a sync_status (pending/synced/failed_rejected/failed_transient), retry_count, last_synced_at, last_error.
  • Everything else the module reads/writes lives on central-DB models it does not own: App\Models\Website, App\Models\WebsiteMarketingSettings, App\Models\PlatformConnection, App\Models\PlatformConnectionEvent. This split (one tenant-scoped module model, several central models it operates on via tenancy()->central()) is why the module’s controllers explicitly wrap DB access in tenancy()->central(fn () => ...) closures rather than reading them directly.

Marketing settings (self-service, no OAuth)

Section titled “Marketing settings (self-service, no OAuth)”

MarketingSettingsController::show/update read and write WebsiteMarketingSettings (Pixel/GA4/GTM/verification IDs) for the current store’s website. show also returns feeds (the public google-merchant.xml/meta-catalog.csv URLs served from the shop’s own domain, not the API host) and a cached feed_readiness summary (total/ready/held_back/reasons) computed by ProductFeedQualification over StorefrontCatalogService::feedProducts(), cached 5 minutes per website since it walks the whole published catalogue. update skips readiness entirely since saving a Pixel ID can’t change it.

PlatformConnectionController::index/connect/disconnect are the tenant-side self-service surface: connect returns an authorization URL for the frontend to redirect the browser to (via PlatformConnectorRegistry::resolve($platform)->getAuthorizationUrl()), and disconnect looks up the store’s PlatformConnection row and hands it to the connector to tear down.

OAuth callback and webhooks (central, not tenant)

Section titled “OAuth callback and webhooks (central, not tenant)”

PlatformWebhookController::handle currently only logs the payload and returns 200 for any registered platform (always 200 even for an unregistered one, deliberately, so a provider doesn’t retry-storm a dead endpoint) - per its own docblock, this was built ahead of Phase 3 connector work, so no connector consumes the webhook body yet.

Tenant-scoped, auth:sanctum, prefix integrations/stores/{store}, registered via modules/Integrations/Routes/integrations.php (required from routes/tenant.php):

Method Path Controller method Permission
GET marketing-settings MarketingSettingsController::show storefront:view-settings
PUT marketing-settings MarketingSettingsController::update storefront:manage-settings
GET platform-connections PlatformConnectionController::index storefront:view-settings
POST platform-connections/{platform}/connect PlatformConnectionController::connect storefront:manage-settings
POST platform-connections/{platform}/disconnect PlatformConnectionController::disconnect storefront:manage-settings

Central, no tenancy middleware, no X-Tenant-ID header, registered directly in routes/api.php:

Method Path Controller method
GET integrations/{platform}/callback PlatformOAuthCallbackController::handle
POST integrations/{platform}/webhook PlatformWebhookController::handle

A comment on the tenant-route registration in routes/tenant.php notes that MarketingSettingsController and PlatformConnectionController were pre-existing but “never wired into tenant.php until now” before this require was added, meaning they were previously unreachable from an actual tenant request despite existing in code.

  • Ecommerce - the storefront/website these settings and feeds belong to
  • Inventory - PlatformProductMapping.internal_variant_id points at a stock variant
  • Tuma - listed as a required dependency in config/modules.php