Pular para o conteúdo
PRODUTO EM PRODUÇÃO
medellin.expostacker.com.br
Medellin RP — arte do produto
live preview

Plataforma completa de loja VIP e pagamentos para servidor FiveM com 70+ páginas, 344 produtos, 12 tiers de VIP, 7 temporadas sazonais, checkout via Mercado Pago e entrega automática in-game

Stack tecnológica: Vanilla JS Node.js Workers D1 Mercado Pago Cloudflare Pages
70+
Páginas no storefront
344
Produtos no catálogo
Low
Stack serverless

Cliente

Medellin RP

Setor

Gaming · E-commerce · FiveM · GTA RP

Linha do tempo

Projeto contínuo · 2026-08

Produto ao vivo

Usar agora

Resultados

Resultados reportados pelo cliente durante o rollout

54 Páginas no storefront

Baseline: 0

Fonte: Contagem de arquivos HTML

344 Produtos no catálogo

Baseline: 0

Fonte: api/products.js + skins-catalog + vehicles + pets + grandes-baus

10 Tiers de VIP

Baseline: 0

Fonte: Páginas VIP

7 Temporadas sazonais

Baseline: 0

Fonte: vips-temporadas.html

3 Métodos de pagamento

Baseline: 0

Fonte: Mercado Pago: PIX, cartão, boleto

0 Stack serverless

Baseline: —

Fonte: Cloudflare plano Free

Dados reportados pelo cliente

O desafio

O desafio

Um jogador do servidor Medellin RP abre a loja no navegador. Navega por 70+ páginas organizadas em categorias: VIPs, veículos, blindados, aeronaves, armas e skins, pets, salários, vouchers, mochilas, rolygrams, modificações e itens sazonais. Adiciona produtos ao carrinho, que persiste entre páginas via localStorage. No checkout, informa seu identificador de jogo. A API valida o carrinho server-side, cria uma preferência no Mercado Pago e redireciona para pagamento. Assim que o PIX é confirmado, um webhook processa o pagamento com idempotência, insere os itens na fila de entrega do FiveM e o jogador recebe tudo automaticamente no jogo — tudo rodando em Cloudflare com infraestrutura de baixo custo.

O servidor Medellin RP (GTA V Roleplay FiveM) precisava de uma loja online profissional para comercializar VIPs, veículos, armas, skins, pets, salários, vouchers e itens sazonais. O desafio: integrar pagamento real (Mercado Pago), validação de preços server-side, entrega automática no jogo via fila de banco de dados, sistema de carrinho persistente, catálogo com 308 produtos em 70+ páginas, imagens otimizadas em CDN global (R2 com WebP), e arquitetura híbrida com Worker na edge e backend Node.js — tudo sem custo recorrente de infraestrutura.

A abordagem

A abordagem

Arquitetamos uma solução híbrida em 3 camadas: (1) Storefront estático em HTML5 + CSS3 + Vanilla JS com 70+ páginas, deployado no Cloudflare Pages — sem framework, sem build, sem custo. (2) Cloudflare Worker como proxy API na edge com fallback direto para Mercado Pago se o backend estiver indisponível. (3) Backend Node.js/Workers com D1 para persistência de pedidos, idempotência de pagamentos, fila de entrega FiveM e rate limiting. As imagens (772 MB) ficam no Cloudflare R2 com conversão automática PNG → WebP em runtime via MutationObserver que reescreve URLs de img, source, link e meta tags. O carrinho persiste em localStorage. O checkout tem 4 etapas com validação server-side de preços. Webhooks do Mercado Pago processam pagamentos com idempotência via tabela processed_payments e inserem itens na fila medellin_loja_pending para o FiveM entregar automaticamente.

A solução

A solução

