E-commerce Checkout Example
A complete checkout flow combining sequential and parallel steps.
The Scenario
- Validate Order: Basic checks.
- Parallel Preparation:
- Calculate Shipping.
- Check Fraud Status.
- Check Loyalty Points.
- Process Payment: Main sequential step.
- Finalize Order: Mark as ready for shipping.
The Code
ts
import { create } from "@eddiecbrl/orchestrix";
const checkoutFlow = create("ecommerce-checkout")
.step("validate", (ctx) => {
if (ctx.input.items.length === 0) throw new Error("Cart is empty");
})
.parallel("prepare", [
{
name: "calculate-shipping",
fn: async (ctx) => {
const cost = await shippingProvider.calculate(ctx.input.address);
ctx.set("shippingCost", cost);
}
},
{
name: "fraud-check",
fn: async (ctx) => {
const score = await fraudService.getScore(ctx.input.userId);
if (score > 80) throw new Error("Fraud suspected");
}
},
{
name: "check-loyalty",
fn: async (ctx) => {
const points = await loyaltyService.getPoints(ctx.input.userId);
ctx.set("availablePoints", points);
}
}
])
.step("process-payment", async (ctx) => {
const shipping = ctx.get<number>("shippingCost");
const total = ctx.input.subtotal + shipping;
await paymentService.charge(ctx.input.userId, total);
}, {
retries: 2,
compensate: async (ctx) => {
// Refund if next steps fail
await paymentService.refund(ctx.input.userId);
}
})
.step("finalize", async (ctx) => {
await db.orders.complete(ctx.input.orderId);
});
const result = await checkoutFlow.run({
orderId: "ord_abc",
userId: "user_123",
items: [...],
address: "...",
subtotal: 100
});Highlights
- Parallel Efficiency: Shipping, fraud, and loyalty checks run at the same time, reducing the total checkout time.
- Fail-Fast: If the fraud check fails, the flow stops immediately before any payment is processed.
- Data Sharing: The shipping cost calculated in the parallel block is used later in the sequential payment step.