// routes/tenant/rent/pay/index.tsx import { define } from "../../../../utils.ts"; import { getLeasesByTenant } from "../../../../services/leaseService.ts"; import { getPaymentMethodsByUser, PaymentMethod, } from "../../../../services/paymentService.ts"; import { page } from "fresh"; import { Lease } from "../../../../db/interfaces.ts"; // Flexible interface for rent payment page data interface RentPaymentPageData { currentLease?: Lease | null; paymentMethods?: PaymentMethod[]; error?: string; success?: boolean; paymentAmount?: number; dueDate?: string; lateFee?: number; // Allow additional properties for future extensibility [key: string]: string | number | boolean | object | null | undefined; } export const handler = define.handlers({ async GET(ctx) { const { user_id } = ctx.state.data; if (!user_id) { return new Response("", { status: 302, headers: { Location: "/auth/login" }, }); } try { const leases = await getLeasesByTenant(user_id); const paymentMethods = await getPaymentMethodsByUser(user_id); const currentLease = leases?.[0]; // Assuming tenant has one active lease return page({ currentLease, paymentMethods, error: "", success: false, paymentAmount: 0, dueDate: "", lateFee: 0, }); } catch (error) { console.error("Error loading rent payment page:", error); return page({ error: "Failed to load payment information", }); } }, async POST(ctx) { const { user_id } = ctx.state.data; if (!user_id) { return new Response("", { status: 302, headers: { Location: "/auth/login" }, }); } try { const formData = await ctx.req.formData(); const amount = parseFloat(formData.get("amount") as string); const _payment_method_id = formData.get("payment_method_id") as string; const lease_id = formData.get("lease_id") as string; // Call the payment intent creation endpoint const intentResponse = await fetch(`http://${ctx.req.headers.get("host")}/api/payments/create_intent`, { method: "POST", headers: { "Content-Type": "application/json", "Cookie": ctx.req.headers.get("cookie") || "", }, body: JSON.stringify({ lease_id, amount, payment_method: "ach", }), }); const intentData = await intentResponse.json(); if (!intentData.success) { console.error("Payment intent creation failed:", intentData.error); return page({ error: intentData.error || "Failed to create payment intent. Please try again.", }); } // Redirect to confirmation page with payment details const redirectUrl = new URL("/tenant/rent/confirmation", ctx.req.url); redirectUrl.searchParams.set("success", "true"); redirectUrl.searchParams.set("amount", String(amount)); if (intentData.mode === "stripe") { redirectUrl.searchParams.set( "payment_intent_id", intentData.payment_intent_id, ); redirectUrl.searchParams.set("client_secret", intentData.client_secret); } return new Response("", { status: 302, headers: { Location: redirectUrl.toString() }, }); } catch (error) { console.error("Error processing payment:", error); return page({ error: "Payment processing failed. Please try again.", }); } }, }); export default define.page( function RentPayment({ data }: { data: RentPaymentPageData }) { const { currentLease, paymentMethods, error } = data; if (!currentLease) { return (
Make your monthly rent payment securely online