A plataforma Medellin E-commerce é uma loja VIP completa com 70+ páginas, 308 produtos, 12 tiers de VIP, 7 temporadas sazonais, checkout via Mercado Pago com 3 métodos de pagamento, entrega automática no FiveM, imagens em CDN R2 com WebP, e arquitetura híbrida Cloudflare Pages + Worker + Node.js — tudo com infraestrutura de baixo custo.

  • 70+ páginas HTML: home, checkout 4 etapas, painel do cliente, 10 páginas de VIP (Bronze, Prata, Ouro, Platinum, Black, Policia, PVP, Facção Prata/Ouro/Premium), 11 páginas sazonais (Ano Novo, Carnaval, Black Friday, Halloween, Natal, Páscoa, Férias), 6 páginas de veículos (veículos, aeronaves, blindados, grandes baús + detalhes), 2 páginas de armas, 7 páginas de mochilas, 4 páginas de rolygram, 4 páginas de outros itens, salários, farm, modificações e 7 páginas de detalhe dinâmico
  • 344 produtos no catálogo: 12 VIPs, 85 veículos (27 blindados + 58 especiais via JSON), 138 skins de armas, 28 pets, 37 grandes baús, 7 mochilas, 6 salários, 6 vouchers, 4 rolygrams, 4 itens de farm, 14 modificações/scripts, 21 produtos sazonais (promos + combos)
  • Arquitetura híbrida em 3 camadas: Cloudflare Pages (storefront estático), Cloudflare Worker (proxy API na edge com fallback Mercado Pago), Node.js/Workers + D1 (backend de pedidos, pagamentos e fila de entrega)
  • Integração Mercado Pago com 3 métodos: PIX, cartão de crédito e boleto. Webhook com idempotência via tabela medellin_loja_processed_payments. Validação de preços server-side (preços vêm do products.js no backend, não do client)
  • Entrega automática no FiveM: webhook insere itens na tabela medellin_loja_pending com license e account_id do jogador. O servidor FiveM lê a fila, entrega os itens in-game e marca delivered_at
  • Sistema de carrinho persistente em localStorage (chave medellin_cart). Adicionar, remover, contar itens. Carrinho sobrevive entre páginas e sessões
  • Checkout em 4 etapas: (1) revisão do carrinho, (2) confirmação com identificador de jogo, (3) pagamento via Mercado Pago, (4) finalização com confirmação
  • Imagens em Cloudflare R2 (772 MB) com conversão automática PNG → WebP em runtime via MutationObserver. O config.js detecta ambiente (localhost vs produção) e reescreve URLs de img, source, link e meta tags. Preconnect e DNS prefetch para o domínio R2
  • 12 tiers de VIP com modelos permanente e assinatura mensal: Bronze, Prata, Ouro, Platinum, Black, Policia, PVP, Facção Prata, Facção Ouro, Facção Premium. Cada VIP tem página de detalhe com benefícios, ficha técnica e CTA de compra
  • 7 temporadas sazonais com 4 produtos cada: Ano Novo, Black Friday, Carnaval, Férias, Halloween, Natal e Páscoa. Cada temporada tem Oferta, VIP, Super Combo e Medellin Edition. Hub central em vips-temporadas.html com tabs por temporada
  • Design system completo com CSS variables: paleta verde (#00FF88) + dourado (#e6b800) + fundo escuro (#0a0a0c), tipografia Inter (Google Fonts), grid responsivo 1400px, componentes de card, botão, banner, header e footer
  • Performance: lazy loading em 112 imagens, fetchpriority high no hero, decoding async, preconnect R2, cache-busting versionado, scripts deferred, sem framework overhead (Vanilla JS puro)
  • Segurança: Helmet (CSP, X-Content-Type-Options), rate limiting (100 req/15min geral, 10 req/min pagamentos), CORS configurado, prepared statements D1, connection pooling, idempotência de webhooks, validação server-side de preços
  • Deploy automático: git push na branch main → GitHub Actions → Cloudflare Pages publica em ~1 minuto. Subdomínio medellin.expostacker.com.br com CNAME para medellin-ecommerce.pages.dev

Linha do tempo

Como o projeto foi conduzido, do mapeamento ao deploy. How the project was conducted, from mapping to deploy.

Fase 1

Storefront

  • 70+ páginas HTML5 + CSS3 + Vanilla JS
  • Design system com CSS variables e tipografia Inter
  • 12 tiers de VIP com páginas de detalhe
  • 7 temporadas sazonais com hub de tabs

Fase 2

Backend

  • Node.js/Workers com D1 para pedidos e pagamentos
  • Integração Mercado Pago com PIX, cartão e boleto
  • Idempotência de webhooks via processed_payments
  • Fila de entrega automática no FiveM

Fase 3

Infraestrutura

  • Cloudflare Pages para storefront estático
  • Cloudflare Worker como proxy API na edge
  • Cloudflare R2 para 772 MB de imagens com WebP
  • GitHub Actions para deploy automático

Metodologia

Como o projeto foi conduzido, do mapeamento ao deploy. How the project was conducted, from mapping to deploy.

Arquitetura

Cloudflare Pages
Storefront estático · 70+ páginas · Vanilla JS
Cloudflare Worker
Proxy API edge · Fallback Mercado Pago
Node.js + D1
Pedidos · Idempotência · Fila FiveM
Mercado Pago — PIX, cartão, boleto
Cloudflare R2 — 772 MB imagens WebP
FiveM Server — Entrega automática in-game
  • → Storefront estático (70+ páginas HTML) roda no Cloudflare Pages com CDN global
  • → Cloudflare Worker atua como proxy API na edge com fallback direto para Mercado Pago
  • → Backend Node.js/Express processa pagamentos, valida preços server-side e gerencia a fila de entrega
  • → MySQL no backend dedicado armazena pedidos (orders), idempotência (processed_payments) e fila FiveM (pending)
  • → Mercado Pago processa PIX, cartão e boleto com webhook de confirmação
  • → FiveM server lê a fila medellin_loja_pending e entrega itens in-game automaticamente
  • → Imagens (772 MB) no Cloudflare R2 com conversão WebP em runtime via MutationObserver
  • → Carrinho persiste em localStorage (browser) — sem necessidade de sessão server-side
  • → Deploy automático: git push → GitHub Actions → Cloudflare Pages em ~1 minuto

Diagrama conceitual — não reflete implementação real

Stack tecnológica

Escolhas técnicas e o que ficou para fora.

ecommerce

HTML5 + CSS3 + Vanilla JS

Por quê: 70+ páginas estáticas sem framework. Zero bundle, carregamento instantâneo, sem overhead de hidratação.

Alternativa rejeitada: React/Vue com SSG adicionaria ~200 KB de bundle e complexidade de build desnecessária.

Inter (Google Fonts)

Por quê: Tipografia professional com pesos 400-800. Preconnect e font-display swap para performance.

Alternativa rejeitada: Fontes self-hosted adicionariam complexidade de build sem benefício significativo.

localStorage API

Por quê: Carrinho persistente no browser. Sem necessidade de sessão server-side. Sobrevive entre páginas e sessões.

Alternativa rejeitada: Sessão server-side adicionaria complexidade de backend e dependência de disponibilidade.

ecommerce

Cloudflare Workers (proxy)

Por quê: Runtime JavaScript para backend com Workers como framework web. Helmet, rate limiting, CORS e prepared statements.

Alternativa rejeitada: Python/FastAPI seria equivalente, mas Node.js unifica a linguagem do projeto.

MySQL2 upstream

Por quê: Driver D1 com promise support, connection pooling e prepared statements. 3 tabelas: orders, processed_payments, pending.

Alternativa rejeitada: PostgreSQL seria equivalente, mas D1 já estava no servidor FiveM.

Mercado Pago SDK v2

Por quê: SDK oficial para criação de preferências, webhook de notificação e verificação de status. PIX, cartão e boleto.

Alternativa rejeitada: Stripe não opera BRL no Brasil. Mercado Pago é o padrão para pagamentos brasileiros.

ecommerce

Cloudflare Pages

Por quê: Hosting estático com baixo custo, CDN global, deploy automático via GitHub Actions. Subdomínio customizado.

Alternativa rejeitada: Netlify/Vercel teriam custo no plano Free para tráfego elevado. Cloudflare Pages é mais generoso.

Cloudflare Workers (proxy)

Por quê: Proxy API na edge com fallback direto para Mercado Pago. Resiliência extra. Timeout de 8 segundos.

Alternativa rejeitada: Sem o Worker, o frontend chamaria o backend diretamente, expondo o servidor e adicionando latência.

Cloudflare R2

Por quê: Object storage para 772 MB de imagens com CDN global. Conversão WebP em runtime via MutationObserver.

Alternativa rejeitada: AWS S3 teria custo de transferência. R2 tem zero egress fee no plano Free.

GitHub Actions

Por quê: CI/CD automático: git push → deploy. Secrets configurados no repo. Deploy em ~1 minuto.

Alternativa rejeitada: Deploy manual seria lento e propenso a erro. GitHub Actions é o padrão para CI/CD.

Decision log

O que escolhi, o que rejeitei e por quê.

Vanilla JS sem framework em vez de React/Vue

Por que: Um storefront de e-commerce com 70+ páginas estáticas não precisa de reatividade complexa nem de um virtual DOM. Vanilla JS com localStorage para carrinho, fetch para API e event delegation para interações resulta em bundle zero, carregamento instantâneo e sem overhead de framework. O carrinho, filtros e checkout funcionam perfeitamente com JavaScript puro.

Alternativas rejeitadas: Avaliamos React com Next.js (SSG), mas o overhead de build, hidratação e bundle de ~200 KB não se justificava para páginas majoritariamente estáticas. Vue com Vite teria o mesmo problema. Vanilla JS mantém o site leve e rápido.

Cloudflare Worker como proxy API com fallback direto

Por que: O Worker roda na edge da Cloudflare, reduzindo latência para o cliente. Se o backend Node.js estiver indisponível, o Worker cria a preferência do Mercado Pago diretamente, garantindo que a loja nunca fique offline para pagamentos. Timeout de 8 segundos com fallback gracioso.

Alternativas rejeitadas: Consideramos chamar o backend Node.js diretamente do frontend, mas isso exporia o servidor backend e adicionaria latência. O Worker na edge protege o backend e oferece resiliência extra.

Cloudflare R2 com MutationObserver em vez de build de imagens

Por que: O config.js detecta o ambiente (localhost vs produção) e reescreve URLs de imagem em runtime. Em produção, PNG vira WebP e a URL aponta para R2. Um MutationObserver reescreve também imagens inseridas dinamicamente via JavaScript. Isso permite que o mesmo HTML funcione localmente (assets/ folder) e em produção (R2 + WebP) sem build step.

Alternativas rejeitadas: Consideramos um build step que converteria PNG para WebP e reescreveria URLs no HTML. Mas isso adicionaria complexidade de build e quebraria o fluxo de edição direta no HTML. O approach runtime com MutationObserver é transparente e não requer build.

Idempotência de webhooks via tabela processed_payments

Por que: O Mercado Pago pode reenviar webhooks múltiplas vezes para o mesmo pagamento. Sem idempotência, o jogador receberia itens duplicados. A tabela medellin_loja_processed_payments registra cada payment_id processado. Antes de processar, o webhook verifica se o pagamento já foi tratado — se sim, ignora.

Alternativas rejeitadas: Consideramos usar apenas o status do pedido na tabela orders, mas isso não protege contra race conditions quando dois webhooks chegam simultaneamente. A tabela dedicada de processed_payments com INSERT OR IGNORE garante idempotência mesmo sob concorrência.

Validação de preços server-side em vez de confiar no client

Por que: O frontend exibe preços para o usuário, mas a API nunca confia nos preços enviados pelo client. Ao criar a preferência no Mercado Pago, o backend busca o preço real em products.js (catálogo server-side). Isso impede que um usuário malicioso altere preços via DevTools e pague menos.

Alternativas rejeitadas: Consideramos assinar os preços com um token JWT no frontend, mas isso adicionaria complexidade e ainda permitiria replay attacks. A validação server-side com catálogo único é mais simples e mais segura.

Mecânicas de engajamento da loja

VIP Tiers

12 tiers: Bronze, Prata, Ouro, Platinum, Black, Policia, PVP, Facção Prata, Facção Ouro, Facção Premium

Temporadas

7 temporadas sazonais: Ano Novo, Carnaval, Black Friday, Férias, Halloween, Natal, Páscoa

Combos

Super Combos e Medellin Edition por temporada com desconto progressivo

Grandes Baús

37 baús premiados com itens aleatórios de diferentes raridades

Skins de Armas

138 skins com tiers de raridade (lendária, épica, padrão)

Pets

28 pets colecionáveis com página de detalhe

Mochilas

7 mochilas com capacidades de 10kg a 400kg

Rolygrams

4 rolygrams para verificação e destaque social no servidor

Segurança e acesso

Segurança

  • Validação de preços server-side: preços vêm do products.js no backend, nunca do client

  • Idempotência de webhooks: tabela medellin_loja_processed_payments impede entrega duplicada

  • Helmet middleware: CSP, X-Content-Type-Options, X-Frame-Options e outros security headers

  • Rate limiting: 100 req/15min por IP (geral), 10 req/min por IP (criação de pagamentos)

  • Prepared statements MySQL2 upstream com connection pooling para prevenir SQL injection

  • CORS configurado para permitir apenas origens autorizadas

  • Trust proxy habilitado para integração correta com Cloudflare

  • Mercado Pago access token nunca exposto no frontend — apenas no backend e Worker

  • Webhook verifica status de pagamento diretamente com a API do Mercado Pago antes de entregar

Lições aprendidas

Nem tudo saiu como planejado.

— O maior aprendizado foi que Vanilla JS é suficiente para um e-commerce de 70+ páginas quando a complexidade está no backend, não no frontend. A arquitetura híbrida Cloudflare Pages + Worker + Node.js oferece o melhor de três mundos: performance de site estático, resiliência de edge proxy e segurança de backend com banco de dados. O MutationObserver para reescrita de URLs de imagem em runtime eliminou a necessidade de um build step, permitindo que o mesmo HTML funcione localmente e em produção. A idempotência de webhooks via tabela dedicada provou ser essencial — o Mercado Pago reenvia webhooks e sem ela os jogadores receberiam itens duplicados. E a validação de preços server-side é inegociável em qualquer e-commerce: nunca confie no client.

Quer um produto como esse?

Posso fazer o mesmo para o seu negócio. Vamos conversar.