AkiraAkira.dev
4 min de leitura

Laravel SISP 0.7 torna o estado do checkout visível

A release 0.7 transforma o Laravel SISP de ajudante de redirect de pagamento em infraestrutura de checkout com memória.

também em EN FR

O Laravel SISP 0.7 não é um ajudante de pagamento maior. É a release onde o pacote começa a tratar o checkout como infraestrutura.

Essa distinção importa porque a parte fácil do SISP é enviar o pedido de pagamento. A parte difícil começa depois do redirect. Um cliente paga, o browser regressa, o callback aterra, uma fatura muda de estado, um retry pode ter de acontecer, um reembolso pode ser parcial, e uma transação pendente pode ficar no meio tempo suficiente para deixar toda a gente nervosa.

Um wrapper fino consegue esconder isso numa demo. Um pacote de produção não consegue.

Os pagamentos precisam de memória

A feature que mais me importa na 0.7 não é a mais visível. São os logs de auditoria de transações.

O checkout tem transições a mais para confiar só no valor final. Quando uma transação passa de pendente para concluída, falhada, reembolsada, ou de volta por um caminho de recuperação, a pergunta útil não é só “qual é o estado agora?”. A pergunta útil é “o que mudou, de onde, e porquê?”.

A nova action de logging regista os atributos alterados, os valores antigos, os valores novos e o contexto de origem de cada atualização de transação.

src/Actions/LogTransactionChangesAction.php

$transaction->logs()->create([
    'source' => TransactionLogContext::current(),
    'changed_attributes' => $changes['changed_attributes'],
    'old_values' => $changes['old_values'],
    'new_values' => $changes['new_values'],
]);

É código pequeno com uma consequência grande. Dá ao pacote uma memória. Quando o suporte, as finanças ou a engenharia perguntam o que aconteceu a um pagamento, a resposta deixa de ter de ser reconstruída a partir do fluxo do controller e de snapshots da base de dados.

Reembolsos não são um booleano

A 0.7 também adiciona reembolsos parciais. Isso muda a forma do modelo.

Antes disso, um caminho de reembolso podia ser tratado como operação terminal: pago torna-se reembolsado. Os reembolsos parciais partem esse atalho. Uma transação pode continuar concluída enquanto parte do seu saldo já foi devolvida ao cliente. O pacote tem de seguir o saldo reembolsável, acrescentar histórico de reembolsos, e só marcar a transação inteira como reembolsada quando o saldo restante chega a zero.

src/Actions/RefundTransactionAction.php

$remainingThousandths = $refundableThousandths - $refundThousandths;

TransactionLogContext::run(
    'refund',
    fn (): bool => $transaction->update([
        'status' => $remainingThousandths === 0 ? TransactionStatus::refunded->value : TransactionStatus::completed->value,
        'merchant_response' => "{$reason}::{$refundAmount}",
        'payload' => $payload,
        'refunded_at' => now(),
    ])
);

Esse compromisso torna o pacote mais pesado. Também o torna mais honesto. Sistemas de pagamento reais não vivem em estados binários limpos. Vivem em saldos, históricos, retries e exceções.

Pendente é um estado de produção

O outro movimento da 0.7 é a reconciliação através da facade.

Pendente não é um erro. É um estado que precisa de um caminho de recuperação. Se o callback falha, chega atrasado, ou deixa a transação local atrás da verdade do provedor, a aplicação precisa de uma forma de perguntar ao SISP de novo e aplicar a resposta sem construir esse fluxo do zero.

src/Facades/Sisp.php

 * @method static TransactionStatusResponse queryTransactionStatus(Transaction|string $transaction)
 * @method static Transaction reconcileTransactionStatus(Transaction $transaction)

A implementação mantém a regra estreita: só transações pendentes são reconciliadas, chamadas de API com estado falhado deixam a transação inalterada, e respostas bem-sucedidas atualizam tanto o estado da transação como o da fatura.

É esse o padrão que quero deste pacote. Fazer o trabalho específico do SISP uma vez. Expor uma API com forma de Laravel. Manter o código da aplicação focado no fluxo de negócio em vez da canalização de pagamentos.

O contra-argumento óbvio

O contra-argumento é justo: isto é mais do que um wrapper. Um wrapper seria mais pequeno. Instalava-se mais depressa na tua cabeça.

Mas o checkout não é um único pedido. É uma superfície operacional. Se o pacote é dono da construção do pedido mas deixa o histórico de auditoria, o estado da fatura, os reembolsos e a reconciliação espalhados pelo código da aplicação, moveu o trabalho difícil em vez de o resolver.

A linha 0.7 também é pública agora. O Packagist mostra 661 instalações, 15 estrelas no GitHub, e a v0.7.0 publicada a 2026-05-31. Ainda é cedo, mas é uso suficiente para justificar tratar o pacote como infraestrutura em vez de um script de fim de semana.

A linha para guardar

Um pacote de checkout não está pronto quando o redirect funciona. Está pronto quando os estados feios têm onde viver.

share
Caption copied — paste in the compose box