diff --git a/shared/transak.ts b/shared/transak.ts index 164db3e..4187f56 100644 --- a/shared/transak.ts +++ b/shared/transak.ts @@ -13,16 +13,18 @@ export type TransakEnv = 'STAGING' | 'PRODUCTION'; -const API_URLS = { - STAGING: 'https://api-stg.transak.com', - PRODUCTION: 'https://api.transak.com', -} as const; - +// Both token refresh and session creation go through the gateway const GATEWAY_URLS = { STAGING: 'https://api-gateway-stg.transak.com', PRODUCTION: 'https://api-gateway.transak.com', } as const; +// Fallback: legacy partner API (if gateway token refresh fails) +const API_URLS = { + STAGING: 'https://api-stg.transak.com', + PRODUCTION: 'https://api.transak.com', +} as const; + // Cached access token (valid for 7 days) let _cachedToken: { token: string; expiresAt: number; env: TransakEnv } | null = null; @@ -76,30 +78,39 @@ async function getAccessToken(): Promise { const apiSecret = getTransakApiSecret(); if (!apiKey || !apiSecret) throw new Error('Transak API key or secret not configured'); - const apiUrl = API_URLS[env]; - const res = await fetch(`${apiUrl}/partners/api/v2/refresh-token`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'api-secret': apiSecret, - }, - body: JSON.stringify({ apiKey }), - }); + const body = JSON.stringify({ apiKey }); + const headers = { 'Content-Type': 'application/json', 'api-secret': apiSecret }; - if (!res.ok) { - const err = await res.text(); - throw new Error(`Transak refresh-token failed: ${res.status} ${err}`); + // Try gateway first (required for production session tokens), then legacy API + const urls = [ + `${GATEWAY_URLS[env]}/partners/api/v2/refresh-token`, + `${API_URLS[env]}/partners/api/v2/refresh-token`, + ]; + + let lastError = ''; + for (const url of urls) { + try { + const res = await fetch(url, { method: 'POST', headers, body }); + if (!res.ok) { + lastError = `${url}: ${res.status} ${await res.text()}`; + console.warn(`[transak] Token refresh failed at ${url}: ${res.status}`); + continue; + } + const data = await res.json() as { data: { accessToken: string; expiresAt: number } }; + _cachedToken = { + token: data.data.accessToken, + expiresAt: data.data.expiresAt, + env, + }; + console.log(`[transak] Access token refreshed from ${url} (env=${env}, expires=${new Date(data.data.expiresAt * 1000).toISOString()})`); + return _cachedToken.token; + } catch (err) { + lastError = `${url}: ${err}`; + console.warn(`[transak] Token refresh error at ${url}:`, err); + } } - const data = await res.json() as { data: { accessToken: string; expiresAt: number } }; - _cachedToken = { - token: data.data.accessToken, - expiresAt: data.data.expiresAt, - env, - }; - - console.log(`[transak] Access token refreshed (env=${env}, expires=${new Date(data.data.expiresAt * 1000).toISOString()})`); - return _cachedToken.token; + throw new Error(`Transak refresh-token failed on all endpoints: ${lastError}`); } /**