API Reference: Loja
Base URL: /api/loja. Todos os endpoints requerem autenticacao (AuthGuard).
Restricao de convidados: Membros com is_nucleo_origem = false (convidados de outro nucleo) recebem 403 Forbidden em comprar, doar e checkout. A loja esta disponivel apenas no nucleo de origem do membro.Resumo de Endpoints
| Metodo | Rota | Permissao | Descricao |
|---|---|---|---|
| POST | /api/loja/produtos | COORDENADOR / ADMINISTRADOR | Criar produto |
| GET | /api/loja/produtos | Autenticado | Listar produtos (vitrine) |
| GET | /api/loja/produtos/:id | Autenticado | Detalhe do produto + galeria + similares |
| PATCH | /api/loja/produtos/:id | COORDENADOR / ADMINISTRADOR | Atualizar produto |
| POST | /api/loja/comprar | Autenticado (nao convidado) | Compra unitaria com split payment |
| POST | /api/loja/checkout | Autenticado (nao convidado) | Checkout de carrinho multi-item |
| GET | /api/loja/meus-pedidos | Autenticado | Historico de pedidos do usuario |
| GET | /api/loja/pedidos | COORDENADOR / ADMINISTRADOR | Listar todos os pedidos do nucleo |
| PATCH | /api/loja/pedidos/:id/status | COORDENADOR / ADMINISTRADOR | Atualizar status do pedido |
| POST | /api/loja/pedidos/:id/cancelar | COORDENADOR / ADMINISTRADOR | Cancelar pedido (estorna CC + devolve estoque) |
| POST | /api/loja/cupons | ADMINISTRADOR | Criar cupom de desconto |
| GET | /api/loja/cupons | ADMINISTRADOR | Listar cupons do nucleo |
| PATCH | /api/loja/cupons/:id | ADMINISTRADOR | Atualizar cupom |
| POST | /api/loja/cupons/validar | Autenticado | Validar cupom por codigo |
| POST | /api/loja/doar | Autenticado (nao convidado) | Fazer doacao ao nucleo |
| GET | /api/loja/doacoes | ADMINISTRADOR | Listar doacoes do nucleo |
Produtos
POST /api/loja/produtos
Cria um novo produto na loja do nucleo.
Permissao: COORDENADOR / ADMINISTRADOR
Body
| Campo | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
nome | string | Sim | Nome do produto |
descricao | string | Nao | Descricao do produto |
categoria | string | Sim | Categoria do produto |
precoMoedas | number | Sim | Preco em moeda do nucleo (CC) |
precoReal | number | Sim | Preco em R$ |
estoque | number | Sim | Quantidade em estoque |
isIlimitado | boolean | Nao | Estoque ilimitado (default: false) |
fotoUrl | string | Nao | URL da foto principal |
imagensUrls | string[] | Nao | URLs da galeria de imagens (tabela produto_imagens) |
precoPromocionalMoedas | number | Nao | Preco promocional em CC |
precoPromocionalReal | number | Nao | Preco promocional em R$ |
dataInicioPromo | string (ISO) | Nao | Inicio do periodo promocional |
dataFimPromo | string (ISO) | Nao | Fim do periodo promocional |
isDestaque | boolean | Nao | Produto em destaque na vitrine (default: false) |
Response 200
{
"id": "uuid",
"nome": "Camiseta MBL",
"categoria": "VESTUARIO",
"preco_moedas": 500,
"preco_real": 59.90,
"estoque": 30,
"ativo": true
}GET /api/loja/produtos
Lista produtos do nucleo. Ordenados por destaque (desc) e data de criacao (desc).
Query Params
| Param | Tipo | Descricao |
|---|---|---|
todos | string | Se true, retorna todos (incluindo inativos). Default: apenas ativos. |
Campos extras no response
isPromoAtiva: boolean calculado — true se o preco promocional esta definido e a data atual esta dentro do periodo.isNovo: boolean calculado — true se o produto foi criado ha menos de 7 dias.
GET /api/loja/produtos/:id
Detalhe completo do produto incluindo galeria de imagens e ate 4 produtos similares (mesma categoria, mesmo nucleo, ativos).
Response inclui
- Todos os campos do produto +
isPromoAtiva+isNovo imagens: array de{ id, url, ordem }ordenado por ordemsimilares: ate 4 produtos da mesma categoria comisPromoAtivaeisNovo
PATCH /api/loja/produtos/:id
Atualiza campos permitidos de um produto. Se imagensUrls for enviado, substitui toda a galeria.
Permissao: COORDENADOR / ADMINISTRADOR
Campos permitidos
nome, descricao, categoria, precoMoedas, precoReal, estoque, isIlimitado, ativo, fotoUrl, precoPromocionalMoedas, precoPromocionalReal, dataInicioPromo, dataFimPromo, isDestaque
Compra (Split Payment)
POST /api/loja/comprar
Compra unitaria de um produto com split payment (CC + R$).
Restricoes
- assertNaoEhConvidado: verifica
membros_nucleos.is_nucleo_origem. Convidados recebem 403. - Quantidade entre 1 e 3.
- Saldo de CC verificado via
membros_nucleos.saldo_capixacoins(filtrado por usuario + nucleo).
Body
{
"produtoId": "uuid",
"quantidade": 2,
"valorCC": 3000,
"metodo": "PIX"
}Fluxo
- 100% CC (
valorRealAPagar <= 0): debita CC instantaneamente, pedido vai paraPENDENTE. - Mix CC + R$: calcula proporcao CC/total, gera cobranca Asaas pelo restante em R$, pedido fica
AGUARDANDO_PAGAMENTO. - 100% R$ (
valorCC = 0): gera cobranca Asaas pelo total. - Se a cobranca Asaas falhar, o pedido criado e deletado (rollback).
- Precos promocionais sao usados automaticamente quando a promocao esta ativa.
Response 200 (100% CC)
{
"pedidoId": "uuid",
"status": "PENDENTE",
"message": "Compra realizada com Capixacoins"
}Response 200 (com R$)
{
"pedidoId": "uuid",
"status": "AGUARDANDO_PAGAMENTO",
"pagamento": {
"pagamentoId": "uuid",
"pixQrCode": "00020126...",
"urlPagamento": "https://...",
"status": "PENDENTE"
},
"message": "Pedido criado. Pague R$45.90 via PIX."
}Checkout (Carrinho Multi-item)
POST /api/loja/checkout
Checkout de carrinho com multiplos itens, suporte a cupom de desconto e parcelamento no cartao.
Restricoes
- assertNaoEhConvidado: convidados (
is_nucleo_origem = false) recebem 403. - Saldo de CC verificado via
membros_nucleos.saldo_capixacoins. valorCCe truncado para inteiro (campo INTEGER no banco).- Parcelamento apenas disponivel para
CARTAO_CREDITO, limitado pornucleos.max_parcelas_cartao.
Body
{
"items": [
{ "produtoId": "uuid-1", "quantidade": 2 },
{ "produtoId": "uuid-2", "quantidade": 1 }
],
"valorCC": 5000,
"metodo": "PIX",
"cupomCodigo": "DESCONTO10",
"parcelas": 3,
"dadosCartao": {
"holderName": "JOAO SILVA",
"number": "4111111111111111",
"expiryMonth": "12",
"expiryYear": "2028",
"ccv": "123"
}
}Fluxo detalhado
- Valida todos os itens (existencia, estoque, ativo).
- Calcula totais usando precos promocionais quando ativos.
- Valida e aplica cupom (PERCENTUAL ou FIXO). Desconto distribuido proporcionalmente entre itens.
- Valida valor CC e verifica saldo.
- Reduz estoque de cada produto.
- Cria um
pedido_lojapor item (comvalor_cc_pagoevalor_real_pagoproporcionais). - Incrementa
uso_atualdo cupom se aplicavel. - Se 100% CC: debita CC agora (unica transacao no ledger, referenciando o primeiro pedido).
- Se tem R$: gera cobranca unica Asaas e vincula
pagamento_ida todos os pedidos. - Para PIX: tenta obter QR code encoded image via Asaas.
- Se a cobranca falhar: rollback (deleta pedidos e restaura estoque).
Response 200 (com pagamento)
{
"pedidos": [
{ "id": "uuid-1", "status": "AGUARDANDO_PAGAMENTO", "produtoNome": "Camiseta MBL" },
{ "id": "uuid-2", "status": "AGUARDANDO_PAGAMENTO", "produtoNome": "Bone MBL" }
],
"pagamento": {
"pixQrCode": "00020126...",
"pixEncodedImage": "base64...",
"urlPagamento": "https://...",
"status": "PENDENTE"
},
"message": "Pedido criado. Pague R$89.90 via PIX."
}Pedidos
GET /api/loja/meus-pedidos
Historico de pedidos do usuario logado com paginacao.
Query Params
| Param | Tipo | Descricao |
|---|---|---|
page | number | Pagina (default: 1) |
limit | number | Itens por pagina (default: 20) |
Response 200
{
"data": [
{
"id": "uuid",
"quantidade": 2,
"valor_total_moedas": 1000,
"valor_cc_pago": 600,
"valor_real_pago": 35.94,
"status": "PENDENTE",
"data_pedido": "2026-04-01T12:00:00Z",
"produtos_loja": { "nome": "Camiseta MBL", "foto_url": "https://..." }
}
],
"pagination": { "page": 1, "limit": 20, "total": 5, "totalPages": 1 }
}GET /api/loja/pedidos
Lista todos os pedidos do nucleo (gestao administrativa).
Permissao: COORDENADOR / ADMINISTRADOR
Query Params
| Param | Tipo | Descricao |
|---|---|---|
status | string | Filtrar por status do pedido |
page | number | Pagina (default: 1) |
limit | number | Itens por pagina (default: 20) |
PATCH /api/loja/pedidos/:id/status
Atualiza o status de um pedido. Envia notificacao ao usuario.
Permissao: COORDENADOR / ADMINISTRADOR
Body
{ "status": "SEPARADO" }Status validos
PENDENTE → SEPARADO → ENTREGUE
POST /api/loja/pedidos/:id/cancelar
Cancela um pedido. Nao permite cancelar pedidos ja entregues ou ja cancelados.
Permissao: COORDENADOR / ADMINISTRADOR
Efeitos do cancelamento
- Estorna CC pagas: insere transacao
CREDITOcomorigem: ESTORNOno ledger. - Devolve estoque ao produto (exceto se
is_ilimitado). - Atualiza status do pedido para
CANCELADO. - Envia notificacao ao usuario.
Response 200
{ "message": "Pedido cancelado. CC estornadas e estoque devolvido." }Cupons de Desconto
POST /api/loja/cupons
Cria um novo cupom de desconto.
Permissao: ADMINISTRADOR
Body
| Campo | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
codigo | string | Sim | Codigo do cupom (convertido para maiusculas) |
tipo | string | Sim | PERCENTUAL ou FIXO |
valor | number | Sim | Valor do desconto (% ou R$ fixo) |
usoMaximo | number | Nao | Limite de usos (null = ilimitado) |
validade | string (ISO) | Nao | Data de validade (null = sem expiracao) |
Response 200
{
"id": "uuid",
"codigo": "DESCONTO10",
"tipo": "PERCENTUAL",
"valor": 10,
"uso_maximo": 100,
"ativo": true
}GET /api/loja/cupons
Lista todos os cupons do nucleo (ativos e inativos). Ordenados por data de criacao desc.
Permissao: ADMINISTRADOR
PATCH /api/loja/cupons/:id
Atualiza campos de um cupom existente.
Permissao: ADMINISTRADOR
Campos permitidos
codigo, tipo, valor, usoMaximo, ativo, validade
POST /api/loja/cupons/validar
Valida um cupom por codigo antes de aplicar no checkout.
Body
{ "codigo": "DESCONTO10" }Validacoes
- Cupom existe no nucleo (codigo convertido para maiusculas).
- Cupom esta ativo.
- Cupom nao expirou (
validade). - Cupom nao atingiu limite de uso (
uso_atual < uso_maximo).
Response 200
{ "cupomId": "uuid", "tipo": "PERCENTUAL", "valor": 10 }Erros
404— Cupom nao encontrado400— Cupom inativo / expirado / limite atingido
Doacoes
POST /api/loja/doar
Registra uma doacao ao nucleo. Aceita CC, R$ ou mix.
Restricoes
- assertNaoEhConvidado: convidados (
is_nucleo_origem = false) recebem 403. Doacao e receita do nucleo de origem. - Ao menos um dos valores (
valorRealouvalorCC) deve ser positivo. - Saldo de CC verificado via
membros_nucleos.saldo_capixacoins.
Body
{
"valorReal": 50.00,
"valorCC": 200,
"metodo": "PIX"
}Fluxo
- Cria registro na tabela
doacoes. - Se
valorCC > 0: debita CC imediatamente (transacao DEBITO/LOJA). - Se
valorReal > 0: gera cobranca Asaas e vinculapagamento_ida doacao. - Se 100% CC: marca doacao como
CONFIRMADOimediatamente.
Response 200 (100% CC)
{ "doacaoId": "uuid", "message": "Doacao realizada com sucesso!" }GET /api/loja/doacoes
Lista todas as doacoes do nucleo com dados do doador.
Permissao: ADMINISTRADOR
Response 200
[
{
"id": "uuid",
"valor_real": 50.00,
"valor_cc": 200,
"status": "CONFIRMADO",
"criado_em": "2026-04-01T12:00:00Z",
"usuarios": { "nome": "Joao Silva", "email": "joao@email.com" }
}
]Status de Pedido (ciclo de vida)
| Status | Descricao |
|---|---|
AGUARDANDO_PAGAMENTO | Pedido criado com parte em R$, aguardando confirmacao Asaas |
PENDENTE | Pagamento confirmado (ou 100% CC), aguardando separacao |
SEPARADO | Produto separado, pronto para entrega |
ENTREGUE | Produto entregue ao membro |
CANCELADO | Pedido cancelado (CC estornadas, estoque devolvido) |
Notas de Arquitetura
- Todas as queries filtram por
nucleo_id— multi-tenant com RLS ativo. - O guard
assertNaoEhConvidadoverifica emmembros_nucleosse o membro temis_nucleo_origem = trueestatus = ATIVO. Membros de outros nucleos (convidados) nao podem transacionar na loja. - Saldo de CC e sempre verificado via
membros_nucleos.saldo_capixacoins(nunca mais via tabelausuariosdiretamente). - Precos promocionais sao verificados em tempo real via
isPromoAtiva()(checa data atual vs periodo configurado). - Galeria de imagens usa tabela separada
produto_imagenscom campoordempara controle de exibicao. - Integracoes de pagamento via Asaas: PIX (QR code), boleto e cartao de credito (com parcelamento configuravel por nucleo).