Real Estate & Property Featured

Laravel Real Estate Portal with Property Listings, Agents & Razorpay

Overview

EstateHub — Self-Hosted Real Estate Portal with Agent Credits & Razorpay

A self-hosted multi-agent real estate portal — buyers search and enquire, agents publish credit-gated listings, the admin moderates everything — built on Laravel 13 & PHP 8.3. One install runs your whole marketplace: public storefront with map search, buyer accounts, an agent panel with Razorpay credit packages, an admin moderation desk, trash & restore, and a Sanctum REST API v1. No listing fees, no per-lead charges, no monthly commission — zero commission forever, one-time licence, your server, your data.

Live Demo — Search, Enquire, Moderate

Browse the storefront, the agent panel and the admin desk before you buy. The demo catalog is a live Indian portal — 20 properties across Mumbai, Pune, New Delhi and Bengaluru, 3 approved agents, an agency, enquiries, a viewing request, reviews, favorites and a saved search — so it feels like a running site, not a skeleton.

  • Storefront: https://estatehub.laravelsiteshub.com
  • Search: /properties — purpose, type, city, price, beds, keyword and amenity filters, sort, map view
  • Listing page: /property/{slug} — gallery, specs, amenities, map, floor plans, similar homes
  • Agent page: /agents/{slug} — listings, rating, reviews, contact box
  • Agency & city pages: /agencies/{slug}, /location/{city}
  • API docs (in-app): /api/docs — plus a downloadable Postman collection at /api/docs/postman.json (both need API_DOCS_ENABLED=true; otherwise 404)
  • Buyer login: /login — Email: user@estatehub.test
  • Agent login: /login — Email: agent1@estatehub.test
  • Admin login: /login — Email: admin@estatehub.test
  • Password (all demo accounts): password

php artisan migrate --seed on a live install loads settings, locations, packages and the full demo catalog above — the demo credentials are for evaluation only; change them before going live. Set DEMO_MODE=true only on a staging demo; it renders an amber demo banner on the storefront, agent and admin layouts (it blocks authenticated writes with a friendly notice while leaving search, listings, map browsing and guest enquiries fully live; logout stays working).

Why EstateHub — Stop Renting Your Listings

Portal listing packs, visibility boosters and lead bundles on the big property sites charge per listing, per city, per month — and the meter restarts every renewal cycle. Every fee goes up the day you depend on it. EstateHub turns your own domain into the portal: agents buy credit packs from you through Razorpay, buyers enquire free, and every listing, lead and review stays in your own MySQL.

Existing portal SaaS charges per agent seat per month, takes a cut of closures, and holds your data hostage behind export limits. EstateHub is the opposite: self-hosted, one-time licence, agents pay you — not a platform — it runs on the same shared hosting your WordPress already does (MySQL 8, PHP 8.3, no build step).

How It Works

For buyers — 30 seconds, no account needed to browse:

  1. Open the homepage — hero search, Buy/Rent shortcuts, featured and latest listings, browse-by-city and browse-by-type. No login.
  2. Filter on /properties — purpose, property type, city, price range, beds, keyword, amenities — then sort (newest, price, most viewed) or flip to Map View and pan.
  3. Open a listing — gallery with primary photo, specs, description, amenities, map pin, floor plans, similar homes. Bad slugs get a branded 404, never a stack trace.
  4. Send an enquiry or request a viewing — guests can too. The agent is emailed, the lead lands on their desk, and signed-in buyers keep copies under /account/enquiries and /account/viewings — viewings can be cancelled from My Viewings on the web (POST /account/viewings/{viewing}/cancel) and over the API too.

