Back to Blog
Salesforce

How to Create a Shopify Custom App and Admin API Token for a Salesforce Integration

TS

Tushar Sharma

Chief Executive Officer

9 min read - Jun 29, 2026

The Token Comes Before the Integration

Every Shopify to Salesforce integration starts in the same place, and it is not Salesforce. Before one order, product, or customer record can land in your org, Shopify needs to know exactly who is calling its Admin API and what they are allowed to touch. The answer is a custom app plus an access token sent in the X-Shopify-Access-Token header on every request. Get this right and the Salesforce side is twenty minutes of clicking. Get it wrong and you will lose a day to identical-looking 401s.

This article is the zoomed-in first step of our full technical guide at cloudsheer.com/integrations/shopify/technical-guide. We have shipped this exact setup across 5 client projects, and the same three traps appear every time: a token shown exactly once, the January 1, 2026 cutoff that closed the classic custom app flow, and two Salesforce checkboxes that silently break the header.

What You Need Before You Start

  • Shopify store owner access, or a staff account with the app development permission. Collaborator accounts cannot use the Dev Dashboard, it is an org-level permission.
  • The exact myshopify.com subdomain of the store. Tokens are store-specific, calling a custom domain or the wrong subdomain returns 401.
  • A Salesforce org, sandbox first, where you can create External Credentials, Named Credentials, and permission sets.
  • A secret manager open before you click anything. One token in this flow is displayed exactly once.
  • A scope decision. This tutorial grants read_orders, read_products, and read_customers, and explains when you also need read_all_orders.

Step 1: Pick Your Path, Legacy Custom App or Dev Dashboard

Since January 1, 2026, Shopify no longer lets you create new custom apps from Shopify admin under Settings > Apps and sales channels > Develop apps. Apps created before that date keep working and are still managed there, but every new app must be created in the Dev Dashboard at https://dev.shopify.com/dashboard/. The difference matters for Salesforce. Legacy custom apps issue a static shpat_ token that never expires, the simplest thing to wire into a Named Credential. Dev Dashboard apps use a client credentials grant whose tokens expire roughly every 24 hours, so a static paste into Salesforce dies daily unless you build a refresh job.

If the store already has a pre-2026 custom app, use it and continue with Step 2. Starting fresh, skip to Step 3 and plan for token refresh from day one.

Step 2: Legacy Path, Configure Scopes, Install, and Reveal the Token Once

  • In Shopify admin, open Settings > Apps and sales channels > Develop apps and select your existing app. If app development was never enabled, the store owner must click Allow custom app development, then confirm it a second time.
  • On the Configuration tab, under Admin API integration, click Configure Admin API scopes. Check read_orders, read_products, and read_customers, then Save. read_orders only returns the last 60 days of orders, add read_all_orders for older history. The same panel sets the webhook Event version, pick the newest stable API version.
  • Open the API credentials tab, click Install app, then click Install in the confirmation modal.
  • Under Admin API access token, click Reveal token once. The button means it. Copy the shpat_ token into your secret manager immediately, no email, no Slack, no spreadsheet. Lose it and the only recovery is Uninstall app plus reinstall, which regenerates the token and the API key and secret and breaks webhook HMAC verification.
  • The API secret key on the same page is the HMAC signing key for this app's webhooks, save it too.

Step 3: New Path, Create the App in the Dev Dashboard

  • Go to https://dev.shopify.com/dashboard/, click Apps in the left nav, then Create app at the top right. Choose Start from Dev Dashboard, enter an app name, and click Create.
  • Open the Versions tab. Set the App URL, the default https://shopify.dev/apps/default-app-home is fine for an API-only app. Pick the newest Webhooks API version, add read_orders, read_products, and read_customers under Access scopes, then click Release.
  • On the Home panel, scroll to Install app, select the target store, and click Install. Scopes lock at install time, adding one later means a new release and reinstall.
  • Open the app's Settings and copy the Client ID and Client secret. These stay viewable, unlike the legacy token, but treat the secret like a production password from this second onward.
  • Know the approval wall: protected customer data, names, emails, addresses, and phones on customers and orders, requires Shopify approval, and the API silently omits those fields on non-development stores until you are approved.

Step 4: Exchange the Client Credentials for a 24-Hour Token

Dev Dashboard apps never show you a token, you mint one. POST to https://yourstore.myshopify.com/admin/oauth/access_token with the form body grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET. The response contains access_token, scope, and expires_in: 86399. There is no redirect URI and no consent screen, because this grant only works for apps your own organization built and installed on stores you own.

The Salesforce implication is blunt: the token dies in about 24 hours. Our production pattern is a scheduled Apex job that reruns this exchange and updates the External Credential's authentication parameter through the Connect API before expiry. If that is more machinery than you want and a pre-2026 legacy app exists, the static shpat_ token is the simpler wire.

Step 5: Create the External Credential in Salesforce

  • In Setup, type Named Credentials into Quick Find, open the External Credentials subtab, and click New. Label: Shopify Admin API. Name: ShopifyAdminAPI. Authentication Protocol: Custom. Save.
  • Under Permission Set Mappings, click New. Pick the integration user's permission set, set a Sequence Number, and choose Identity Type Named Principal so every mapped user shares the one store token. Under Authentication Parameters click Add: Name ShopifyToken, Value your shpat_ or 24-hour token. Save. The value is masked from then on, paste it exactly.
  • Under Custom Headers, click New. Name: X-Shopify-Access-Token. Value: {!$Credential.ShopifyAdminAPI.ShopifyToken}. The container is the External Credential API name and the second segment is the auth parameter you just created. Keep the default Sequence Number and Save.

