01Visão geral do projeto
Admister é um marketplace multi-vertical. Sob um mesmo teto, ele opera classificados, um quadro de carros e peças, imóveis para venda e aluguel, um mercado de produtos com lojas de vendedores, bens digitais, um serviço de cupons e um agregador de preços. Cada um deles tem seu próprio subdomínio, sua própria página inicial e sua própria ideia do que é um item.
Por fora, eles parecem sete produtos separados. Por dentro, são uma única aplicação: o serviço é decidido pelo nome do host da solicitação, e tudo o que está por trás — contas, dinheiro, moderação, busca, mídia, notificações — é compartilhado. O projeto foi nosso do início ao fim: o modelo, o motor, a interface e o lançamento de cada vertical.
02Contexto e o problema
A maneira usual de lançar vários marketplaces é lançar vários sites. Funciona até o segundo: agora há duas tabelas de usuários, duas filas de moderação, duas integrações de pagamento e dois lugares onde o mesmo bug precisa ser corrigido duas vezes — e corrigido de maneira diferente, porque até lá o código se desviou.
O extremo oposto é igualmente ruim. Um site com uma categoria chamada «Carros» não pode pedir quilometragem, motor e placa da maneira que um quadro de carros deve, e uma busca de imóveis que não pode filtrar por andar e quartos não é uma busca de imóveis. A tarefa era manter um único motor sem fingir que sete catálogos muito diferentes são o mesmo catálogo.
03Objetivos do projeto
- um código base e uma conta para todos os verticais, com o serviço escolhido pelo nome do host;
- atributos e filtros por vertical: dezenas de campos para carros e imóveis, nenhum deles arrastado para os outros serviços;
- dinheiro em que o proprietário pode confiar — um saldo, faturas em criptomoeda, creditação idempotente e reconciliação de pagamentos pendentes;
- razões para os compradores voltarem: pesquisas salvas com notificações, emblemas de vendedores, leilões e compras em grupo;
- duas línguas e quatro moedas de exibição sem duplicar conteúdo;
- um aplicativo móvel que se comunica com um backend-for-frontend em vez de raspar o site.
04O que fizemos
Construímos o registro de serviços na sequência de inicialização. Um pedido chega, o nome do host é comparado com o registro, e a partir desse momento a aplicação sabe qual vertical é: quais módulos carregar, qual conjunto de atributos usar, qual página inicial e qual menu renderizar. O domínio básico é o quadro de classificados, então o endereço mais curto também é o mais geral.
Tudo que não é específico de vertical foi escrito uma vez: contas e sessões, saldo e pagamentos, recebimento de mídia, moderação, pesquisas salvas, notificações, o sitemap e a API. Adicionar o sétimo serviço foi principalmente escrever seus atributos e sua página inicial — não outro mercado.
05Sete serviços, sete catálogos
- Classificados — o quadro geral: qualquer coisa, de uma bicicleta a um sofá, grátis para postar.
- Carros — veículos, placas e peças, com um conjunto de atributos dedicado de várias dezenas de campos e filtros construídos sobre isso.
- Imóveis — venda e aluguel, seu próprio conjunto de atributos, mapas e busca por distrito.
- Mercado — produtos com lojas de vendedores: uma vitrine por vendedor, estoque, pedidos.
- Digital — chaves, cartões-presente e eSIM: produtos que são entregues, não enviados.
- Negócios — cupons e códigos promocionais de lojas parceiras.
- Preço — um agregador de preços: o mesmo produto em lojas, comparado, com cliques de saída contados.
Eles compartilham a conta, o saldo, a fila de moderação e o índice de busca — e não compartilham nada em seus atributos, que é o ponto.
06Dinheiro: um saldo, faturas em cripto, reconciliação
Recursos pagos — promoção, planos de loja, bens digitais — são pagos a partir de um saldo interno, e o saldo é recarregado com cripto através de Payora, nosso próprio gateway. O corpo da fatura é construído em exatamente uma função, porque o mesmo corpo é reproduzido pelo cron de reconciliação sob a mesma chave de idempotência: um único campo que difere entre os dois retornaria como um conflito e deixaria o pagamento pendente.
Dois detalhes que repetiríamos em qualquer gateway. A fatura carrega o próprio local do comprador retirado da linha de sua conta, não da solicitação da web — o cron não tem solicitação e, caso contrário, enviaria todos em inglês. E carrega um endereço de retorno que leva de volta à conta no domínio básico, para que um comprador que começou na vertical de carros retorne logado, e não para uma página que pede para que ele faça login novamente.
07Confiança: moderação, distintivos, disputas
Um marketplace é julgado pela sua pior listagem, então a moderação não é uma tela lateral aqui. Cada decisão — aprovar, rejeitar, remover — passa por um único responsável, e «rejeitar» não é deliberadamente a mesma coisa que «remover»: o primeiro é uma resposta ao autor com uma razão, o segundo remove algo que já estava ativo. Dois verbos, duas letras diferentes, dois estados diferentes no registro.
Vendedores e lojas possuem emblemas que são conquistados, não comprados: há quanto tempo a conta existe, quantos negócios foram fechados, se o telefone e o e-mail estão confirmados. O comprador vê o mesmo emblema em todos os lugares onde o vendedor aparece, porque é calculado em um só lugar.
08Pesquisa, pesquisas salvas e push
A busca sabe em qual vertical está. No quadro de carros, oferece os campos que um carro possui; em imóveis, oferece quartos, andar e distrito; no quadro geral, permanece deliberadamente simples. As sugestões vêm de um endpoint próprio, então o campo responde enquanto a página ainda está sendo lida.
Uma busca pode ser salva — e isso é o que transforma um visitante em um retornante. Novas correspondências chegam como um web push, a assinatura pertence à conta em vez de à aba do navegador, e o mesmo mecanismo carrega os eventos que as pessoas realmente esperam: um leilão prestes a fechar, uma compra em grupo que atingiu seu limite.
09Um aplicativo móvel com seu próprio backend
O aplicativo não faz scraping do site. Ele se comunica com um backend-for-frontend próprio: um pequeno conjunto de endpoints que respondem nas formas que as telas precisam, com tokens emitidos separadamente das sessões da web. Dois caminhos estão abertos sem um token — os dados de referência que o aplicativo precisa antes que alguém faça login, e um endpoint de saúde.
Esse endpoint de saúde é um endereço separado de propósito. O registro que monitora a frota costumava perguntar ao endpoint de referência, e esse compila todos os dicionários e todas as taxas — uma verificação de vivacidade não deve custar mais do que o trabalho. Ele responde com a versão do contrato também, então um cliente construído para um contrato mais antigo é notado antes que seus usuários percebam.
10Sete frentes de SEO
Sete serviços em um domínio significam sete sitemaps, sete conjuntos de dados estruturados e uma maneira muito fácil de produzir duplicatas. Cada vertical publica seu próprio sitemap a partir do cache, as páginas de listagem declaram seu próprio tipo de dados estruturados, e as páginas de resultados de busca nunca afirmam ser canônicas para uma listagem.
O lado do conteúdo também é automatizado: um fluxo editorial chega de Astrina, a plataforma que construímos exatamente para isso, e no momento em que um artigo chega, o cache do sitemap para sua vertical é descartado — caso contrário, a nova página aguardaria a próxima reconstrução e ninguém saberia por que estava faltando.
11Um canal de saída
Tudo que a aplicação envia para fora — chamadas de API, webhooks, feeds de parceiros, imagens que busca, e-mail — passa por um único módulo vinculado a um proxy de saída SOCKS5, com DNS resolvido através do proxy também. O módulo é fail-closed: se o proxy estiver indisponível, a solicitação é bloqueada em vez de ser enviada silenciosamente do próprio endereço do servidor.
Isso não é decoração. Um marketplace puxa feeds de parceiros e imagens remotas o dia todo; cada um deles é uma solicitação que, de outra forma, carregaria o endereço de origem do site para um terceiro. O e-mail vai pelo mesmo caminho, através de YourTrend, então as cartas são assinadas e o nome do host do servidor nunca aparece em um cabeçalho.
12Pilha de tecnologia
- PHP 8.3 sem um framework, um wrapper PDO fino e declarações preparadas em todos os lugares;
- MariaDB, esquema mantido como arquivos de migração numerados em vez de como a memória de alguém;
- mídia armazenada fora da raiz da web e servida por um controlador, de modo que um upload nunca seja um caminho executável;
- uma etapa de construção que hash assets e não insere nada que deva ser armazenado em cache, com um interruptor de desligamento para quando ele se comporta mal;
- SAÍDA SOCKS5 para cada chamada de saída, e-mail através do SMTP do YourTrend;
- Payora para faturas de criptomoedas, Astrina para login e conteúdo editorial, Adgora para publicidade interna.
13O resultado
Sete serviços ao vivo em uma única base de código, uma conta e um saldo em todos eles, com atributos e filtros que diferem tanto quanto os catálogos. Um novo vertical é um conjunto de atributos e uma página inicial — não um novo projeto, não uma segunda tabela de usuários, não uma segunda integração de pagamento.
O que o proprietário recebe dia a dia é um lugar para olhar. Moderação, dinheiro, vendedores e conteúdo são gerenciados a partir do painel de controle compartilhado de todo o grupo, e o marketplace os expõe através de uma API de admin assinada em vez de através de um segundo site de admin próprio.
14Principais aprendizados
A lição que levaríamos para o próximo marketplace: compartilhe a maquinaria, não o significado. Contas, dinheiro, moderação e busca são o mesmo problema em todos os verticais e devem ser escritos uma vez. Atributos, filtros e a forma de um anúncio são o próprio produto, e forçá-los em uma tabela universal é como os marketplaces se tornam inutilizáveis para todos ao mesmo tempo.
A segunda lição é sobre dinheiro. O lugar onde um pagamento é descrito deve ser uma única função, porque algo mais irá reproduzi-lo — um cron, uma nova tentativa, uma reconciliação — e duas descrições de um pagamento é a maneira mais barata de perder dinheiro silenciosamente.
Se você está construindo um marketplace, um quadro de classificados ou uma plataforma multi-vertical em um único motor, este é o tipo de trabalho que fazemos de ponta a ponta.