For agents — your shopfront, your credits:

  1. Join at /become-agent — account fields plus a display name. The admin approves (or auto-approve via setting); pending or suspended agents are redirected to /agent/pending (only banned or awaiting-approval accounts hit a 403 at the panel gate), never a broken page.
  2. Buy a credit pack — Basic (5 listings + 1 featured, 30 days, ₹499), Pro (20 + 5, 90 days, ₹1499), Elite (100 + 20, 180 days, ₹3999) — pay through Razorpay checkout; credits land only after server-side signature and amount verification.
  3. Publish — each submit consumes one listing credit (or post free while free_posting is on); listings auto-approve or queue for moderation per setting, and expire automatically after listing_expiry_days (60 by default) with one-click renew.
  4. Work the desk — leads move new → contacted → closed/spam, viewings move requested → confirmed → completed/cancelled, reviews get a public reply, and featuring a listing consumes a featured credit for 1–30 days (admins can feature any published property for 1–365 days).

For admins — the moderation desk:

  1. Approve or suspend agents, toggle verified badges, and watch the dashboard: property/agent/user/enquiry totals, the pending queues and the five latest paid purchases.
  2. Moderate properties — approve to publish, reject with a mandatory reason (max 500 chars, shown on the detail page), feature/unfeature with an expiry. Rejected listings refund the listing credit when refund_credit_on_reject is on.
  3. Recover from trash — soft-deleted users, agents and properties restore with email/slug collision checks, and permanent deletes are blocked where they would orphan profiles or listings.

Storefront & Search — Built to Browse

  • Homepage sections — hero search with Buy/Rent toggle, featured (8) and latest (8) listings, top cities with live counts, browse-by-type, agent call-to-action. Only published listings of approved agents ever render.
  • Filter panel that keeps its state — every filter survives sort, pagination and the map/list toggle; Apply/Clear and an honest no-results page with a clear-filters link.
  • Map search on Leaflet + OpenStreetMap by default — numeric bounding-box endpoint, featured markers starred, popups linking to listings, with Searching… and No properties in this area states. Mapbox, Google and MapTiler are a settings-dropdown away.
  • Cascading location selects (country → state → city → locality) served by dedicated AJAX endpoints, plus a click-to-drop map pin that stores exact latitude/longitude.
  • Phone-first navigation — hamburger menu under md with Buy/Rent/All Properties, zero horizontal overflow at 375px, verified by automated browser sweep.
  • Contact page at /contact (5/min throttle, honeypot + TimeTrap anti-spam) — every message lands in the admin inbox (/admin/contact-messages, filterable with per-row status updates) and notifies the site admin by queued email.
  • Legal pages included — Terms (/terms), Privacy (/privacy), Refund Policy (/refund-policy) and a RERA disclosure page (/rera-disclosure) explaining how registration numbers on listings should be read.

Property Pages — Everything a Buyer Asks

  • Gallery with primary-photo switching, price (or “price on request”), beds/baths/area/year-built specs, full description (up to 10,000 chars), amenity list, embedded map when geocoded, downloadable floor plans (images + PDF), video and virtual-tour links, and a similar-homes rail.
  • Up to 20 photos (3MB each, JPG/PNG/WebP) and 10 floor plans per listing, with set-primary, delete and drag-to-reorder that persists on reload.
  • SEO meta title (160) and description (320) per listing, clean unique slugs, and a RealEstateListing JSON-LD block with Offer and PostalAddress for rich results.
  • View counts increment once per session — ten reloads count as one view.
  • RERA numbers where the agent provides one — optional per-listing field with a teal RERA badge on the detail page and in the specs table, linking to the /rera-disclosure page. No number, no badge — never a fake one.
  • Share row on every listing — Facebook, X and WhatsApp share links plus a copy-link button (clipboard API with fallback) so buyers can pass a home to family in one tap.
  • Report-this-listing modal on every listing — reason dropdown plus optional details, honeypot + TimeTrap guarded and throttled (report-store bucket). Reports queue in the admin desk (/admin/reports) for human moderation; nothing is ever auto-hidden or auto-removed by a report.

