import express from “express”; import cors from “cors”; import multer from “multer”; import nodemailer from “nodemailer”; import axios from “axios”; import Twilio from “twilio”; import Stripe from “stripe”; import dotenv from “dotenv”; dotenv.config(); const app = express(); app.use(cors()); app.use(express.json()); // —- File upload (local disk for demo). Swap to S3 in production. const upload = multer({ dest: “uploads/” }); const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: “2024-06-20” }); const twilio = Twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN); // —- Email const transporter = nodemailer.createTransport({ service: “gmail”, auth: { user: process.env.EMAIL_USER, pass: process.env.EMAIL_APP_PASSWORD }, // use Gmail App Password }); // Utility: send SMS async function sendSms(to, body) { return twilio.messages.create({ from: process.env.TWILIO_FROM, to, body, }); } // Utility: tag in CRM (example patterns below) async function tagLeadInCRM({ name, email, phone, tag }) { // OPTION A: GoHighLevel (example) // You’ll use your GHL API key + locationId + contact endpoint // Docs differ by version; many teams instead use an inbound webhook from GHL workflow. if (process.env.CRM_WEBHOOK_URL) { await axios.post(process.env.CRM_WEBHOOK_URL, { name, email, phone, tag }); return; } // OPTION B: If no CRM hooked yet, just no-op return; } app.post(“/api/buy-it-now”, upload.single(“pof”), async (req, res) => { try { const { name, email, phone, strategy } = req.body; if (!req.file) return res.status(400).json({ error: “Proof of funds is required.” }); if (!name || !email || !phone) return res.status(400).json({ error: “Name, email, phone required.” }); const property = “110 Mosby Ave, Littleton, NC 27850”; const buyNowPrice = 110000; const emdAmount = Number(process.env.EMD_AMOUNT || 2500); // default $2,500 EMD // 1) Email to dispo inbox (attach file) await transporter.sendMail({ from: process.env.EMAIL_USER, to: “jdrealestategroup@yahoo.com”, subject: `BUY IT NOW Lead — ${property} — $${buyNowPrice.toLocaleString()}`, text: `New BUY IT NOW lead:\n` + `Name: ${name}\nEmail: ${email}\nPhone: ${phone}\nStrategy: ${strategy || “N/A”}\n` + `POF file: ${req.file.originalname}\n`, attachments: [ { filename: req.file.originalname, path: req.file.path, }, ], }); // 2) CRM tag await tagLeadInCRM({ name, email, phone, tag: “Buy It Now – Hot” }); // 3) SMS alert to Janice (fastest response) const janiceNumber = process.env.JANICE_PHONE || “+12523261197”; await sendSms( janiceNumber, `🔥 BUY IT NOW lead (${property})\n${name} | ${phone}\nPOF received. Check email. EMD checkout next.` ); // 4) Create Stripe Checkout for EMD const session = await stripe.checkout.sessions.create({ mode: “payment”, payment_method_types: [“card”], line_items: [ { price_data: { currency: “usd”, product_data: { name: `EMD Deposit — ${property}` }, unit_amount: emdAmount * 100, }, quantity: 1, }, ], metadata: { property, name, email, phone, tag: “Buy It Now – Hot”, }, success_url: `${process.env.PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`, cancel_url: `${process.env.PUBLIC_URL}/canceled`, }); return res.json({ checkoutUrl: session.url }); } catch (err) { console.error(err); return res.status(500).json({ error: “Server error creating Buy It Now flow.” }); } }); // Stripe webhook: confirm EMD paid -> CRM tag + SMS app.post( “/api/stripe/webhook”, express.raw({ type: “application/json” }), async (req, res) => { try { const sig = req.headers[“stripe-signature”]; const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET); if (event.type === “checkout.session.completed”) { const session = event.data.object; const { name, email, phone, property } = session.metadata || {}; // Tag CRM as EMD Paid await tagLeadInCRM({ name, email, phone, tag: “EMD Paid” }); // SMS Janice: paid const janiceNumber = process.env.JANICE_PHONE || “+12523261197”; await sendSms( janiceNumber, `✅ EMD PAID — LOCK IT\n${property}\n${name} | ${phone}\nStripe Session: ${session.id}` ); } res.json({ received: true }); } catch (err) { console.error(“Webhook error:”, err.message); res.status(400).send(`Webhook Error: ${err.message}`); } } ); app.listen(process.env.PORT || 5050, () => { console.log(`API running on port ${process.env.PORT || 5050}`); });