API Brainit XD ERP

Documentação Completa - Criação de Documentos de Venda / Compras

Introdução

Esta API permite criar documentos de vendas / compras no XD ERP.

✅ Funcionalidades:
  • Criação automática de clientes (com NIF)
  • Suporte a "Consumidor Final" (sem NIF)
  • Idempotência através de externalRef único
  • Validação completa de dados antes do processamento
  • Suporte a múltiplas linhas de produtos por documento

Endpoint Principal

POST /api/v1/orders

Content-Type: application/json

Autenticação: API Key via header X-API-Key

Como Obter API Key

A API Key é fornecida pela equipa Brainit após configuração inicial. Entre em contacto através de:

  • Email: webmaster@brainit.pt

Campos do Documento

CampoTipoObrigatórioDescrição
docTypeIdintegerObrigatórioID do tipo de documento (ver tabela abaixo)
serieIdintegerObrigatórioID da série do documento. Solicitar à equipa Brainit o ID correto.
userIdintegerObrigatórioID do utilizador/vendedor no XD. Fornecido pela equipa Brainit.
paymentTypeintegerObrigatórioID do tipo de pagamento (1=Numerário, 2=MB, 3=Cartão, etc.)
externalRefstringOpcionalReferência externa ÚNICA do pedido. Usado para idempotência. Máximo: 50 caracteres
observationsstringOpcionalObservações do documento (aparece no PDF). Máximo: 4000 caracteres
dueDatedatetimeOpcionalData de vencimento (ISO 8601: YYYY-MM-DDTHH:mm:ss)
integrationTagstringOpcionalTag de identificação da integração (ex: "WOOCOMMERCE", "AUTO21"). Necessário para criação automática de clientes/artigos.
⚠️ Importante sobre externalRef:
  • Deve ser único para cada pedido
  • Se enviar a mesma externalRef duas vezes, o sistema retorna 409 Conflict
  • Recomendado usar: [SISTEMA]-[ID] (ex: "WC-12345", "AUTO21-5678")

Objeto Cliente

CampoTipoObrigatórioDescrição
keyIdstringOpcionalKeyId do cliente existente no XD. Se fornecido, ignora todos os outros campos.
vatstringOpcionalSe vazio/null: usa "Consumidor Final" (KeyId=0)
Se preenchido: procura cliente ou cria novo (com integrationTag)
namestringObrigatórioNome do cliente (aparece no documento PDF)
contactEmailstringOpcionalEmail do cliente
phonestringOpcionalTelefone do cliente
addressstringOpcionalMorada completa
citystringOpcionalCidade
postalCodestringOpcionalCódigo postal (formato: 4700-123)
countrystringOpcionalCódigo do país (ISO 2 letras, padrão: PT)
Consumidor Final (sem NIF):
  • Usa o cliente especial "Consumidor Final" (KeyId=0)
  • Preserva os dados fornecidos (nome, email, morada) no documento
  • Não cria um novo cliente na base de dados

Linhas do Documento

CampoTipoObrigatórioDescrição
referencestringObrigatórioReferência/KeyId do artigo no XD
descriptionstringOpcionalDescrição personalizada (substitui a descrição padrão do artigo)
quantitydecimalObrigatórioQuantidade (deve ser > 0)
unitPricedecimalObrigatórioPreço unitário (deve ser >= 0)
taxIdintegerOpcionalID da taxa de IVA. Se omitido, usa a taxa padrão do artigo (Tax1)
discountPercentagedecimalOpcionalPercentagem de desconto (0-100)

Exemplos de Utilização

Cliente COM NIF - Cria/Atualiza Cliente

{
  "cliente": {
    "vat": "PT123456789",
    "name": "João Silva",
    "contactEmail": "joao@example.com",
    "phone": "912345678",
    "address": "Rua das Flores, 123",
    "city": "Braga",
    "postalCode": "4700-123",
    "country": "PT"
  },
  "lines": [
    {
      "reference": "CAR001",
      "description": "Mercedes Classe A 180d",
      "quantity": 1,
      "unitPrice": 28500.00,
      "taxId": 1
    }
  ],
  "document": {
    "docTypeId": 64,
    "serieId": 1,
    "userId": 1,
    "paymentType": 1,
    "observations": "Veículo com garantia de 2 anos.",
    "dueDate": "2026-12-31T23:59:59"
  },
  "externalRef": "AUTO21-12345",
  "integrationTag": "AUTO21"
}

