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.
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.