- Em vez de chamar diretamente a API de pagamentos em várias partes da lógica do produto, a exe registra mudanças de estado como fatos faturáveis (billable facts) e reconcilia o estado confirmado com a Stripe
- Na arquitetura anterior, transações de banco de dados e chamadas à API de pagamentos ficavam entrelaçadas, e exceções como falhas parciais, estados anômalos de assinatura e recusas de pagamento abalavam até o fluxo do produto
- Quando uma licença de equipe é adicionada, o estado é marcado como dirty, e um worker posterior calcula a quantidade conforme as regras de negócio e atualiza a quantidade da assinatura na Stripe apenas se houver mudança
- Ao separar pagamentos, o onboarding de novos membros da equipe deixa de depender do código de pagamento, e alterações nas regras de cálculo de licenças não afetam os fluxos de convite e cadastro
- A mesma estrutura de reconciliação é aplicada a cobrança por uso, como VMs ativas e uso de disco, e também a compras in-app no iOS, permitindo manter os eventos do produto e mudar apenas a integração específica de cada provedor de pagamentos
Separando a lógica de pagamentos do fluxo do produto
- Quando a lógica de pagamentos se mistura à lógica comum de negócio, o código relacionado se espalha por todos os caminhos críticos que exigem cobrança, e a estrutura de preços também fica frágil e difícil de alterar
- A exe busca permitir que qualquer pessoa altere o código relacionado sem que o conhecimento sobre pagamentos fique concentrado em uma só pessoa, deixando as exceções complexas para responsáveis especializados
- A cobrança inicial de licenças de equipe estava agrupada em um grande fluxo, desde a aceitação do convite até o pagamento
- O usuário aceitava o convite, verificava a conta e depois entrava na equipe
- Recebia permissão de acesso a VMs compartilhadas e recursos de computação conforme o plano
- Nesse processo, a API de pagamentos também era chamada
- Ao combinar alterações no banco de dados com chamadas a APIs externas, podem ocorrer falhas parciais, em que apenas um dos lados é concluído com sucesso
- O estado da assinatura da equipe pode ficar anômalo
- O pagamento por licenças adicionais pode ser recusado
- Quanto mais exceções se acumulam, mais frágil toda a arquitetura se torna
Fatos faturáveis e reconciliação posterior
- Um fato faturável é uma operação atômica que indica que determinado estado mudou
- Primeiro, a lógica do produto é executada para confirmar o novo estado do recurso
- Depois, com base no fato confirmado, o estado do provedor de pagamentos é reconciliado
- A Stripe precisa apenas da quantidade final, não do processo que levou a esse estado
-
Reconciliação de licenças de equipe
- Quando um convite é aceito, o estado das licenças da equipe é marcado como dirty
- Um worker posterior detecta o estado dirty e calcula o aumento ou a redução de licenças conforme as regras de negócio
- A quantidade da assinatura na Stripe é atualizada apenas se a quantidade tiver mudado
- Como a adição de membros à equipe e o código de pagamentos ficam separados, reescrever o fluxo de convites não quebra a cobrança junto, e a forma de calcular licenças também pode ser alterada de modo independente
-
Cobrança por uso e compras in-app
- O mesmo processo de reconciliação se aplica a toda cobrança por uso
- O sistema registra fatos sobre VMs ativas e uso de disco
- Um worker de medição reconcilia esses fatos com o estado do provedor de pagamentos
- Mesmo ao adicionar uma nova forma de cobrança, os fatos permanecem os mesmos; muda apenas a forma de reconciliar com cada API
- O app iOS também apenas informa o fato de que alguém assinou via compra in-app, e o estado real do pagamento é reconciliado depois
- A arquitetura de pagamentos se tornou uma área que outros integrantes também conseguem lidar, e a chance de mudanças em funcionalidades do produto, como o fluxo de convites, danificarem o sistema de cobrança também diminuiu
- O mesmo processo de reconciliação se aplica a toda cobrança por uso
1 comentários
Comentários no Lobste.rs
O ponto central do texto — detectar e processar mudanças de forma assíncrona — reduz acoplamento e é bom para implementar efeitos colaterais
Mas LLM é uma ferramenta que acelera, em vez de impedir, o espalhamento do código por toda parte, então tende a virar dívida arquitetural. Também fica a dúvida de como revisar código que é gerado mais rápido do que conseguimos entender; o trecho dizendo que a Exe nem faz revisão de código assusta ainda mais
A arquitetura é interessante, mas não está claro como ela resolve o problema apresentado no início do texto. Se um pagamento for recusado, parece que recursos não pagos seriam entregues primeiro, em vez de garantir o pagamento de todos os recursos
Um operador de cobrança poderia publicar o fato de que foi
declinedpara recolher os recursos, mas isso vira uma estrutura cíclica em comparação com um fluxo unidirecional limpo. Pode funcionar bem para um serviço de computação com cobrança mensal como a Exe, mas é um compromisso difícil de aceitar em negócios que enviam equipamento físico ou revendem assentos de outros serviçosAinda assim, isso não responde diretamente como lidar com falhas de chamada de API ou transação de banco de dados, estados anormais de assinatura, ou recusas no pagamento de assentos. Também continuam existindo problemas como uma refatoração quebrar a coleta analítica, uma linha específica deixar de ser marcada como alterada, ou um novo caminho esquecer de marcar a mudança
Também não resolve estados relacionados à cobrança que existem dentro do produto, como limites de assentos e cotas gratuitas, teto máximo de gastos e abatimento de saldo pré-pago. O serviço de produto pode emitir eventos e o serviço de cobrança pode refletir o estado de conformidade de volta no produto, mas aí passamos a ter dois agentes atuando em um sistema distribuído com estado
Parece que a Stripe quer só um número, mas em certa escala, fornecer até os itens detalhados do pagamento pode reduzir taxas de intercâmbio e aumentar a taxa de aprovação
A forma como a Exe não faz revisão de código é algo novo. Nesse caso, fico curioso para saber como eles operam releases e testes