Statefully Documentation

E-commerce Checkout

Multi-step checkout process with cart, shipping, and payment

Try It

Step through the checkout process from Cart to Confirmation. Notice how errors can occur and be recovered from.

E-commerce Checkout State Machine

State Diagram

Cart*
Empty Cart
Shipping
Payment
Processing
Confirmation
Payment Error

Preview

State Specification

Spec
Cart *
	checkout -> Shipping
	empty -> Empty Cart
Empty Cart
	browse -> Cart
Shipping
	continue -> Payment
	back -> Cart
Payment
	pay -> Processing
	back -> Shipping
Processing
	success -> Confirmation
	failure -> Payment Error
Confirmation
	done -> Cart
Payment Error
	retry -> Payment
	cancel -> Cart

Prototype Code

Prototype
[Cart]
  div.cart style="max-width: 400px; padding: 24px;":
    h2 style="margin-bottom: 16px;": "Your Cart"
    div.item style="padding: 12px; border: 1px solid #eee; margin-bottom: 8px;":
      span: "Product 1 - $29.99"
    div.item style="padding: 12px; border: 1px solid #eee; margin-bottom: 16px;":
      span: "Product 2 - $49.99"
    div.total style="font-weight: bold; margin-bottom: 16px;": "Total: $79.98"
    button @click=checkout style="width: 100%; padding: 12px; background: #000; color: #fff;": "Checkout"

[Empty Cart]
  div.empty style="text-align: center; padding: 48px;":
    p style="color: #666; margin-bottom: 16px;": "Your cart is empty"
    button @click=browse style="padding: 12px 24px;": "Continue Shopping"

[Shipping]
  div.shipping style="max-width: 400px; padding: 24px;":
    h2 style="margin-bottom: 16px;": "Shipping Address"
    input placeholder="Full Name" style="width: 100%; padding: 8px; margin-bottom: 8px; border: 1px solid #ccc;":
    input placeholder="Address" style="width: 100%; padding: 8px; margin-bottom: 8px; border: 1px solid #ccc;":
    input placeholder="City, State, ZIP" style="width: 100%; padding: 8px; margin-bottom: 16px; border: 1px solid #ccc;":
    div.buttons style="display: flex; gap: 8px;":
      button @click=back style="flex: 1; padding: 12px; border: 1px solid #ccc;": "Back"
      button @click=continue style="flex: 1; padding: 12px; background: #000; color: #fff;": "Continue"

[Payment]
  div.payment style="max-width: 400px; padding: 24px;":
    h2 style="margin-bottom: 16px;": "Payment"
    input placeholder="Card Number" style="width: 100%; padding: 8px; margin-bottom: 8px; border: 1px solid #ccc;":
    div style="display: flex; gap: 8px; margin-bottom: 16px;":
      input placeholder="MM/YY" style="flex: 1; padding: 8px; border: 1px solid #ccc;":
      input placeholder="CVC" style="flex: 1; padding: 8px; border: 1px solid #ccc;":
    div.buttons style="display: flex; gap: 8px;":
      button @click=back style="flex: 1; padding: 12px; border: 1px solid #ccc;": "Back"
      button @click=pay style="flex: 1; padding: 12px; background: #000; color: #fff;": "Pay $79.98"

[Processing]
  div.processing style="text-align: center; padding: 48px;":
    p: "Processing payment..."

[Confirmation]
  div.confirmation style="text-align: center; padding: 48px;":
    h2 style="color: #22c55e; margin-bottom: 16px;": "Order Confirmed!"
    p style="color: #666; margin-bottom: 16px;": "Thank you for your purchase."
    button @click=done style="padding: 12px 24px;": "Continue Shopping"

[Payment Error]
  div.error style="text-align: center; padding: 48px;":
    h2 style="color: #ef4444; margin-bottom: 16px;": "Payment Failed"
    p style="color: #666; margin-bottom: 16px;": "Your card was declined."
    div.buttons style="display: flex; gap: 8px; justify-content: center;":
      button @click=cancel style="padding: 12px 24px; border: 1px solid #ccc;": "Cancel"
      button @click=retry style="padding: 12px 24px; background: #000; color: #fff;": "Try Again"

Key Concepts

  • Linear flow - Cart → Shipping → Payment → Confirmation
  • Back navigation - Each step can go back to the previous
  • Error handling - Processing can fail and go to Payment Error
  • Recovery paths - Retry from error or cancel back to Cart
  • Edge case - Empty Cart is a separate state from Cart with items