Laravel SISP 0.7 makes checkout state visible
The 0.7 release turns Laravel SISP from a payment redirect helper into checkout infrastructure with memory.
Laravel SISP 0.7 is not a bigger payment helper. It is the release where the package starts treating checkout as infrastructure.
That distinction matters because the easy part of SISP is sending the payment request. The hard part starts after the redirect. A customer pays, the browser returns, the callback lands, an invoice changes state, a retry may need to happen, a refund may be partial, and a pending transaction may sit in the middle long enough to make everyone nervous.
A thin wrapper can hide that for a demo. A production package cannot.
Payments need memory
The feature I care about most in 0.7 is not the most visible one. It is transaction audit logs.
Checkout has too many transitions to trust the final value alone. When a transaction moves from pending to completed, failed, refunded, or back through a recovery path, the useful question is not only “what is the status now?” The useful question is “what changed, from where, and why?”
The new logging action records changed attributes, old values, new values, and the source context for each transaction update.
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'],
]);
That is small code with a large consequence. It gives the package a memory. When support, finance, or engineering asks what happened to a payment, the answer no longer has to be reconstructed from controller flow and database snapshots.
Refunds are not a boolean
0.7 also adds partial refunds. That changes the shape of the model.
Before that, a refund path can be treated as a terminal operation: paid becomes refunded. Partial refunds break that shortcut. A transaction can remain completed while part of its balance has already moved back to the customer. The package has to track the refundable balance, append refund history, and only mark the whole transaction as refunded when the remaining balance reaches 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(),
])
);
That tradeoff makes the package heavier. It also makes it more honest. Real payment systems do not live in clean binary states. They live in balances, histories, retries, and exceptions.
Pending is a production state
The other 0.7 move is reconciliation through the facade.
Pending is not an error. It is a state that needs a recovery path. If the callback fails, arrives late, or leaves the local transaction behind the provider’s truth, the application needs a way to ask SISP again and apply the answer without building that flow from scratch.
src/Facades/Sisp.php
* @method static TransactionStatusResponse queryTransactionStatus(Transaction|string $transaction)
* @method static Transaction reconcileTransactionStatus(Transaction $transaction)
The implementation keeps the rule narrow: only pending transactions are reconciled, failed status API calls leave the transaction unchanged, and successful responses update both transaction state and invoice state.
That is the pattern I want from this package. Do the SISP-specific work once. Expose a Laravel-shaped API. Keep the application code focused on the business flow instead of payment plumbing.
The obvious counter
The counterargument is fair: this is more than a wrapper. A wrapper would be smaller. It would install faster in your head.
But checkout is not a single request. It is an operational surface. If the package owns request building but leaves audit history, invoice state, refunds, and reconciliation scattered across application code, it has moved the hard work instead of solving it.
The 0.7 line is also public now. Packagist shows 661 installs, 15 GitHub stars, and v0.7.0 published on 2026-05-31. That is still early, but it is enough usage to justify treating the package like infrastructure instead of a weekend script.
The line to remember
A checkout package is not done when the redirect works. It is done when the ugly states have somewhere to live.