Pular para conteúdo

Configuração

Guia completo de configuração da integração Nayax → Saipos.

Variáveis de Ambiente

Arquivo .env

Todas as configurações são gerenciadas através de variáveis de ambiente no arquivo .env:

# =============================================================================
# DATABASE
# =============================================================================
DATABASE_URL="postgresql://usuario:senha@localhost:5432/nayax_saipos?schema=public"

# =============================================================================
# SERVER
# =============================================================================
PORT=3000
NODE_ENV=development

# =============================================================================
# JWT (Autenticação de Usuários)
# =============================================================================
JWT_SECRET="sua_chave_secreta_jwt_muito_forte_aqui"
JWT_EXPIRES_IN="7d"

# =============================================================================
# NAYAX (Webhook)
# =============================================================================
NAYAX_BEARER_TOKEN="token_fornecido_pelo_nayax"

# =============================================================================
# SAIPOS (API Destino)
# =============================================================================
# Homologação
SAIPOS_BASE="https://homolog-order-api.saipos.com"

# Produção
# SAIPOS_BASE="https://order-api.saipos.com"

# =============================================================================
# JOBS (Processamento Assíncrono)
# =============================================================================
PROCESSING_TTL_MS=120000
LOG_SAIPOS_BODY=false

# =============================================================================
# LOGGING
# =============================================================================
LOG_LEVEL=debug

Variáveis Obrigatórias

Variável Descrição Exemplo
DATABASE_URL String de conexão PostgreSQL postgresql://user:pass@localhost:5432/db
JWT_SECRET Chave secreta para JWT minha_chave_super_secreta_123

Variáveis Opcionais

Variável Padrão Descrição
PORT 3000 Porta do servidor
NODE_ENV development Ambiente (development, staging, production)
JWT_EXPIRES_IN 7d Tempo de expiração do JWT
SAIPOS_BASE (homolog) URL base da API Saipos
PROCESSING_TTL_MS 120000 Tempo máximo de processamento (ms)
LOG_SAIPOS_BODY false Logar corpo das requisições Saipos
LOG_LEVEL info Nível de log (debug, info, warn, error)

Configuração do Banco de Dados

1. Criar Database

-- Conectar como postgres
psql -U postgres

-- Criar database
CREATE DATABASE nayax_saipos
    WITH 
    OWNER = postgres
    ENCODING = 'UTF8'
    LC_COLLATE = 'pt_BR.UTF-8'
    LC_CTYPE = 'pt_BR.UTF-8'
    TEMPLATE = template0;

-- Criar usuário (produção)
CREATE USER nayax_user WITH PASSWORD 'senha_forte_aqui';
GRANT ALL PRIVILEGES ON DATABASE nayax_saipos TO nayax_user;

-- Sair
\q

2. Executar Migrations

# Aplicar migrations
npx prisma migrate deploy

# Ou em dev (cria nova migration se necessário)
npx prisma migrate dev --name init

3. Verificar Schema

# Abrir Prisma Studio
npx prisma studio

# Ou via psql
psql -U postgres -d nayax_saipos

# Listar tabelas
\dt

# Ver schema de uma tabela
\d "User"
npm run seed

O seed cria:

  • Usuário admin:
  • Email: admin@example.com
  • Senha: admin123
  • Role: OWNER

  • Configurações:

  • NAYAX_BEARER_TOKEN
  • SAIPOS_BASE
  • PROCESSING_TTL_MS

  • Restaurante exemplo (apenas dev):

  • Nome: "Restaurante Teste"
  • Slug: "restaurante-teste"

Alterar senha padrão

Em produção, sempre altere a senha do usuário admin após o primeiro login.

Configuração por Restaurante

Cada restaurante precisa ser configurado com suas credenciais Saipos:

Via SQL

-- Atualizar credenciais Saipos
UPDATE "Restaurant"
SET 
  "codeStoreNayax" = 'LOJA001',           -- Código no Nayax
  "codeStoreSaipos" = 'LOJA_SAIPOS_001',  -- Código no Saipos
  "saiposIdPartner" = 'partner_123',       -- ID do parceiro
  "saiposSecret" = 'secret_xyz'            -- Chave secreta
