import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'; import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'; import Stripe from 'https://esm.sh/stripe@14?target=deno'; const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!, { apiVersion: '2023-10-16' }); const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', }; serve(async (req) => { if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders }); const supabase = createClient( Deno.env.get('SUPABASE_URL')!, Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!, ); // Find all paid invoices that don't have a stripe_fee yet const { data: invoices, error } = await supabase .from('invoices') .select('id, invoice_number, total') .eq('status', 'paid') .is('stripe_fee', null); if (error) { return new Response(JSON.stringify({ error: error.message }), { status: 500, headers: corsHeaders }); } if (!invoices?.length) { return new Response(JSON.stringify({ message: 'No invoices missing fees', updated: 0 }), { headers: corsHeaders }); } const results: { invoice_id: string; invoice_number: string; status: string; fee?: number }[] = []; for (const invoice of invoices) { try { // Search Stripe checkout sessions by invoice_id metadata const sessions = await stripe.checkout.sessions.search({ query: `metadata["invoice_id"]:"${invoice.id}"`, limit: 1, expand: ['data.payment_intent.latest_charge.balance_transaction'], }); const session = sessions.data[0]; if (!session) { results.push({ invoice_id: invoice.id, invoice_number: invoice.invoice_number, status: 'no_session' }); continue; } const paymentIntent = session.payment_intent as Stripe.PaymentIntent | null; const charge = paymentIntent?.latest_charge as Stripe.Charge | null; const balanceTx = charge?.balance_transaction as Stripe.BalanceTransaction | null; if (balanceTx?.fee == null) { results.push({ invoice_id: invoice.id, invoice_number: invoice.invoice_number, status: 'no_balance_tx' }); continue; } const stripe_fee = balanceTx.fee / 100; await supabase.from('invoices').update({ stripe_fee }).eq('id', invoice.id); results.push({ invoice_id: invoice.id, invoice_number: invoice.invoice_number, status: 'updated', fee: stripe_fee }); } catch (err) { results.push({ invoice_id: invoice.id, invoice_number: invoice.invoice_number, status: `error: ${err.message}` }); } } const updated = results.filter(r => r.status === 'updated').length; return new Response( JSON.stringify({ updated, total: invoices.length, results }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }, ); });