fix: try gateway for Transak token refresh before legacy API
Production gateway rejects tokens from api.transak.com. Try getting the access token from the gateway endpoint first (which staging confirms works), then fall back to the legacy API endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e61da960ea
commit
125bed3ad7
|
|
@ -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<string> {
|
|||
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}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue