initial commit: rocket.new export of broadcastbeat

This commit is contained in:
Ryan Salazar
2026-05-07 16:39:17 +00:00
commit 70aa1ad46e
302 changed files with 60710 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{ db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'bb' } }
);
export async function POST(req: NextRequest) {
const body = await req.text();
let event: any;
try {
event = JSON.parse(body);
} catch {
return NextResponse.json({ error: 'Invalid payload' }, { status: 400 });
}
try {
await handleStripeEvent(event, 'jtr');
return NextResponse.json({ received: true });
} catch (err: any) {
console.error('[Stripe JTR Webhook]', err.message);
return NextResponse.json({ error: err.message }, { status: 500 });
}
}
async function handleStripeEvent(event: any, company: 'rmp' | 'jtr') {
const data = event?.data?.object;
switch (event.type) {
case 'payment_intent.succeeded': {
const piId = data?.id;
if (piId) {
const { data: inv } = await supabase
.from('billing_invoices')
.select('id')
.eq('stripe_payment_link', piId)
.single();
if (inv) {
await supabase.from('billing_invoices').update({
status: 'paid',
amount_paid: data.amount_received / 100,
paid_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
}).eq('id', inv.id);
await supabase.from('billing_payments').insert({
invoice_id: inv.id,
amount: data.amount_received / 100,
payment_date: new Date().toISOString().split('T')[0],
payment_method: 'stripe',
stripe_payment_intent_id: piId,
status: 'succeeded',
});
}
}
break;
}
case 'payment_intent.payment_failed': {
await supabase.from('billing_payments').insert({
amount: (data?.amount || 0) / 100,
payment_date: new Date().toISOString().split('T')[0],
payment_method: 'stripe',
stripe_payment_intent_id: data?.id,
status: 'failed',
notes: data?.last_payment_error?.message || 'Payment failed',
});
break;
}
case 'charge.dispute.created': {
await supabase.from('billing_payments').insert({
amount: (data?.amount || 0) / 100,
payment_date: new Date().toISOString().split('T')[0],
payment_method: 'stripe',
stripe_charge_id: data?.id,
status: 'disputed',
notes: `Dispute created: ${data?.reason || 'unknown reason'}`,
});
break;
}
case 'payout.paid': {
await supabase.from('billing_sync_log').insert({
sync_type: `stripe_payout_${company}`,
records_synced: 1,
status: 'completed',
started_at: new Date().toISOString(),
completed_at: new Date().toISOString(),
});
break;
}
default:
break;
}
}

View File

@@ -0,0 +1,106 @@
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{ db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'bb' } }
);
export async function POST(req: NextRequest) {
const body = await req.text();
const sig = req.headers.get('stripe-signature') || '';
// Stripe signature verification would go here when STRIPE_SECRET_KEY_RMP is configured
// For now, parse the raw event
let event: any;
try {
event = JSON.parse(body);
} catch {
return NextResponse.json({ error: 'Invalid payload' }, { status: 400 });
}
try {
await handleStripeEvent(event, 'rmp');
return NextResponse.json({ received: true });
} catch (err: any) {
console.error('[Stripe RMP Webhook]', err.message);
return NextResponse.json({ error: err.message }, { status: 500 });
}
}
async function handleStripeEvent(event: any, company: 'rmp' | 'jtr') {
const data = event?.data?.object;
switch (event.type) {
case 'payment_intent.succeeded': {
const piId = data?.id;
if (piId) {
// Find invoice by stripe payment intent and mark paid
const { data: inv } = await supabase
.from('billing_invoices')
.select('id')
.eq('stripe_payment_link', piId)
.single();
if (inv) {
await supabase.from('billing_invoices').update({
status: 'paid',
amount_paid: data.amount_received / 100,
paid_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
}).eq('id', inv.id);
await supabase.from('billing_payments').insert({
invoice_id: inv.id,
amount: data.amount_received / 100,
payment_date: new Date().toISOString().split('T')[0],
payment_method: 'stripe',
stripe_payment_intent_id: piId,
status: 'succeeded',
});
}
}
break;
}
case 'payment_intent.payment_failed': {
// Log failed payment — dashboard will show in red
await supabase.from('billing_payments').insert({
amount: (data?.amount || 0) / 100,
payment_date: new Date().toISOString().split('T')[0],
payment_method: 'stripe',
stripe_payment_intent_id: data?.id,
status: 'failed',
notes: data?.last_payment_error?.message || 'Payment failed',
});
break;
}
case 'charge.dispute.created': {
// Log dispute — urgent alert
await supabase.from('billing_payments').insert({
amount: (data?.amount || 0) / 100,
payment_date: new Date().toISOString().split('T')[0],
payment_method: 'stripe',
stripe_charge_id: data?.id,
status: 'disputed',
notes: `Dispute created: ${data?.reason || 'unknown reason'}`,
});
break;
}
case 'payout.paid': {
await supabase.from('billing_sync_log').insert({
sync_type: `stripe_payout_${company}`,
records_synced: 1,
status: 'completed',
started_at: new Date().toISOString(),
completed_at: new Date().toISOString(),
});
break;
}
default:
break;
}
}