Orchestrate high-value order fulfillment
Validate an order, check inventory and fraud concurrently, route only risky orders to a durable human decision, and write one auditable outcome.
This is not a chain of disconnected API boxes. It is one readable program with input validation, bounded concurrency, retries, a conditional human wait, application data, and a final business result.
The workflow at a glance
Order webhook
→ Calculate total
→ [Reserve inventory ∥ Screen fraud]
→ Risky? ─ yes → Human approval
└ no → Automatic approval
→ Record outcome in PostgreSQL
→ Publish order.fulfillment-readyThe workflow
<woml>
<workflow
id="order-fulfillment"
name="Order fulfillment"
description="Validate, review, and admit customer orders for fulfillment."
version="1.0.0"
>
<config concurrency="20" rate-limit="300/1m" timeout="48h" queue="orders" />
<triggers>
<webhook
id="newOrder"
path="/webhooks/orders"
method="POST"
auth="bearer"
secret="{{secrets.ORDER_WEBHOOK_TOKEN}}"
>
<schema>
{
"type": "object",
"required": ["orderId", "customerId", "items"],
"properties": {
"orderId": { "type": "string" },
"customerId": { "type": "string" },
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["sku", "price", "quantity"],
"properties": {
"sku": { "type": "string" },
"price": { "type": "number", "minimum": 0 },
"quantity": { "type": "integer", "minimum": 1 }
}
}
}
}
}
</schema>
</webhook>
</triggers>
<steps>
<step id="priceOrder" name="Calculate order total">
<script>
const total = context.payload.items.reduce(
(sum, item) => sum + item.price * item.quantity,
0
);
return {
orderId: context.payload.orderId,
customerId: context.payload.customerId,
total: Number(total.toFixed(2)),
items: context.payload.items
};
</script>
</step>
<parallel id="checks" name="Run fulfillment checks" concurrency="2" on-error="wait-all">
<step id="reserveInventory" name="Reserve inventory" retry="3" retry-backoff="exponential">
<script>
const response = await services.http.request({
method: "POST",
url: "https://inventory.example.com/reservations",
headers: { authorization: `Bearer ${secrets.INVENTORY_API_TOKEN}` },
json: {
orderId: context.steps.priceOrder.orderId,
items: context.steps.priceOrder.items
},
idempotency: {
header: "Idempotency-Key",
value: attempt.idempotencyKey
}
}, { name: "reserve-order-inventory" });
return response.data;
</script>
</step>
<step id="screenFraud" name="Screen fraud" retry="3" retry-backoff="exponential">
<script>
const response = await services.http.request({
method: "POST",
url: "https://risk.example.com/orders/screen",
headers: { authorization: `Bearer ${secrets.RISK_API_TOKEN}` },
json: {
orderId: context.steps.priceOrder.orderId,
customerId: context.steps.priceOrder.customerId,
amount: context.steps.priceOrder.total
}
}, { name: "screen-order-fraud" });
return {
score: response.data.score,
requiresReview: response.data.score >= 70
};
</script>
</step>
</parallel>
<choose id="decision" name="Select approval route">
<when test="{{context.steps.screenFraud.requiresReview}}">
<approval
id="reviewRiskyOrder"
name="Review high-risk order"
description="A fraud analyst must approve or reject this order."
timeout="24h"
on-timeout="reject"
>
<notify>
<slack
channels="#order-approvals"
bot-token="{{secrets.SLACK_BOT_TOKEN}}"
app-token="{{secrets.SLACK_APP_TOKEN}}"
/>
</notify>
<when-approved>
<step id="approveRiskyOrder"><script>return { decision: "approved", source: "analyst" };</script></step>
</when-approved>
<when-rejected>
<step id="rejectRiskyOrder"><script>return { decision: "rejected", source: "analyst" };</script></step>
</when-rejected>
</approval>
<result value="{{context.steps.reviewRiskyOrder}}" />
</when>
<otherwise>
<step id="approveSafeOrder" name="Approve safe order">
<script>return { decision: "approved", source: "policy" };</script>
</step>
<result value="{{context.steps.approveSafeOrder}}" />
</otherwise>
</choose>
<step id="recordOrder" name="Record fulfillment decision" retry="3">
<script>
const db = services.db({
driver: "postgres",
connection: secrets.POSTGRES_URL
});
await db.insert({
table: "order_decisions",
values: {
order_id: context.steps.priceOrder.orderId,
customer_id: context.steps.priceOrder.customerId,
amount: context.steps.priceOrder.total,
risk_score: context.steps.screenFraud.score,
decision: context.steps.decision.decision,
reservation_id: context.steps.reserveInventory.reservationId
}
}, { name: "record-order-decision" });
return {
orderId: context.steps.priceOrder.orderId,
decision: context.steps.decision.decision,
total: context.steps.priceOrder.total
};
</script>
</step>
<step id="announceOutcome" name="Publish fulfillment outcome">
<script>
await services.events.emit(
"order.fulfillment-decided",
context.steps.recordOrder,
{ name: "publish-order-outcome" }
);
return context.steps.recordOrder;
</script>
</step>
</steps>
</workflow>
</woml>Configure and run it
woml secrets set ORDER_WEBHOOK_TOKEN
woml secrets set INVENTORY_API_TOKEN
woml secrets set RISK_API_TOKEN
woml secrets set POSTGRES_URL
woml secrets set SLACK_BOT_TOKEN
woml secrets set SLACK_APP_TOKEN
woml check order-fulfillment.woml
woml run order-fulfillment.womlReplace the example inventory and risk URLs with your APIs, then use the curl command WOML prints at startup.
Why this shows WOML's range
The workflow remains readable while combining code-level pricing logic, concurrent managed effects, external idempotency, a conditional durable approval, SQL persistence, and event fan-out. Every run and retry remains inspectable without spreading the process across a visual canvas and several hidden code nodes.