Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/alex-pizza-assistant/llms.txt

Use this file to discover all available pages before exploring further.

Once all pizzas are added and the customer has chosen carry out or delivery, the app asks a single question: “Will you be paying with cash or card?” The answer to this question determines which of two distinct checkout paths the conversation follows. The cash path ends the order immediately with a short confirmation message. The card path collects three card fields, shows a simulated approval, and — for delivery orders only — asks for an optional driver tip before completing the order.

Cash Checkout

When paymentMethod normalizes to "cash", advanceStep() calls finishOrder() immediately. No card fields are ever shown. The bot’s response message in respondToAnswer() depends on the order method:
  • Delivery — the bot says: “Your driver will collect your cash payment upon delivery.”
  • Carry out — the bot says: “Please pay for your order when you pick it up.”
if (id === "paymentMethod" && value === "cash") {
  if (order.method === "delivery") {
    addBubble("Your driver will collect your cash payment upon delivery.", "bot");
  } else {
    addBubble("Please pay for your order when you pick it up.", "bot");
  }
}
After the confirmation bubble is added, advanceStep() calls finishOrder() and the session ends.

Card Checkout

When paymentMethod normalizes to "card", the step pointer advances to cardNumber and three card-specific steps run in sequence.
1

cardNumber

The customer enters their credit or debit card number. Leading/trailing spaces and hyphens are stripped by normalizeValue() before validation. The validator requires 13–19 digits after stripping: /^\d{13,19}$/.Only the last four digits are stored. saveAnswer() sets order.cardLastFour = value.slice(-4). The full card number is never saved to the order object.
2

cardExpiration

The customer enters the card expiration date in MM/YY format. The validator is /^(0[1-9]|1[0-2])\/\d{2}$/, which requires a valid two-digit month (01–12) followed by a two-digit year. The expiration date is not stored on the order object — it is validated and discarded.
3

cardCvv

The customer enters the 3 or 4 digit security code. The validator is /^\d{3,4}$/. Like the expiration date, the CVV is not stored after validation. Once cardCvv passes, the bot adds a simulated card approval bubble:
if (id === "cardCvv") {
  addBubble(
    `Card payment approved for the card ending in ${order.cardLastFour}.`,
    "bot"
  );
}
Alex Pizza Assistant is a front-end demo only. No real payment processing occurs. Card numbers, expiration dates, and CVV codes are never transmitted to any server and are not stored anywhere beyond the browser session. Only the last four digits of the card number are retained in the order object, solely for display in the approval message.

Card field validation reference

FieldValidatorExample valid input
cardNumber13–19 digits after stripping spaces/hyphens4111 1111 1111 1111
cardExpiration/^(0[1-9]|1[0-2])\/\d{2}$/09/27
cardCvv/^\d{3,4}$/123 or 1234

Driver Tip

The tip step is only reached when both of the following are true: order.method === "delivery" and order.paymentMethod === "card". advanceStep() checks order.method immediately after cardCvv to decide whether to route to tip or call finishOrder() directly.
} else if (id === "cardCvv") {
  if (order.method === "delivery") {
    currentStep = getStepIndex("tip");  // ask for tip
  } else {
    finishOrder();                      // carry out — end after CVV
    return;
  }
}
The tip prompt reads: “Would you like to add a tip for your delivery driver? Enter a dollar amount, or enter 0 for no tip. 100% of tips are kept by the driver.” Tip input is validated with isValidMoney():
function isValidMoney(value) {
  return /^\$?\d+(\.\d{1,2})?$/.test(value.trim());
}
This accepts plain integers (3), decimals up to two places (3.50), and values prefixed with a dollar sign ($3.50). An entry of 0 is also accepted — no tip is a valid answer. The normalizeValue() function strips the $ sign and casts the result to a Number before it is stored as order.tip, which is then added to the grand total in calculateTotals().
The tip step is skipped entirely for carry out orders regardless of payment method, and for delivery orders that are paid with cash. The cash delivery confirmation message already informs the customer that the driver will collect payment — asking for a card tip in that scenario would be contradictory. Only delivery + card orders reach the tip question.

Payment Normalization

The paymentMethod step accepts a wider range of natural inputs than the two canonical values "cash" and "card". normalizeValue() collapses all variants:
if (id === "paymentMethod")
  return normalized.includes("card") || ["credit", "debit"].includes(normalized)
    ? "card"
    : "cash";
Raw inputNormalized to
cash"cash"
card"card"
credit"card"
debit"card"
credit card"card"
debit card"card"
Any input that contains the word "card" or is exactly "credit" or "debit" resolves to "card". Everything else — in practice only "cash" — stays as-is. The branching logic in advanceStep() exclusively checks for the string "card" to route to card fields, so this normalization step is essential for all credit/debit variants to work correctly.

Build docs developers (and LLMs) love