Buyer Account — Enquire, Save, Review

  • One dashboard with live counts — favorites, saved searches, enquiries — plus details, enquiry history, My Viewings with one-click cancel, review history and a password screen where a wrong current password fails loudly and a correct change signs out every other session.
  • Enquiries (name ≤100, valid email, message ≤1000) and viewing requests (future date enforced server-side via after:today, optional time, note ≤500) carry a honeypot field plus a TimeTrap timestamp (forms submitted in under 5 seconds are rejected) — bots that fill the honeypot are rejected with Submission rejected. Guests can send both; both are throttled at 5/minute per IP.
  • Favorite heart toggles Save ↔ Saved over JSON without a reload (and degrades to a redirect + flash with JavaScript off); the Save control is auth-gated (guests are sent to login).
  • Saved searches store the exact filter set — re-run it with one click, flip email alerts on/off, delete with a confirm. Reviews are 1–5 stars with an optional ≤1000-char comment, one per buyer per agent enforced by a database unique constraint too; an optional setting requires a prior enquiry or viewing before reviewing.
  • Email verification on every account — signed verification link with a notice page and resend (separate web/API throttle buckets). Login always works while unverified, but all writes (reviews, favorites, saved searches, agent publishing, lead/viewing updates) require a verified email.
  • Self-serve account deletion — DELETE /account is always available to the signed-in user, even with demo mode on; bans and demo locks never trap a user inside their account.

Agent Panel — Gated, Credited, Complete

  • Single-role gate — 32 web agent routes (31 gated by login + agent role + approved status, plus the /agent/pending notice page); buyers meet a branded 403, guests meet the login page.
  • Dashboard with totals (all/published/pending/drafts), credit balances with expiry date, and the five most recent listings.
  • Property table with status badges, view counts and expiry colouring; Submit appears only on drafts/rejected, Sold only on published for-sale, Rented only on published for-rent, Renew only near expiry — never an action that cannot succeed.
  • Profile with photo upload (2MB, JPG/PNG/WebP), display name, bio (≤2000), phone, WhatsApp (drives the public Call/WhatsApp buttons), licence number, verified badge and live status.
  • Leads board with per-status counts and property links; viewings with confirm/complete/cancel and queued confirmation emails; review replies (≤1000 chars) stamped with replied_at; credits ledger with purchase history (10 per page) where every paid row links its GST invoice.

Admin Desk — Moderate Without Fear

  • Dashboard — seven stat widgets (total/pending/published properties, total/pending agents, buyers, enquiries), the five newest pending properties with review links, and the five latest paid purchases.
  • Agents — approve, suspend, toggle verified; badges and buttons flip immediately and stay consistent on reload.
  • Properties — all by default with pending/published/rejected pills that keep the filter; detail page shows gallery, full specs, agent card and the red rejection reason when present.
  • Reviews — hide/show dims the row and recomputes the agent’s average from visible reviews only; enquiries are a filterable table with per-row status updates where trashed properties show title + (deleted) instead of crashing.
  • Reports & contact inbox — property reports (new/reviewed/dismissed/actioned) with listing links for human moderation (reports never auto-hide anything); contact messages (new/read) with their own status flow. Both filterable, both paginated.
  • Users — searchable table with all/active/pending/banned pills; ban, unban or mark-pending with one click (bans revoke tokens and wipe sessions instantly; self-ban and admin-ban refused).
  • Settings — nine validated keys plus display-only INR currency: currency, area unit, agent/property auto-approve, listing expiry (server-enforced integer ≥ 1, not just the browser min), free posting, map provider and geocoder (whitelisted — a bad stored value can never break the map), refund-on-reject, require-contact-for-review.
  • Packages — full CRUD with credits ≥ 0 and validity ≥ 1 day enforced; enable/disable toggle; delete blocked with an explanation while pending/paid purchases reference the package.
  • Trash — the soft-deletes per type (users, agents, properties), 20 per page; restore fails closed with a named error on email/slug collision; permanent delete spells out its cascade in the confirm dialog and refuses where agent profiles or listings would be orphaned.

