SonaCORE

Conceitos

Dinheiro como objeto, não como linha.

Um core convencional guarda o saldo de uma conta como um número e o reescreve a cada transação. O Sona Core guarda objetos discretos com dono e deriva o saldo somando aqueles que ninguém gastou ainda. Quase tudo o que parece incomum nesta API é consequência dessa única diferença, então vale dez minutos.

Obrigação

A unidade de valor. Uma obrigação é um objeto discreto com dono, valor, origem e ciclo de vida. Ela é criada e consumida de forma atômica: uma transferência não decrementa um número e incrementa outro, ela gasta obrigações existentes e produz obrigações novas dentro de uma única transação que se aplica por inteiro ou não se aplica.

Como obrigações são saídas de transação, o identificador de uma obrigação é um hash de transação mais um índice de saída. A API escreve isso com um sublinhado.

id de obrigação
abc123def456…_0
└──────────────┘ └┘
   transação     índice de saída

Uma obrigação tem exatamente quatro estados, e a diferença entre dois deles é o erro de integração mais comum de todos.

EstadoSignificaO que um cliente deve fazer
OPENcriadaA obrigação está registrada e é durável. Ela não está necessariamente no ledger ainda. OPEN não é confirmação.
PENDINGsubmetidaSubmetida ao processador de transações, aguardando confirmação. Consulte a obrigação por id.
FINALterminalO ciclo de vida terminou. FINAL não significa liquidado: leia o desfecho da resolução. Veja Garantias.
EXCEPTIONprecisa de atençãoAlgo externo discordou do ledger: um crédito que nunca chegou, um valor que não bateu, uma duplicidade. Fica visível em vez de ser resolvido em silêncio.
FINAL não é liquidado
Uma obrigação pode estar FINAL com o desfecho da resolução ainda nulo, o que significa que o ciclo de vida fechou sem liquidar. Qualquer filtro que queira dizer “o dinheiro se moveu” tem que testar o desfecho da resolução, nunca o estado sozinho. Se você levar uma única coisa desta página, leve esta.

Saldo é derivado, nunca armazenado

Não existe campo de saldo em lugar nenhum para ler ou para corrigir. Uma resposta de saldo é calculada no momento da leitura, somando as obrigações que a conta possui e não gastou, e é por isso que ela vem decomposta em vez de colapsar em uma cifra só.

ComponenteSignificado
availableGastável agora. A soma das obrigações não gastas que a conta possui.
pendingRegistrado e ainda não confirmado, ou aguardando um fato de liquidação externo.
committed_to_productsValor travado dentro de uma custódia condicional que nomeia esta conta. Visível, e não gastável.
committed_to_squadsAs dívidas de cota em aberto de quem chama, em uma conta em grupo. Comprometido, não perdido.

A decomposição é o ponto: um número único teria que escolher entre superestimar o que você pode gastar e esconder o que você deve. Note que a leitura de saldo não é read-your-writes, e Garantias explica o que consultar no lugar.

Contas e partes

Uma party é uma pessoa física ou jurídica. Uma account guarda valor e pertence a uma parte. Criar uma parte não cria uma conta, e uma parte pode ter várias.

Tipo de contaGuarda valorPara que serve
CUSTOMERsimA conta de um cliente final.
ASSET / REVENUE / TRANSIT / EXCEPTIONsimContas de razão. Tarifas, valores em suspenso, valor em trânsito e o balde de exceções são contas de verdade, não ajustes.
EXTERNALnãoUm invólucro não custodial para uma contraparte fora do ledger, para que um produto possa nomeá-la antes de ela entrar. Estruturalmente impedida de custodiar: sem endereço, sem saldo. Uma leitura de saldo devolve lista de ativos vazia em vez de um zero, porque não há nada ali para ser zero.
GUESTsimUma conta limitada, criada por um fluxo de convite.
SQUADsimA conta por trás de uma reserva em grupo.

Evidência é o que traz valor de fora para dentro

O ledger não vai até um trilho de pagamento perguntar o que aconteceu. Um fato de liquidação externo é submetido a ele como evidência: um crédito chegou, com valor, data e hora e uma coordenada de destino. O ledger casa isso com um meio de pagamento vinculado e cria as obrigações.

Então financiar uma conta são dois passos, não um. Vincule uma coordenada à conta, depois submeta um crédito que a nomeie.

Valor se move em quatro trilhos: QUADRA para transferências internas, ACH e PIX para as externas, e MOCK para um trilho que liquida na hora, sem contraparte externa. Note que as coordenadas de meio de pagamento declaram mais nomes de trilho do que existem adaptadores, então o trilho da obrigação é a lista honesta.

No ambiente de avaliação
O adaptador de Pix está implementado, mas não há patrocinador de pagamento contratado e não há simulador de patrocinador publicado, então no ambiente de avaliação as respostas dele são valores fixos. MOCK e ACH são os caminhos que os roteiros de demonstração usam para financiar uma conta.

Produtos são regras, não funcionalidades

Um produto é um conjunto de regras que o próprio ledger impõe no momento em que o valor se move, e não um serviço que verifica uma política depois. Uma custódia condicional guarda valor e o libera apenas quando as condições que as partes acordaram foram cumpridas; uma reserva em grupo controla quem contribuiu com o quê e liquida por membro, não por grupo. Nenhuma das duas pode ser burlada escrevendo em uma tabela, porque não existe tabela onde escrever.

Na prática, isso significa que o estado de um produto mora dentro do objeto e não ao lado dele, e que ler uma instância de produto é decodificar esse estado, não cruzar dados entre serviços.

Idempotência é obrigatória, não opcional

Toda escrita que cria valor recebe um cabeçalho Idempotency-Key, e ele é obrigatório, não recomendado. Repetir uma chave com o mesmo corpo devolve o resultado original; repetir com um corpo diferente é conflito, não transação nova.

obrigatório em
POST /v1/parties
POST /v1/accounts
POST /v1/obligations
POST /v1/evidence