@shopify/shopify-api nodejs - Set permanent access token for private app installed on only one store
Solution:
See answer from Shopify here (https://github.com/Shopify/shopify-api-js/issues/700#issuecomment-1410780918).
When creating the client in a private app, a dummy session can be created like so
const session = new Session({
id: 'not-a-real-session-id',
shop: 'shop.myshopify.com,
state: 'state',
isOnline: false,
});
const client = new shopify.clients.Rest({ session: session })
When config.isPrivateApp is set to true only the shop property is used by the client - the other three (id, state, isOnline) properties are ignored (but are required when creating a Session object). config.apiSecretKey is used as the access token, and is read directly from the config (no need to set the accessToken property of the dummy session as it will be ignored). Essentially, config.apiSecretKey is the permanent access token for a private app.
The scopes can be omitted, as it defaults to an empty scopes array internally anyway and (from a quick search through the library code) is only used when doing OAuth, validating sessions, etc., which won't apply to private apps.
As for the apiKey, while it's mostly used as part of the OAuth process, it is also used in a few other places (e.g., shopify.auth.getEmbeddedAppUrl()), so I'd recommend setting the apiKey to be that of your private app.
However, in my testing, scopes, even whenisPrivateApp
, are currently required. If you leave the array empty forscopes
it will have a config error.
Also, myshopifyApi
config mounts rest resources (https://github.com/Shopify/shopify-api-js/blob/main/docs/guides/rest-resources.md#mounting-rest-resources) so that when you're in Shopify REST docs (https://shopify.dev/api/admin-rest/2022-04/resources/transaction#get-orders-order-id-transactions) on the nodejs tab, you can easily use the REST resources examples on the nodejs to make calls, rather than creating a REST client and use standardpost
, etc.
Complete code to setup a private app connection to Shopify:
import '@shopify/shopify-api/adapters/node'
import { shopifyApi, LATEST_API_VERSION, Session } from '@shopify/shopify-api'
import { restResources } from '@shopify/shopify-api/rest/admin/2023-01'
const debug = process.env.FUNCTIONS_EMULATOR === 'true'
const shopify = shopifyApi({
apiKey: 'myprivateAppApiKey',
apiSecretKey: 'myPermanentAccessToken',
apiVersion: LATEST_API_VERSION,
isPrivateApp: true,
scopes: [
'read_customers',
'write_customers',
'read_fulfillments',
'write_fulfillments',
'read_inventory',
'write_inventory',
'write_order_edits',
'read_order_edits',
'write_orders',
'read_orders',
'write_products',
'read_products',
],
isEmbeddedApp: false,
hostName: debug ? '127.0.0.1:5001' : 'shop.myshopify.com',
// Mount REST resources.
restResources,
})
// Create a sanitized "fake" sessionId. E.g.
// "offline_my.myshopify.com".
const sessionId = shopify.session.getOfflineId('shop.myshopify.com')
const session = new Session({
id: sessionId,
shop: 'shop.myshopify.com,
state: 'state',
isOnline: false,
})
// Use mounted REST resources to make calls.
const transactions = await shopify.rest.Transaction.all({
session,
order_id: 123456789,
})
// Alternatively, if not using mounted REST resources
// you could create a standard REST client.
const client = new shopify.clients.Rest({ session })
Source
Didn't find the answer?
Our community is visited by hundreds of Shopify development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.