Set up Recharge authentication for Shopify Customer Account UI extensions
Custom-built Shopify Customer Account UI extensions require a backend to exchange Shopify customer identity for a Recharge customer session.
This guide explains how to authenticate logged-in Shopify customers in a Customer Account UI extension and create a Recharge customer session so developers can build custom customer portals powered by Recharge.
Overview
This guide applies specifically to merchant-built Shopify Customer Account UI extensions.
In this context, the extension can identify the logged-in Shopify customer but cannot independently create a Recharge customer session.
To authenticate the customer with Recharge, a small backend service is required to exchange the Shopify customer session token for a Recharge customer session.
Why this is required
The limitation is not that Shopify apps or extensions cannot call Recharge.
The limitation is that Customer Account UI extensions cannot negotiate Recharge customer sessions directly.
Once a Recharge customer session is created on the server, the UI extension may use that session token to make authenticated Recharge Storefront API calls.
Why does this backend exist?
This backend exists only in the context of merchant-built Shopify Customer Account UI extensions.
Customer Account UI extensions can identify the logged-in Shopify customer using a session token, but they cannot create a Recharge customer session on their own. Creating a Recharge session requires securely negotiating credentials and customer identity, which must happen server-side in this context.
The backend acts as a minimal session exchange service that:
- Verifies the Shopify customer session token
- Maps the Shopify customer to a Recharge customer
- Creates a Recharge customer session
- Returns the session token to the UI extension
Once the session is created, the UI extension can use the returned token to make authenticated Recharge Storefront API calls directly.
Step 1: Create Recharge API Tokens
In the Recharge Merchant Portal, navigate to:
- Tools & Apps → API Tokens
- Create two tokens:
| Token type | Required scopes | Used for |
|---|---|---|
| Storefront token | Select required scopes | Create customer session in Recharge |
| Admin token | write_session, read_customer | Look up customer by Shopify ID |
Step 2: Create a backend session broker (Customer Account UI extensions only)
When a merchant builds their own Shopify Customer Account UI extension, the extension runs in a constrained environment:
- It can read the Shopify customer session token
- It cannot mint or negotiate third-party customer sessions on its own
Recharge customer sessions must be created using Recharge API tokens, which must be used server-side in this context.
To bridge this gap, create a backend endpoint that:
- Accepts the Shopify session token (JWT) from the UI extension
- Verifies the token server-side
- Maps the Shopify customer to a Recharge customer
- Creates a Recharge customer session
- Returns the session token to the extension
This backend acts as a minimal session exchange service for Customer Account UI extensions — not a general API proxy.
Step 3: Call the backend endpoint from the UI extension
From your Shopify Customer Account UI extension, send the Shopify session token to your backend endpoint.
await fetch("https://YOUR-SERVER.COM/create_recharge_customer_session", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
token: SHOPIFY_SESSION_TOKEN, // JWT provided by Shopify session-token API
}),
});Step 4: Implement the backend endpoint
Implement the backend endpoint that your Shopify Customer Account UI extension calls to create a Recharge customer session.
This endpoint is responsible for:
- Validating the incoming Shopify session token (JWT)
- Extracting the Shopify customer ID from the token
- Looking up the corresponding customer in Recharge
- Creating a Recharge customer session using the Storefront API
- Returning the customer session token to the caller
Important
- The Shopify session token is a JWT and must be verified server-side.
- The Recharge customer session returned by this endpoint is not a JWT. Treat it as an opaque, customer-scoped token.
The example below shows a simple JavaScript implementation:
Example implementation (JavaScript)
// Helper: Validate incoming Shopify session token properly
function validateShopifyToken(token) {
// Follow Shopify verification steps:
// https://shopify.dev/docs/apps/build/authentication-authorization/session-tokens/set-up-session-tokens#verify-the-session-tokens-signature
}
// Helper: Parse Shopify `gid://shopify/Customer/<id>` string format
function parseGid(gid) {
return gid.split("/").pop(); // returns <customerId>
}
export async function createRechargeCustomerSession(req, res) {
try {
const sessionToken = req?.body?.token;
// 1. Verify the incoming Shopify session token
if (!validateShopifyToken(sessionToken)) {
return res.status(401).json({ error: "Invalid Shopify session token" });
}
// 2. Decode Shopify token to extract the customer ID
const tokenInfo = readSessionToken(sessionToken); // implement readSessionToken
const shopifyCustomerId = parseGid(tokenInfo.sub);
console.log("Mapped Shopify Customer ID:", shopifyCustomerId);
// 3. Look up the matching Recharge customer
const customerResponse = await fetch(
`https://api.rechargeapps.com/customers?external_customer_id=${shopifyCustomerId}`,
{
headers: {
"X-Recharge-Version": "2021-11",
"X-Recharge-Access-Token": process.env.RECHARGE_ADMIN_TOKEN,
},
}
);
const customerData = await customerResponse.json();
const customer = customerData?.customers?.[0];
if (!customer) {
return res.status(404).json({
error:
"Customer not found in Recharge — no subscriptions for this account yet.",
});
}
// 4. Create a Recharge customer session
const sessionResponse = await fetch(
`https://api.rechargeapps.com/customers/${customer.id}/sessions`,
{
method: "POST",
headers: {
"X-Recharge-Version": "2021-11",
"Content-Type": "application/json",
"X-Recharge-Access-Token": process.env.RECHARGE_ADMIN_TOKEN,
"x-recharge-storefront-access-token":
process.env.RECHARGE_STOREFRONT_TOKEN,
},
body: JSON.stringify({}),
}
);
const result = await sessionResponse.json();
const customerSession = result.customer_session;
// Example response:
// { api_token: "...", customer_id: 12345 }
return res.json({ customerSession });
} catch (err) {
console.error(err);
res.status(500).json({
error: "Failed to create Recharge session",
message: err.message,
});
}
}Step 5: Use the Session with the Recharge API/SDK
Use the value from Step 3 in Recharge API/SDK Calls:
// fetchRechargeSession implements Step 3
const session = await fetchRechargeSession();
// productSearch is a Recharge SDK method
const { products } = await productSearch(session, {
external_variant_ids: productVariantIds,
format_version: '2022-06',
product_published_status: 'any',
})Updated 20 days ago