WHERE slug = 'restaurante-teste';

Via API (recomendado)

# Criar restaurante
curl -X POST http://localhost:3000/restaurants \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Meu Restaurante",
    "slug": "meu-restaurante",
    "codeStoreSaipos": "LOJA_SAIPOS_001",
    "saiposIdPartner": "partner_123",
    "saiposSecret": "secret_xyz"
  }'

# Atualizar credenciais
curl -X PATCH http://localhost:3000/restaurants/{id} \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "saiposIdPartner": "novo_partner",
    "saiposSecret": "novo_secret"
  }'

Configuração do Webhook Nayax

1. Obter URL do Webhook

https://seu-dominio.com/webhooks/nayax

2. Configurar no Painel Nayax

Acesse o painel administrativo do Nayax e configure:

URL do Webhook: https://seu-dominio.com/webhooks/nayax

Método: POST

Headers:

Authorization: Bearer SEU_NAYAX_BEARER_TOKEN
Content-Type: application/json

Eventos: Selecione "Transaction Complete" ou "All Events"

3. Testar Webhook

# Teste manual
curl -X POST http://localhost:3000/webhooks/nayax \
  -H "Authorization: Bearer $NAYAX_BEARER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionKey": "test-'$(date +%s)'",
    "transactionNumber": "TEST123",
    "transactionDate": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
    "storeCode": "LOJA001",
    "posCode": "POS01",
    "totalAmount": 10.00,
    "isTestTransaction": true,
    "items": [{
      "itemCode": "PROD001",
      "itemName": "Café",
      "quantity": 1,
      "price": 10.00
    }],
    "payments": [{
      "tenderType": 1,
      "tenderName": "Dinheiro",
      "amount": 10.00
    }]
  }'

Resposta esperada (200 OK):

{
  "success": true,
  "transactionKey": "test-1234567890",
  "jobId": "job_abc123"
}

Configuração do Saipos

1. Obter Credenciais

Entre em contato com o suporte Saipos para obter:

  • idPartner: ID do parceiro
  • secret: Chave secreta
  • cod_store: Código da loja no Saipos

2. Testar Conexão

# Teste de autenticação
curl -X POST https://homolog-order-api.saipos.com/auth \
  -H "id-partner: $ID_PARTNER" \
  -H "secret: $SECRET" \
  -H "Content-Type: application/json"

3. Ambientes

Ambiente URL Base Uso
Homologação https://homolog-order-api.saipos.com Desenvolvimento e testes
Produção https://order-api.saipos.com Produção

Ambiente de testes

Use sempre homologação durante desenvolvimento. Mude para produção apenas após testes completos.

Configuração de Logs

Níveis de Log

Configure via LOG_LEVEL:

# Development
LOG_LEVEL=debug

# Staging
LOG_LEVEL=info

# Production
LOG_LEVEL=warn

Logs Detalhados do Saipos

# Logar corpo das requisições (apenas debug)
LOG_SAIPOS_BODY=true

Exemplo de log:

[SAIPOS][CREATE] Request body:
{
  "order_id": "550e8400-...",
  "cod_store": "LOJA_001",
  "total_amount": 50.00,
  "items": [...]
}

Performance

Nunca use LOG_SAIPOS_BODY=true em produção - gera logs muito grandes.

Configuração de Jobs

TTL de Processamento

Tempo máximo que um job pode ficar em PROCESSING:

# 2 minutos (padrão)
PROCESSING_TTL_MS=120000

# 5 minutos
PROCESSING_TTL_MS=300000

Após esse tempo, o Reaper reseta o job para FAILED.

Backoff de Retry

O backoff é hardcoded mas pode ser ajustado editando src/jobs/jobs.processor.ts:

function backoffMs(attempts: number) {
  const table = [
    30_000,    // 30s   - tentativa 1
    120_000,   // 2min  - tentativa 2
    300_000,   // 5min  - tentativa 3
    900_000,   // 15min - tentativa 4
    1_800_000, // 30min - tentativa 5
    3_600_000  // 60min - tentativa 6+
  ];

  const base = table[Math.min(attempts - 1, table.length - 1)];
  const jitter = Math.floor(base * (Math.random() * 0.4 - 0.2));

  return base + jitter;
}

