ContasReceber
CRUD de Título a Receber (tabela SE1) via rotina automática
FINA040 (MsExecAuto). Cobre títulos comuns
(NF, PRV, CHQ) e adiantamentos (PA) — o que muda é o
tipo do payload. O identificador externo é a
chave composta natural da SE1 com 7 partes:
filial-prefixo-num-parcela-tipo-cliente-loja.
No POST sem {key} o servidor gera
E1_NUM via GetSXENum (avança SX8 em caso
de gap). Esta revisão adiciona validação de domínio
(fValDom) sobre E1_FLUXO antes do
FINA040.
Endpoint OAuth2
Sem credenciais? Você pode pegar o token rodando
./src/scripts/get-token.sh na biblioteca e
colar o access_token aqui no campo de refresh
(ou clique em "Logout" para limpar e voltar ao fake).
Vinculação com o ERP
Convenções
Identificador externo — chave composta. A chave é um único
parâmetro {key} com 7 partes separadas por hífen:
filial-prefixo-num-parcela-tipo-cliente-loja. Exemplo:
01-TST-000123-001-NF-000001-01. Quando o body do
POST/PUT traz os mesmos campos, o path
sempre vence. Pattern: ^[^-]+-[^-]+-[^-]+-[^-]+-[^-]+-[^-]+-[^-]+$.
Título normal × Adiantamento (PA). O endpoint serve os
dois cenários — o que muda é o tipo. NF,
PRV, CHQ, BOL representam títulos
comuns; PA indica adiantamento a cliente (sem nota
fiscal). Em PA o E1_NATUREZ tipicamente
referencia uma natureza de adiantamento, e o título já nasce com
E1_SALDO = E1_VALOR aguardando baixa contra a nota futura.
Whitelist única. POST e PUT compartilham o mesmo
conjunto CAMPOS_ALLOW (13 campos: E1_NATUREZ,
E1_EMISSAO, E1_VENCTO, E1_VENCREA,
E1_VALOR, E1_HIST, E1_PORTADO,
E1_AGEDEP, E1_CONTA, E1_X_PRJTO,
E1_X_TASK, E1_FLUXO, E1_ORIGEM).
Campo-chave (filial/prefixo/num/parcela/tipo/cliente/loja) não é
alterável; para mudar a chave, faça DELETE +
POST. Diferente do WsSE2, onde o PUT é restrito a 4
campos.
Validação de domínio no POST/PUT. E1_FLUXO
aceita apenas "S" ou "N" (Pertence "SN" do SX3).
Static fValDom rejeita valores fora do domínio com
422 antes do FINA040, devolvendo mensagem
clara em vez do HELP opaco da rotina:
"E1_FLUXO invalido: 'X'. Aceitos: S (Sim, gera fluxo de caixa), N (Nao).".
Campo não informado / vazio é aceito (default do dicionário).
E1_FILIAL nunca vai no array do MsExecAuto em UPDATE/DELETE.
O caller posiciona SE1 antes da chamada e FINA040
usa xFilial("SE1") internamente. Passar E1_FILIAL em
nOper=4 ou nOper=5 reentra em FA050INCLU e
dispara o erro "Numero titulo ja existe" (FA050NUM) de
forma espúria. Esta restrição vem da build atual (240223P/PRX 04/09/2025).
Soft-delete & unique index. A exclusão via
FINA040 modo 5 marca o registro com D_E_L_E_T_='*'
(soft-delete TOTVS) — o slot do índice único SE1990_UNQ
continua ocupado. Logo, recriar título com chave idêntica
(mesma filial/prefixo/num/parcela/tipo/cliente/loja) falha com 422
até purge físico. Em smoke tests, use num diferente ou
parcela diferente entre execuções.
Formato de datas. Campos E1_EMISSAO,
E1_VENCTO, E1_VENCREA aceitam string
YYYYMMDD (8 dígitos, sem separadores) no payload. A
conversão interna usa SToD(AllTrim(valor)). Em qualquer GET,
datas voltam serializadas pelo U_RestMontaRegistro.
Paginação e delta-sync. /_list usa
page/pageSize (default 50, máx
500) com orderBy=chave. Para sincronização
incremental, alterne para orderBy=recno e use
cursor conforme o nextCursor retornado. Em
orderBy=chave, since filtra
RecNo() < since.
ContasReceber
CRUD por chave composta — título normal e adiantamento (PA)num via GetSXENum)
Descrição
Inclui um título a receber via FINA040 em modo 3
(MODEL_OPERATION_INSERT). O servidor gera E1_NUM
via GetSXENum + Soma1 em loop até encontrar gap
livre na chave. Retorna a chave técnica completa em data,
com auto: true.
- Para título comum (NF/PRV/CHQ), informe o
tipousual da parametrização. - Para adiantamento (sem nota), use
tipo: "PA"— mesmo endpoint, mesmo payload. E1_FLUXOvalidado contra o domínio do SX3 (Pertence "SN") antes do FINA040.- Whitelist completa: ver
TituloPayload.
Request body
num) + campos do whitelist.
Schema completo em TituloPayload.
POST https://erpapi.jetme.com.br/api/99/01/WsContasReceber/INCLUIR Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "filial": "01", "prefixo": "TST", "parcela": "001", "tipo": "NF", "cliente": "000002", "loja": "01", "E1_NATUREZ": "201", "E1_EMISSAO": "20991231", "E1_VENCTO": "20991231", "E1_VALOR": 99.99, "E1_HIST": "TESTE_REST CONTAS A PAGAR" }
POST https://erpapi.jetme.com.br/api/99/01/WsContasReceber/INCLUIR Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "filial": "01", "prefixo": "TST", "parcela": "001", "tipo": "NF", "cliente": "000002", "loja": "01", "E1_NATUREZ": "201", "E1_EMISSAO": "20991231", "E1_VENCTO": "20991231", "E1_VALOR": 99.99, "E1_HIST": "TESTE_REST FLUXO S", "E1_FLUXO": "S" }
POST https://erpapi.jetme.com.br/api/99/01/WsContasReceber/INCLUIR Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "filial": "01", "prefixo": "TST", "parcela": "001", "tipo": "NF", "cliente": "000002", "loja": "01", "E1_NATUREZ": "201", "E1_EMISSAO": "20991231", "E1_VENCTO": "20991231", "E1_VALOR": 99.99, "E1_HIST": "TESTE_REST FLUXO INVALIDO", "E1_FLUXO": "X" }
{
"success": false,
"message": "E1_FLUXO invalido: 'X'. Aceitos: S (Sim, gera fluxo de caixa), N (Nao).",
"data": ""
}
POST https://erpapi.jetme.com.br/api/99/01/WsContasReceber/INCLUIR Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "filial": "01", "prefixo": "TST", "parcela": "001", "tipo": "NF", "cliente": "000002", "loja": "01", "E1_EMISSAO": "20991231", "E1_VENCTO": "20991231", "E1_VALOR": 99.99 }
Respostas
CrudResponse com data = TituloRef (chave de negócio resolvida + auto: true + ids técnicos).filial, prefixo, parcela, tipo, cliente, loja). Tier: validation-error.SE1990_UNQ. Tier: business-error.fValDom) ou rejeição do FINA040 — E1_FLUXO fora de "SN", cliente inexistente/bloqueado, natureza inválida, valor zerado, vencimento < emissão, etc. Mensagem editorial em message. Tier: business-error.num forçado pelo cliente
Descrição
Variante do POST em que o cliente impõe a chave completa
via path (incluindo num). Útil para integrações que precisam
preservar o número de origem (NF do cliente, número externo do sistema
consumidor). Se a chave já existir, retorna 409 sem tocar
no registro existente.
O path sempre vence sobre o body. Os 7 segmentos do path substituem os campos correspondentes do payload — o body só precisa carregar os campos não-chave (valor, vencimento, natureza, histórico).
Path parameter
filial-prefixo-num-parcela-tipo-cliente-loja. Pattern: ^[^-]+-[^-]+-[^-]+-[^-]+-[^-]+-[^-]+-[^-]+$.Request body
TituloPayload.
POST https://erpapi.jetme.com.br/api/99/01/WsContasReceber/INCLUIR/01-TST-999998-001-NF-000002-01 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "E1_NATUREZ": "201", "E1_EMISSAO": "20991231", "E1_VENCTO": "20991231", "E1_VALOR": 250.00, "E1_HIST": "NF EXTERNA 999998" }
Respostas
num forçado. data.auto = false.fValDom (E1_FLUXO fora de "SN") ou rejeição do FINA040 (mesmas causas do POST sem key).Descrição
Altera campos do título via FINA040 em modo 4
(MODEL_OPERATION_UPDATE). Whitelist única
— PUT aceita o mesmo conjunto de CAMPOS_ALLOW do POST
(13 campos não-chave). Campo-chave (filial/prefixo/num/parcela/tipo/
cliente/loja) não é alterável; para mudar a chave use DELETE + POST.
E1_FILIAL nunca entra no array em UPDATE — ver
Convenções.
Path parameter
Request body
TituloPayload.
PUT https://erpapi.jetme.com.br/api/99/01/WsContasReceber/ALTERAR/01-TST-000123-001-NF-000002-01 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "E1_VALOR": 199.99, "E1_HIST": "TESTE_REST CONTAS A PAGAR ALTERADO" }
Respostas
CrudResponse.FINA040 — natureza inexistente, valor inválido, regra de negócio violada. Tier: business-error.Descrição
Exclui o título via FINA040 em modo 5
(MODEL_OPERATION_DELETE). Pré-requisitos:
- Título sem baixa parcial (
E1_SALDO == E1_VALOR). - Sem movimentação contábil/bancária pendente.
- Cliente não bloqueado.
Soft-delete TOTVS: marca D_E_L_E_T_='*', mantendo
o slot do unique index ocupado. Reincluir título com chave idêntica falha até
purge físico (ver Convenções).
Path parameter
Cenario
Exemplo da requisicao (cenario ativo)
DELETE https://erpapi.jetme.com.br/api/99/01/WsContasReceber/EXCLUIR/01-TST-000123-001-NF-000002-01 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
Descrição
Retorna o cabeçalho do título posicionado pela chave composta (índice 1
da SE1: E1_FILIAL+E1_PREFIXO+E1_NUM+E1_PARCELA+E1_TIPO+E1_CLIENTE+E1_LOJA).
Cada parte é preenchida com PadR no TamSX3 correspondente
antes do DbSeek. Aplica whitelist de CAMPOS_GET
(cabeçalho da SE1, sem o detalhe de movimento da SE5).
Path parameter
Cenario
Exemplo da requisicao (cenario ativo)
GET https://erpapi.jetme.com.br/api/99/01/WsContasReceber/01-TST-000123-001-NF-000002-01 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
{ success: true, data: Titulo }.Descrição
Busca o título por id técnico — útil para integrações que persistem
recno ou msuid e querem reconfirmar o registro
sem decompor a chave de negócio em 7 partes.
Query parameters
recnomsuidtipo=recno, string para tipo=msuid.Cenarios
Exemplo da requisicao (cenario ativo)
GET https://erpapi.jetme.com.br/api/99/01/WsContasReceber/_byid?tipo=recno&valor=12345 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsContasReceber/_byid?tipo=msuid&valor=9f7a3e2c4b8d1a0e Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
{ success: true, data: Titulo }.tipo/valor ausentes, tipo fora do enum, valor não numérico para recno.msuid requer campo E1_MSUID no dicionário.Listagem
Paginação por filtros e delta-syncDescrição
Lista títulos com filtros por filial, prefixo,
num, cliente, loja em dois modos:
orderBy=chave(default) — usa o índice 1 da SE1; paginação porpage/pageSize.orderBy=recno— varre fisicamente (ordem 0); paginação por keyset comcursor/nextCursor. Indicado para sync incremental.
Em orderBy=chave, since descarta registros com
RecNo() < since. Em orderBy=recno,
cursor retoma logo após o último RecNo retornado.
Query parameters
xFilial("SE1").CAMPOS_GET.1, mínimo 1). Só faz sentido com orderBy=chave.50, máx 500).chave.chaverecnoorderBy=chave, descarta RecNo() < since.orderBy=recno, retoma após este RecNo (vindo de nextCursor).Cenarios
Exemplo da requisicao (cenario ativo)
GET https://erpapi.jetme.com.br/api/99/01/WsContasReceber/_list?page=1&pageSize=50 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsContasReceber/_list?cliente=000002&loja=01 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsContasReceber/_list?orderBy=recno&cursor=0&pageSize=200 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
data (array de Titulo), orderBy, pageSize, count, opcionalmente page ou nextCursor conforme o modo.fields com campo fora do whitelist, pageSize > 500).Schemas
Definições canônicas — campos com origemSX3 rastreável
/{key}, /_list,
/_byid). Cabeçalho da SE1 + ids técnicos.
GetSXENum no POST sem key).NF / PRV / CHQ / BOL / PA ... (parametrização SX5/05).YYYYMMDD).E1_MSUID.POST (whitelist CAMPOS_ALLOW_POST).
Campos-chave (filial, prefixo, num,
parcela, tipo, cliente, loja)
podem vir tanto no path ({key}) quanto no body — path sempre vence.
xFilial("SE1") quando omitido.POST /INCLUIR (servidor gera)."001" para única).NF/PRV/CHQ/BOL/PA...YYYYMMDD.YYYYMMDD.fValDom.SN
* Obrigatoriedade dos campos-chave: no POST /INCLUIR sem
{key}, os 6 campos não-num são obrigatórios no body.
Quando há {key} no path, o body não precisa repeti-los.
PUT (CAMPOS_ALLOW) — no WsSE1,
mesmo conjunto de campos do POST (PUT
unificado). Campos editáveis: E1_NATUREZ,
E1_EMISSAO, E1_VENCTO, E1_VENCREA,
E1_VALOR, E1_HIST, E1_PORTADO,
E1_AGEDEP, E1_CONTA, E1_X_PRJTO,
E1_X_TASK, E1_FLUXO, E1_ORIGEM.
Campo fora desta lista é silenciosamente ignorado pelo
FINA040. Para alterar fornecedor/prefixo/num/parcela/tipo,
faça DELETE + POST.
data nas respostas
de POST e PUT. Acrescenta ids técnicos.
true quando o servidor gerou num (POST sem key); false caso contrário.E1_MSUID.data traz
TituloRef em POST/PUT, string vazia em DELETE.
true em sucesso.message traz a
mensagem do NomeAutoLog do FINA040 (ou a mensagem
editorial de fValDom quando o erro é de domínio).
false em erros.Cenários
Catálogo de combinações de payload/query reconhecidas pelos métodos. Cada cenário usa o mesmo schema mas demonstra um uso típico distinto. Tier semântico no slug; endpoint notype-pill.
num gerado pelo servidor via GetSXENum.
Quando usar: caso de uso padrao do CRUD.
incluir-simples + E1_FLUXO="S"
(gera lancamento no fluxo de caixa). fValDom aceita; FINA040 grava.
Quando usar: titulos que devem refletir em projecao de fluxo de caixa.
num). Util para
preservar numero externo (NF do cliente, ID de sistema integrador). Path vence
sobre body.
Quando usar: integracoes que precisam manter o numero de origem.
E1_FLUXO fora do
Pertence("SN"). Static fValDom rejeita antes do FINA040,
devolvendo mensagem clara em vez do HELP opaco. Valores aceitos:
S (Sim, gera fluxo de caixa), N (Nao).
SE1990_UNQ. Por causa do soft-delete TOTVS, o slot do indice
fica ocupado mesmo apos DELETE -- recriar com chave identica falha ate purge
fisico. Use num ou parcela distintos.
CAMPOS_ALLOW do POST —
13 campos) via FINA040 Op=4. Campos-chave no body sao silenciosamente ignorados (path vence).
Quando usar: reagendar vencimento, ajustar valor, trocar natureza ou historico.
FINA040 Op=5. Soft-delete TOTVS
(D_E_L_E_T_='*') -- slot do unique index continua ocupado.
Bloqueio: 422 quando ha saldo parcial, movimentacao pendente ou cliente bloqueado.
DbSeek pelo indice 1 da SE1 (chave composta com PadR). Retorna
envelope { success, data: Titulo }.
RecNo() via tipo=recno&valor=N. Identificador
tecnico sempre disponivel.
E1_MSUID via tipo=msuid&valor=GUID. Requer
o campo no dicionario (UPDDISTR de MVC). Sem o campo -> 501.
orderBy=chave + page/pageSize.
Paginacao por offset sobre o indice 1 da SE1.
cliente + loja percorrem o indice ate o
cliente mudar. num, prefixo, filial
tambem combinaveis.
orderBy=recno + cursor retomavel. Cada pagina devolve
nextCursor para a proxima chamada. since (RecNo<valor)
tambem aceito como filtro de corte.
Quando usar: sincronizacao incremental do consumer (Angular embarcado, integradores externos).
Pendências conhecidas (rev2)
Cenários FINA040 avançados não cobertos. O CRUD
básico desta revisão expõe título "puro". Cenários avançados que o
FINA040 suporta mas que ainda não estão no payload (analogia direta
à FEAT-WsSE2-complementos-fina050): rateio contábil, rateio de
projeto (PMS), abatimento, valores acessórios, PA com cheque,
código de retenção. Backlog específico do WsSE1 será aberto em
.meta/wip/FEAT-WsSE1-complementos-fina040.md quando
houver demanda.
PUT unificado — não há schema restrito. No WsSE1
o PUT aceita o mesmo conjunto de campos do POST
(CAMPOS_ALLOW). Diferente do WsSE2, onde o PUT
é limitado a 4 campos de negócio. Para alterar
fornecedor/prefixo/num/parcela/tipo (campos-chave), continua sendo
necessário DELETE + POST — o
FINA040 Op=4 não muda a chave do título.
Bloqueio MSBLQL/MSBLQD ainda não aplicado em SE1.
O padrão da biblioteca (validado em SA1/SA2/SB1/SB5/SC1) ainda não
chegou ao WsSE1. Hoje o PUT em título não-bloqueado
opera normal. Quando entrar a onda em SE1, será necessário aceitar
PUT apenas em E1_MSBLQL/E1_MSBLQD
enquanto o título estiver bloqueado — mesmo contrato do
WsSE2.
Soft-delete TOTVS e índice SE1990_UNQ.
O DELETE faz soft-delete (D_E_L_E_T_='*'),
mas o slot do índice único permanece ocupado no MSSQL —
recriar o mesmo título logo após um DELETE pode
retornar 409 mesmo o registro não estando mais
visível via GET. Mesmo quirk do WsSE2
(SE2990_UNQ). Para reaproveitar a chave, fazer
DELETE físico via DBA ou usar nova chave.
Bloqueio do cliente (SA1). SE1 não expõe
campos próprios de bloqueio; o FINA040 consulta
SA1->A1_MSBLQL e rejeita inclusão de título
(422) quando o cliente está bloqueado. Sem semáforo
editorial — a rotina decide e devolve a mensagem.