connexion nouvelle api

This commit is contained in:
balvarez
2026-01-03 21:11:17 +01:00
parent 40ce29753d
commit 4293fa76af
10 changed files with 721 additions and 120 deletions

View File

@@ -0,0 +1,163 @@
/* 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,
},
);
}
});