Separar a entrega do evento
Um evento lógico pode chegar várias vezes. O recetor precisa de distinguir o envelope de cada tentativa da identidade que representa o trabalho. A documentação Stripe ilustra assinaturas sobre o corpo original e entregas que podem repetir ou chegar fora de ordem. O laboratório usa um contrato próprio, sem SDK Stripe: X-Lab-Time e X-Lab-Signature autenticam timestamp, um ponto e os bytes do corpo com HMAC SHA-256. A chave é pública e didática. A janela temporal usa relógio sintético; a assinatura e a frescura não substituem deduplicação nem autorização do produtor sobre os recursos.
Validar antes de persistir
O ensaio rejeita ausência de assinatura, chave errada, corpo alterado e envelope antigo antes de inserir na inbox. A comparação usa hmac.compare_digest. Depois valida o schema, os tipos, os limites e o âmbito do produtor: a chave fictícia só autoriza tenant A. Um evento assinado para B1 continua proibido. A identidade do evento é estável entre tentativas. Se o mesmo ID reaparecer com outros bytes, o contrato didático devolve 409 e preserva o estado anterior. Esta regra é deliberadamente estrita; uma implementação real precisa de definir a equivalência de payloads e a resposta a conflitos.
Confirmar efeitos locais numa transação
A base SQLite mantém objetos, inbox e outbox. BEGIN IMMEDIATE inicia a decisão de escrita; a chave única da inbox e a transação coordenam os pedidos concorrentes deste ficheiro. Um evento novo pode atualizar o objeto e guardar intenção de notificação na outbox antes do commit. A falha didática before-commit provoca rollback dos três conjuntos de dados. Repetir depois permite executar a operação completa. Este desenho seria insuficiente se um efeito externo já tivesse ocorrido entre essas escritas. A outbox permite guardar intenção local; enviar, recuperar e reconciliar o destino exige trabalho adicional.
Tratar ordem segundo garantias explícitas
Neste contrato fictício, cada evento contém o estado completo e uma versão monotónica do recurso. Se a versão 2 já foi aplicada, a versão 1 é registada como antiga e não volta a alterar o montante. Não transportes esta regra para eventos delta: ignorar uma alteração incremental pode perder trabalho. Também não assumes que created ou o timestamp da assinatura ordenam todas as alterações de negócio. Quando o produtor não oferece a garantia necessária, define reconciliação com a fonte autoritativa. Dois IDs diferentes do mesmo tipo podem representar alterações legítimas distintas, pelo que deduplicar apenas por tipo seria destrutivo.
Comparar observações antes e depois do reinício
O código da aula anterior envia dois pedidos HTTP simultâneos com E3. Um fica aceite e outro duplicado; objeto, inbox e outbox terminam com o mesmo resultado de uma aceitação local. Depois termina o processo de forma limpa, inicia outro com o mesmo ficheiro e repete E3. A nova resposta continua a ser duplicado e a outbox não cresce. Isto demonstra persistência nesse reinício, não perda de energia, replicação ou recuperação regional. Examina evidence.json e regista a versão efetiva de Python e SQLite. O programa fecha os processos e remove a base temporária no fim.
Preparar o contrato operacional
Antes de uma integração real, define a retenção de identidades de acordo com reenvios, recuperação e obrigações aplicáveis. Se a inbox expirar antes do último reenvio permitido, uma tentativa antiga pode voltar a produzir efeitos. A monitorização deve distinguir mensagens recusadas, duplicadas, antigas, aceites localmente e pendentes de entrega. Um 200 não prova conclusão financeira. A oficina desta aula pede uma matriz de evidência e um plano para dispatcher, reconciliação e testes autorizados do destino. Todos os exemplos bancários são fictícios e não descrevem processos internos BNP Paribas. Revisão especializada independente permanece pendente.
OFICINA / WORKSHOP: 40 minutos / 40 minutes
Dados fictícios; não usar APIs bancárias ou credenciais reais.
Fictional data; do not use banking APIs or real credentials.
0-8: Guardar o código da aula anterior como run.py. Executar:
Save the preceding lesson code as run.py. Execute:
python3 run.py --output evidence.json
Registar runtime, sqliteVersion, runnerSha256 e passed.
Record runtime, sqliteVersion, runnerSha256, and passed.
8-18: Comparar / Compare:
- raw byte change invalidates signature: 400
- signed producer outside allowed tenant: 403
- no untrusted event reached inbox: 0
Explicar porque assinatura, âmbito e deduplicação são decisões separadas.
Explain why signature, scope, and deduplication are separate decisions.
18-28: Relacionar / Relate:
- fault rolled back inbox state and outbox
- retry after rollback can be accepted
- concurrent local effects occur once
- new HTTP process deduplicates replay
Para cada observação: identidade, estado antes/depois e limite demonstrado.
For each observation: identity, before/after state, and demonstrated limit.
28-36: Desenhar aceitação do dispatcher sem executar pedidos externos:
Design dispatcher acceptance without sending external requests:
timeout após efeito / timeout after effect;
reenvio com identidade estável / replay with stable identity;
destino indisponível / unavailable destination;
retenção e reconciliação / retention and reconciliation.
Definir responsável, evidência e critério de reabertura para cada caso.
Define an owner, evidence, and reopening criterion for each case.
36-40: Entregar matriz PT ou EN com observações e trabalho pendente.
Deliver a PT or EN matrix with observations and remaining work.
Não afirmar entrega externa, recuperação regional ou autenticação real.
Do not claim external delivery, regional recovery, or real authentication.
E1 confirma versão 2 e uma intenção de outbox. E1 repetido não acrescenta efeitos; E0 versão 1 fica registado sem regredir o objeto.
Armadilhas comuns
Assumir execução única universal, ordenar por assinatura, deduplicar só por tipo ou confundir uma linha de outbox com entrega confirmada.
Tópicos relacionados: Pedidos e resultados · Cache e paginação · Alterações concorrentes e recuperação verificável
A evidência local deve demonstrar identidade, atomicidade e recuperação; cada sistema externo precisa de um contrato de entrega observável.
Referência: Receive Stripe events in your webhook endpoint · HTTP semantics RFC9110; OpenAPI3.2.1; selected primary standards and provider contracts consulted2026-09-30