Consumidor Final - SEM NIF

{
  "cliente": {
    "vat": null,
    "name": "Maria Costa",
    "contactEmail": "maria@example.com",
    "phone": "933444555",
    "address": "Av. Central, 45",
    "city": "Porto",
    "postalCode": "4000-123"
  },
  "lines": [
    {
      "reference": "PROD001",
      "quantity": 2,
      "unitPrice": 15.50
    }
  ],
  "document": {
    "docTypeId": 12,
    "serieId": 1,
    "userId": 1,
    "paymentType": 1
  },
  "externalRef": "WC-67890"
}

Cliente Existente - Usar KeyId

{
  "cliente": {
    "keyId": "CLI001"
  },
  "lines": [
    {
      "reference": "SERV001",
      "description": "Revisão Completa",
      "quantity": 1,
      "unitPrice": 120.00,
      "taxId": 3
    }
  ],
  "document": {
    "docTypeId": 1,
    "serieId": 1,
    "userId": 1,
    "paymentType": 2,
    "dueDate": "2026-12-31T23:59:59"
  },
  "externalRef": "SRV-2024-001"
}

Exemplo Mínimo

{
  "cliente": {
    "name": "Cliente Teste"
  },
  "lines": [
    {
      "reference": "PROD001",
      "quantity": 1,
      "unitPrice": 10.00
    }
  ],
  "document": {
    "docTypeId": 12,
    "serieId": 1,
    "userId": 1,
    "paymentType": 1
  }
}

✅ Respostas da API

Sucesso (HTTP 200)

{
  "success": true,
  "document": "NE A/1",
  "message": "Pedido criado com sucesso",
  "clientId": "auto21-integration",
  "integrationTag": "AUTO21"
}

Documento Duplicado (HTTP 409)

{
  "success": false,
  "message": "Já existe um documento com a referência 'AUTO21-12345'.",
  "errorCode": "DuplicateDocument"
}

Erro de Validação (HTTP 400)

{
  "success": false,
  "message": "Validação falhou",
  "errors": [
    "Campo 'cliente' é obrigatório",
    "Linha 1: quantidade deve ser maior que 0"
  ]
}

Erro de Autenticação (HTTP 401)

{
  "error": "unauthorized",
  "message": "API Key obrigatória no header X-API-Key"
}

Erro Interno (HTTP 500)

{
  "success": false,
  "error": "Artigo 'PROD999' não existe no XD"
}

Códigos de Erro Comuns

HTTPErroSolução
401API Key missing / inválidaVerificar se o header X-API-Key está presente e correto
400Documento sem linhasIncluir pelo menos 1 linha no array lines
400Campo 'cliente.name' é obrigatórioPreencher o campo name do cliente
400Artigo 'XXX' não existeVerificar se a reference existe no XD
400Cliente com VAT 'XXX' não existeAdicionar integrationTag para permitir criação automática
409Documento duplicadoO externalRef já foi usado. Cada documento deve ter referência única.
500Erro ao gravar documentoErro interno. Contactar suporte com o externalRef do pedido

Tipos de Documento

IDTipoDescriçãoUso Recomendado
1FaturaDocumento fiscal com IVAVendas com exigência de fatura
12Nota de EncomendaDocumento pré-venda (não fiscal)Orçamentos, encomendas pendentes
64EncomendaEncomenda de clientePedidos de produtos/serviços
15Fatura FornecedorDocumento de compra padrãoCompras a fornecedores
65Fatura Fornecedor Auto21Documento de compra Auto21Compras específicas Auto21
Nota: Os IDs podem variar conforme a configuração do XD para a sua empresa. A equipa Brainit fornecerá os IDs corretos durante a integração.