Configuração de Segurança

JWT Secret

Gere uma chave forte:

# Gerar secret aleatório
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"

# Ou usando openssl
openssl rand -hex 64

Adicione no .env:

JWT_SECRET="sua_chave_gerada_aqui"

Senha do Admin

Após seed, altere a senha do admin:

-- Gerar hash bcrypt manualmente (10 rounds)
-- Senha: nova_senha_forte

UPDATE "User"
SET "passwordHash" = '$2b$10$...'  -- Use bcrypt para gerar
WHERE email = 'admin@example.com';

Ou via API:

curl -X PATCH http://localhost:3000/users/me/password \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "currentPassword": "admin123",
    "newPassword": "nova_senha_forte"
  }'

Configuração de CORS

Edite src/main.ts para permitir origens específicas:

app.enableCors({
  origin: [
    'https://seu-frontend.com',
    'https://admin.seu-dominio.com'
  ],
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
});

Configuração de Rate Limiting

Para proteger o webhook, adicione rate limiting:

npm install @nestjs/throttler
// src/app.module.ts
import { ThrottlerModule } from '@nestjs/throttler';

@Module({
  imports: [
    ThrottlerModule.forRoot([{
      ttl: 60000,  // 1 minuto
      limit: 100,  // 100 requisições
    }])
  ]
})

Verificar Configuração

Checklist

  • .env criado com todas as variáveis
  • Database criada e migrations aplicadas
  • Seed executado (dados iniciais)
  • Webhook Nayax configurado
  • Credenciais Saipos testadas
  • Restaurante(s) configurado(s)
  • JWT secret forte gerado
  • Senha admin alterada (produção)
  • Logs configurados corretamente
  • CORS configurado (se necessário)

Script de Verificação

#!/bin/bash

echo "🔍 Verificando configuração..."

# 1. Variáveis obrigatórias
if [ -z "$DATABASE_URL" ]; then
  echo "❌ DATABASE_URL não configurada"
else
  echo "✅ DATABASE_URL configurada"
fi

if [ -z "$JWT_SECRET" ]; then
  echo "❌ JWT_SECRET não configurada"
else
  echo "✅ JWT_SECRET configurada"
fi

if [ -z "$NAYAX_BEARER_TOKEN" ]; then
  echo "❌ NAYAX_BEARER_TOKEN não configurada"
else
  echo "✅ NAYAX_BEARER_TOKEN configurada"
fi

# 2. Banco de dados
psql $DATABASE_URL -c "SELECT 1;" > /dev/null 2>&1
if [ $? -eq 0 ]; then
  echo "✅ Conexão com banco OK"
else
  echo "❌ Erro ao conectar no banco"
fi

# 3. Aplicação
curl -s http://localhost:3000/health > /dev/null 2>&1
if [ $? -eq 0 ]; then
  echo "✅ Aplicação rodando"
else
  echo "❌ Aplicação não está rodando"
fi

echo "✨ Verificação completa!"

Configurações Avançadas

Multi-tenant Isolation

Para isolar dados entre restaurantes, use Row Level Security (RLS) no PostgreSQL:

-- Habilitar RLS
ALTER TABLE "NayaxEvent" ENABLE ROW LEVEL SECURITY;

-- Criar policy
CREATE POLICY restaurant_isolation ON "NayaxEvent"
  USING ("restaurantId" = current_setting('app.restaurant_id')::uuid);

Cache de Tokens

Para melhorar performance, implemente cache de tokens Saipos usando Redis:

npm install @nestjs/cache-manager cache-manager
npm install cache-manager-redis-yet redis

Monitoramento

Configure variáveis para integração com ferramentas:

# Sentry
SENTRY_DSN="https://...@sentry.io/..."

# DataDog
DD_API_KEY="..."
DD_SITE="datadoghq.com"

# Prometheus
METRICS_PORT=9090

Próximos Passos

Configuração completa! Agora faça o primeiro deploy:

Primeiro Deploy

Referências