Within Shopify, store owners are restricted from having full control of their store’s checkout page. This is a safety feature on Shopify’s end, protectecting store owners and customers from accidentally (or purposely) exposing private information. This can make something like editing checkout behavior VERY complicated within Shopify.
While building a headless Shopify store, I needed an automated way to link authenticated customers to a checkout that is already authenticated for them. Because if not, customers would have to sign in a second time once they arrive to the checkout. This would greatly degrade our UX.
To link an authenticated user (Storefront API) to an authenticated checkout session, we need to use customer access tokens and multipass tokens.
What are these tokens?
Customer Access Tokens
- Generated by the storefront API. Requires a user’s email and password as variables, then returns an encrypted access code to authenticate the user’s session without exposing user information.
Multipass Tokens
Allows 3rd-party systems (headless stores, login federation etc) to authenticate users into the Shopify backend without needing to log in manually.
In this tutorialy, these are used to send a storefront-authenticated customer to a pre-authenticated Shopify checkout.
Make sure to get your multipass secret from Shopify Admin before following this tutorial
How To
Now let’s write some javascript code to automate this process, that runs the neccessary API requests, generates a multipass token and redirects the user to the authenticated checkout URL.
In my example, I am using Hydrogen & Remix, but this code can be refactored to be used with any framework or even vanilla JS.
Gather the right data
You will need to have access to the following data for this to work
Customer access token
Customer email
Current cart ID
Pull the Cart Contents using Cart ID
Use the following request to get the cart line items and the checkout URL, using the cart ID.
const cartQuery = `
query CartQuery($cartId: ID!) {
cart(id: $cartId) {
lines(first: 50) {
nodes {
quantity
merchandise {
... on ProductVariant {
id
}
}
}
}
checkoutUrl
}
}
`;
const cartResponse = await fetch(
`https://your-store-domain.myshopify.com/api/2024-01/graphql.json`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': <access_token_here>,
},
body: JSON.stringify({
query: cartQuery,
variables: { cartId },
}),
}
);
const cartData = await cartResponse.json();
// Error handling
if (!cartResponse.ok || cartData.errors) {
console.error("Cart fetch failed:", cartData.errors[0]);
return json({ errors: cartData.errors || 'Failed to fetch cart' }, { status: 400 });
}
// Grab and map the line items into an object array
const lineItems = cartData.data.cart.lines.nodes.map((line) => ({
quantity: line.quantity,
merchandiseId: line.merchandise.id,
}));
// Update checkout URL (will be used later)
let checkoutUrl = cartData.data.cart.checkoutUrl;
Create a Multipass Token, and Redirect to Checkout
Now that we have the checkout URL, customer access token and customer email, we can create a multipass token. Here is how I did this. You need a createdAt date, and to create a secure password for each token.
see Shopify documentation for more in-depth guidance on creating multipass tokens
function generateCreatedAt() {
const now = new Date();
const offsetMinutes = now.getTimezoneOffset();
const offsetHours = Math.floor(Math.abs(offsetMinutes) / 60);
const offsetRemainder = Math.abs(offsetMinutes) % 60;
const offsetSign = offsetMinutes > 0 ? '-' : '+';
const formattedOffset = `${offsetSign}${String(offsetHours).padStart(2, '0')}:${String(offsetRemainder).padStart(2, '0')}`;
return now.toISOString().replace('Z', formattedOffset);
}
const multipassSecret = context.env.MULTIPASS_SECRET;
if (!multipassSecret) throw new Error("Multipass secret is missing.");
const multipassify = new Multipassify(multipassSecret);
if (customerAccessToken) {
const createdAt = generateCreatedAt();
const multipassPayload = {
created_at: createdAt,
email: customerEmail,
token: customerAccessToken,
return_to: checkoutUrl,
};
const multipassToken = multipassify.encode(multipassPayload);
const authenticatedCheckoutUrl = `https://www.your-store-domain.com/account/login/multipass/${multipassToken}`;
return redirect(authenticatedCheckoutUrl);
}
return redirect(checkoutUrl);
Conclusion
Your customers should now be redirected to an pre-authenticated Shopify checkout!
Hopefully this tutorial has helped you, not only with authenticated checkouts, but with Multipass in general. Multipass tokens have a wide variation of use cases, including implementing federated logins (Sign in with Google etc.).