Endpoint de Compras

POST /api/v1/purchases

Content-Type: application/json

Autenticação: API Key via header X-API-Key

Diferenças em relação a Orders:
  • O docTypeId aceita 15 (Fatura Fornecedor) ou 65 (Fatura Fornecedor Auto21)
  • O fornecedor é procurado por keyId, vat ou contactEmail — e criado automaticamente se tiver integrationTag
  • Os artigos são procurados por reference — e criados automaticamente se tiver integrationTag
  • O campo raiz é fornecedor em vez de cliente
  • Documentos duplicados retornam 409 Conflict

Objeto Fornecedor

CampoTipoObrigatórioDescrição
keyIdstringOpcionalKeyId do fornecedor existente no XD. Se fornecido, ignora todos os outros campos.
vatstringOpcionalNIF/NIPC do fornecedor. Procura o fornecedor existente. Se não encontrar e tiver integrationTag, cria automaticamente.
namestringOpcional*Nome do fornecedor. Obrigatório apenas na criação automática.
contactEmailstringOpcionalEmail do fornecedor. Usado também como critério de pesquisa.
phonestringOpcionalTelefone do fornecedor
addressstringOpcionalMorada completa
citystringOpcionalCidade
postalCodestringOpcionalCódigo postal (formato: 4700-123)
countrystringOpcionalCódigo do país (ISO 2 letras, padrão: PT)
Lógica de procura do Fornecedor (por ordem):
  1. Se keyId preenchido → procura diretamente por KeyId
  2. Se vat preenchido → procura por NIF (memória → base de dados)
  3. Se contactEmail preenchido → procura por email na base de dados
  4. Se não encontrar + tem integrationTagcria automaticamente com EntityType=1 (Fornecedor)
  5. Se não encontrar + sem integrationTag → retorna erro 500

Campos do Documento (Compra)

CampoTipoObrigatórioDescrição
docTypeIdintegerObrigatório15 = Fatura Fornecedor | 65 = Fatura Fornecedor Auto21. Qualquer outro valor será rejeitado.
serieIdintegerObrigatórioID da série do documento de compra. Fornecido pela equipa Brainit.
userIdintegerObrigatórioID do utilizador no XD que registará a compra.
paymentTypeintegerObrigatórioID do tipo de pagamento (1=Numerário, 2=MB, 3=Cartão, etc.)
dueDatedatetimeOpcionalData de vencimento da fatura do fornecedor (ISO 8601: YYYY-MM-DDTHH:mm:ss)
observationsstringOpcionalObservações internas do documento. Máximo: 4000 caracteres
externalRefstringOpcionalReferência externa única (ex: número da fatura do fornecedor). Documentos duplicados retornam 409 Conflict.
integrationTagstringOpcionalTag da integração (ex: "AUTO21"). Necessário para criação automática de fornecedores e artigos.

Linhas do Documento (Compra)

CampoTipoObrigatórioDescrição
referencestringObrigatórioKeyId do artigo no XD. Se não existir e tiver integrationTag, é criado automaticamente.
descriptionstringOpcionalDescrição personalizada da linha (substitui a descrição padrão do artigo no documento)
quantitydecimalObrigatórioQuantidade (deve ser > 0)
unitPricedecimalObrigatórioPreço de custo unitário (deve ser >= 0)
taxIdintegerOpcionalID da taxa de IVA. Se omitido, usa a taxa padrão do artigo (Tax1)

Exemplos de Utilização — Purchases

Compra Auto21 — Fornecedor criado automaticamente (docTypeId: 65)

Se o fornecedor não existir no XD, é criado automaticamente graças ao integrationTag. O artigo também é criado se não existir.

