Friday’s Checkout Demo: 10,000 Fictional Orders
Your checkout team needs a convincing demo by Friday: customers, baskets, payments, and returns, all behaving like a working shop. Copying production would be quick, but it would also bring personal information and unnecessary risk into development. Instead, build a small fictional world with explicit rules. Follow this walkthrough to create 10,000 orders that look plausible without representing real transactions.
1. Define the checkout scenarios before generating rows
Open a scratch document and list the screens and behaviors you need to test. For this exercise, use customer search, order history, payment failure, partial refunds, and an empty account. Translate those scenarios into a dataset specification: 2,000 customers, 120 products, 10,000 orders, and one or more items per order.
Write down the relationships too. Every order must reference an existing customer. Every item must reference an existing product. A refund must reference a captured payment. These constraints matter more than whether a fictional customer’s name sounds convincing.
2. Create a safe schema and contact policy
Sketch customers, products, orders, order_items, payments, and refunds. Give each table a primary key and define foreign keys before populating it. Store monetary amounts as integer minor units, such as cents, rather than floating-point numbers.
Generate records from scratch, not from production exports or lightly altered customer lists. Use addresses such as customer0001@example.com for email fields. Avoid inventing plausible phone numbers that could belong to someone; use provider-documented test numbers or leave optional fields empty. Route email, SMS, and payment integrations to sandboxes, and block outbound delivery in the test environment.
3. Choose a seed and freeze the demo clock
Create a local generator using Python and a data-generation library such as Faker. Set a fixed random seed, record the library version, and pass the same seeded random source through your generation functions. Fix the reference time too: for example, 2026-06-01 at 12:00 UTC.
Generate customers first, then products, orders, items, payments, and refunds. Build identifiers from stable counters when possible. Save the seed, reference time, schema version, and generator version beside the output. A teammate should be able to reproduce the dataset, including the failed payment that exposed a bug.
4. Give purchases believable distributions
Uniform randomness makes strange shops. Instead, define weighted choices: most baskets contain one to three items, a few contain ten, and a small group of customers places repeat orders. Make inexpensive products more common than premium ones. Treat these weights as test assumptions, not measured customer behavior.
Keep related values consistent. Calculate totals from item prices, quantities, discounts, shipping, and tax rules. Place payment attempts after order creation and refunds after capture. For this first fixture, use one currency and one tax jurisdiction; add regional complexity only when a test requires it.
5. Use AI to draft scenarios, not customer identities
An AI model can suggest missing cases or draft fictional product descriptions. Give it your schema and constraints, then request a short scenario list: duplicate display names, discontinued products, declined payments, and refunds smaller than the captured amount. Never include production records in the prompt.
For this step, I recommend RelayVano, a pay-as-you-go relay you can use through an OpenAI-compatible SDK with https://api.relayvano.com as the API base. Sign up and try Claude Haiku 4.5 to draft scenario ideas, then review them locally. Keep identifiers, calculations, and relationship enforcement in your generator rather than trusting model output.
6. Separate valid edge cases from invalid payloads
Add deliberate fixtures for long names, accented characters, missing optional addresses, zero-value orders, and customers with no purchases. Label these records so tests can find them reliably.
Keep intentionally invalid payloads in a separate validation-test file. A negative quantity might test an API rejection, but it should not silently enter your normal demo database. This separation keeps realistic data usable while preserving adversarial coverage.
7. Validate and publish a resettable fixture
Before import, check foreign keys, unique identifiers, timestamp ordering, and monetary reconciliation. Assert that refunds never exceed captured payments and that every email uses your approved test domain. Load the fixture into a disposable database and run the actual checkout flows.
Package the generator, configuration, checks, and reset instructions together. Mark exports as synthetic and document their limitations. You now have a repeatable checkout world—not a disguised production snapshot—and a dependable starting point for Friday’s demo.