connexion nouvelle api
This commit is contained in:
163
supabase/functions/create-checkout-session/index.js
Normal file
163
supabase/functions/create-checkout-session/index.js
Normal 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,
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user