Skip to content

E-commerce Checkout Example

A complete checkout flow combining sequential and parallel steps.

The Scenario

  1. Validate Order: Basic checks.
  2. Parallel Preparation:
    • Calculate Shipping.
    • Check Fraud Status.
    • Check Loyalty Points.
  3. Process Payment: Main sequential step.
  4. 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.

Released under the MIT License.