const API_VERSION = '2024-01' function getConfig() { const domain = process.env.SHOPIFY_STORE_DOMAIN const token = process.env.SHOPIFY_ADMIN_API_TOKEN if (!domain || !token) { throw new Error('SHOPIFY_STORE_DOMAIN et SHOPIFY_ADMIN_API_TOKEN requis') } return { baseUrl: `https://${domain}/admin/api/${API_VERSION}`, headers: { 'X-Shopify-Access-Token': token, 'Content-Type': 'application/json', }, } } export type ShopifyProductResult = | { found: false } | { found: true; shopifyId: string; title: string } /** * Recherche un produit Shopify par sa référence. * Tente d'abord par handle (ex: "ref-1042"), puis par titre exact. */ export async function searchProductByRef(ref: string): Promise { const { baseUrl, headers } = getConfig() // Normalise la référence en handle Shopify (minuscules, tirets) const handle = ref.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') const tryFetch = async (params: string) => { const res = await fetch(`${baseUrl}/products.json?${params}&fields=id,title,handle&limit=1`, { headers }) if (!res.ok) throw new Error(`Shopify API error: ${res.status}`) const data = await res.json() return (data.products ?? []) as Array<{ id: number; title: string; handle: string }> } let products = await tryFetch(`handle=${encodeURIComponent(handle)}`) if (products.length === 0) { products = await tryFetch(`title=${encodeURIComponent(ref)}`) } if (products.length === 0) return { found: false } return { found: true, shopifyId: String(products[0].id), title: products[0].title, } } /** * Upload une image (base64) vers un produit Shopify via l'API REST. * @param shopifyProductId — ID numérique du produit (string) * @param imageBase64 — contenu JPEG encodé en base64 (sans le préfixe data:) * @param filename — nom de fichier avec extension (ex: "REF-1042.jpg") */ export async function uploadProductImage( shopifyProductId: string, imageBase64: string, filename: string, ): Promise<{ url: string }> { const { baseUrl, headers } = getConfig() const res = await fetch(`${baseUrl}/products/${shopifyProductId}/images.json`, { method: 'POST', headers, body: JSON.stringify({ image: { attachment: imageBase64, filename } }), }) if (!res.ok) { const body = await res.text() throw new Error(`Shopify upload error: ${res.status} — ${body}`) } const data = await res.json() if (!data.image?.src) { throw new Error('Shopify response invalide : champ image.src manquant') } return { url: data.image.src as string } }