{
  "fornecedor": {
    "name": "AUTO 21 LDA",
    "vat": "506776352",
    "contactEmail": "auto21@auto21.pt",
    "address": "Rua de Portugal",
    "postalCode": "4100-020",
    "city": "PORTO",
    "country": "PT",
    "phone": "253999888"
  },
  "lines": [
    {
      "reference": "CAR001",
      "description": "Renault Coupe 1.5 Blue dCi Limited J17",
      "quantity": 1,
      "unitPrice": 3922.00,
      "taxId": 1
    }
  ],
  "document": {
    "docTypeId": 65,
    "serieId": 1,
    "userId": 1,
    "paymentType": 7,
    "observations": "RENAULT MEGANE – Sedan de 2019. Primeiro registo: Agosto 2019. 4 portas, 5 lugares.",
    "dueDate": "2026-03-31T23:59:59"
  },
  "externalRef": "AUTO21-1262226",
  "integrationTag": "AUTO21"
}

Fornecedor por KeyId (docTypeId: 15)

Quando já conhece o KeyId do fornecedor no XD, use apenas esse campo.

{
  "fornecedor": {
    "keyId": "123"
  },
  "lines": [
    {
      "reference": "CAR001",
      "description": "Mercedes Classe C180d",
      "quantity": 1,
      "unitPrice": 7500.00,
      "taxId": 2
    }
  ],
  "document": {
    "docTypeId": 15,
    "serieId": 1,
    "userId": 1,
    "paymentType": 9,
    "observations": "Fatura referente a compra de viatura.",
    "dueDate": "2026-03-31T23:59:59"
  },
  "externalRef": "AUTO215-20260101"
}

Resposta de Sucesso (HTTP 200)

{
  "success": true,
  "document": "VFC 1/8",
  "message": "Purchase criada com sucesso",
  "clientId": "auto21-integration",
  "integrationTag": "AUTO21"
}

Documento Duplicado (HTTP 409)

{
  "success": false,
  "message": "Já existe um documento com a referência 'AUTO21-1262226'.",
  "errorCode": "DuplicateDocument"
}

Erros Específicos de Compras

DocTypeId inválido (HTTP 400):

{
  "success": false,
  "message": "DocTypeId '51' inválido para purchases. Valor permitido: (Fatura Fornecedor)."
}

Fornecedor não existe sem integrationTag (HTTP 500):

{
  "success": false,
  "error": "Fornecedor com VAT '506776352' não existe. Para criar automaticamente, defina 'integrationTag'."
}

Artigo não existe sem integrationTag (HTTP 500):

{
  "success": false,
  "error": "Artigo 'CAR999' não existe e criação automática não permitida."
}

Códigos de Erro Específicos de Compras

HTTPErroSolução
400DocTypeId inválido para purchasesUsar docTypeId: 15 (Fatura Fornecedor) ou docTypeId: 65 (Fatura Fornecedor Auto21)
409Documento duplicadoO externalRef já foi usado. Cada compra deve ter referência única.
500Fornecedor com VAT 'XXX' não existeAdicionar integrationTag para criação automática, ou usar keyId existente.
500Artigo 'XXX' não existeAdicionar integrationTag para criação automática, ou verificar a reference.
500Erro ao gravar compraContactar suporte com o externalRef e timestamp da requisição.

Configuração Inicial

Dados Fornecidos pela Brainit

  • API Key - Chave de autenticação única para sua integração
  • userId - ID do utilizador XD que criará os documentos
  • serieId - ID da série de documentos a utilizar
  • Lista de Artigos - Referências (KeyIds) dos produtos/serviços disponíveis
  • Tipos de Documento - IDs dos tipos de documento configurados
  • URL Base - Endereço do servidor da API
Segurança:
  • Nunca partilhe sua API Key publicamente
  • Armazene a API Key de forma segura (variáveis de ambiente, cofres de segredos)
  • Use HTTPS em todas as requisições
  • Implemente rate limiting no seu lado para evitar sobrecarga

📞 Suporte

  • 📧 Email: webmaster@brainit.pt
  • 🕐 Horário: Segunda a Sexta, 9h00 - 18h00

Ao contactar o suporte, forneça sempre:

  • O valor do campo externalRef do pedido problemático
  • Código de erro HTTP recebido
  • Timestamp aproximado da requisição
  • Mensagem de erro completa