# Crie uma aplicação com o FIZ

> Edição Markdown de https://api.fiz.co/docs/apps?lang=pt. English: https://api.fiz.co/docs/apps.md. Índice: https://api.fiz.co/llms.txt

Ligue as empresas dos seus clientes, crie rascunhos de faturas e integre faturação certificada no seu produto. Comece com um exemplo funcional e reproduza o mesmo fluxo no seu servidor.

## 1. Execute o exemplo

O exemplo é **a sua aplicação parceira**: um ecrã de encomendas com cliente, serviço e ação de faturação. O FIZ aparece como fornecedor de faturação. Defina `APP_NAME` com o nome do seu produto, igual ao nome registado no FIZ.

`localhost:3100` executa esta aplicação parceira no seu computador. A entrada e o registo acontecem em `app.fiz.co`; OAuth e os pedidos REST usam `api.fiz.co`. A aplicação liga-se diretamente ao **FIZ de produção**.

Precisa de **Node.js 22.17 ou superior**, Git e uma [aplicação Development registada](#2-registe-a-aplicação). Não há dependências de pacotes nem chave API.

```
git clone https://github.com/FIZ-co/partner-app-demo.git
cd partner-app-demo
cp .env.example .env
# Fill in APP_NAME and the three FIZ credentials, then:
npm start
# Open http://localhost:3100
```

Use o mesmo nome de aplicação que no FIZ e preencha o ID da aplicação, client ID e segredo no `.env` do servidor:

```
APP_NAME="Your product name"
FIZ_APP_ID=YOUR_APPLICATION_ID
FIZ_CLIENT_ID=YOUR_CLIENT_ID
FIZ_CLIENT_SECRET=YOUR_CLIENT_SECRET
```

Abra a encomenda e escolha **Connect FIZ** ou **Create a FIZ account**. Após o consentimento, regressa à mesma encomenda com a empresa ligada. Escolha o CAE e a categoria de IVA e clique em **Create invoice draft**. A encomenda passa a mostrar o ID do rascunho guardado no FIZ.

> A encomenda contém dados de exemplo; a ligação ao FIZ é real. Criar o rascunho guarda um cliente, um artigo de serviço e um rascunho de fatura reais na empresa escolhida. O exemplo não pede `invoicing.issue` e não tem uma ação de emissão.

Sem credenciais, **Set up FIZ** mostra instruções e o callback correto para a sua porta. Nunca é iniciada uma ligação FIZ fictícia. Guarde o segredo apenas no servidor.

## 2. Registe a aplicação

Entre no FIZ e abra [Definições → Integrações → Aplicações de programador](https://app.fiz.co/settings/integrations). Se o FIZ pedir que conclua a configuração da conta/empresa, termine-a para abrir Definições. Criar uma aplicação não exige um plano pago. Escolha **Development** para a primeira aplicação.

| Definição | Valor para o exemplo local |
| --- | --- |
| Nome / nome do programador | O produto e a pessoa ou empresa responsável. Ambos aparecem no consentimento. |
| URL do site público | `http://localhost:3100` — identifica a aplicação no ecrã de consentimento. |
| URL da política de privacidade | `http://localhost:3100/privacy` no exemplo local; publique a sua própria política para clientes. |
| URL do logótipo (opcional) | Imagem acessível publicamente. O FIZ guarda o URL, não o ficheiro. Use HTTPS em produção. |
| URL para iniciar ou retomar a ligação (`installUrl`) | `http://localhost:3100/resume` — inicia um novo pedido OAuth após o registo. |
| URLs de callback OAuth (`redirectUris`) | `http://localhost:3100/callback` — recebe o resultado OAuth. A correspondência é exata, incluindo porta, caminho e barra final. |
| Permissões autorizadas | `company.read`, `invoicing.read`, `invoicing.write` |
| Testadores | Até 20 emails. Pode adicionar um email antes de existir uma conta FIZ. O testador verifica-o através do código normal de registo/entrada; não há confirmação adicional. |

### Três URLs com funções diferentes

Na sua aplicação alojada, use endereços que controla. Estes caminhos são exemplos, não são endpoints do FIZ:

| Campo | Exemplo | Função |
| --- | --- | --- |
| URL do site público | `https://your-app.example` | O site público do produto ou de marketing, apresentado ao cliente no consentimento. |
| URL para iniciar ou retomar a ligação | `https://your-app.example/fiz/connect` | A página ou o endpoint que inicia uma nova ligação OAuth. O FIZ regressa aqui após a criação do perfil e o passo da AT. |
| URLs de callback OAuth | `https://your-app.example/fiz/callback` | Recebe `code` ou `error` depois de o cliente permitir ou recusar o acesso. |

O URL para iniciar ou retomar a ligação é guardado em `installUrl` (anteriormente apresentado como “URL de instalação”). Tem de retomar a ligação: uma página genérica de marketing sem este comportamento deixa o cliente sem poder continuar. O callback recebe o resultado; não inicia o percurso.

Copie o **ID da aplicação**, o **client ID** (`fiz_app_…`) e o **client secret**. O ID da aplicação identifica as ligações de registo; o client ID identifica os pedidos OAuth. O segredo só é mostrado uma vez. Guarde-o no servidor, nunca em JavaScript do navegador, aplicações móveis ou controlo de versões. O FIZ guarda apenas o hash. Se o perder, terá de o rodar explicitamente.

### Development e Production são tipos de aplicação

As aplicações **Development funcionam no FIZ de produção**, apenas para o criador e os testadores indicados. Cada pessoa tem de ser proprietária da empresa que liga. O acesso OAuth de desenvolvimento não exige um plano pago com API. Os dados são reais: não é um ambiente fiscal fictício e qualquer ação fiscal autorizada continua a ser real.

As aplicações **Production** podem ligar outros clientes após revisão do FIZ. Todos os URLs devem ser HTTPS públicos; localhost não é permitido. Crie uma aplicação Production separada quando estiver pronto: terá outro client ID, segredo e autorizações. O ambiente de uma aplicação não pode ser alterado.

Pode manter até 10 aplicações não arquivadas. Arquivar liberta uma vaga; pausar não. Registe entre 1 e 10 callbacks. A criação e o envio para revisão têm, cada um, um limite partilhado de 10 tentativas por conta e por hora civil.

## 3. Ligue uma empresa por OAuth

Use **Authorization Code + PKCE (S256)** com autenticação do cliente no servidor. Uma chave API pertence a uma empresa; uma aplicação obtém consentimento OAuth explícito para cada ligação. Não existe um fluxo client-credentials sem utilizador.

1.  O servidor gera state + PKCE
2.  O cliente escolhe empresa e permissões no FIZ
3.  O FIZ devolve um código ao callback
4.  O servidor troca-o por tokens

|   |   |
| --- | --- |
| Issuer / recurso REST | `https://api.fiz.co` |
| Descoberta | [`/.well-known/oauth-authorization-server`](https://api.fiz.co/.well-known/oauth-authorization-server) |
| Autorização | `GET https://api.fiz.co/oauth/authorize` |
| Token | `POST https://api.fiz.co/oauth/token` |

### Inicie a autorização

```
import { createHash, randomBytes } from 'node:crypto';

const state = randomBytes(32).toString('base64url');
const verifier = randomBytes(32).toString('base64url');
// Store state + verifier in the customer's server-side session with a short TTL.
const url = new URL('https://api.fiz.co/oauth/authorize');
url.search = new URLSearchParams({
  response_type: 'code',
  client_id: process.env.FIZ_CLIENT_ID,
  redirect_uri: 'http://localhost:3100/callback',
  state,
  code_challenge: createHash('sha256').update(verifier).digest('base64url'),
  code_challenge_method: 'S256',
  resource: 'https://api.fiz.co',
  scope: 'company.read invoicing.read invoicing.write',
}).toString();
// Redirect the customer's browser to url.href.
```

Guarde o verifier e o state na sessão do navegador, no servidor. Devem ser imprevisíveis, novos em cada tentativa e nunca partilhados entre utilizadores. As permissões pedidas devem estar autorizadas nas definições da aplicação.

### Valide o callback antes de trocar o código

Exija a sessão original, correspondência exata de `state`, `iss=https://api.fiz.co` e exatamente um `code` ou `error`. Rejeite parâmetros duplicados e callbacks que misturem sucesso e erro. Um `error=access_denied` validado significa que o cliente cancelou; permita tentar novamente. Nunca troque um código de um callback não validado.

```
curl --request POST https://api.fiz.co/oauth/token \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode "client_id=$FIZ_CLIENT_ID" \
  --data-urlencode "client_secret=$FIZ_CLIENT_SECRET" \
  --data-urlencode "code=$CODE" \
  --data-urlencode "code_verifier=$VERIFIER" \
  --data-urlencode 'redirect_uri=http://localhost:3100/callback' \
  --data-urlencode 'resource=https://api.fiz.co'
```

Envie parâmetros de formulário com `client_secret_post`, não JSON. Use o verifier original e o mesmo redirect URI e recurso. O pedido de autorização expira em 10 minutos; o código emitido expira em 60 segundos e só pode ser usado uma vez.

A resposta contém `access_token`, `refresh_token`, `expires_in`, `token_type` e o `scope` concedido. Guarde os tokens no servidor. Confirme as permissões concedidas em vez de assumir que todas foram aceites.

Cada autorização liga **um utilizador, uma empresa e uma aplicação**. Consulte `GET /company` e associe esse ID ao seu cliente antes de escrever. Outra empresa exige outro consentimento; nenhum cabeçalho de tenant pode mudar a empresa do token.

## 4. Traga um novo cliente para o FIZ

### Quem emite a fatura e quem paga ao FIZ?

**Uma aplicação, uma ligação separada por emitente.** Cada lojista ou estafeta que emite com o seu próprio NIF precisa do seu perfil de faturação no FIZ e de uma ligação autorizada. Neste percurso, cria ou entra numa conta FIZ e configura a sua atividade empresarial ou independente atual. “Criar uma empresa” significa criar esse perfil no FIZ, não constituir uma nova entidade jurídica.

A ligação da empresa da plataforma só permite emitir por essa empresa. Não existe um parâmetro de NIF do emitente por fatura que permita emitir por outro lojista. O registo de cliente e o respetivo NIF identificam o *comprador*, não outro emitente. Guarde o client ID e o segredo da aplicação no servidor, mas mantenha um par de tokens separado e a associação devolvida por `GET /company` para cada emitente ligado.

**A cobertura de plataforma dispensa a subscrição separada, não o registo nem o consentimento.** Quando o FIZ ativa a cobertura da aplicação Production e a ligação específica continua coberta, o cliente não precisa de uma subscrição FIZ separada para acesso à API e emissão fiscal através da aplicação. A cobertura não inclui funcionalidades pagas de uso manual no FIZ, declarações ou acesso por chave API. Mantêm-se os requisitos de titularidade, permissões concedidas e preparação da AT. Combine a cobertura e as condições comerciais com o [suporte FIZ](mailto:support@fiz.co); aprovar a aplicação, por si só, não ativa a cobertura.

### Iniciar o registo sem enviar o cliente para a escolha de planos

Para novos clientes, use esta ligação de registo do parceiro, não uma ligação de registo genérica nem um pedido OAuth pendente. Use o **ID de registo da aplicação**:

```
const signup = new URL('https://app.fiz.co/auth/signup');
signup.searchParams.set('path', '/auth/app-return?' +
  new URLSearchParams({ app: process.env.FIZ_APP_ID }));
// Link to signup.href. Use the application ID, not the fiz_app_ client ID.
```

O cliente verifica o email, configura o perfil de faturação com o seu NIF e chega ao passo de ligação à AT. Pode ligar a AT ou escolher **Mais tarde**. Este percurso salta a escolha de planos e as perguntas genéricas sobre produtos de interesse e como conheceu o FIZ. Criar o perfil não subscreve um plano pago do FIZ.

### Continue automaticamente após a criação do perfil

O FIZ regressa depois ao **URL para iniciar ou retomar a ligação** registado (`installUrl`). Este retorno não é um callback OAuth: o FIZ não acrescenta código de autorização, token de acesso, ID de empresa, email ou um URL de retorno arbitrário. No exemplo, `/resume` trata este retorno e `/callback` recebe o resultado OAuth posterior.

1.  FIZ: criação do perfil e passo da AT
2.  A sua app: URL para iniciar ou retomar a ligação
3.  FIZ: empresa e permissões → Permitir
4.  A sua app: callback OAuth
5.  A sua app: ligação concluída

1.  Antes de encaminhar o cliente para o FIZ, guarde a identidade e a ligação pretendida na sessão do seu servidor.
2.  O endpoint de início ou retoma registado recupera esse contexto. Se o cliente precisar de voltar a iniciar sessão na sua app, continue a partir deste endpoint após o login.
3.  Inicie um **novo pedido OAuth com state e PKCE novos**, conforme [Ligue uma empresa com OAuth](#3-ligue-uma-empresa-por-oauth). Reutilize a lógica do botão “Ligar FIZ”. O pedido original pode expirar durante o registo; não volte a abrir um URL de consentimento antigo.
4.  O FIZ apresenta a empresa e as permissões. Após Permitir, valide o callback, troque o código, associe a ligação com `GET /company` e mostre o sucesso na sua app.

**O cliente não deve ter de fechar o navegador nem voltar a premir “Ligar FIZ”.** Teste o percurso completo com uma conta FIZ nova, não apenas com uma conta que já tenha empresa.

Se um cliente com sessão iniciada abrir OAuth sem qualquer vínculo ativo a uma empresa, o consentimento oferece **Configurar o meu perfil**. A opção abre o mesmo percurso do parceiro e regressa ao URL para iniciar ou retomar a ligação e começa um novo OAuth. Quem já é membro de uma empresa, mas não a pode autorizar, continua a precisar do titular para a ligar. O consentimento mostra a cobertura confirmada para a empresa escolhida; escolher outra empresa ou perder a cobertura altera esse estado.

As credenciais AT permanecem no FIZ. A aplicação consulta `GET /company` para verificar a preparação. Escolher Mais tarde permite ligar para criar rascunhos, mas não dispensa os requisitos de emissão.

> Mantenha o percurso no mesmo navegador. O email com o código não inclui o caminho de retorno ao parceiro. Concluir o registo noutro dispositivo sem a ligação original pode perder o retorno e a atribuição ao parceiro; não atribui um parceiro incorreto. Se necessário, reinicie a partir da ligação do parceiro.

## 5. Faça os primeiros pedidos à API

### Confirme a empresa ligada

```
curl https://api.fiz.co/company \
  --header "Authorization: Bearer $ACCESS_TOKEN"
```

A resposta inclui `id`, `name`, `taxpayerNumber`, `cae` e `readiness`. Não expõe credenciais AT, dados bancários ou dados pessoais do proprietário.

Se `readiness.ready` for false, consulte `reasons[].code` e apresente o `actionUrl` devolvido como ligação de configuração: `AT_CREDENTIALS_REQUIRED`, `AT_SYNC_REQUIRED` ou `SERIES_REQUIRED`. Atualize a verificação após configurar. O endpoint de escrita faz sempre a verificação final.

### Crie o cliente e o artigo desta aplicação

Envie estes JSON para `POST /customers` e `POST /items`, com o cabeçalho bearer, `Content-Type: application/json` e uma `Idempotency-Key` estável e diferente para cada operação.

```
{
  "name": "Example customer",
  "country": "PT"
}
```

```
{
  "name": "Example service",
  "type": "SERVICE",
  "unitPrice": 10,
  "vatRate": "NORMAL"
}
```

Guarde os dois `id` devolvidos. Escolha a categoria de IVA e o motivo de isenção aplicáveis à empresa; a categoria do exemplo não determina o enquadramento fiscal.

### Crie um rascunho

Guarde este JSON como `draft.json`. Substitua os IDs pelos valores devolvidos e `cae` por um valor da resposta da empresa. A referência ao artigo é `items[].id`, não `itemId`.

```
{
  "type": "INVOICE",
  "cae": "62010",
  "customerId": "aaaaaaaaaaaaaaaaaaaaaaaa",
  "items": [
    {
      "id": "bbbbbbbbbbbbbbbbbbbbbbbb",
      "quantity": 1
    }
  ]
}
```

```
curl --request POST https://api.fiz.co/invoices \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: order-1042-draft' \
  --data @draft.json
```

Consulte-o com `GET /invoices/{id}`. Um `INVOICE` criado neste endpoint é um rascunho. A emissão é uma ação separada, `POST /invoices/{id}/issue`, com `invoicing.issue`; envie o `expectedUpdatedAt` mais recente para evitar emitir uma versão desatualizada. Após emitir, `GET /invoices/{id}/pdf` obtém o PDF.

> Emitir, liquidar ou cancelar documentos fiscais afeta a empresa real. As aplicações registadas precisam de credenciais AT verificadas, sincronização AT ativa e séries válidas. O FIZ não apresenta uma confirmação adicional por cada emissão via API do parceiro. O seu produto deve tornar a ação clara para o utilizador.

## 6. Permissões e isolamento

| Permissão | Capacidade REST |
| --- | --- |
| `company.read` | Identidade da empresa, preparação para emissão e lista de séries. |
| `invoicing.read` | Ler faturas, documentos de transporte, clientes e artigos desta aplicação; os respetivos PDF. |
| `invoicing.write` | Criar/alterar/remover rascunhos (faturas e documentos de transporte), clientes e artigos desta aplicação. |
| `invoicing.issue` | Emitir, pagar e cancelar documentos, incluindo documentos de transporte; criar notas de crédito nos registos permitidos desta aplicação. |
| `invoicing.read_all` | Ler faturas, documentos de transporte, clientes e artigos de toda a empresa. Não permite alterar registos manuais ou de outra aplicação. |

Escolha apenas as permissões necessárias. Por compatibilidade, os metadados da empresa também aceitam a permissão existente de leitura de faturação; nas novas integrações, peça `company.read` explicitamente. Uma permissão de escrita não concede leitura automaticamente.

Por defeito, a aplicação A não pode ler ou alterar registos da aplicação B ou criados manualmente. Crie um registo de cliente e artigo próprio para a sua aplicação, mesmo que esse comprador já exista no FIZ. O proprietário continua a ver os registos no FIZ.

A referência inclui também endpoints para chaves API. OAuth para aplicações registadas suporta atualmente **empresa, séries, faturas, documentos de transporte, clientes e artigos**; faturas agendadas, modelos, rotas bancárias e pro formas não são disponibilizados por estas permissões REST. Os documentos de transporte seguem as regras das faturas: uma aplicação vê e altera apenas as guias que criou, envia as moradas de carga e descarga por extenso (as moradas guardadas da empresa não estão disponíveis para aplicações) e emitir ou anular uma guia requer `invoicing.issue`. Uma rota sem permissão OAuth explícita é recusada.

O [conector MCP](https://api.fiz.co/docs/mcp.md) usa outro recurso, `https://api.fiz.co/mcp`. Tokens REST não servem para MCP, nem o inverso. Clientes CIMD pessoais não podem obter acesso REST. Aplicações registadas não podem usar as ferramentas MCP de pro formas.

## 7. Mantenha ligações fiáveis

### Renove os tokens

Os access tokens duram atualmente uma hora; use o `expires_in` da resposta. Os refresh tokens duram até 90 dias e são rodados a cada utilização. Serialize a renovação por ligação, incluindo entre réplicas do seu servidor, e guarde o novo par de tokens atomicamente.

```
curl --request POST https://api.fiz.co/oauth/token \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode "client_id=$FIZ_CLIENT_ID" \
  --data-urlencode "client_secret=$FIZ_CLIENT_SECRET" \
  --data-urlencode "refresh_token=$REFRESH_TOKEN" \
  --data-urlencode 'resource=https://api.fiz.co'
```

Se perder a resposta, não reutilize o refresh token às cegas: pode já ter sido rodado, e a reutilização pode revogar a ligação. Trate o resultado como incerto e ofereça nova ligação explícita. Um bloqueio temporário confirmado conserva as credenciais para tentar mais tarde.

### Repita escritas conforme o resultado registado

Envie `Idempotency-Key` em cada pedido de escrita para o poder repetir com segurança. Atualmente, pedidos sem a chave são executados sem proteção contra repetições; se perder a resposta, verifique o resultado antes de repetir um pedido sem chave. Use uma `Idempotency-Key` estável por operação, por exemplo `order-1042-draft`. Use chaves distintas para criar cliente, artigo e emitir. Após timeout, repita a *mesma* operação com a mesma chave e corpo, parâmetros de caminho e query idênticos para consultar o resultado registado. Nem todos os erros 409 permitem repetição.

As chaves têm 1–128 caracteres ASCII imprimíveis sem espaços. Os resultados são guardados 30 dias e separados por aplicação + utilizador que autorizou + empresa + operação. Novo consentimento do mesmo utilizador mantém esse espaço; outro utilizador tem um diferente. Mantenha a sua própria associação durável entre encomenda e documento. A repetição inclui `Idempotent-Replayed`.

**IN\_PROGRESS:** enquanto a execução tem um prazo ativo (atualmente 90 segundos), o REST responde 409 com `Retry-After`. Aguarde e repita com a mesma chave. Uma operação concluída pode devolver o resultado guardado durante os 30 dias de retenção, não apenas dentro desse prazo.

**ABANDONED / resultado desconhecido:** um prazo expirado sem resultado comunicado, ou uma falha depois de a execução poder ter começado, produz outro 409. Pare as repetições automáticas. Essa chave não pode iniciar outra execução; um registo explicitamente abandonado também não pode devolver um resultado guardado. Esperar não torna a chave reutilizável. Verifique se a operação original teve efeito antes de considerar uma chave nova.

Por exemplo, após `POST /invoices/{id}/issue`, consulte essa mesma fatura e confirme o estado e número. Se foi emitida, guarde o resultado localmente e não emita novamente. Use uma **chave nova apenas depois de confirmar que não houve efeitos e que a operação original já não está em execução**. Se não conseguir confirmar, contacte o suporte para evitar duplicados. Uma rejeição de validação antes da execução permite repetir o pedido original inalterado; um payload corrigido é um pedido novo e exige outra chave.

### Pausa, revogação e rotação

Pausar, suspender pelo FIZ ou devolver uma aplicação Production para revisão bloqueia temporariamente o uso, conservando as credenciais. Arquivar, desligar ou remover um testador pode revogar acesso. Reduzir permissões invalida autorizações com permissões antigas; volte a ligar com as novas. Rodar o segredo substitui imediatamente o anterior: atualize a configuração do servidor. Não substitui a revogação de tokens já emitidos.

Os clientes podem desligar em [Definições → Integrações](https://app.fiz.co/settings/integrations). Pare tarefas de ligações revogadas e ofereça uma ação explícita para voltar a ligar.

## 8. Resolva erros frequentes

| Resultado | O que fazer |
| --- | --- |
| Aplicação indisponível no consentimento | Verifique pausa/arquivo/suspensão, aprovação Production, identidade do criador/testador Development e permissões pedidas. Um novo testador pode registar-se com o email indicado. |
| Após o registo: página de marketing em vez do consentimento | Verifique o URL para iniciar ou retomar a ligação (`installUrl`). Deve abrir o percurso de ligação e iniciar um novo pedido OAuth, em vez de apenas mostrar a página inicial. Registe o endpoint correto e preserve a sessão do parceiro durante o registo; mantenha o callback OAuth como endpoint separado para o resultado. Teste perfil → AT → retoma → consentimento → callback sem reiniciar manualmente. |
| Plano com API necessário | Uma ligação Production exige cobertura de plataforma ativa ou um plano da empresa com API. Confirme a cobertura desta aplicação e empresa com o FIZ; não peça a um cliente coberto que compre outro plano. O teste Development está isento do requisito de plano API, mas não das regras de emissão e preparação fiscal. |
| `invalid_client` | Verifique client ID, segredo atual e codificação do formulário. Não altere nem remova espaços de um segredo silenciosamente. |
| `invalid_grant` | Código/token expirado, usado, revogado ou já não permitido. Volte a ligar explicitamente; não repita refresh em ciclo. |
| `temporarily_unavailable` | Conserve as credenciais, pause a tarefa e tente mais tarde com espera progressiva. Não force todos os clientes a voltar a ligar. |
| REST 401 | Verifique validade, revogação e audience exata. Uma aplicação suspensa também falha introspeção. Distinga bloqueio temporário de autorização revogada. |
| REST 403 | Verifique permissões concedidas, acesso/propriedade da empresa, cobertura de plataforma ou plano Production e suporte OAuth da rota. |
| REST 400 | Consulte a validação e a preparação da empresa. Verifique maiúsculas dos enums, CAE, IDs e campos obrigatórios na referência. |
| REST 409 — IN\_PROGRESS | A resposta indica que o pedido continua em processamento e inclui `Retry-After`. Aguarde e repita com a **mesma chave** e pedido idêntico. |
| REST 409 — ABANDONED / resultado desconhecido | A resposta indica que o pedido anterior pode ter tido efeito; não inclui prazo para repetição. **Pare as repetições automáticas: a chave está consumida para execução.** Consulte os documentos/registos existentes. Só use uma chave nova após confirmar que a primeira tentativa não teve efeito e já não está em execução; caso contrário, reconcilie ou contacte o suporte. Estes nomes descrevem resultados internos: consulte a mensagem HTTP e `Retry-After`, não um campo outcome inexistente. |
| REST 422 | A mesma chave foi usada com outro payload. Recupere a operação original; não mude continuamente a chave para contornar o conflito. |
| 429 | Respeite `Retry-After`, use espera progressiva com jitter e distribua tarefas no tempo. REST permite atualmente 300 pedidos/minuto por autorização/empresa; tokens têm limites separados por aplicação/IP. |

Ao contactar suporte, indique ID da aplicação, ambiente, endpoint, hora UTC, estado HTTP e ID do pedido/idempotência. Não envie segredos, tokens ou credenciais AT.

## 9. Prepare a abertura a clientes

1.  Teste uma ligação Development como criador e como testador, incluindo o registo de uma conta nova que regresse pelo endpoint de início ou retoma ao consentimento e ao callback, sem um segundo clique em “Ligar FIZ”. Verifique cancelamento, remoção de testadores, escolha da empresa e repetições.
2.  Crie uma aplicação Production separada com nome real, URLs HTTPS públicos, política de privacidade e apenas as permissões necessárias.
3.  Envie-a para revisão em Aplicações de programador. Trate dúvidas através do [suporte FIZ](mailto:support@fiz.co). A aprovação é necessária antes de ligar clientes.
4.  Guarde segredos e tokens em armazenamento seguro/cifrado no servidor. Substitua a memória do exemplo por ligações duráveis por cliente e um bloqueio de refresh partilhado.
5.  Verifique associação da empresa, idempotência, revogação e preparação para emissão. Use a sua interface para ações fiscais deliberadas.
6.  Configure as credenciais da aplicação Production e obtenha novo consentimento. As autorizações Development não são migradas.

Editar definições aprovadas devolve a aplicação a Draft e exige nova revisão; pausa/retoma e rotação do segredo mantêm o estado da revisão. Planeie as alterações antes de convidar clientes.

O exemplo é um servidor local de aprendizagem, não um serviço para vários clientes pronto a publicar. Tokens e chaves de pedido desaparecem ao reiniciar; isso não revoga autorizações FIZ. Não dependa dessa memória para deduplicação ou recuperação em produção.

- [Abrir o exemplo no GitHub ↗](https://github.com/FIZ-co/partner-app-demo)
- [Explorar a referência API](https://api.fiz.co/)
