PRODUCTO SAAS v1.0

FiveM Store

Premium marketplace for the FiveM community: buy and download scripts, assets, and resources for your server.

Timeline

3 Weeks

Role

Full Stack Developer

Slide 1
1 / 19

The Problem

The FiveM community lacks a centralized, trustworthy platform for acquiring premium server resources. Content creators have no professional channel to monetize their work, and server administrators must search scattered forums, risking malicious or outdated downloads.

  • No reliable, secure marketplace specifically built for FiveM.
  • No protection for digital content: files could be freely redistributed.
  • Lack of real-time support to resolve purchase or installation questions.
  • Manual inventory and order management with no centralized admin panel.

The Solution

I designed and developed a full-featured e-commerce platform for the FiveM community, combining secure payments, protected digital content downloads, and real-time support via WebSockets.

Full E-commerce

Shopping cart, discount system, and secure payment gateway integrated with Stripe Checkout.

Secure Downloads

One-time-use temporary token system to protect digital content and prevent unauthorized redistribution.

Admin Panel

Complete management of products, categories, orders, and customer support from a single dashboard.

Real-time Support

Integrated ticket chat with instant notifications via Socket.io for seamless customer service.

Multi-language

Full support for Spanish and English via next-intl with automatic language detection.

Premium Design

Responsive interface with dark mode, smooth animations, and a high-quality user experience.

Tech Stack

Next.js 16

Framework

React 19

Frontend

TypeScript

Language

PostgreSQL

Database

Prisma

ORM

Stripe

Payments

Socket.io

Realtime

TailwindCSS

Styling

next-intl

i18n

Nodemailer

Email

Technical Challenges

Secure Download System

Protecting digital content required implementing one-time download tokens with temporal expiration. Each token is generated after payment confirmation, stored in the database, and automatically invalidated after first use, preventing unauthorized redistribution.

download-token.ts
// Generate a one-time signed download token
export async function generateDownloadToken(orderId: string, productId: string) {
  const token = crypto.randomUUID();
  const expiresAt = new Date(Date.now() + 15 * 60 * 1000); // 15 min

  await db.downloadToken.create({
    data: { token, orderId, productId, expiresAt, used: false },
  });

  return token;
}

// Validate and consume the token (one-time use)
export async function consumeDownloadToken(token: string) {
  const record = await db.downloadToken.findUnique({ where: { token } });

  if (!record || record.used || record.expiresAt < new Date()) {
    throw new Error('Invalid or expired download token');
  }

  await db.downloadToken.update({ where: { token }, data: { used: true } });
  return record;
}

WebSockets in a Serverless Environment

Maintaining persistent Socket.io connections on a serverless platform like Vercel was the biggest challenge. The solution was migrating to Pusher as a managed WebSocket provider, enabling real-time notifications without a dedicated server.