new-site/api/src/routes/fcc-carrier-registration.ts
justin 53857574d3 Add referral/discount code to FCC carrier page + REF-JAYK05 agent
Frontend (order/fcc-carrier-registration):
- Add a referral/discount code box on the review step that validates
  against /api/v1/discount/:code and shows the discount line + adjusted
  total. Discount applies to service fee + add-ons, never state filing fees.
- Prefill + auto-apply from ?code= / ?ref= query param (referral links).

Backend (fcc-carrier-registration route):
- Accept discount_code, validate it, store discount_code/discount_cents,
  and subtract from the total. Checkout already reads discount_cents to
  apply the Stripe coupon.
- Create a pending commission when the code belongs to an active sales agent.

Commission fix (agents.createCommission):
- Percent-type agents now earn commission_pct on ALL order types. Previously
  canada_crtc/formation/bundle used flat defaults and ignored percent agents.

Agent: created sales agent Jay Kordic (The Horizon Group) with custom code
REF-JAYK05 -> client gets 5% off discountable services, agent earns 15%.
Idempotent setup script in scripts/create_agent_jaykordic.cjs.
2026-06-02 14:31:22 -05:00

332 lines
13 KiB
TypeScript

/**
* FCC Carrier / ISP Registration — order creation & status API.
*
* POST /api/v1/fcc-carrier-registration — create order
* GET /api/v1/fcc-carrier-registration/:id — get order status
* GET /api/v1/fcc-carrier-registration/state-fees — formation fees per state
*/
import { Router, type Request, type Response } from "express";
import { pool } from "../db.js";
import { randomBytes } from "crypto";
const router = Router();
const BASE_FEE_CENTS = 129900; // $1,299
const FORMATION_MARKUP_CENTS = 2500; // $25 filing service
const STIR_SHAKEN_FEE_CENTS = 49900;
const OCN_FEE_CENTS = 265000;
const STATE_PUC_FEE_CENTS = 39900; // per state
function generateOrderNumber(): string {
const year = new Date().getFullYear();
const id = randomBytes(4).toString("hex").toUpperCase();
return `FCR-${year}-${id}`;
}
// ── GET /api/v1/fcc-carrier-registration/state-fees ─────────────────────────
router.get("/api/v1/fcc-carrier-registration/state-fees", async (_req: Request, res: Response) => {
try {
const { rows } = await pool.query(
`SELECT state_code, state_name, llc_formation_fee, corp_formation_fee,
expedited_fee, typical_processing_days
FROM state_filing_fees ORDER BY state_name`,
);
res.json({ states: rows, markup_cents: FORMATION_MARKUP_CENTS });
} catch (err) {
console.error("[fcc-carrier-reg] state-fees error:", err);
res.status(500).json({ error: "Could not load state fees" });
}
});
// ── POST /api/v1/fcc-carrier-registration ───────────────────────────────────
router.post("/api/v1/fcc-carrier-registration", async (req: Request, res: Response) => {
try {
const {
customer_name, customer_email, customer_phone,
entity_source, entity_legal_name, ein, formation_state, entity_type, frn,
contact_name, contact_email, contact_phone, contact_title,
address_street, address_city, address_state, address_zip,
service_wizard, services,
engagement_accepted,
discount_code,
} = req.body ?? {};
// Validate required fields
if (!customer_email || !customer_name) {
res.status(400).json({ error: "customer_name and customer_email are required." });
return;
}
if (!entity_source || !["existing", "new_formation"].includes(entity_source)) {
res.status(400).json({ error: "entity_source must be 'existing' or 'new_formation'." });
return;
}
if (!contact_name || !contact_email) {
res.status(400).json({ error: "contact_name and contact_email are required." });
return;
}
// Determine included services from wizard + checklist
const svcList: string[] = Array.isArray(services) ? services : [];
const wizardData = service_wizard || {};
const includeFormation = entity_source === "new_formation";
const includeRmd = true; // always included in base
const includeCpni = true;
const includeCalea = true;
const includeBdc = true;
const includeDcAgent = true;
const includeStirShaken = svcList.includes("stir_shaken");
const includeOcn = svcList.includes("ocn");
const statePucStates = svcList.includes("state_puc") ? (wizardData.puc_states || []) : [];
// Calculate pricing
let formationFeeCents = 0;
let stateFeeCents = 0;
if (includeFormation && formation_state) {
// Look up state filing fee
const feeCol = (entity_type === "corporation") ? "corp_formation_fee" : "llc_formation_fee";
try {
const feeResult = await pool.query(
`SELECT ${feeCol} AS fee FROM state_filing_fees WHERE state_code = $1`,
[formation_state.toUpperCase()],
);
if (feeResult.rows.length > 0 && feeResult.rows[0].fee) {
stateFeeCents = Number(feeResult.rows[0].fee);
}
} catch {}
formationFeeCents = FORMATION_MARKUP_CENTS;
}
let addonFeeCents = 0;
if (includeStirShaken) addonFeeCents += STIR_SHAKEN_FEE_CENTS;
if (includeOcn) addonFeeCents += OCN_FEE_CENTS;
const pucFeeCents = statePucStates.length * STATE_PUC_FEE_CENTS;
// ── Discount / referral code ──────────────────────────────────────────────
// Discounts apply to the Performance West service fee only. State filing fees
// (passed through at cost) are never discountable, matching the CRTC flow.
let discountCents = 0;
let normalizedDiscountCode: string | null = null;
if (discount_code && typeof discount_code === "string" && discount_code.trim().length >= 2) {
const code = discount_code.toUpperCase().trim();
try {
const dcResult = await pool.query(
"SELECT * FROM discount_codes WHERE code = $1",
[code],
);
if (dcResult.rows.length > 0) {
const dc = dcResult.rows[0];
const now = new Date();
const active = dc.active === true;
const notExpired = !dc.expires_at || new Date(dc.expires_at) >= now;
const started = !dc.starts_at || new Date(dc.starts_at) <= now;
const underGlobalLimit = dc.max_uses === null || dc.current_uses < dc.max_uses;
// Scope check: allow codes scoped to this service (or unscoped)
let inScope = true;
if (dc.applies_to) {
const allowed = String(dc.applies_to).split(",").map((s: string) => s.trim().toLowerCase());
inScope = allowed.includes("fcc_carrier_registration") || allowed.includes("all");
}
// Email allowlist check
let emailOk = true;
if (dc.allowed_emails && dc.allowed_emails.length > 0) {
const allowed = dc.allowed_emails.map((e: string) => e.toLowerCase());
emailOk = allowed.includes(customer_email.toLowerCase().trim());
}
if (active && notExpired && started && underGlobalLimit && inScope && emailOk) {
// Discountable base = service fee + add-ons (not state filing fees).
const discountable = BASE_FEE_CENTS + addonFeeCents;
if (dc.discount_type === "percent") {
discountCents = Math.round((discountable * dc.discount_value) / 100);
} else {
discountCents = Math.min(dc.discount_value, discountable);
}
normalizedDiscountCode = code;
}
}
} catch (dcErr) {
console.warn("[fcc-carrier-reg] Discount lookup failed (non-fatal):", dcErr);
}
}
const orderNumber = generateOrderNumber();
const result = await pool.query(
`INSERT INTO fcc_carrier_registrations (
order_number, customer_email, customer_name, customer_phone,
entity_source, entity_legal_name, entity_type, formation_state, ein, frn,
contact_name, contact_email, contact_phone, contact_title,
address_street, address_city, address_state, address_zip,
service_wizard,
include_formation, include_dc_agent, include_rmd, include_cpni,
include_calea, include_bdc, include_stir_shaken, include_ocn,
state_puc_states,
service_fee_cents, formation_fee_cents, state_fee_cents,
puc_fee_cents, addon_fee_cents,
discount_code, discount_cents,
engagement_accepted_at, engagement_accepted_ip
) VALUES (
$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,
$19::jsonb,$20,$21,$22,$23,$24,$25,$26,$27,$28::text[],
$29,$30,$31,$32,$33,$34,$35,$36,$37
) RETURNING *`,
[
orderNumber,
customer_email.toLowerCase().trim(),
customer_name.trim(),
customer_phone || null,
entity_source,
entity_legal_name || null,
entity_type || null,
formation_state ? formation_state.toUpperCase() : null,
ein || null,
frn || null,
contact_name.trim(),
contact_email.toLowerCase().trim(),
contact_phone || null,
contact_title || null,
address_street || null,
address_city || null,
address_state ? address_state.toUpperCase() : null,
address_zip || null,
JSON.stringify(wizardData),
includeFormation,
includeDcAgent,
includeRmd,
includeCpni,
includeCalea,
includeBdc,
includeStirShaken,
includeOcn,
statePucStates,
BASE_FEE_CENTS,
formationFeeCents,
stateFeeCents,
pucFeeCents,
addonFeeCents,
normalizedDiscountCode,
discountCents,
engagement_accepted ? new Date().toISOString() : null,
engagement_accepted ? (req.ip || req.headers["x-forwarded-for"] || null) : null,
],
);
const order = result.rows[0];
// If formation needed, create a formation_orders row
if (includeFormation && formation_state) {
try {
const formationOrderNumber = `FO-${new Date().getFullYear()}-${randomBytes(3).toString("hex").toUpperCase()}`;
await pool.query(
`INSERT INTO formation_orders (
order_number, customer_name, customer_email, customer_phone,
state_code, entity_type, entity_name,
principal_address, principal_city, principal_state, principal_zip,
service_fee_cents, state_fee_cents, payment_status
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,'paid')`,
[
formationOrderNumber,
customer_name.trim(),
customer_email.toLowerCase().trim(),
customer_phone || null,
formation_state.toUpperCase(),
entity_type || "llc",
entity_legal_name || null,
address_street || null,
address_city || null,
address_state ? address_state.toUpperCase() : null,
address_zip || null,
FORMATION_MARKUP_CENTS,
stateFeeCents,
],
);
// Link formation order to carrier registration
await pool.query(
`UPDATE fcc_carrier_registrations SET formation_order_number = $1 WHERE order_number = $2`,
[formationOrderNumber, orderNumber],
);
} catch (formErr) {
console.warn("[fcc-carrier-reg] Formation order creation failed (non-fatal):", formErr);
}
}
const subtotalCents = BASE_FEE_CENTS + formationFeeCents + stateFeeCents + pucFeeCents + addonFeeCents;
const totalCents = Math.max(0, subtotalCents - discountCents);
// If this order used a sales agent's referral code, record a pending commission.
if (normalizedDiscountCode) {
try {
const agentCheck = await pool.query(
"SELECT sa.agent_code FROM sales_agents sa JOIN discount_codes dc ON sa.discount_code_id = dc.id WHERE dc.code = $1 AND sa.active = TRUE",
[normalizedDiscountCode],
);
if (agentCheck.rows.length > 0) {
const { createCommission } = await import("./agents.js");
await createCommission({
agentCode: agentCheck.rows[0].agent_code,
orderType: "fcc_carrier_registration",
orderId: order.id,
orderNumber: orderNumber,
serviceSlug: "fcc-carrier-registration",
customerName: customer_name.trim(),
customerEmail: customer_email.toLowerCase().trim(),
orderAmountCents: totalCents,
discountCents: discountCents,
});
}
} catch (commErr) {
console.warn("[fcc-carrier-reg] Commission creation failed (non-fatal):", commErr);
}
}
console.log(
`[fcc-carrier-reg] Created ${orderNumber}: ${entity_source} for ${customer_email}$${(totalCents / 100).toFixed(2)}` +
(discountCents > 0 ? ` (discount ${normalizedDiscountCode} -$${(discountCents / 100).toFixed(2)})` : ""),
);
res.json({
success: true,
order_number: orderNumber,
order_id: orderNumber,
order_type: "fcc_carrier_registration",
total_cents: totalCents,
pricing: {
base: BASE_FEE_CENTS,
formation: formationFeeCents + stateFeeCents,
addons: addonFeeCents,
puc: pucFeeCents,
subtotal: subtotalCents,
discount_code: normalizedDiscountCode,
discount_cents: discountCents,
total: totalCents,
},
});
} catch (err) {
console.error("[fcc-carrier-reg] Create error:", err);
res.status(500).json({ error: "Could not create order." });
}
});
// ── GET /api/v1/fcc-carrier-registration/:id ────────────────────────────────
router.get("/api/v1/fcc-carrier-registration/:id", async (req: Request, res: Response) => {
try {
const { rows } = await pool.query(
`SELECT * FROM fcc_carrier_registrations WHERE order_number = $1`,
[req.params.id],
);
if (rows.length === 0) {
res.status(404).json({ error: "Order not found" });
return;
}
res.json(rows[0]);
} catch (err) {
console.error("[fcc-carrier-reg] Get error:", err);
res.status(500).json({ error: "Could not load order." });
}
});
export default router;