Skip to content

Instantly share code, notes, and snippets.

@jnormore
Created June 16, 2026 22:10
Show Gist options
  • Select an option

  • Save jnormore/abe729f77b9f7f16c1e5170c970d1084 to your computer and use it in GitHub Desktop.

Select an option

Save jnormore/abe729f77b9f7f16c1e5170c970d1084 to your computer and use it in GitHub Desktop.
shopify app session exchange for contact capture
/* client side */
if (typeof shopify !== "undefined") {
//get the current session token from shopify
const sessionToken = await shopify.idToken();
// send the session token to your server to exchange it for an online token with the user info
const response = await fetch(GET_USER_INFO_FROM_SESSION_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
// TODO: add your server api auth headers here
},
body: JSON.stringify({
sessionToken,
}),
});
const data = await response.json();
// data contains the user info
}
/* server side */
const Handler = async (ctx) => {
if (ctx.request.method === "POST") {
let { sessionToken } = ctx.request.body;
// TODO: you have shop domain from your auth mechanism
const shopDomain = ctx.auth.shopDomain;
// exchange the session token for an online token with the user info
// https://shopify.dev/docs/apps/build/authentication-authorization/access-tokens/token-exchange#example
const response = await fetch(
`https://${shopDomain}/admin/oauth/access_token`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
client_id: process.env.SHOPIFY_CLIENT_ID,
client_secret: process.env.SHOPIFY_CLIENT_SECRET,
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
subject_token: sessionToken,
subject_token_type: "urn:ietf:params:oauth:token-type:id_token",
requested_token_type:
"urn:shopify:params:oauth:token-type:online-access-token",
}),
}
);
if (!response.ok) {
ctx.status = 400;
ctx.body = { error: await response.text() };
return;
}
const data = await response.json();
const user = data?.associated_user;
ctx.body = { user };
ctx.status = 200;
} else {
ctx.status = 405;
ctx.body = { error: "Method not allowed" };
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment