A production-ready order processing system built with Temporal.io that demonstrates the Saga pattern for distributed transaction management.
- Overview
- Architecture
- Setup
- Running the Application
- Testing
- Configuration
- Key Features
- Production Considerations
- Deployment
- Resources
- License
This workflow orchestrates a complete order processing flow including:
- Inventory reservation
- Payment processing
- Shipment creation
- Automatic compensation on failures (Saga pattern)
- Order cancellation support via signals
- Real-time status queries
Orchestrates the order processing with automatic compensation:
- Reserve Inventory → Compensate: Release inventory
- Process Payment → Compensate: Refund payment
- Create Shipment → Compensate: Cancel shipment
- Complete Order
All external I/O operations are implemented as activities:
reserveInventory- Reserve stock for order itemsreleaseInventory- Release reserved inventory (compensation)processPayment- Process payment through payment gatewayrefundPayment- Refund payment (compensation)createShipment- Create shipment with shipping providercancelShipment- Cancel shipment (compensation)notifyCustomer- Send notifications (email/SMS)updateOrderStatus- Update order status in database
- Signal:
cancelOrder- Cancel an in-progress order - Query:
orderStatus- Get real-time order status
- Node.js 16+
- Temporal Server running locally or Temporal Cloud account
npm installtemporal server start-devOr use Docker:
docker run -p 7233:7233 -p 8233:8233 temporalio/auto-setup:latestnpm run buildThe worker processes workflows and activities:
npm run workerStart an order:
npm run client startCancel an order:
npm run client cancel ORD-1234567890 "Customer requested cancellation"Check order status:
npm run client status ORD-1234567890For a browser-based interface, start the web server:
npm run webThe web interface will be available at http://localhost:3000
- Create Orders: Submit new orders through a web form
- View Order Status: Check the status of any order by ID
- Cancel Orders: Send cancellation signals to running workflows
- List Orders: View all recent orders
The web server exposes a REST API:
POST /api/orders- Create a new orderGET /api/orders/:orderId- Get order statusPOST /api/orders/:orderId/cancel- Cancel an orderGET /api/orders- List recent ordersGET /health- Health check
Example: Create an order via API
curl -X POST http://localhost:3000/api/orders \
-H "Content-Type: application/json" \
-d '{
"customerId": "CUST-123",
"items": [
{"productId": "PROD-001", "quantity": 2, "price": 29.99}
],
"paymentDetails": {
"paymentMethodId": "pm_test_123",
"amount": 59.98,
"currency": "USD"
},
"shippingAddress": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zipCode": "94105",
"country": "USA"
}
}'Run the test suite:
npm testTests cover:
- Successful order processing
- Payment failure compensation
- Order cancellation via signal
- Status queries
TEMPORAL_ADDRESS- Temporal server address (default:localhost:7233)TEMPORAL_NAMESPACE- Temporal namespace (default:default)
Activities are configured with exponential backoff:
retry: {
initialInterval: '1s',
backoffCoefficient: 2,
maximumInterval: '1 minute',
maximumAttempts: 3,
}- Activity timeout: 5 minutes
- Worker shutdown grace time: 30 seconds
Automatic compensation ensures data consistency:
try {
await reserveInventory();
await processPayment();
await createShipment();
} catch (error) {
// Compensate in reverse order
await cancelShipment();
await refundPayment();
await releaseInventory();
}All activities are designed to be idempotent using order IDs as idempotency keys.
Workflow code is deterministic:
- Uses
workflow.now()instead ofDate.now() - All I/O in activities
- No random values or external dependencies
- Non-retryable errors for business logic failures
- Retryable errors for transient failures
- Graceful degradation with notifications
Current activities contain placeholder implementations. Replace with:
-
Inventory Management
- Database queries for stock levels
- Distributed locking for reservations
- Reservation expiration handling
-
Payment Gateway
- Stripe/PayPal/Square integration
- 3DS authentication flows
- PCI compliance considerations
-
Shipping Provider
- FedEx/UPS/USPS API integration
- Address validation
- Label generation
-
Notifications
- Email service (SendGrid, SES)
- SMS service (Twilio)
- Push notifications
-
Database
- PostgreSQL/MySQL for order storage
- Transaction management
- Audit logging
- Enable Temporal Web UI: http://localhost:8233
- Add custom metrics and logging
- Set up alerts for workflow failures
- Run multiple workers for horizontal scaling
- Configure worker concurrency based on load
- Use task queue partitioning for high throughput
- Use TLS for Temporal Cloud connections
- Encrypt sensitive data in workflow state
- Implement authentication/authorization
- Audit trail for all transactions
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist ./dist
CMD ["node", "dist/worker.js"]Deploy workers as separate deployments:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-processing-worker
spec:
replicas: 3
template:
spec:
containers:
- name: worker
image: your-registry/order-worker:latest
env:
- name: TEMPORAL_ADDRESS
value: "temporal-frontend:7233"MIT