import { NextRequest, NextResponse } from 'next/server' /** * eBay API Proxy Route * Proxies requests to eBay Finding API to avoid CORS issues */ interface eBaySearchParams { keywords: string categoryId?: string sortOrder?: string maxResults?: number } interface eBaySearchResult { itemId: string title: string price: string currency: string imageUrl?: string viewItemUrl: string condition?: string shippingCost?: string affiliateLink: string } type MaybeArray = T | T[] // Affiliate campaign ID for generating links const AFFILIATE_CAMPAIGN_ID = process.env.EBAY_AFFILIATE_CAMPAIGN_ID?.trim() || '' // Generate eBay affiliate link function generateAffiliateLink(viewItemUrl: string): string { if (!AFFILIATE_CAMPAIGN_ID) { return viewItemUrl } try { const url = new URL(viewItemUrl) url.searchParams.set('mkcid', '1') url.searchParams.set('mkrid', '711-53200-19255-0') url.searchParams.set('siteid', '0') url.searchParams.set('campid', AFFILIATE_CAMPAIGN_ID) url.searchParams.set('toolid', '10001') url.searchParams.set('mkevt', '1') return url.toString() } catch { return viewItemUrl } } function first(value: MaybeArray | undefined): T | undefined { if (!value) { return undefined } return Array.isArray(value) ? value[0] : value } function normalizeItem(item: any): eBaySearchResult { const currentPrice = first(item.sellingStatus?.currentPrice) const shippingCost = first(item.shippingInfo?.shippingServiceCost) const condition = first(item.condition) const viewItemUrl = item.viewItemURL || item.viewItemUrl || '' return { itemId: item.itemId || '', title: item.title || 'Unknown Item', price: `${currentPrice?.value || '0'} ${currentPrice?.currencyId || 'USD'}`, currency: currentPrice?.currencyId || 'USD', imageUrl: first(item.galleryURL) || undefined, viewItemUrl, condition: condition?.conditionDisplayName || undefined, shippingCost: shippingCost?.value ? `${shippingCost.value} ${shippingCost.currencyId || currentPrice?.currencyId || 'USD'}` : undefined, affiliateLink: generateAffiliateLink(viewItemUrl), } } export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url) const keywords = searchParams.get('keywords') const categoryId = searchParams.get('categoryId') || undefined const sortOrder = searchParams.get('sortOrder') || 'BestMatch' const maxResults = parseInt(searchParams.get('maxResults') || '6', 10) if (!keywords) { return NextResponse.json({ error: 'Keywords parameter is required' }, { status: 400 }) } const appId = process.env.EBAY_APP_ID?.trim() if (!appId) { console.error('EBAY_APP_ID not configured') return NextResponse.json( { error: 'eBay API not configured. Please set EBAY_APP_ID environment variable.' }, { status: 503 } ) } // Build eBay Finding API URL const baseUrl = 'https://svcs.ebay.com/services/search/FindingService/v1' const url = new URL(baseUrl) url.searchParams.set('OPERATION-NAME', 'findItemsAdvanced') url.searchParams.set('SERVICE-VERSION', '1.0.0') url.searchParams.set('SECURITY-APPNAME', appId) url.searchParams.set('RESPONSE-DATA-FORMAT', 'JSON') url.searchParams.set('REST-PAYLOAD', 'true') url.searchParams.set('keywords', keywords) url.searchParams.set('sortOrder', sortOrder) url.searchParams.set('paginationInput.entriesPerPage', maxResults.toString()) if (categoryId) { url.searchParams.set('categoryId', categoryId) } try { const response = await fetch(url.toString(), { method: 'GET', headers: { 'Accept': 'application/json', }, }) if (!response.ok) { const errorText = await response.text() console.error('eBay API error:', response.status, errorText) return NextResponse.json( { error: `eBay API error: ${response.status}` }, { status: response.status } ) } const data = await response.json() // Parse eBay API response const findItemsAdvancedResponse = data.findItemsAdvancedResponse?.[0] if (!findItemsAdvancedResponse) { return NextResponse.json([]) } const searchResult = findItemsAdvancedResponse.searchResult?.[0] if (!searchResult || !searchResult.item || searchResult.item.length === 0) { return NextResponse.json([]) } const items = Array.isArray(searchResult.item) ? searchResult.item : [searchResult.item] const results: eBaySearchResult[] = items.map((item: any) => normalizeItem(item)) return NextResponse.json(results) } catch (error) { console.error('Error fetching from eBay API:', error) return NextResponse.json( { error: 'Failed to fetch products from eBay' }, { status: 500 } ) } }