// routes/tenant/rent/pay/index.tsx import { define } from "../../../../utils.ts"; import { SessionCookie } from "../../../auth/callback.ts"; import { getLeasesByTenant } from "../../../../services/leaseService.ts"; import { getPaymentMethodsByUser, PaymentMethod, } from "../../../../services/paymentService.ts"; import { createPaymentTransaction } from "../../../../services/paymentService.ts"; import { getE2ENow, isE2EEnabled } from "../../../../services/e2eFixtures.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("/api/payments/create_intent", { method: "POST", headers: { "Content-Type": "application/json" }, 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 (

No Active Lease

You don't have an active lease to make payments for.

Return to Dashboard
); } return (

Pay Rent

Make your monthly rent payment securely online

{error && (
{error}
)} {/* Property Information */}

Property Information

Property Address
{currentLease.property_address || "Property Address"}
Monthly Rent
${currentLease.rent?.toLocaleString() || "N/A"}
Due Date
1st of each month
Late Fee
$50 after 5th of month
{/* Payment Amount */}
$

Standard monthly rent: ${currentLease.rent?.toLocaleString() || "N/A"}

{/* Payment Method */}
{(!paymentMethods || paymentMethods.length === 0) && (

You need to add a payment method first.{" "} Add payment method

)}
{/* Payment Schedule */}

Automatic Payments Available

Set up automatic monthly payments to never miss a due date.{" "} Enable autopay

{/* Security Notice */}

Secure Payment Processing

Your payment information is encrypted and processed securely. You will receive a confirmation email once your payment is processed.

{/* Submit Button */}
Cancel
); }, );