The tree was a debranded snapshot of upstream taken around 2026-02-20, and upstream has moved about five months since. This replaces it with upstream master, mechanically re-derived: bin/debrand does the rename, and the pipeline and squashed migrations are restored from the shipped tree. Not a merge. The previous import replaced the tree wholesale in a single commit, so there is no shared content history to merge against. Reproducing the rename on the new tree is what actually converges. What survives: .hanzo/workflows, the Dockerfiles and bin/docker* entrypoints, compose files, LLM.md, and insights/migrations. The squashed initial migration is load-bearing — the live database records it by name, so upstream's ~918 individual migrations cannot come back. Nine products are dropped as unreferenced. Twenty-one more that we do not run are kept anyway because the core app still imports them; unpicking those is a refactor and does not belong in a rebase. This base does not build yet, and the reasons are not in the rename: upstream now wants Python 3.13.13 against our 3.12.12 and Django 5.2 against our 4.2, and the dependency manifests still name upstream packages that we republish under our own names. Those are decisions, not renames.
5.7 KiB
Configuration reference
The stripe-mock service is configured via stripe-mock.config.yaml in the service root.
All values are optional — defaults match the revenue_analytics scenario.
Changes take effect on restart (uvicorn --reload picks up file changes automatically).
Timeline
start_date
Default: "2024-03-01"
Start date for data generation. All customer subscriptions begin on or after this date. Changing this shifts the entire dataset forward or backward in time.
start_date: '2023-01-01' # Generate 3+ years of data
end_date
Default: "2026-03-01"
End date for data generation. No invoices or charges are created after this date. Subscriptions that would extend past this date are capped.
end_date: '2025-06-01' # Shorter dataset
seed
Default: 42
Random seed for deterministic data generation. Same seed always produces identical output. Change it to get a different but equally valid dataset.
seed: 123
Customer configuration
customer_metadata
Default: {} (empty)
Key-value pairs injected into the metadata field of every generated customer.
Useful for tagging mock data or testing metadata-based filters.
customer_metadata:
source: 'stripe-mock'
environment: 'development'
team_id: '12345'
customer_types
Default: See below
Controls how many customers of each persona type to generate.
Set any type to 0 to skip it entirely.
customer_types:
loyalists_monthly: 12 # Stable monthly subscribers
loyalists_annual: 6 # Stable annual subscribers
churners: 8 # Cancel after N months
resubscribers: 1 # Cancel then resubscribe
upgraders: 1 # Upgrade to higher tier
downgraders: 1 # Downgrade to lower tier
interval_switchers: 1 # Switch monthly → yearly
coupon_users: 3 # Have discount coupons
multi_currency_eur: 5 # EUR subscribers
multi_currency_gbp: 2 # GBP subscribers
multi_currency_jpy: 3 # JPY subscribers (zero-decimal)
refund_recipients: 3 # Receive refunds
trial_users: 2 # Start with free trial
late_joiners: 11 # Join at staggered dates
edge_combos: 1 # Unusual combinations
Quick presets:
- Minimal smoke test: set everything to 0 except
loyalists_monthly: 3 - Churn-heavy: set
churners: 50, reduce others - Multi-currency focus: increase
multi_currency_*counts
Product catalog
products
Default: 3 tiers × 4 currencies × 2 intervals = 24 prices
Controls the product catalog. Each tier has prices for every currency/interval combination. Amounts are in minor units (cents for USD/EUR/GBP, yen for JPY).
products:
tiers: ['basic', 'standard', 'premium']
currencies: ['usd', 'eur', 'gbp', 'jpy']
intervals: ['month', 'year']
prices:
basic:
monthly_usd: 699 # $6.99/mo
yearly_usd: 6999 # $69.99/yr
monthly_eur: 649
yearly_eur: 6499
monthly_gbp: 499
yearly_gbp: 4999
monthly_jpy: 790 # ¥790/mo (zero-decimal)
yearly_jpy: 7900
standard:
monthly_usd: 1549 # $15.49/mo
yearly_usd: 15499
monthly_eur: 1299
yearly_eur: 12999
monthly_gbp: 1099
yearly_gbp: 10999
monthly_jpy: 1780
yearly_jpy: 17800
premium:
monthly_usd: 2299 # $22.99/mo
yearly_usd: 22999
monthly_eur: 1999
yearly_eur: 19999
monthly_gbp: 1799
yearly_gbp: 17999
monthly_jpy: 2980
yearly_jpy: 29800
Coupons
coupons
Default: 3 coupons (WELCOME20, BETA100, EMPLOYEE)
Defines discount coupons that coupon_users customers receive.
coupons:
WELCOME20:
percent_off: 20
duration_months: 3 # Applied to first 3 invoices
BETA100:
percent_off: 100 # Free for 12 months
duration_months: 12
EMPLOYEE:
percent_off: 100
duration: 'forever' # Free forever
Behavioral parameters
churn_months
Default: [1, 2, 3, 4, 5, 6, 7, 9]
Month numbers at which churner customers cancel. Each churner gets assigned one value from this list (cycling if there are more churners than months).
churn_months: [1, 3, 6] # All churners cancel within 6 months
trial_days
Default: [7, 14]
Trial durations in days for trial_users. Alternates between values.
trial_days: [7, 14, 30] # Add a 30-day trial variant
late_joiner_offsets
Default: [1, 3, 4, 6, 7, 9, 10, 12, 15, 18, 20]
Month offsets from start_date at which late_joiners start their subscriptions.
late_joiner_offsets: [6, 12, 18] # Only join at 6-month intervals
payout_frequency_months
Default: 1
How often payouts are generated (in months). Set to 2 for bi-monthly payouts.
stripe_fee_percent
Default: 2.9
Stripe's percentage fee applied to each charge for balance transaction calculations.
stripe_fee_fixed_cents
Default: 30
Stripe's fixed fee per transaction in cents.
Error injection
errors
Default: {} (no errors)
Make specific API routes return errors to test resiliency. Each key is a URL path prefix, and the value configures the error response.
errors:
'/v1/charges':
status: 500 # HTTP status code
message: 'Internal server error' # Error message in response body
rate: 1.0 # Probability (0.0 to 1.0)
'/v1/customers/search':
status: 429
message: 'Rate limit exceeded'
rate: 0.5 # 50% of requests fail
'/v1/invoices':
status: 403
message: 'Insufficient permissions'
rate: 0.1 # 10% failure rate
Use cases:
rate: 1.0— route always fails (test error handling paths)rate: 0.5— intermittent failures (test retry logic)status: 429— simulate rate limitingstatus: 500— simulate server errorsstatus: 403— simulate permission errors