PaymentReceipt) representa o registro de uma liquidação total ou parcial de um pagamento (parcela). Um pagamento pode acumular múltiplas baixas ao longo do tempo — por exemplo, duas baixas parciais que juntas liquidam o valor total.Contrato de API (não confundir com armazenamento). Esta tabela descreve o payload das respostas e requisições. A estrutura aninhada ( paymentMethod,snapshot,charges,cancellation,registeredBy) é resultado de serialização — o modelo de dados em12. Modelo de Dados.mdarmazena os campos em colunas flat. O backend hidrata e agrupa na hora de devolver.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | UUID | Sim | Identificador único da baixa. |
paymentId | UUID | Sim | Referência ao pagamento (parcela) liquidado. |
contractId | UUID | Sim | Referência ao contrato pai. Desnormalizado. |
companyId | UUID | Sim | Empresa. Desnormalizado. |
receivedAmount | Decimal | Sim | Valor efetivamente recebido neste registro. Deve ser maior que zero e menor ou igual ao amounts.remaining da parcela. |
receivedAt | Datetime (ISO YYYY-MM-DD) | Sim | Data efetiva da liquidação. Aceita retroativas, não aceita datas futuras. |
status | Enum | Sim | ACTIVE (baixa válida que conta para o saldo) ou CANCELLED (baixa anulada, não conta). |
paymentStatus | Enum | Não | Apenas em responses. Reflete o status recalculado do pagamento (parcela) após esta baixa ou cancelamento. Evita roundtrip do frontend. |
notes | String | Não | Observações livres sobre a baixa. |
paymentMethod | Object | Sim | Objeto com forma de pagamento. Ver detalhe abaixo. |
snapshot | Object | Sim | Snapshot imutável do estado do contrato/parcela no momento da baixa. Ver detalhe abaixo. |
charges | Object | Sim | Encargos com snapshot duplo. Ver detalhe abaixo. |
cancellation | Object | Sim | Dados de cancelamento. Sempre presente, com null em todos os campos quando status = ACTIVE. Ver detalhe abaixo. |
registeredBy | Object | Sim | Usuário que registrou, hidratado: { id, name }. |
createdAt | DateTime (ISO 8601 UTC) | Sim | Data de criação do registro. |
updatedAt | DateTime (ISO 8601 UTC) | Sim | Data da última atualização (geralmente igual a createdAt, exceto se cancelada). |
paymentMethod (objeto)| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
paymentMethod.type | Enum | Sim | Forma: BOLETO, PIX, BANK_TRANSFER, CASH, CHECK, OTHER. |
paymentMethod.description | String | Condicional | Descrição livre quando type = OTHER. Obrigatório nesse caso. |
paymentMethod.reference | String | Não | Referência externa: endToEndId do PIX, número do boleto, número do cheque, ID da transação. Formato livre. |
snapshot (objeto, imutável após criação)| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
snapshot.value | Decimal | Sim | Snapshot do amounts.value do pagamento no momento da baixa. |
snapshot.corrected | Decimal | Não | Snapshot do amounts.corrected. null quando sem correção monetária. |
snapshot.correctionIndex | Enum | Não | Snapshot do correctionIndex do contrato. null quando sem correção. |
snapshot.interestCalculationMethod | Enum | Não | Método aplicado: SIMPLE ou COMPOUND. Snapshot do contrato. null quando juros não aplicáveis. |
charges (objeto)calculated (o que o sistema calculou — imutável) e charged (o que foi efetivamente cobrado — editável apenas na criação).| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
charges.interest | Object | Sim | Juros de mora. Objeto { calculated, charged }. |
charges.interest.calculated | Decimal | Não | Calculado pelo sistema (snapshot, imutável). null quando não aplicável. |
charges.interest.charged | Decimal | Não | Efetivamente cobrado. Default = calculated. Editável apenas na criação. |
charges.fine | Object | Sim | Multa por atraso. Objeto { calculated, charged }. |
charges.fine.calculated | Decimal | Não | Calculado pelo sistema. null quando não aplicável. |
charges.fine.charged | Decimal | Não | Efetivamente cobrado. Default = calculated. Editável apenas na criação. |
charges.discount | Object | Sim | Desconto. Objeto { calculated, charged }. |
charges.discount.calculated | Decimal | Não | Calculado pelo sistema. null quando não aplicável (ex: baixa após o vencimento — RN-REC-010). |
charges.discount.charged | Decimal | Não | Efetivamente aplicado. Default = calculated. Editável apenas na criação. Pode ser informado mesmo quando calculated = null (acordo pontual). |
cancellation (objeto, sempre presente)null quando status = ACTIVE.| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
cancellation.at | DateTime (ISO 8601 UTC) | Não | Data/hora do cancelamento. null quando status = ACTIVE. |
cancellation.by | Object | Não | Usuário que cancelou, hidratado: { id, name }. null quando status = ACTIVE. |
cancellation.reason | Enum | Não | Motivo do cancelamento (ver seção 2.2). null quando status = ACTIVE. |
cancellation.notes | String | Não | Observações livres do cancelamento. null quando status = ACTIVE. |
registeredBy (objeto)| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
registeredBy.id | UUID | Sim | ID do usuário que registrou a baixa. |
registeredBy.name | String | Sim | Nome do usuário, hidratado pelo backend. |
cancellation.reason:| Código | Significado |
|---|---|
INCORRECT_VALUE | Valor recebido foi registrado incorretamente. |
INCORRECT_DATE | Data da baixa foi registrada incorretamente. |
WRONG_PAYMENT | Baixa foi registrada na parcela errada. |
TYPING_ERROR | Erro de digitação em qualquer campo da baixa. |
OTHER | Outros motivos. Recomenda-se preencher cancellation.notes com detalhe. |
charges.*.calculated):charges.interest.calculated, charges.fine.calculated e charges.discount.calculated com base nos percentuais do contrato (finePercentage, dailyInterestPercentage, configuração de desconto da parcela) e nas regras de aplicabilidade do template (paymentDefaults). Esses campos ficam imutáveis após criação.charges.*.charged):charges.interest.charged, charges.fine.charged e charges.discount.charged são preenchidos pelo usuário no body da requisição. Quando ausentes, recebem o valor de calculated correspondente (default). Quando informados, podem diferir — refletindo acordos comerciais, descontos pontuais ou perdão de mora.receivedAt <= dueDate. Após o vencimento, charges.discount.calculated é null. O usuário pode ainda informar charges.discount.charged manualmente para um acordo pontual.snapshot.value, snapshot.corrected, snapshot.correctionIndex e snapshot.interestCalculationMethod são preenchidos automaticamente e são imutáveis.| Condição | Status da parcela |
|---|---|
amounts.received acumulado (de baixas ACTIVE) = 0 e dueDate não ultrapassado | PENDING |
amounts.received acumulado = 0 e dueDate ultrapassado, sem daysToDefault ultrapassado | OVERDUE |
amounts.received acumulado = 0 e daysToDefault do contrato ultrapassado | DEFAULTED (via job) |
0 < amounts.received acumulado < amounts.due | PARTIALLY_PAID |
amounts.received acumulado >= amounts.due | PAID |
amounts.received acumulado da parcela é a soma dos receivedAmount de todas as baixas com status = ACTIVE. Baixas CANCELLED são ignoradas no cálculo do saldo.PAID → PARTIALLY_PAID, PARTIALLY_PAID → PENDING/OVERDUE).status = PENDING, PARTIALLY_PAID, OVERDUE ou DEFAULTED. Erro: PAYMENT_NOT_RECEIVABLE.receivedAmount deve ser maior que zero. Erro: INVALID_RECEIVED_AMOUNT.receivedAmount deve ser menor ou igual ao amounts.remaining da parcela no momento do registro. Não é permitida baixa que cause "saldo negativo" (excedente). Erro: RECEIVED_AMOUNT_EXCEEDS_REMAINING.amounts.received acumulado é a soma do receivedAmount de todas as baixas ACTIVE. O status da parcela é recalculado após cada registro (ver seção 2.4).receivedAt pode ser anterior à data atual (retroativo é aceito). Não aceita datas futuras. Erro: FUTURE_RECEIPT_DATE.paymentMethod.reference é opcional e de formato livre.charges.interest.calculated, charges.fine.calculated e charges.discount.calculated no momento da criação. Esses campos não são editáveis depois — representam "o que o sistema calculou no momento da baixa".charges.interest.charged, charges.fine.charged e charges.discount.charged recebem como default os respectivos calculated. O usuário pode informar valores diferentes na criação para refletir acordos comerciais ou descontos pontuais. Após criada, esses valores também ficam imutáveis (para alterar, cancela a baixa e cria nova).paymentDefaults.interestApplicable = false, charges.interest.calculated é null. Quando o contrato não tem dailyInterestPercentage configurado, idem. O usuário pode informar charges.interest.charged manualmente nesse caso (acordo). Mesma lógica para multa e desconto.charges.discount.calculated só é diferente de null quando receivedAt <= dueDate da parcela. Após vencimento, null. charges.discount.charged pode ser informado manualmente em qualquer caso.correctionIndex != NONE, o amounts.corrected é base para cálculo de encargos. Registrado em snapshot.corrected.status = CANCELLED). O registro original permanece visível no histórico. Para registrar valores corretos, cria-se nova baixa.cancellation.reason é obrigatório no cancelamento e deve ser um dos códigos pré-definidos (INCORRECT_VALUE, INCORRECT_DATE, WRONG_PAYMENT, TYPING_ERROR, OTHER). cancellation.notes é opcional para texto livre. Erro: CANCELLATION_REASON_REQUIRED.receivedAmount do total acumulado da parcela (amounts.received). O status da parcela é recalculado conforme regras da seção 2.4 — pode reverter (ex.: PAID → PARTIALLY_PAID/OVERDUE).status = CANCELLED não pode ser reativada nem editada. Para registrar nova liquidação, criar nova baixa. Erro: RECEIPT_ALREADY_CANCELLED.payment_receipt:create) na v1. Não há action separada para cancelamento. A separação pode ser revisada em versões futuras se houver demanda operacional (ex.: separar operador que registra vs. supervisor que cancela).paymentMethod.type = OTHER, paymentMethod.description é obrigatório. Erro: MISSING_PAYMENT_METHOD_DESCRIPTION.status = CANCELLED).| Status | Código | Descrição |
|---|---|---|
| 404 | PAYMENT_NOT_FOUND | Pagamento (parcela) não encontrado. |
| 404 | RECEIPT_NOT_FOUND | Baixa não encontrada. |
| 422 | PAYMENT_NOT_RECEIVABLE | Pagamento em status que não permite baixa. |
| 422 | INVALID_RECEIVED_AMOUNT | receivedAmount deve ser > 0. |
| 422 | RECEIVED_AMOUNT_EXCEEDS_REMAINING | receivedAmount excede o saldo aberto da parcela. |
| 422 | FUTURE_RECEIPT_DATE | receivedAt é data futura. |
| 422 | MISSING_PAYMENT_METHOD_DESCRIPTION | paymentMethod.type = OTHER sem descrição. |
| 422 | RECEIPT_ALREADY_CANCELLED | Baixa já cancelada. |
| 422 | CANCELLATION_REASON_REQUIRED | Motivo do cancelamento ausente ou inválido. |
/v2/companies/:companyId/portfolios/:portfolioId/contracts/:contractId/payments/:paymentId/receiptspayment_receipt:create{
"receivedAmount": 153225.00,
"receivedAt": "2024-03-14T00:00:00.000+00:00",
"notes": "Pagamento confirmado via comprovante PIX.",
"paymentMethod": {
"type": "PIX",
"reference": "E12345678202503201234abcdef123456"
}
}charges não é informado — o sistema preenche cada charged com o respectivo calculated.{
"receivedAmount": 152000.00,
"receivedAt": "2025-03-20",
"notes": "Acordo negociado com desconto sobre multa.",
"paymentMethod": {
"type": "BANK_TRANSFER",
"reference": "TED-001-20250320"
},
"charges": {
"interest": { "charged": 200.00 },
"fine": { "charged": 1000.00 },
"discount": { "charged": 500.00 }
}
}No request, apenas chargedé aceito em cada componente decharges(ocalculatedé sempre derivado pelo backend). Enviarcalculatedresulta no campo ser ignorado.
{
"id": "rec-001",
"paymentId": "pay-001",
"contractId": "contract-001",
"companyId": "company-001",
"receivedAmount": 153225.00,
"receivedAt": "2025-03-20",
"status": "ACTIVE",
"paymentStatus": "PAID",
"notes": "Pagamento confirmado via comprovante PIX.",
"paymentMethod": {
"type": "PIX",
"description": null,
"reference": "E12345678202503201234abcdef123456"
},
"snapshot": {
"value": 150000.00,
"corrected": null,
"correctionIndex": null,
"interestCalculationMethod": "SIMPLE"
},
"charges": {
"interest": { "calculated": 225.00, "charged": 225.00 },
"fine": { "calculated": 3000.00, "charged": 3000.00 },
"discount": { "calculated": null, "charged": null }
},
"cancellation": {
"at": null,
"by": null,
"reason": null,
"notes": null
},
"registeredBy": {
"id": "8c3f1a2b-...",
"name": "João Silva"
},
"createdAt": "2025-03-20T10:00:00.000+00:00",
"updatedAt": "2025-03-20T10:00:00.000+00:00"
}paymentStatus reflete o novo status do pagamento (parcela) após o registro, evitando roundtrip do frontend.PAYMENT_NOT_RECEIVABLE, INVALID_RECEIVED_AMOUNT, RECEIVED_AMOUNT_EXCEEDS_REMAINING, FUTURE_RECEIPT_DATE, MISSING_PAYMENT_METHOD_DESCRIPTION.payment_receipt:read| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
status | Enum (multi) | Não | Filtrar por status: ACTIVE, CANCELLED. |
orderBy | Enum | Não | Ordenação: receivedAt, createdAt. Default: receivedAt. |
order | Enum | Não | asc ou desc. Default: desc. |
offset | Integer | Não | Default: 0. |
limit | Integer | Não | Default: 20. Máximo: 100. |
{
"items": [
{
"id": "rec-001",
"paymentId": "pay-001",
"contractId": "contract-001",
"receivedAmount": 153225.00,
"receivedAt": "2025-03-20",
"status": "ACTIVE",
"notes": "Pagamento confirmado via comprovante PIX.",
"paymentMethod": {
"type": "PIX",
"description": null,
"reference": "E12345678202503201234abcdef123456"
},
"snapshot": {
"value": 150000.00,
"corrected": null,
"correctionIndex": null,
"interestCalculationMethod": "SIMPLE"
},
"charges": {
"interest": { "calculated": 225.00, "charged": 225.00 },
"fine": { "calculated": 3000.00, "charged": 3000.00 },
"discount": { "calculated": null, "charged": null }
},
"cancellation": {
"at": null,
"by": null,
"reason": null,
"notes": null
},
"registeredBy": {
"id": "8c3f1a2b-...",
"name": "João Silva"
},
"createdAt": "2025-03-20T10:00:00.000+00:00",
"updatedAt": "2025-03-20T10:00:00.000+00:00"
}
],
"nextPage": false
}payment_receipt:read{
"id": "rec-001",
"paymentId": "pay-001",
"contractId": "contract-001",
"companyId": "company-001",
"receivedAmount": 153225.00,
"receivedAt": "2025-03-20",
"status": "CANCELLED",
"notes": "Pagamento confirmado via comprovante PIX.",
"paymentMethod": {
"type": "PIX",
"description": null,
"reference": "E12345678202503201234abcdef123456"
},
"snapshot": {
"value": 150000.00,
"corrected": null,
"correctionIndex": null,
"interestCalculationMethod": "SIMPLE"
},
"charges": {
"interest": { "calculated": 225.00, "charged": 225.00 },
"fine": { "calculated": 3000.00, "charged": 3000.00 },
"discount": { "calculated": null, "charged": null }
},
"cancellation": {
"at": "2025-03-20T11:00:00.000+00:00",
"by": {
"id": "8c3f1a2b-...",
"name": "João Silva"
},
"reason": "INCORRECT_VALUE",
"notes": "Valor incorreto registrado. Nova baixa será criada com valor correto."
},
"registeredBy": {
"id": "8c3f1a2b-...",
"name": "João Silva"
},
"createdAt": "2025-03-20T10:00:00.000+00:00",
"updatedAt": "2025-03-20T11:00:00.000+00:00"
}status = CANCELLED e o objeto cancellation preenchido.payment_receipt:create (mesma da criação na v1){
"cancellation": {
"reason": "INCORRECT_VALUE",
"notes": "Valor incorreto registrado. Nova baixa será criada com valor correto."
}
}{
"id": "rec-001",
"status": "CANCELLED",
"paymentStatus": "OVERDUE",
"cancellation": {
"at": "2025-03-20T11:00:00.000+00:00",
"by": {
"id": "8c3f1a2b-...",
"name": "João Silva"
},
"reason": "INCORRECT_VALUE",
"notes": "Valor incorreto registrado. Nova baixa será criada com valor correto."
},
"updatedAt": "2025-03-20T11:00:00.000+00:00"
}paymentStatus reflete o status recalculado da parcela após o cancelamento.RECEIPT_NOT_FOUND, RECEIPT_ALREADY_CANCELLED, CANCELLATION_REASON_REQUIRED.| Resource | Domínio | Actions |
|---|---|---|
payment_receipt | TENANT | create, read |
create cobre tanto a criação de baixa quanto seu cancelamento na v1 — não há action separada para cancelamento (RN-REC-016). Caso surja necessidade operacional de granularidade (operador registra, supervisor cancela), uma action cancel pode ser introduzida em versão futura.POST /receipts/:receiptId/replace que executa em uma única transação o cancelamento da baixa antiga e a criação de uma nova com os dados corretos. Reduz risco de "esqueceu de criar nova após cancelar". Decisão registrada no consolidado para reavaliação futura.