From 0027b897f2038e4bd986cec5408260bba38de838 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Tue, 7 Oct 2025 13:37:20 -0600 Subject: [PATCH] fix: B2B-3725 add required b2b headers --- .env.example | 8 +++++--- core/b2b/client.ts | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.env.example b/.env.example index c540804870..80240ce092 100644 --- a/.env.example +++ b/.env.example @@ -44,9 +44,11 @@ DEFAULT_REVALIDATE_TARGET=3600 # URL for the B2B API. This is used to connect to the B2B API for features like customer impersonation and B2B-specific data B2B_API_HOST=https://api-b2b.bigcommerce.com -# The B2B API Token is used to authenticate requests to the B2B API. -# It can be generated in the B2B control panel Settings > API Accounts > Create API Account. -B2B_API_TOKEN= +# A store-level API account token used for REST API actions. Optional by default, but required in +# the sign-in logic that interacts with the buyer portal. This integration requires a +# `BIGCOMMERCE_ACCESS_TOKEN` with `modify` scope on B2B Edition. +# See https://support.bigcommerce.com/s/article/Store-API-Accounts?language=en_US +BIGCOMMERCE_ACCESS_TOKEN= # URL for the local buyer portal instance. Uncomment if developing locally. # LOCAL_BUYER_PORTAL_HOST=http://localhost:3001 \ No newline at end of file diff --git a/core/b2b/client.ts b/core/b2b/client.ts index 54de580e67..f884c88e6a 100644 --- a/core/b2b/client.ts +++ b/core/b2b/client.ts @@ -11,10 +11,17 @@ interface LoginWithB2BParams { const ENV = z .object({ - env: z.object({ - B2B_API_TOKEN: z.string(), - BIGCOMMERCE_CHANNEL_ID: z.string(), - }), + env: z.union([ + z.object({ + BIGCOMMERCE_CHANNEL_ID: z.string(), + B2B_API_TOKEN: z.string(), + }), + z.object({ + BIGCOMMERCE_CHANNEL_ID: z.string(), + BIGCOMMERCE_STORE_HASH: z.string(), + BIGCOMMERCE_ACCESS_TOKEN: z.string(), + }), + ]), }) .transform(({ env }) => env); @@ -29,17 +36,27 @@ const B2BTokenResponseSchema = z.object({ }); export async function loginWithB2B({ customerId, customerAccessToken }: LoginWithB2BParams) { - const { B2B_API_TOKEN, BIGCOMMERCE_CHANNEL_ID } = ENV.parse(process); + const env = ENV.parse(process); + const BIGCOMMERCE_CHANNEL_ID = env.BIGCOMMERCE_CHANNEL_ID; + const headers: HeadersInit = { + Accept: 'application/json', + 'Content-Type': 'application/json', + }; - const apiHost = getAPIHostname(); + if ('BIGCOMMERCE_ACCESS_TOKEN' in env) { + headers['X-Auth-Token'] = env.BIGCOMMERCE_ACCESS_TOKEN; + headers['X-Store-Hash'] = env.BIGCOMMERCE_STORE_HASH; + } else if ('B2B_API_TOKEN' in env) { + headers['authToken'] = env.B2B_API_TOKEN; + console.warn('This is deprecated in favour or BIGCOMMERCE_ACCESS_TOKEN, read https://support.bigcommerce.com/s/article/Store-API-Accounts?language=en_US') + } else { + throw new Error('No B2B API token or BigCommerce token found in environment variables.'); + } + const apiHost = getAPIHostname(); const response = await fetch(`${apiHost}/api/io/auth/customers/storefront`, { method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - authToken: B2B_API_TOKEN, - }, + headers, body: JSON.stringify({ channelId: BIGCOMMERCE_CHANNEL_ID, customerId,