Ir para o conteúdo

Configuração

Opções do VendusClient

from vendus import VendusClient

client = VendusClient(
    api_key="a-tua-key",
    base_url="https://www.vendus.pt/ws",  # produção (default)
    timeout=30.0,                          # segundos
    max_retries=3,                         # GETs retentam, POST só com external_reference
)
Parâmetro Tipo Default Descrição
api_key str API key da Vendus (obrigatório)
base_url str https://www.vendus.pt/ws Base da API. Para Espanha: https://www.vendus.es/ws
timeout float 30.0 Timeout HTTP em segundos
max_retries int 3 Número máximo de retentativas em pedidos elegíveis
default_mode DocumentMode \| None None Modo aplicado a cada criação que omite mode (ver abaixo)

Modo por omissão dos documentos

O mode herda, por omissão, o modo configurado na caixa. Contas Vendus novas têm a caixa em modo teste, por isso uma criação sem mode emite silenciosamente um documento de teste (não-fiscal). Define default_mode uma vez para que todos os documentos saiam no modo que pretendes:

from vendus import DocumentMode, VendusClient

client = VendusClient(api_key="...", default_mode=DocumentMode.NORMAL)
# cada create_* passa a emitir um documento real, a menos que passes mode= explícito

Um mode= por chamada sobrepõe-se sempre ao default do cliente.

Caixas (registers)

Uma caixa (register) é a configuração de POS de onde os documentos são emitidos — passas o seu id como register_id. As caixas são só de leitura via API (criadas e configuradas no backoffice da Vendus). Lista-as para descobrir o id e o modo de funcionamento:

for r in client.documents.list_registers():
    print(r.id, r.title, r.mode)   # mode: "normal" ou "tests"

A partir do ambiente

client = VendusClient.from_env()             # lê VENDUS_API_KEY
client = VendusClient.from_env(env_var="X")  # variável custom

Política de retries

Método Retenta? Quando
GET ✅ Sempre 408, 429, 5xx, timeout
POST / PUT / PATCH Condicional Apenas se o body contém external_reference
DELETE ❌ Nunca Cancelamento tem que ser explicitamente idempotente do lado da app

A regra existe porque a Vendus não oferece idempotency keys. Sem external_reference, um POST repetido poderia criar dois documentos fiscais (e dois números de série gastos). O parâmetro external_reference é o âncora de deduplicação que a Vendus aceita.

Recomendação: passa sempre external_reference ao emitir documentos.

invoice = client.documents.create_invoice(
    register_id=1,
    items=[...],
    external_reference="ORD-2026-001",  # idempotência
)

Logging

O SDK usa o logger vendus. Tem um filtro automático que redige PII: fiscal_id, email, phone, mobile, address, postalcode, billing_email.

import logging
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("vendus").setLevel(logging.DEBUG)

Nunca faças bypass ao logger

Não imprimas payloads diretamente com print(json) ou outro logger. Usa sempre logging.getLogger("vendus") para que a redação se aplique.

Testes

A Vendus não tem um host de sandbox separado — não há URL de testes; todos os pedidos vão para www.vendus.pt. O que a Vendus tem é um modo de testes ao nível do documento ("Modo de Formação/Testes"): documentos emitidos em modo testes não têm validade fiscal e nunca são comunicados à AT.

O modo de testes controla-se de duas formas:

  1. Por caixa (register). Cada caixa tem um modo de funcionamento (normal ou tests), configurado no backoffice da Vendus (Configuração → Definições → Lojas e Caixas). Contas novas vêm em tests — uma conta acabada de criar emite documentos sem validade fiscal até a passares para normal.
  2. Por pedido. Passa mode a qualquer método de criação:
from vendus import DocumentMode

invoice = client.documents.create_invoice(
    register_id=1,
    items=[...],
    mode=DocumentMode.TESTS,   # não-fiscal — não comunicado à AT
)

Se omitires mode, a Vendus usa o modo configurado na caixa. Um documento de teste recebe na mesma um number e é impresso com a nota "sem validade fiscal". Confirmas que um documento não foi comunicado à AT porque o tax_authority_id vem vazio (esse campo só é preenchido quando a Vendus comunica o documento à AT).

O que está verificado e o que não está

O comportamento acima vem da documentação oficial: o campo mode (documents.doc), o modo por caixa (registers.doc) e a página de ajuda Modo de Formação/Testes. O que ainda não confirmámos contra a API ao vivo é se um mode=tests por pedido é respeitado numa caixa configurada como normal. O caminho fiável e verificado é usar uma caixa que esteja ela própria em modo tests.

Setup recomendado

  • Testes unitários — mock com respx; nunca tocar na API real.
  • Testes de integração — correr contra uma caixa em modo tests, assertar que tax_authority_id está vazio e cancelar o que for criado (ver tests/integration/).