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.
abc123def456…_0
└──────────────┘ └┘
transação índice de saídaUma obrigação tem exatamente quatro estados, e a diferença entre dois deles é o erro de integração mais comum de todos.
| Estado | Significa | O que um cliente deve fazer |
|---|---|---|
| OPEN | criada | A obrigação está registrada e é durável. Ela não está necessariamente no ledger ainda. OPEN não é confirmação. |
| PENDING | submetida | Submetida ao processador de transações, aguardando confirmação. Consulte a obrigação por id. |
| FINAL | terminal | O ciclo de vida terminou. FINAL não significa liquidado: leia o desfecho da resolução. Veja Garantias. |
| EXCEPTION | precisa de atenção | Algo 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 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ó.
| Componente | Significado |
|---|---|
| available | Gastável agora. A soma das obrigações não gastas que a conta possui. |
| pending | Registrado e ainda não confirmado, ou aguardando um fato de liquidação externo. |
| committed_to_products | Valor travado dentro de uma custódia condicional que nomeia esta conta. Visível, e não gastável. |
| committed_to_squads | As 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 conta | Guarda valor | Para que serve |
|---|---|---|
| CUSTOMER | sim | A conta de um cliente final. |
| ASSET / REVENUE / TRANSIT / EXCEPTION | sim | Contas 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. |
| EXTERNAL | não | Um 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. |
| GUEST | sim | Uma conta limitada, criada por um fluxo de convite. |
| SQUAD | sim | A 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.
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.
POST /v1/parties
POST /v1/accounts
POST /v1/obligations
POST /v1/evidence