Packages & Razorpay — Money Handled Like Money

  • Credit packs are entitlement snapshots — buying Pro locks in 20 + 5 for 90 days even if the admin reprices the package tomorrow. Checkout creates a Pending purchase first; credits move only after proof of payment.
  • Return verification never trusts the browser — the payment is re-fetched from Razorpay and the amount, currency, status and order id are cross-checked against the purchase snapshot; mismatches grant nothing and leave the purchase Pending for manual/webhook review (Failed only for sub-minimum amounts; the webhook marks amount/currency mismatches Failed).
  • Webhooks are replay-safe — HMAC over the raw body, payment.captured only (everything else is acknowledged untouched), settled purchases are never re-judged so a retried delivery cannot flip Failed back to Paid, and orphan captures are logged critical for manual refund.
  • Razorpay-only by design (price_inr, no dead multi-currency columns) — with no keys configured, checkout fails closed with an error instead of creating a charge.
  • GST invoices on every paid purchase — deterministic EH-YYYY-XXXXXX numbers (activation year + purchase id, unique column, replay-safe), amount treated as GST-inclusive at BILLING_GST_RATE (default 18) split equally into CGST + SGST with taxable value shown, and the full breakup plus seller name/address/GSTIN snapshotted into invoice_meta so a later rate change never rewrites history. Agents open a printable invoice at /agent/invoices/{purchase} (ownership-checked) and the credits ledger links straight to it; a backfill command stamps invoices for older purchases.
  • Stale purchases clean themselves up — the daily purchases:cancel-stale-pending schedule fails Pending rows older than 24h (configurable --hours) with failure_reason=stale, grants no credits, never overwrites an existing failure reason, and never touches Paid rows. And verify is forgiving in the right direction: if the gateway later proves a stale purchase was actually captured, it resurrects to Paid with the reason cleared.

Read-Only Storefront API + Full Account/Agent REST API

Sanctum bearer-token REST at /api/v1 — public reads for storefronts and apps, authenticated writes for accounts and agents. Auth returns a top-level {user, token} (201 register / 200 login); resources are {data} or Laravel paginators; errors are flat {message} with errors on 422. The admin desk is web-session only by design — there are no admin API endpoints to probe.

  • POST /api/v1/auth/register (10/min) and POST /api/v1/auth/login (5/min) → token; POST /api/v1/auth/logout revokes it; bad credentials are 401, banned/deactivated accounts are 403 with a named reason.
  • GET /api/v1/properties (20/page) and GET /api/v1/properties/{slug} — published-only, like the site; GET /api/v1/agents and GET /api/v1/agents/{slug} — approved-only.
  • Account — me, favorites list/add/remove, enquiries, viewings list + cancel (POST /api/v1/account/viewings/{viewing}/cancel or DELETE /api/v1/account/viewings/{viewing}), password update (revokes other tokens and wipes DB sessions, mirroring the web eviction); POST /api/v1/properties/{slug}/enquire (201, guests get an explicit 401, throttled in its own api-enquire bucket).
  • Verification over API too — signed GET /api/v1/email/verify/{id}/{hash} plus resend at POST /api/v1/email/verification-notification (separate verify-api/resend-api throttle buckets); authenticated writes additionally require verified, and every authenticated route sits behind not.banned.
  • Agent CRUD — list/create/patch/delete/publish properties, fenced by role + approval + ownership: another agent’s listing is 403, not a leak.

