fix: try gateway for Transak token refresh #9

Merged
jeffemmett merged 1 commits from dev into main 2026-04-03 05:58:20 +02:00
1 changed files with 37 additions and 26 deletions

View File

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