Step 6: Create the Named Credential and Grant Principal Access

  • Switch to the Named Credentials subtab and click New. Label and Name: Shopify. URL: https://yourstore.myshopify.com. Keep the /admin/api/{version} segment in your callout path, not in this URL, so quarterly Shopify version bumps never require editing the credential.
  • Set External Credential to ShopifyAdminAPI. Then the two checkboxes that cause most silent failures: uncheck Generate Authorization Header and check Allow Formulas in HTTP Header. Save.
  • Assign the mapped permission set to the integration user, and on that permission set grant External Credential Principal Access to the ShopifyAdminAPI principal. Yes, even System Administrators need this.
  • Non-admin users also need object CRUD on User External Credentials, or callouts fail before leaving the org.

Step 7: Smoke Test with a Real GraphQL Call

Open Developer Console, then Debug > Open Execute Anonymous Window, and run: HttpRequest req = new HttpRequest(); req.setEndpoint('callout:Shopify/admin/api/2026-07/graphql.json'); req.setMethod('POST'); req.setHeader('Content-Type', 'application/json'); req.setBody('{"query":"{ shop { name myshopifyDomain } }"}'); System.debug(new Http().send(req).getBody());

A 200 with your shop name and myshopify domain proves the token, the header formula, and principal access at once. Salesforce injected X-Shopify-Access-Token for you, so your Apex never touched the secret. Use GraphQL for anything new, Shopify marked REST legacy in October 2024 and has required GraphQL for new apps since April 2025. Pre-existing REST integrations on legacy apps can still call callout:Shopify/admin/api/2026-07/orders.json, but build nothing new on REST.

Common Errors and How to Fix Them

  • 401 {"errors":"[API] Invalid API key or access token (unrecognized login or wrong password)"}: wrong or revoked token, a token from a different store, an expired 24-hour Dev Dashboard token, or a stray newline pasted into the header value. Confirm the token, the exact myshopify.com subdomain, and that the app is still installed.
  • 403 {"errors":"[API] This action requires merchant approval for read_orders scope."}: the installed grant lacks the scope. Legacy apps: add it under Configure Admin API scopes and Save. Dev Dashboard apps: release a new version with the scope and reinstall, scopes lock at install time.
  • 429 with 'Exceeded 2 calls per second for api client': the REST leaky bucket drained, 40 requests leaking 2 per second on standard plans. Honor Retry-After and watch X-Shopify-Shop-Api-Call-Limit.
  • 404 on /admin/api/{version}/ paths: the version segment is invalid or retired, versions older than roughly 12 months are removed. Switch to a currently supported YYYY-MM version.
  • Salesforce says it couldn't access the credential(s): the running user lacks External Credential Principal Access. Add the principal under Enabled External Credential Principals on their permission set, and give non-admins CRUD on User External Credentials.
  • Callout reaches Shopify but 401s even though the formula looks right: Allow Formulas in HTTP Header is unchecked, or Generate Authorization Header is still checked and Salesforce injected a bogus Authorization header. Flip both and retest.
  • Webhook HMAC never matches: wrong secret or wrong bytes. App-subscribed webhooks are signed with the app's API secret key or client secret, webhooks created under Settings > Notifications > Webhooks use the separate secret at the bottom of that page. Compute base64 HMAC-SHA256 over the raw body, never a re-serialized one, and compare constant-time.

Security Checklist Before You Ship

  • The token and API secret key exist only in your secret manager and the External Credential parameter, never in Apex, email, Slack, or a spreadsheet.
  • Scopes are minimal: the three read scopes here, plus read_all_orders only if you truly need orders older than 60 days.
  • Generate Authorization Header is unchecked on the Named Credential, so no stray Authorization header leaks to Shopify.
  • Principal access flows through a dedicated integration permission set, not sprinkled across profiles.
  • Your inbound webhook endpoint verifies X-Shopify-Hmac-Sha256 over the raw body with a constant-time comparison, and you know which of the two Shopify secrets signs your subscriptions. After a client secret rotation, tolerate old-secret signatures for up to 1 hour.
  • You have a written rotation runbook. Legacy tokens cannot be rotated, the only path is uninstall plus reinstall, which also regenerates the API key and secret.
  • A quarterly reminder reviews the API version in your callout paths and watches for the X-Shopify-API-Deprecated-Reason response header.

Where This Fits in the Full Shopify Build

Credentials are chapter one of a real integration. From here the build moves to data mapping, Shopify orders into Salesforce Orders or Opportunities and customers into Contacts or Person Accounts, then sync architecture, scheduled GraphQL pulls versus near-real-time webhooks landing on a public Apex REST endpoint behind a Site guest user, then dedup, error handling, and go-live. The full sequence lives in our technical guide at cloudsheer.com/integrations/shopify/technical-guide.

If you build with Claude Code, we packaged the whole playbook as a free skill. Run npx skills add shivamgoel-cloudsheer/Claude-skills --skill shopify-salesforce and your agent gets the same scope lists, header formulas, and error fixes.

How Cloudsheer Can Help

Cloudsheer has shipped this Shopify to Salesforce integration across 5 client projects, and every fix in the error list above came out of a real incident, not a docs page. The pattern in this article, a custom app token in an External Credential custom header, a Named Credential pointed at the myshopify.com domain, and HMAC-verified webhooks inbound, is the exact production architecture we deploy.

If you would rather have it stood up for you, we handle app creation, token strategy including the 24-hour refresh job for Dev Dashboard apps, the Salesforce wiring, webhook verification, and the data mapping that follows. Book a free discovery call at cal.com/cloudsheer-consulting/30min.

Want to see how this applies to your business?

Book a free 30-minute call. We will walk through your specific use case and show you what's possible.

Book Free Discovery Call
Ask me anything