Order Processing
A multi-step order processing workflow with payment, fulfillment, and compensation (rollback). Demonstrates the saga pattern for distributed transactions.
Prerequisites: Workflows, Compensation & Sagas, Activities. What you'll learn: How to orchestrate multi-step business processes with automatic rollback.
The Pattern
- Validate the order
- Reserve inventory
- Charge payment
- Fulfill the order
- If any step fails, compensate (rollback) completed steps in reverse order
Workflow
workflow process_order v1 {
node validate = validate_order v1
node reserve = reserve_inventory v1
node charge = charge_payment v1
node fulfill = fulfill_order v1
node notify = send_confirmation v1
edge validate -> reserve
edge reserve -> charge
edge charge -> fulfill
edge fulfill -> notify
on compensated -> OrderResult {
return {
order_id: input.order_id,
status: "cancelled",
reason: compensation.reason
}
}
}
Activities with Compensation
Each activity defines what happens if it needs to be rolled back:
activity reserve_inventory v1 {
data reservation {
fetch warehouse.reserve {
items: input.items
}
}
apply(input: OrderInput) -> ReservationResult {
return {
reservation_id: reservation.id,
items: reservation.items
}
}
compensate {
fetch warehouse.release {
reservation_id: input.reservation_id
}
}
retry_policy {
max_attempts: 3
backoff: 1s
}
}
activity charge_payment v1 {
data charge {
fetch stripe.create_charge {
amount: input.total
currency: input.currency
customer_id: input.customer_id
}
}
apply(input: PaymentInput) -> ChargeResult {
return {
charge_id: charge.id,
status: charge.status
}
}
compensate {
fetch stripe.refund {
charge_id: input.charge_id
}
}
retry_policy {
max_attempts: 3
backoff: 2s
max_backoff: 30s
}
}
How Compensation Works
If fulfill_order fails after charge_payment and reserve_inventory have succeeded:
- The workflow engine detects the failure
- It calls
charge_payment.compensate(refund the charge) - It calls
reserve_inventory.compensate(release the reservation) - Compensation runs in LIFO order (last completed, first compensated)
- The workflow's
on compensatedblock returns the final result
See Also
- Compensation & Sagas -- Full compensation reference
- API Calls with Retries -- Retry patterns
- Approval Workflows -- Human-in-the-loop