Skip to content

Workflow Definitions

Workflow definitions are JSON structures stored in the database that describe the steps, transitions, and behavior of a workflow.

Definition Schema

php
[
    'name' => 'order_processing',        // Required: workflow name
    'initial_step' => 'process_order',   // Required: first step to execute
    'steps' => [                         // Required: map of step definitions
        'step_name' => [
            'type' => 'action',  // Required: step type
            'handler' => 'handler_name',  // Type-specific config
        ],
    ],
    'transitions' => [                 // Required: map of step transitions
        'step_name' => 'next_step',    // Simple: always go to next_step
        // OR
        'step_name' => [               // Conditional: route by result
            'true' => 'step_a',
            'false' => 'step_b',
        ],
    ],
]

Steps

Each step has a type that determines how it executes. Built-in types:

Action

Executes a registered action handler:

php
'process_payment' => [
    'type' => 'action',
    'handler' => 'process_payment',                      // Registry name (preferred)
    // OR
    'handler' => 'App\\Actions\\ProcessPayment',         // Class with handle() method
]

The handler receives an ExecutionContext and returns an array that gets merged into the workflow's state.

Action steps can include additional configuration keys that the handler reads via getStepConfig():

php
'send_email' => [
    'type' => 'action',
    'handler' => 'send_email',
    'template' => 'order-confirmation',  // Custom config
    'subject' => 'Your order is confirmed',
]

If the handler implements DefinesParameters, required parameters are validated at definition time. See Action Parameters for details.

Conditional

Evaluates a registered conditional handler and branches the workflow:

php
'check_amount' => [
    'type' => 'conditional',
    'handler' => 'is_high_value',   // Registered conditional name
    'threshold' => 1000,            // Optional step config for the handler
]

The handler must implement the Conditional interface. Conditionals route via 'true'/'false' in transitions. See Conditional Step Type for details.

Transitions

Transitions define the flow between steps.

Simple Transitions

A step always goes to the same next step:

php
'transitions' => [
    'process_order' => 'check_amount',
    'fulfill_order' => 'completed',
]

Conditional Transitions

Route based on a step's result:

php
'transitions' => [
    'check_amount' => [
        'true' => 'high_value_processing',
        'false' => 'fulfill_order',
    ],
]

Terminal Steps

Two special step names end the workflow:

  • 'completed' - Marks the instance as successfully completed
  • 'failed' - Marks the instance as failed

Retry Policies

Steps can define retry behavior for transient failures:

php
'process_payment' => [
    'type' => 'action',
    'handler' => 'charge_card',
    'retry' => [
        'max_attempts' => 3,
        'backoff' => 'exponential',  // 'fixed', 'linear', or 'exponential'
        'delay_seconds' => 5,        // Base delay between retries
    ],
]

See Retry Policies for details.

Complete Example

php
Workflow::create([
    'name' => 'order_processing',
    'event_name' => 'order_submitted',
    'definition' => [
        'name' => 'order_processing',
        'initial_step' => 'process_order',
        'steps' => [
            'process_order' => [
                'type' => 'action',
                'handler' => 'process_order',
            ],
            'check_amount' => [
                'type' => 'conditional',
                'handler' => 'is_high_value',
                'threshold' => 1000,
            ],
            'high_value_processing' => [
                'type' => 'action',
                'handler' => 'high_value_processing',
            ],
            'fulfill_order' => [
                'type' => 'action',
                'handler' => 'fulfill_order',
            ],
        ],
        'transitions' => [
            'process_order' => 'check_amount',
            'check_amount' => [
                'true' => 'high_value_processing',
                'false' => 'fulfill_order',
            ],
            'high_value_processing' => 'fulfill_order',
            'fulfill_order' => 'completed',
        ],
    ],
    'is_active' => true,
]);