246 lines
7.0 KiB
JavaScript
246 lines
7.0 KiB
JavaScript
const express = require("express");
|
|
const { authenticateToken } = require("../middleware/auth");
|
|
const { User, Item } = require("../models");
|
|
const StripeService = require("../services/stripeService");
|
|
const logger = require("../utils/logger");
|
|
const router = express.Router();
|
|
|
|
// Get checkout session status
|
|
router.get("/checkout-session/:sessionId", async (req, res) => {
|
|
try {
|
|
const { sessionId } = req.params;
|
|
|
|
const session = await StripeService.getCheckoutSession(sessionId);
|
|
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.info("Stripe checkout session retrieved", {
|
|
sessionId: sessionId,
|
|
status: session.status,
|
|
payment_status: session.payment_status,
|
|
metadata: session.metadata,
|
|
});
|
|
|
|
res.json({
|
|
status: session.status,
|
|
payment_status: session.payment_status,
|
|
customer_email: session.customer_details?.email,
|
|
setup_intent: session.setup_intent,
|
|
metadata: session.metadata,
|
|
});
|
|
} catch (error) {
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.error("Stripe checkout session retrieval failed", {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
sessionId: sessionId,
|
|
});
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Create connected account
|
|
router.post("/accounts", authenticateToken, async (req, res) => {
|
|
try {
|
|
const user = await User.findByPk(req.user.id);
|
|
|
|
if (!user) {
|
|
return res.status(404).json({ error: "User not found" });
|
|
}
|
|
|
|
// Check if user already has a connected account
|
|
if (user.stripeConnectedAccountId) {
|
|
return res
|
|
.status(400)
|
|
.json({ error: "User already has a connected account" });
|
|
}
|
|
|
|
// Create connected account
|
|
const account = await StripeService.createConnectedAccount({
|
|
email: user.email,
|
|
country: "US", // You may want to make this configurable
|
|
});
|
|
|
|
// Update user with account ID
|
|
await user.update({
|
|
stripeConnectedAccountId: account.id,
|
|
});
|
|
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.info("Stripe connected account created", {
|
|
userId: req.user.id,
|
|
stripeConnectedAccountId: account.id,
|
|
});
|
|
|
|
res.json({
|
|
stripeConnectedAccountId: account.id,
|
|
success: true,
|
|
});
|
|
} catch (error) {
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.error("Stripe connected account creation failed", {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
userId: req.user.id,
|
|
});
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Generate onboarding link
|
|
router.post("/account-links", authenticateToken, async (req, res) => {
|
|
try {
|
|
const user = await User.findByPk(req.user.id);
|
|
|
|
if (!user || !user.stripeConnectedAccountId) {
|
|
return res.status(400).json({ error: "No connected account found" });
|
|
}
|
|
|
|
const { refreshUrl, returnUrl } = req.body;
|
|
|
|
if (!refreshUrl || !returnUrl) {
|
|
return res
|
|
.status(400)
|
|
.json({ error: "refreshUrl and returnUrl are required" });
|
|
}
|
|
|
|
const accountLink = await StripeService.createAccountLink(
|
|
user.stripeConnectedAccountId,
|
|
refreshUrl,
|
|
returnUrl
|
|
);
|
|
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.info("Stripe account link created", {
|
|
userId: req.user.id,
|
|
stripeConnectedAccountId: user.stripeConnectedAccountId,
|
|
expiresAt: accountLink.expires_at,
|
|
});
|
|
|
|
res.json({
|
|
url: accountLink.url,
|
|
expiresAt: accountLink.expires_at,
|
|
});
|
|
} catch (error) {
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.error("Stripe account link creation failed", {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
userId: req.user.id,
|
|
stripeConnectedAccountId: user?.stripeConnectedAccountId,
|
|
});
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Get account status
|
|
router.get("/account-status", authenticateToken, async (req, res) => {
|
|
try {
|
|
const user = await User.findByPk(req.user.id);
|
|
|
|
if (!user || !user.stripeConnectedAccountId) {
|
|
return res.status(400).json({ error: "No connected account found" });
|
|
}
|
|
|
|
const accountStatus = await StripeService.getAccountStatus(
|
|
user.stripeConnectedAccountId
|
|
);
|
|
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.info("Stripe account status retrieved", {
|
|
userId: req.user.id,
|
|
stripeConnectedAccountId: user.stripeConnectedAccountId,
|
|
detailsSubmitted: accountStatus.details_submitted,
|
|
payoutsEnabled: accountStatus.payouts_enabled,
|
|
});
|
|
|
|
res.json({
|
|
accountId: accountStatus.id,
|
|
detailsSubmitted: accountStatus.details_submitted,
|
|
payoutsEnabled: accountStatus.payouts_enabled,
|
|
capabilities: accountStatus.capabilities,
|
|
requirements: accountStatus.requirements,
|
|
});
|
|
} catch (error) {
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.error("Stripe account status retrieval failed", {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
userId: req.user.id,
|
|
stripeConnectedAccountId: user?.stripeConnectedAccountId,
|
|
});
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Create embedded setup checkout session for collecting payment method
|
|
router.post(
|
|
"/create-setup-checkout-session",
|
|
authenticateToken,
|
|
async (req, res) => {
|
|
try {
|
|
const { rentalData } = req.body;
|
|
|
|
const user = await User.findByPk(req.user.id);
|
|
|
|
if (!user) {
|
|
return res.status(404).json({ error: "User not found" });
|
|
}
|
|
|
|
// Create or get Stripe customer
|
|
let stripeCustomerId = user.stripeCustomerId;
|
|
|
|
if (!stripeCustomerId) {
|
|
// Create new Stripe customer
|
|
const customer = await StripeService.createCustomer({
|
|
email: user.email,
|
|
name: `${user.firstName} ${user.lastName}`,
|
|
metadata: {
|
|
userId: user.id.toString(),
|
|
},
|
|
});
|
|
|
|
stripeCustomerId = customer.id;
|
|
|
|
// Save customer ID to user record
|
|
await user.update({ stripeCustomerId });
|
|
}
|
|
|
|
// Add rental data to metadata if provided
|
|
const metadata = rentalData
|
|
? {
|
|
rentalData: JSON.stringify(rentalData),
|
|
}
|
|
: {};
|
|
|
|
const session = await StripeService.createSetupCheckoutSession({
|
|
customerId: stripeCustomerId,
|
|
metadata,
|
|
});
|
|
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.info("Stripe setup checkout session created", {
|
|
userId: req.user.id,
|
|
stripeCustomerId: stripeCustomerId,
|
|
sessionId: session.id,
|
|
hasRentalData: !!rentalData,
|
|
});
|
|
|
|
res.json({
|
|
clientSecret: session.client_secret,
|
|
sessionId: session.id,
|
|
});
|
|
} catch (error) {
|
|
const reqLogger = logger.withRequestId(req.id);
|
|
reqLogger.error("Stripe setup checkout session creation failed", {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
userId: req.user.id,
|
|
stripeCustomerId: user?.stripeCustomerId,
|
|
});
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
);
|
|
|
|
module.exports = router;
|