/* eslint-disable no-undef */ // Edge Function: create-checkout-session // Environnement: Deno (Supabase Edge Functions self-host) // Secrets/vars à définir (ex: volumes/functions/.env ou env docker): // STRIPE_SECRET_KEY=sk_live_... // SUPABASE_URL=https://supabase.abcdcode.fr (ou ce que tu utilises) // SUPABASE_SERVICE_ROLE_KEY=xxxxxxxxxxxxxxxx import { serve } from "https://deno.land/std@0.168.0/http/server.ts"; import Stripe from "https://esm.sh/stripe@12.0.0"; import { createClient } from "https://esm.sh/@supabase/supabase-js@2"; const STRIPE_SECRET_KEY = Deno.env.get("STRIPE_SECRET_KEY") ?? ""; const SUPABASE_URL = Deno.env.get("SUPABASE_URL") ?? ""; const SUPABASE_SERVICE_ROLE_KEY = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") ?? ""; if (!STRIPE_SECRET_KEY) { console.warn("⚠️ STRIPE_SECRET_KEY is not set – Stripe calls will fail."); } if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE_KEY) { console.warn( "⚠️ SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY is not set – database writes may fail.", ); } const stripe = new Stripe(STRIPE_SECRET_KEY, { apiVersion: "2022-11-15", httpClient: Stripe.createFetchHttpClient(), }); const corsHeaders = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type", }; serve(async (req) => { // Préflight CORS if (req.method === "OPTIONS") { return new Response("ok", { headers: corsHeaders }); } try { const body = await req.json().catch(() => null); if (!body) { return new Response( JSON.stringify({ error: "Invalid JSON body" }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" }, }, ); } const { priceId, orderData, successUrl, cancelUrl } = body; if (!priceId) { return new Response( JSON.stringify({ error: "priceId is required" }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" }, }, ); } if (!successUrl || !cancelUrl) { return new Response( JSON.stringify({ error: "successUrl and cancelUrl are required", }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" }, }, ); } if (!STRIPE_SECRET_KEY) { return new Response( JSON.stringify({ error: "Stripe secret key is not configured on the server", }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" }, }, ); } // 1. Client Supabase pour sauver la commande const supabaseClient = createClient( SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, { global: { // On forwarde l'Authorization si tu en as besoin côté RLS headers: { Authorization: req.headers.get("Authorization") ?? "", }, }, }, ); // 2. Insertion dans la table "orders" const { data: order, error: orderError } = await supabaseClient .from("orders") .insert({ ...orderData, status: "pending_payment", created_at: new Date().toISOString(), }) .select() .single(); if (orderError) { console.error("Error saving order:", orderError); throw new Error(`Error saving order: ${orderError.message}`); } // 3. Création de la session de paiement Stripe const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price: priceId, quantity: 1, }, ], mode: "payment", // ⚠️ Champs Stripe doivent être en snake_case success_url: `${successUrl}&session_id={CHECKOUT_SESSION_ID}&order_id=${order?.id}`, cancel_url: cancelUrl, metadata: { order_id: order?.id?.toString(), product_name: orderData?.productName ?? "", }, customer_email: orderData?.email ?? undefined, }); return new Response( JSON.stringify({ sessionId: session.id, url: session.url }), { headers: { ...corsHeaders, "Content-Type": "application/json" }, status: 200, }, ); } catch (error) { console.error("create-checkout-session error:", error); return new Response( JSON.stringify({ error: error.message ?? "Unknown error" }), { headers: { ...corsHeaders, "Content-Type": "application/json" }, status: 400, }, ); } });