Overview
This documentation describes how to register and configure a Shopify Public App in the Shopify Dev Dashboard and integrate it into AdlerDo V6.1 for OAuth installation. The process produces a Client ID and Client Secret that AdlerDo uses to authenticate against any Shopify store installing the app.
Architecture context
AdlerDo exposes /api/shopify/install as the OAuth entry point. The Dev Dashboard app redirects every install request to this endpoint, which performs the OAuth code exchange, persists the access token in the tenant database, and registers required webhooks via Hangfire background jobs.
Prerequisites
Before starting, ensure:
- Access to the TecSee GmbH Shopify Organization with permission to manage apps
- AdlerDo middleware deployed and reachable over HTTPS at the public host configured for the target environment
- The endpoints
/api/shopify/install and /api/shopify/callback are reachable and return valid responses
- A development store is available for end-to-end testing before promoting credentials to production
- The list of OAuth scopes required by AdlerDo has been finalized and stored in configuration
Step 1 — Open the App Development Page

Sign in to the Shopify Organization and navigate to Settings → Apps and sales channels → App development. Click the "Build apps in Dev Dashboard" button.
Important: Do NOT use the "Create an app" button under the Legacy custom apps panel. Legacy custom apps will stop working for new merchants on January 1, 2026.
Step 2 — Create a New App in the Dev Dashboard

The Dev Dashboard opens at dev.shopify.com/dashboard/{organizationId}/apps. Click the "Create app" button in the upper-right corner of the Apps list.
Step 3 — Choose a Creation Path and Set the App Name

Two creation paths are offered:
- Start with Shopify CLI — scaffolds a Node/Remix project locally. AdlerDo does not need this path.
- Start from Dev Dashboard — registers app metadata directly in the dashboard and immediately produces a Client ID and Secret. Use this path for AdlerDo.
Enter the app name (for example: AdlerDo) and click Create.
Naming convention
Use a stable, customer-facing name shown on the install consent screen. For TecSee, prefix per environment if needed: AdlerDo (Production), AdlerDo Staging, AdlerDo Dev.
Step 4 — Configure URLs, Webhooks Version and Scopes

After creation, the app opens on the Versions tab with a new draft version. This is where the install URL, webhooks API version, and scopes are defined.
6.1 App URL
Set App URL to the public AdlerDo install endpoint:
https://whlvm133440.wawihost.de/api/shopify/install
This URL is what Shopify redirects to when a merchant installs the app. AdlerDo's ShopifyInstallController reads the shop and hmac query parameters, validates the HMAC, and redirects to Shopify's OAuth grant page.
6.2 Embed app in Shopify admin
Leave the "Embed app in Shopify admin" checkbox enabled. AdlerDo serves an embedded admin UI inside the Shopify admin frame using App Bridge.
6.3 Preferences URL
Optional. Leave empty unless the app exposes a separate settings page outside the embedded experience.
6.4 Webhooks API version
Pin the webhooks API version explicitly. The example shows 2026-04, which is the version AdlerDo currently consumes. Bumping this value requires reviewing every webhook payload mapping.
6.5 Access scopes
Click "Select scopes" and tick the scopes AdlerDo requires. Keep the list to the minimum AdlerDo actually uses — merchants see the full list on the install consent screen.
The exact same list must also be persisted in AdlerDo configuration (appsettings.Shopify.json → Shopify:Scopes) because the install controller passes it as the scope query parameter. A mismatch will force re-installs.
Optional vs. required scopes
Optional scopes can be requested at runtime after install. AdlerDo treats all listed scopes as required during the initial install, so leave the Optional scopes block empty.
6.6 Redirect URLs
Add the OAuth redirect URL — the public URL of the AdlerDo OAuth callback:
https://whlvm133440.wawihost.de/api/shopify/callback
Add one redirect URL per environment. Shopify rejects the OAuth callback if the URL provided in the redirect_uri parameter is not on this whitelist.
Step 5 — Release the Version

After saving all fields, click Release at the bottom of the version page.
- Version name — a human-readable label. TecSee convention:
alderdoo-{n} where n is the auto-incrementing release number
- Version message — a short changelog (e.g., "added read_locales scope", "bumped webhooks API to 2026-04")
Click Release. The new version becomes Active immediately and replaces the previous Active version for all new installs.
Scope changes after release
Adding a new scope to a released version does NOT automatically grant it on already-installed shops. The shop owner must approve a re-authorization. AdlerDo detects scope drift on each request and triggers a re-install redirect when needed.
Step 6 — Verify the Active Version

Open the Versions tab from the left sidebar. The most recently released version is marked with the green "Active" badge. All previous versions remain visible for audit purposes.
From this view you can click any historical version to inspect its configuration, useful when debugging an install on an older shop.
Step 7 — Retrieve Client ID and Secret

