88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
/**
|
|
* Transak API utilities — shared across rFlows and rCart.
|
|
*
|
|
* Handles access token management (cached 6 days) and
|
|
* widget URL generation via Transak's session API.
|
|
*/
|
|
|
|
let _transakAccessToken: string | null = null;
|
|
let _transakTokenExpiry = 0;
|
|
|
|
export async function getTransakAccessToken(): Promise<string> {
|
|
if (_transakAccessToken && Date.now() < _transakTokenExpiry) return _transakAccessToken;
|
|
|
|
const apiKey = process.env.TRANSAK_API_KEY;
|
|
const apiSecret = process.env.TRANSAK_SECRET;
|
|
if (!apiKey || !apiSecret) throw new Error("Transak credentials not configured");
|
|
|
|
const env = process.env.TRANSAK_ENV || 'PRODUCTION';
|
|
const baseUrl = env === 'PRODUCTION'
|
|
? 'https://api.transak.com'
|
|
: 'https://api-stg.transak.com';
|
|
|
|
const res = await fetch(`${baseUrl}/partners/api/v2/refresh-token`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'api-secret': apiSecret,
|
|
},
|
|
body: JSON.stringify({ apiKey }),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`Transak token refresh failed (${res.status}): ${text}`);
|
|
}
|
|
|
|
const data = await res.json() as any;
|
|
_transakAccessToken = data.data?.accessToken || data.accessToken;
|
|
if (!_transakAccessToken) throw new Error("No accessToken in Transak response");
|
|
|
|
// Cache for 6 days (tokens valid for 7)
|
|
_transakTokenExpiry = Date.now() + 6 * 24 * 60 * 60 * 1000;
|
|
console.log('[transak] Access token refreshed');
|
|
return _transakAccessToken;
|
|
}
|
|
|
|
export async function createTransakWidgetUrl(params: Record<string, string>): Promise<string> {
|
|
const accessToken = await getTransakAccessToken();
|
|
const env = process.env.TRANSAK_ENV || 'PRODUCTION';
|
|
const gatewayUrl = env === 'PRODUCTION'
|
|
? 'https://api-gateway.transak.com'
|
|
: 'https://api-gateway-stg.transak.com';
|
|
|
|
const res = await fetch(`${gatewayUrl}/api/v2/auth/session`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'access-token': accessToken,
|
|
},
|
|
body: JSON.stringify({ widgetParams: params }),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
// If token expired, clear cache and retry once
|
|
if (res.status === 401 || res.status === 403) {
|
|
_transakAccessToken = null;
|
|
_transakTokenExpiry = 0;
|
|
const retryToken = await getTransakAccessToken();
|
|
const retry = await fetch(`${gatewayUrl}/api/v2/auth/session`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'access-token': retryToken,
|
|
},
|
|
body: JSON.stringify({ widgetParams: params }),
|
|
});
|
|
if (!retry.ok) throw new Error(`Transak widget URL failed on retry (${retry.status}): ${await retry.text()}`);
|
|
const retryData = await retry.json() as any;
|
|
return retryData.data?.widgetUrl;
|
|
}
|
|
throw new Error(`Transak widget URL failed (${res.status}): ${text}`);
|
|
}
|
|
|
|
const data = await res.json() as any;
|
|
return data.data?.widgetUrl;
|
|
}
|