SEO Built In

  • Server-rendered Blade throughout — listings, agents, agencies and city pages are semantic HTML readable without JavaScript and indexable without a headless pass.
  • Unique slugs everywhere (agent registration survives collisions — including soft-deleted rows — by suffixing, never 500ing); unknown slugs and unapproved agents resolve to branded 404s.
  • /sitemap.xml and /robots.txt served by the app; per-listing meta title/description plus JSON-LD; web errors are branded pages while /api/* errors stay machine-readable JSON.

Security Hardening

  • Single web guard with roles on the shared users row — admin is a role, not a second auth system. Banned and pending accounts attempt login normally, then see the same generic “These credentials do not match our records.” error as bad credentials (post-attempt check, logged out immediately — no pre-auth account oracle); the named “Your account has been banned.” / “Your account is awaiting approval.” 403s appear only at the panel gate and in the API.
  • Bans bite immediately — the EnsureNotBanned (not.banned) middleware guards every account, agent and admin surface (web + API), and the admin desk (/admin/users) can ban, unban or mark-pending any non-admin account: a ban/suspension revokes all API tokens and wipes DB web sessions on the spot, so a still-valid session cannot keep browsing. Self-ban and admin-ban are refused outright.
  • Verified-email gates on writes — login and browsing stay open while unverified, but reviews, favorites, saved searches, every agent write (listings, images, leads, viewings, replies, packages, profile) and the matching API writes require the verified middleware.
  • Defence in depth on every panel — role middleware plus the agent.approved gate plus per-record ownership gates (UserGate/AgentGate) on saved searches, properties, leads, viewings and reviews. Hidden buttons are never the security.
  • Throttles on every abuse-prone surface — login, registration (including agent-registration), password changes, enquiries, viewing requests, contact form, report form, API register/login, API enquire (api-enquire) and email verification + resend — each in its own named bucket (contact-store, report-store, verify-web/verify-api, resend-web/resend-api, …) with counters in the database cache table, not memory that restarts wipe.
  • Honeypot plus TimeTrap on enquiry, contact, report and viewing-request forms (honeypot must stay empty, form must be open ≥ 5 seconds — bots get Submission rejected.); the buyer registration form carries a honeypot field; CSRF token in every form plus the csrf-token meta tag; uploads validated by extension and size (photos 3MB, floor plans 3MB + PDF allowed, avatars 2MB); passwords minimum 8 with confirmation; login failures preserve only the email, never the password.
  • Password changes evict all other sessions (web) and revoke all other tokens (API) — a second logged-in device is signed out exactly when it should be.

Performance — Fast on Shared Hosting

  • No build step and no required services — Tailwind via CDN, Leaflet via CDN, OpenStreetMap tiles free by default; mail log out of the box; queue database by default (worker + schedule:run cron), sync available as the zero-ops option for small sites.
  • Rate-limit counters and rebuildable derived caches share the database cache table — safe to flush, nothing precious lives there.
  • Eager loading on every list that feeds a view (home sections, search, dashboards, moderation queues); API index paginated at 20/page; home capped at 8 featured + 8 newest + 8 cities.
  • Demo images ship as committed generated photos — no Imagick/GD required, no broken-image icons if storage is unlinked (styled placeholder instead).
  • Money stays exact — decimal columns, integer day/credit counters, and server-side amount cross-checks against the purchase snapshot at the gateway boundary.

Code Quality

Test suite835 tests across 124 files (108 Feature + 16 Unit) — MySQL/MariaDB only (migrations use MySQL-specific MODIFY statements and enums). Run composer test to verify.
Browser coveragePlaywright + Chromium UI suite outside the repo drives every reachable page — auth edge cases, storefront, engagement forms, account, agent and admin panels — every step screenshotted at desktop, with 375px mobile passes over every area.
Static analysisLarastan level 8 — app/ clean (phpstan.neon scans app/ and tests/; the only findings are confined to test helpers).
Guards enforcedcomposer guards runs 12 checks on every change: zero env() outside config/, no closure routes (route:cache-safe), no raw SQL, no destructive migration without acknowledgement, rollback-safe migrations, named web routes used in Blade, controller↔view wiring (including the legal, contact, report and invoice views), no cached Eloquent models, withCount select discipline, no hardcoded paths, named cache stores in tests.

Requirements

  • PHP ^8.3 and Composer 2
  • MySQL 8+ or MariaDB 10.6+, database created with utf8mb4_unicode_ci
  • SQLite is not supported — the schema relies on MySQL-specific migrations
  • PHP extensions: pdo_mysql, mbstring, openssl, curl, fileinfo, plus the standard Laravel set (ctype, json, tokenizer, dom) — no image-processing extension needed
  • Web server: Nginx / Apache (or php artisan serve for dev); outbound internet at runtime for the Tailwind/Leaflet CDNs and map tiles
  • No Node.js build — there is no asset pipeline to compile; public/build/ is not required
  • Razorpay keys optional — without them the storefront, panels and API all work; only credit checkout fails closed. Optional mail defaults to the log driver; queue sync needs nothing, database needs a worker + schedule:run cron.
  • Timezone via APP_TIMEZONE (defaults to Asia/Kolkata) — set it to your portal’s city so listing times, viewing dates and invoice years read correctly.
  • Billing identity optional — BILLING_SELLER_NAME, BILLING_ADDRESS, BILLING_GSTIN stamp every GST invoice; BILLING_GST_RATE (default 18) sets the inclusive GST percent. Leave them unset and invoices still generate with safe defaults.

What Is Included

  • Full Laravel 13 source (no vendor/ in the archive — the deployer runs composer install on the host so the lockfile resolves against that host), plus tests/ (including the tests/Support/FakeRazorpayService.php and tests/Support/RecordingRazorpayService.php offline gateway doubles) and phpunit.xml so the “835 tests pass” claim is buyer-verifiable.
  • Migrations and seeders: settings, admin account, locations, property types, amenities, Basic/Pro/Elite packages, plus RERA numbers, GST invoice fields (invoice_number, seller_gstin, buyer_gstin, invoice_meta), property reports, purchase failure_reason and contact messages — 5 recent additive migrations — plus a demo catalog (php artisan migrate --seed — Premier Realty agency, 3 verified agents with credits, a buyer, ~20 properties with photos across 4 cities, an enquiry, a viewing request, a review, favorites and a saved search).
  • Two artisan commands: invoices:backfill (stamps GST invoices onto older purchases) and purchases:cancel-stale-pending (fails abandoned Pending purchases; also on the daily scheduler alongside listing-expiry and saved-search alerts).
  • Blade views for the legal pages, contact page, report modal, invoice print view and agent credits ledger; services including InvoiceService (GST breakup + numbering), ActivatePackageService (credit grants) and the Razorpay gateway service — buyers of the code get the money path readable end to end.
  • Docs: README.md (features, install, configuration), INSTALL.md (quick install + Razorpay + queue/cron), CHANGELOG.md.
  • In-app API reference at /api/docs (set API_DOCS_ENABLED=true; 404 otherwise) with a downloadable Postman collection — the API ships documented, not tribal.

What This Is Not — Read Before You Buy

  • Does not process buyer payments or collect money from buyers — the only money flow is agents buying credit packs over Razorpay (INR). No buyer checkout, no refunds automation; orphan gateway captures are logged for manual refund.
  • Computes GST, not full tax accounting — every paid purchase gets an EH-YYYY-XXXXXX invoice treating the package price as GST-inclusive at BILLING_GST_RATE (default 18), split into taxable value + CGST/SGST and snapshotted so history never rewrites. There is no VAT engine, no interstate IGST split, no e-invoicing/IRN and no tax filing — your CA still closes the books.
  • No real-time chat between buyers and agents — contact is enquiries, viewing requests and reviews, with the agent notified by queued email.
  • No buyer login with OTP/social — email + password accounts, with remember-me and email-based password reset.
  • No multi-tenancy — one portal per installation; agents are tenants of your portal, not separate sites.
  • No WhatsApp Business API — public pages link Call/tel: and WhatsApp numbers; messaging itself is not in the app.
  • No mobile app and no offline mode — the storefront is a mobile-first web app; Tailwind/Leaflet load from CDN at runtime.
  • Sold and rented listings leave the public site (search and detail pages) — they remain on the agent’s desk with full history. Hidden reviews stay visible to their author with a Hidden badge.
  • Installation requires a developer with SSH/terminal (Composer, MySQL, cron). A paid installation service is available for portal owners without a developer.

Frequently Asked Questions

Do buyers need an account to browse and enquire?
No — search, listing pages, enquiries and viewing requests all work for guests. Accounts add favorites, saved searches with alerts, enquiry history and reviews.

How do agents pay, and what stops double-charging?
Razorpay checkout on Basic/Pro/Elite packs. Credits are granted only after the server re-fetches the payment from Razorpay and matches amount, currency, status and order id against the pending purchase — and both the return URL and the webhook are idempotent, so double-clicks and redeliveries grant credits exactly once. Every paid purchase also gets a GST invoice (EH-YYYY-XXXXXX, inclusive CGST/SGST breakup) the agent can print from the credits ledger.

Does it handle GST on credit sales?
Yes, at the invoice level: the package price is treated as GST-inclusive at your BILLING_GST_RATE (default 18), split into taxable value + CGST/SGST on a snapshotted invoice so later rate changes never rewrite history. It is not full tax accounting — no IGST split, no e-invoicing, no filing.

Do users have to verify their email? What if someone misbehaves?
Login works unverified, but every write — reviews, favorites, saved searches, agent publishing — needs a verified email (signed link + resend, web and API). Admins can ban, unban or mark-pending any non-admin account; a ban kills tokens and sessions immediately and blocks every panel and API route.

What about RERA numbers and bad listings?
Agents can add an optional RERA number per listing, shown as a badge linked to the built-in RERA disclosure page. Any visitor can report a listing from the modal on its page; reports queue in the admin desk for human review and never auto-hide the property.

What happens to a payment that never completes?
Pending purchases older than 24 hours are failed nightly by the scheduler with a recorded failure_reason and no credits granted — but if the gateway later proves the money was captured, verification resurrects the purchase to Paid instead of stranding it.

Can one installation host many agents and agencies?
Yes — unlimited agents and agencies per install, each agent with their own page (/agents/{slug}), listings, rating, leads and credit balance. Agencies group agents under /agencies/{slug}.

Does it work on shared hosting in India?
Yes — MySQL 8 or MariaDB 10.6+, PHP 8.3, no Redis, no build step (the zero-ops queue option needs no worker). Mail works without an SMTP account (log driver); Razorpay and maps run on free defaults (OSM + Nominatim, no keys) until you outgrow them.

What happens when a listing sells or expires?
The agent marks it Sold/Rented (terminal states) or the scheduled command expires it after your listing_expiry_days — either way it leaves public search while staying on the agent’s desk, and Renew spends one listing credit for a fresh expiry cycle.

Can the admin recover a deleted agent or property?
Yes — trash keeps soft-deleted users, agents and properties (20 per page) with one-click restore; email/slug collisions fail with a named error instead of corrupting data, and permanent deletes that would orphan profiles or listings are refused outright.

Is there an API for a mobile app?
Yes — versioned REST at /api/v1 with Sanctum tokens covering public reads, buyer accounts and full agent property CRUD, documented in-app at /api/docs (needs API_DOCS_ENABLED=true) with Postman export. The admin desk is web-session only.

What is in the download — are property photos included?
Generated demo photos are committed under storage/app/public/ and ship with the archive; run php artisan storage:link after install. Uploads thereafter live on the public disk (properties/{id}/images, floor-plans, agents/).

Changelog

v1.1.0

Latest Sep 24, 2026
Trust, billing, and buyer self-service: email verification, ban/report/RERA/contact/legal trust flows, GST invoices with stale-cancel + verify-resurrect, viewing cancel, share row, account delete, throttles, timezone/billing config, 835 tests.

v1.0.0

Sep 20, 2026
Initial release. Self-hosted multi-agent real estate portal on Laravel 13 + MySQL 8: property listings with photos, floor plans and map search, agent credit packs via Razorpay (INR), admin moderation with trash & restore, buyer accounts with favorites and alerts, plus a Sanctum REST API. Ships with demo data, docs, and 681 passing tests.
₹9,999.00

One-time payment · Lifetime license — ownership stays with us

Buy Now

Secure checkout via Razorpay

Instant ZIP download after purchase
Full source code licensed — ownership stays with us
Free future updates

Details

Versionv1.1.0
Last updatedSep 24, 2026
PublishedSep 20, 2026
FrameworkLaravel
Included FilesPHP, Blade, CSS, JS, JSON, XML, MD

Need help launching it?

We handle deployment, SSL, and production setup as a paid service, quoted separately from this purchase.

Get a quote →
Share