interface UspsToken { accessToken: string; expiresAt: number; } let cachedToken: UspsToken | null = null; const USPS_BASE = process.env.USPS_ENV === 'production' ? 'https://apis.usps.com' : 'https://apis-tem.usps.com'; export function uspsConfigured(): boolean { return !!(process.env.USPS_CLIENT_ID && process.env.USPS_CLIENT_SECRET); } async function getToken(): Promise { if (cachedToken && cachedToken.expiresAt > Date.now() + 60_000) { return cachedToken.accessToken; } const resp = await fetch(`${USPS_BASE}/oauth2/v3/token`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: process.env.USPS_CLIENT_ID, client_secret: process.env.USPS_CLIENT_SECRET, grant_type: 'client_credentials', scope: 'addresses' }) }); const data = await resp.json(); if (!resp.ok) throw new Error('USPS auth failed: ' + JSON.stringify(data)); cachedToken = { accessToken: data.access_token, expiresAt: Date.now() + (parseInt(data.expires_in, 10) || 3000) * 1000 }; return cachedToken.accessToken; } export interface AddressInput { addressLine1: string; addressLine2?: string | null; city: string; state: string; postalCode: string; } export interface UspsValidationResult { validated: boolean; deliverable: boolean | null; standardized: Record | null; reason?: string; } // Only validates domestic US addresses — USPS Addresses API has no international coverage. export async function validateAddress(address: AddressInput): Promise { if (!uspsConfigured()) { return { validated: false, deliverable: null, standardized: null, reason: 'USPS not configured' }; } try { const token = await getToken(); const params = new URLSearchParams({ streetAddress: address.addressLine1, city: address.city, state: address.state, ZIPCode: address.postalCode }); if (address.addressLine2) params.set('secondaryAddress', address.addressLine2); const resp = await fetch(`${USPS_BASE}/addresses/v3/address?${params.toString()}`, { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } }); const data = await resp.json(); if (!resp.ok) { return { validated: false, deliverable: null, standardized: null, reason: data.error?.message || 'USPS lookup failed' }; } const deliverable = data.additionalInfo?.DPVConfirmation === 'Y'; return { validated: true, deliverable, standardized: data }; } catch (err) { return { validated: false, deliverable: null, standardized: null, reason: (err as Error).message }; } }