G

GEOCARS

Install & Run Documentation

Laravel API + React App + Stripe Service + Expo Mobile

Run GeoCars with confidence.

This guide was built from the real repository structure in api/, app/, and stripe/. It reflects the actual scripts, ports, Docker services, environment variables, authentication setup, and Stripe payment flow wired into this codebase.

Recommended

Docker Compose

Fastest way to run frontend, backend, Stripe, MySQL, and phpMyAdmin together.

Actual frontend dev port

http://localhost:3001

The Vite app is configured for port 3001, not 3000.

Important caveat

VITE_APP_API_URL matters

The frontend Axios client reads VITE_APP_API_URL. If API calls fail, check that variable before anything else.

Overview

What is in this repository?

api/

Laravel 12 API

Handles authentication, plans, users, companies, cars, rentals, requirements, comments, reactions, OpenAPI generation, Passport OAuth, and payment recording.

  • • Requires PHP 8.2+
  • • Uses Laravel Passport for auth:api
  • • Exposes Stripe endpoints under /api/Stripe/*
app/

React 19 + TypeScript

Vite-based frontend with Tailwind CSS, Radix UI, React Router, React Query, Zustand, and an Orval-generated API client.

  • • Runs on 3001
  • • Reads API base URL from VITE_APP_API_URL
  • • Proxies Stripe checkout in dev when needed
stripe/

Node Stripe Gateway

An Express service that creates Checkout Sessions, verifies Stripe webhooks, and can forward validated payment data to Laravel.

  • • Runs on 5000
  • • Needs Stripe secret and webhook secret
  • • Helps local payment development

Service map

Ports & URLs

Service Port URL Purpose
Frontend 3001 http://localhost:3001 React Vite app
Backend API 8000 http://localhost:8000 Laravel API
Stripe Service 5000 http://localhost:5000 Checkout + webhooks
MySQL 3306 localhost:3306 Database
phpMyAdmin 8080 http://localhost:8080 DB admin UI
Mobile (Expo dev) 8081 http://localhost:8081 React Native app development server

Recommended path

Run everything with Docker Compose

The repository ships with Docker definitions for the frontend, backend, Stripe, MySQL, phpMyAdmin, and mobile app. For most people, Docker is the quickest path to a working development environment.

1) Prepare environment files

cd /home/andydevs69420/Documents/geocars-fullstack-laravel
cp api/.env.example api/.env
cp app/.env.example app/.env
cp stripe/.env.example stripe/.env

2) Build and start services

docker compose up --build -d

3) First-time Laravel setup

docker compose exec backend php artisan key:generate
docker compose exec backend php artisan migrate --seed
docker compose exec backend php artisan passport:install

Important Docker note

The frontend code uses VITE_APP_API_URL, but the current compose file sets REACT_APP_API_URL for the frontend service. If API requests fail in Docker, define VITE_APP_API_URL in app/.env or update the compose service env.

New feature

Mobile QR binding + location tracking

The mobile app now includes an authenticated renter flow with QR-based rental binding, offline-safe queueing, background GPS tracking, and an interactive map with route guidance.

User flow

  1. 1. User signs in on mobile using API login.
  2. 2. App opens scanner and reads a QR payload containing {"car_rental_id":number,"user_id":number}.
  3. 3. If online, the app binds the generated device identifier to a rental via POST /api/Device.
  4. 4. If offline, the binding is stored locally in SQLite and synced on resume.
  5. 5. GPS tracking starts and sends updates to POST /api/DeviceLocation.
  6. 6. Map tab shows live position, route preview, distance, and ETA.

Run mobile locally

cd mobile
npm install
npx expo start
  • • Android: npm run android
  • • iOS: npm run ios
  • • Web: npm run web

Set API host in mobile/src/lib/api.ts (API_BASE) based on target: 10.0.2.2 for Android emulator, 127.0.0.1 for iOS simulator, or your LAN IP for physical devices.

Mobile permissions in app config

  • • Camera permission for QR scanning
  • • Foreground + background location permission
  • • Android foreground service for continuous tracking
  • • iOS background modes for location and fetch

Key mobile routes

  • • /login — token login screen
  • • /scan — QR scanner and bind flow
  • • / — tracking dashboard with status and sync controls
  • • /map — live map + route planner

Alternative path

Run the services locally

This path is useful when you want to work on the code in separate terminals, avoid containers, or debug the frontend, backend, and Stripe gateway independently.

Backend — api/

cd api
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate --seed
php artisan passport:install
php artisan serve --host=127.0.0.1 --port=8000

Needs PHP 8.2+, Composer, and a reachable MySQL database.

Useful shortcut: composer dev runs Laravel serve, queue listener, logs, and Vite concurrently.

Frontend — app/

cd app
npm install
cp .env.example .env
npm run dev

Dev URL: http://127.0.0.1:3001

Required env:

VITE_APP_API_URL=http://127.0.0.1:8000

Optional Stripe env:

VITE_APP_STRIPE_CHECKOUT_URL=http://127.0.0.1:5000

Stripe — stripe/

cd stripe
npm install
cp .env.example .env
npm run dev

Dev URL: http://127.0.0.1:5000

Shortcut: from app/, you can run npm run dev:with-stripe to start Vite and Stripe together.

Configuration

Environment variables you should verify

The repo includes .env.example files for the API, app, and Stripe service. Based on the runtime code and configuration, these are the most important variables.

API — api/.env

  • APP_NAME, APP_ENV, APP_DEBUG, APP_URL
  • APP_KEY — via key:generate
  • DB_CONNECTION=mysql
  • DB_HOST, DB_PORT, DB_DATABASE,
    DB_USERNAME, DB_PASSWORD
  • STRIPE_SECRET_KEY
  • STRIPE_WEBHOOK_SECRET
  • STRIPE_GATEWAY_INGEST_SECRET

Frontend — app/.env

  • VITE_APP_API_URL=http://127.0.0.1:8000
  • VITE_APP_STRIPE_CHECKOUT_URL=http://127.0.0.1:5000 (optional)

In development, if VITE_APP_STRIPE_CHECKOUT_URL is missing, the app falls back to /stripe-service/checkout and Vite proxies it.

Stripe — stripe/.env

  • PORT=5000
  • CLIENT_URL=http://127.0.0.1:3001
  • STRIPE_SECRET_KEY
  • STRIPE_WEBHOOK_SECRET
  • LARAVEL_STRIPE_INGEST_URL=http://127.0.0.1:8000
  • STRIPE_GATEWAY_INGEST_SECRET — must match the API

Seed data

Default accounts

The database seeders create plans, users, companies, cars, car postings, subscriptions, and requirements. These accounts are useful for local testing.

Role Email / Username Password
Admin redondophilippandrewroa.dev@gmail.com / andydevs69420 admin@user69420
User john.doe@example.com / johndoe password123
Renter robert.garcia@rentacar.com / robertgarcia password123

These are development seed credentials and should never be used in production.

Roles

Main application areas

Admin

  • • Dashboard
  • • User configuration
  • • Company configuration
  • • Plan configuration
  • • Requirement configuration

User

  • • Dashboard
  • • Car rental management
  • • Car posting
  • • Car management
  • • Company config

Renter

  • • Browse listings
  • • Submit applications
  • • Complete checkout
  • • Success/cancel return routes

Payments

How Stripe works in this repo

Checkout flow

  1. 1. The frontend posts to the Stripe checkout endpoint.
  2. 2. In dev, this is usually /stripe-service/checkout through Vite proxying, or directly http://127.0.0.1:5000/checkout.
  3. 3. The Node Stripe service creates a Checkout Session with car_rental_id in metadata.
  4. 4. On success, the browser returns to the renter success page with ?session_id=....
  5. 5. The frontend then calls /api/Stripe/checkout/confirm so Laravel can verify and record the payment transaction.

Webhook choices

  • Direct to Laravel: Stripe sends events to /api/Stripe/webhook and Laravel verifies Stripe-Signature using STRIPE_WEBHOOK_SECRET.
  • Via Node gateway: Stripe sends events to the Node service at /webhook, which verifies the event and forwards a smaller payload to /api/Stripe/webhook/ingest.
  • Shared secret: STRIPE_GATEWAY_INGEST_SECRET must match between the API and Stripe service if you use the ingest path.

Stripe CLI → Laravel webhook

stripe listen --forward-to http://127.0.0.1:8000/api/Stripe/webhook

Stripe CLI → Node gateway

stripe listen --forward-to http://127.0.0.1:5000/webhook

Development-friendly detail

Even without a webhook, the renter success page still calls Laravel's checkout confirm endpoint. That means payment recording can work in development as long as the API has a valid STRIPE_SECRET_KEY.

Useful endpoints

API routes worth knowing

  • POST /api/Auth/login — login
  • POST /api/Auth/signup — signup
  • GET /api/User — users
  • GET /api/Plan — plans
  • GET /api/Car — cars
  • GET /api/CarPosting — postings
  • GET /api/CarRental — rentals
  • POST /api/Stripe/checkout/confirm — confirm paid checkout
  • POST /api/Stripe/webhook — direct Stripe webhook
  • POST /api/Stripe/webhook/ingest — gateway ingest

OpenAPI output is generated into api/public/openapi.json, and the frontend Orval config consumes that file.

First-run checklist

What success looks like

  • ✅ Frontend opens on http://localhost:3001
  • ✅ Backend responds on http://localhost:8000
  • ✅ MySQL is reachable and migrations succeed
  • ✅ Passport is installed and login works
  • ✅ Seeded admin, user, and renter accounts can sign in
  • ✅ Stripe checkout returns a hosted session URL when configured
  • ✅ After success redirect, Laravel records the transaction

Troubleshooting

Common issues and fixes

The frontend loads but API requests fail

Check VITE_APP_API_URL first. The frontend Axios client reads that exact variable. In Docker, also note that the compose file currently uses REACT_APP_API_URL for the frontend service.

Stripe checkout cannot reach port 5000

Start the Stripe service with docker compose up stripe or run cd stripe && npm run dev.

Laravel says Stripe is not configured

Set STRIPE_SECRET_KEY in api/.env. The checkout confirmation endpoint returns 503 when it is missing.

Webhooks are not being accepted

Verify that STRIPE_WEBHOOK_SECRET matches your target endpoint and that you are forwarding to the correct URL. For the gateway path, also verify STRIPE_GATEWAY_INGEST_SECRET matches in both services.

Passport auth looks broken

Run php artisan passport:install after migrations. The API guard is configured to use Passport.

Mobile app cannot authenticate against API

Confirm API_BASE in mobile/src/lib/api.ts uses a host your emulator or device can reach. For Android emulator, use 10.0.2.2 instead of localhost.

QR scanning or tracking is not working on mobile

Re-check camera and location permissions in the app, then verify the QR payload format is valid JSON with car_rental_id and user_id. If offline, the app queues binding/location updates locally and syncs when connectivity returns.