PHPackages                             webrek/saga - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. webrek/saga

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

webrek/saga
===========

Orchestration-based sagas for PHP: run multi-step processes and roll them back with per-step compensations when one fails. Framework-agnostic core with an optional Laravel bridge.

v1.0.0(yesterday)00MITPHPPHP ^8.2CI passing

Since Jun 29Pushed yesterdayCompare

[ Source](https://github.com/webrek/saga)[ Packagist](https://packagist.org/packages/webrek/saga)[ Docs](https://github.com/webrek/saga)[ RSS](/packages/webrek-saga/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (10)Versions (2)Used By (0)

Saga
====

[](#saga)

[![Última versión](https://camo.githubusercontent.com/3dab67061fc02765719fdf656e10aa22e4a7f1cf8220a19b50eaf5c48a7f8b48/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f7461672f77656272656b2f736167613f736f72743d73656d766572266c6162656c3d76657273692543332542336e267374796c653d666c61742d737175617265)](https://github.com/webrek/saga/releases)[![Tests](https://camo.githubusercontent.com/3cdd3b84a493aabd5074fa1881b79e3b530956b5b8ad3d6c9a3e5c72e316bec7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f77656272656b2f736167612f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/webrek/saga/actions/workflows/tests.yml)[![PHP](https://camo.githubusercontent.com/2195866c8c0e50a0cac338d708a9c7056b9681de027de3ac357d3fd4f93c55a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e322d3737376262343f7374796c653d666c61742d737175617265)](https://php.net)[![Licencia](https://camo.githubusercontent.com/b36f7c4bc633cd63ef426a3a0053919ef89fadfbb986d8d3452071516f6ee430/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f77656272656b2f736167613f7374796c653d666c61742d737175617265)](LICENSE)

Ejecuta procesos de **varios pasos** y, si uno falla a la mitad, **deshace los anteriores** con su compensación — en orden inverso. El patrón saga, para cuando una operación toca varios servicios y no hay una transacción de base de datos que los abarque a todos.

Un **núcleo independiente de framework** (solo PHP) con un **puente opcional para Laravel** (bitácora en Eloquent, eventos, *facade*).

```
use Webrek\Saga\Laravel\Facades\Saga;
use Webrek\Saga\SagaContext;

$resultado = Saga::for('checkout', ['order_id' => 42])
    ->step('cobrar',
        fn (SagaContext $c) => $c->set('cargo', $pago->charge($c['order_id'])),
        compensate: fn (SagaContext $c) => $pago->refund($c['cargo']))
    ->step('apartar',
        fn (SagaContext $c) => $inventario->reserve($c['order_id']),
        compensate: fn (SagaContext $c) => $inventario->release($c['order_id']))
    ->step('enviar',
        fn (SagaContext $c) => $envios->create($c['order_id']))   // si esto falla…
    ->run();

// …se libera el inventario y se reembolsa el cargo, automáticamente.
$resultado->isCompleted();   // false
$resultado->status;          // SagaStatus::Compensated
```

Completa el **cuarteto de resiliencia** de webrek: entrada ([idempotency](https://github.com/webrek/laravel-idempotency)) · salida ([outbox](https://github.com/webrek/laravel-outbox)) · dependencias ([circuit-breaker](https://github.com/webrek/laravel-circuit-breaker)) · y **coordinación** (este).

Instalación
-----------

[](#instalación)

```
composer require webrek/saga
```

En Laravel, el *service provider* se descubre solo. Publica la migración de la bitácora:

```
php artisan vendor:publish --tag=saga-migrations
php artisan migrate
php artisan vendor:publish --tag=saga-config   # opcional
```

Cómo corre
----------

[](#cómo-corre)

Los pasos se ejecutan **en orden**. Un `SagaContext` (un saco de datos) se pasa a cada paso: lo que un paso escribe, el siguiente —y las compensaciones— lo leen.

Si un paso lanza una excepción, los pasos ya completados se **compensan en orden inverso** y la saga termina con uno de tres estados:

EstadoSignificado`Completed`Todos los pasos corrieron bien.`Compensated`Un paso falló y todo lo anterior se deshizo limpiamente.`CompensationFailed`Un paso falló **y** una compensación también — quedó a medias, requiere intervención manual.El resultado nunca traga la excepción original (`$resultado->failure`), y los estados `CompensationFailed` son justo los que conviene vigilar (`$resultado->needsAttention()`).

La bitácora (Laravel)
---------------------

[](#la-bitácora-laravel)

Cada corrida se registra en la tabla `sagas`: nombre, estado, pasos completados, contexto, paso que falló y errores de compensación. Es tu rastro de auditoría y, sobre todo, la forma de encontrar las sagas cuya compensación falló. Cada corrida también dispara un evento (`SagaCompleted`, `SagaCompensated`, `SagaCompensationFailed`).

Desactívala con `'journal' => false` en la configuración.

Sin Laravel
-----------

[](#sin-laravel)

```
use Webrek\Saga\{Saga, SagaRunner, SagaContext};

$saga = new Saga(new SagaRunner);   // sin eventos ni bitácora
$resultado = $saga->for('checkout', ['order_id' => 42])
    ->step('cobrar', $accion, compensate: $compensacion)
    ->run();
```

Para eventos o persistencia propios, implementa `Webrek\Saga\Contracts\EventDispatcher`y `Webrek\Saga\Contracts\SagaStore` y pásalos al `SagaRunner`.

Alcance
-------

[](#alcance)

Es una saga de **orquestación síncrona, en proceso**: corre dentro de tu petición o tu *job*. No es un *two-phase commit* ni reintenta pasos por sí sola — si necesitas reintentos, combínalo con la cola de Laravel o con [webrek/laravel-circuit-breaker](https://github.com/webrek/laravel-circuit-breaker)dentro de un paso. Las compensaciones deben ser idempotentes.

Pruebas
-------

[](#pruebas)

```
composer test
```

La suite del núcleo (`tests/Unit`) corre sin framework; la de Laravel (`tests/Feature`) ejercita la bitácora de Eloquent.

Contribuir
----------

[](#contribuir)

Consulta [CONTRIBUTING.md](CONTRIBUTING.md). Corre `make check` antes de abrir un *pull request*.

Seguridad
---------

[](#seguridad)

Reporta vulnerabilidades a través del [formulario de avisos de seguridad](https://github.com/webrek/saga/security/advisories/new), no como *issues* públicos. Consulta [SECURITY.md](SECURITY.md).

Licencia
--------

[](#licencia)

Licencia MIT (MIT). Consulta [LICENSE](LICENSE).

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7d8deca81629993819087597b5ad7695976b02e3d014f038e26e985f35f569de?d=identicon)[webrek](/maintainers/webrek)

---

Top Contributors

[![webrek](https://avatars.githubusercontent.com/u/5001338?v=4)](https://github.com/webrek "webrek (1 commits)")

---

Tags

compensationdistributed-transactionslaravelphpprocess-managerresiliencesagaphplaravelorchestrationprocess managerresiliencesagacompensationdistributed-transactions

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/webrek-saga/health.svg)

```
[![Health](https://phpackages.com/badges/webrek-saga/health.svg)](https://phpackages.com/packages/webrek-saga)
```

###  Alternatives

[amranidev/laracombee

Recommendation system for laravel

11537.9k1](/packages/amranidev-laracombee)[yieldstudio/tailwind-merge-php

Merge Tailwind CSS classes without style conflicts

4974.6k1](/packages/yieldstudio-tailwind-merge-php)[wujunze/money-wrapper

MoneyPHP Wrapper

103.8k](/packages/wujunze-money-wrapper)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