Open the Settings tab from the left sidebar. The Credentials block at the top exposes the Client ID and Secret.
9.1 Client ID
Public identifier. Safe to commit to configuration. Copy it via the clipboard icon and paste into AdlerDo configuration.
9.2 Client Secret
Sensitive. Treat as a credential. The secret is only displayed once when first generated; afterwards only the obscured form is shown. Use the eye icon to reveal it once for copying, then store it via the standard AdlerDo secret-storage path.
In AdlerDo, secrets for marketplace integrations are persisted AES-256 encrypted in the tenant DB through MarketplaceCredentialEncryptor.
9.3 Rotating the Secret
Click Rotate to generate a new secret. The previous secret is invalidated immediately. Coordinate the rotation with a deployment of the new secret to AdlerDo.
9.4 API contact email
Set this to a monitored mailbox (currently dev@tecsee.de). Shopify sends API deprecation notices and security advisories to this address.
Wiring the Credentials into AdlerDo
Once the Client ID and Secret are in hand, add the credentials to AdlerDo configuration.
10.1 Configuration
Add the following block to the environment-specific configuration:
"Shopify": {
"ClientId": "1d15c8413f636e7cfda6f4402d9ef552",
"ClientSecret": "<from Settings page>",
"Scopes": "read_products,write_products,read_orders,write_orders,…",
"WebhooksApiVersion": "2026-04",
"InstallRedirectUrl": "https://whlvm133440.wawihost.de/api/shopify/callback"
}
10.2 Install flow
The end-to-end install handshake is:
- Merchant clicks the install link → Shopify redirects to App URL with shop and hmac query parameters
- AdlerDo
/api/shopify/install validates the HMAC against the Client Secret and redirects to https://{shop}/admin/oauth/authorize with the configured scope list and a generated state nonce
- Merchant approves the scopes on the Shopify consent screen
- Shopify redirects to
/api/shopify/callback with code, hmac and state parameters
- AdlerDo validates the HMAC and the state nonce, then POSTs code + Client ID + Client Secret to
https://{shop}/admin/oauth/access_token to receive the offline access token
- The token is stored AES-256 encrypted against the tenant; webhook subscriptions and recurring sync Hangfire jobs are registered
- AdlerDo redirects the merchant to the embedded admin URL
10.3 Verifying the install
After the handshake:
- Confirm a new
ShopifyConnection entity exists in the tenant DB with non-null EncryptedAccessToken and the granted scope list
- Confirm the recurring jobs (
SyncShopifyOrdersV2026, SyncShopifyProductsV2026) are registered in Hangfire under the new tenant identifier
- Trigger a test webhook from the Shopify admin and confirm AdlerDo handler processes it without HMAC errors
Appendix A — Common Scopes Used by AdlerDo
| Scope |
Purpose in AdlerDo |
read_products, write_products |
Catalog sync: create/update products and variants from Odoo or JTL-Wawi |
read_orders, write_orders |
Pull orders into AdlerDo and push order edits / fulfillments back |
read_inventory, write_inventory |
Stock-level sync per location |
read_locations |
Resolve fulfillment locations for inventory and shipping |
read_fulfillments, write_fulfillments |
Create fulfillments and push tracking numbers from carriers: DHL, GLS, DPD, DB Schenker |
read_assigned_fulfillment_orders, write_assigned_fulfillment_orders |
Required when AdlerDo acts as a registered fulfillment service |
read_customers, write_customers |
Customer sync and B2B segmentation |
read_shipping |
Read carrier and zone configuration for rate calculation |
read_app_proxy, write_app_proxy |
Required for the embedded admin proxy routes |
read_analytics |
Reporting dashboards in the embedded admin |
Appendix B — Troubleshooting
Install redirect returns 401 / Invalid HMAC
Cause: Client Secret in AdlerDo configuration does not match the secret in Settings, or the secret was rotated without redeploying.
Action: Copy the secret from the Dev Dashboard Settings page and redeploy.
OAuth callback returns 'redirect_uri is not whitelisted'
Cause: The callback URL is not present in the Redirect URLs field of the active version.
Action: Open the active version, add the URL, release a new version, retry the install.
Shop installs but no Hangfire jobs appear
Cause: The OAuth code exchange succeeded but the post-install bootstrap failed (e.g., tenant provisioning).
Action: Inspect AdlerDo logs around the install timestamp; the ShopifyInstallController emits an Information log per stage and an Error log with the offending step.
Webhook deliveries fail with HMAC errors
Cause: AdlerDo computed the webhook HMAC over a parsed payload instead of the raw body.
Action: Confirm the request middleware buffers the raw request body before model binding for /api/shopify/webhooks/* routes.
Merchant reports missing data after a scope addition
Cause: The shop was installed against an older version that did not include the scope.
Action: Trigger a re-install redirect — AdlerDo detects scope drift in ShopifyConnectionMiddleware and redirects to the install endpoint, where the merchant approves the new scope.