A merchant opens Teya Invoices for the first time. Rather than asking them to type their business name, VAT number, address, and bank details manually, we offer a single shortcut: upload an existing invoice and we'll scrape their own details from it. This flow removes the "empty state tax" that kills most invoicing activations.
graph TD
A[First-time merchant
opens invoices] --> B[Welcome screen:
3-step progress indicator]
B --> C{Set-up shortcut}
C -->|Upload existing invoice| D[Upload zone:
PDF, JPG, PNG up to 10MB]:::track
C -->|Skip, enter manually| E[→ Journey 1 with
empty business details]:::track
D --> F[AI scans document:
animated scan-line preview]:::track
F --> G{Extraction quality}
G -->|High confidence| H[Pre-fill all fields:
business name, VAT,
address, company no.]:::track
G -->|Partial| I[Pre-fill confident fields,
flag uncertain ones
with 'please verify']:::assumed
G -->|Failed| J[Show retry or
manual fallback]:::assumed
H --> K[Review screen:
confidence tiers green/amber]
I --> K
J --> C
K --> L{Merchant reviews
each field}
L -->|Edit inline| M[Update field]:::track
L -->|Accept| N[Keep as-is]
M --> O{All fields reviewed?}
N --> O
O -->|No| L
O -->|Yes| P[Save business profile]:::track
P --> Q[Land in editor
with details pre-populated]:::track
Q --> R[→ Journey 1
from line items step]
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
onboarding_welcome_viewed — merchant opened the first-time welcome screenonboarding_upload_screen_viewed — upload zone screen displayedonboarding_processing_screen_viewed — animated processing screen shown (extracting details)onboarding_review_screen_viewed — field review screen displayed (confidence tiers visible)onboarding_success_screen_viewed — business profile saved, landing in editoronboarding_upload_started — merchant initiated file uploadonboarding_upload_file_selected (file_type: pdf|image|screenshot, file_size_bytes) — file chosenonboarding_upload_progress (bytes_uploaded, total_bytes) — upload in progress (fire every 500ms or per chunk)onboarding_upload_completed (file_type, file_size, duration_ms) — file upload finishedonboarding_upload_failed (error_type, file_type, file_size) — upload failed (network error, size exceeded, unsupported type)onboarding_upload_retry_clicked — merchant tapped "Try another file"onboarding_extraction_started (file_type) — AI service began processingonboarding_extraction_completed (confidence_level: high|partial|failed, fields_extracted_count, processing_time_ms) — extraction finishedonboarding_extraction_failed (error_type, error_message) — extraction service erroronboarding_field_viewed (field_name) — merchant scrolled to or focused on a fieldonboarding_field_focused (field_name, confidence: high|partial) — merchant tapped/clicked a field (form focus)onboarding_field_changed (field_name, previous_value, new_value, confidence_was: high|partial) — merchant edited a fieldonboarding_field_validation_error (field_name, error_type) — field validation failed (e.g. invalid email, malformed VAT)onboarding_field_validation_passed (field_name) — field passed validation after correctiononboarding_confidence_badge_clicked (field_name, confidence_level) — merchant clicked the high/partial confidence indicatoronboarding_field_blur (field_name, final_value) — merchant left a field (blur event, for time-on-field measurement)onboarding_skipped — merchant chose "Skip, enter manually" from welcome screenonboarding_completed — merchant tapped "Save and continue" after reviewing all fieldsonboarding_back_clicked — merchant tapped back button during onboardingonboarding_error_banner_shown (error_type) — error message displayed (e.g. upload failed)onboarding_error_banner_dismissed — merchant closed error banneronboarding_abandoned — merchant navigated away without completing (drop-off signal)---
The core happy path. A merchant opens the invoice editor, fills in client details, adds line items with optional tax and discounts, previews the result, configures payment, and chooses a delivery channel. This is the most common flow and the one every other journey eventually merges into.
graph TD
A[Merchant taps 'New Invoice'] --> B[Single-page editor loads
with smart defaults]
B --> C{Client field}
C -->|Type name/email| D{Client found?}
D -->|Yes| E[Auto-fill billing address,
currency, language]
D -->|No| F[Create new client inline]:::assumed
F --> G{Client details valid?}:::assumed
G -->|Yes| E
G -->|No| H[Show validation error]:::assumed
H --> F
C -->|Skip for now| I[Continue without client]:::assumed
E --> J[Add line items]
I --> J
J --> K{How to add items?}
K -->|Manual entry| L[Type description, qty, rate]
K -->|From catalogue| M[Search saved products/services]
L --> N{Add tax/discount?}
M --> N
N -->|Yes| O[Configure inline tax rate
and/or discount per item]
N -->|No| P[Running total updates]
O --> P
P --> Q{More line items?}
Q -->|Yes| J
Q -->|No| R[Review summary panel]
R --> S{Live preview?}
S -->|Open preview| T[Side-panel shows PDF /
Email / Payment Page tabs]:::track
S -->|Skip preview| U[Configure payment methods]
T --> U
U --> V[Select accepted methods
— card, bank, PayPal, etc.]
V --> W[Payment link auto-generated]:::track
W --> X{Set due date}
X -->|Smart shortcut
Net 15/30/60| Y[Due date set]
X -->|Custom date| Y
X -->|No due date| Z[Flag: no due date warning]:::assumed
Y --> AA{Ready to send?}
Z --> AA
AA -->|Yes| BB[Confirmation modal:
recipient, total, due date, methods]:::track
AA -->|Save as draft| CC[Invoice saved to drafts]:::track
AA -->|Cancel| DD[Discard or keep draft?]:::assumed
DD -->|Keep draft| CC
DD -->|Discard| EE[Return to dashboard]:::assumed
BB --> FF{Delivery channel}
FF -->|Email| GG[Send via email]:::track
FF -->|Shareable link| HH[Generate and copy link]:::track
FF -->|SMS| II[Send via SMS]:::track
FF -->|PDF download| JJ[Download PDF]:::track
FF -->|Schedule send| KK[Pick date/time, queue]:::track
GG --> LL[Success screen +
next actions]:::track
HH --> LL
II --> LL
JJ --> LL
KK --> LL
LL --> MM{Post-send prompts}
MM -->|Set up reminders| NN[Configure auto-reminders]
MM -->|Make recurring| OO[Set recurring schedule]
MM -->|Done| PP[Return to invoice dashboard]
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
invoice_editor_opened — merchant tapped "New Invoice" (funnel entry point)invoice_editor_screen_loaded (time_to_interactive_ms) — page fully interactiveinvoice_editor_mobile_preview_opened — preview panel opened on mobilepayment_config_panel_opened — payment settings accordion expandeddue_date_picker_opened — date picker modal shownconfirmation_modal_opened — pre-send confirmation dialog displayedinvoice_editor_exited — merchant navigated away from editor (drop-off signal)client_field_focused — merchant clicked/tapped on client inputclient_field_changed (search_term_length) — merchant typed in client search boxclient_autocomplete_dropdown_opened — dropdown appearedclient_autocomplete_suggestion_shown (client_count, has_recent: boolean) — suggestions displayedclient_autocomplete_selected (client_id, matched_by: name|email) — merchant selected from dropdownclient_new_inline_modal_opened — modal to create new client appearedclient_new_created (fields_provided: name|email|address) — new client created inlineclient_field_validation_error (error_type: invalid_email|required|...) — validation failedclient_field_skipped — merchant chose to continue without selecting clientclient_field_blur (has_value: boolean) — merchant left field without selectingcurrency_selector_opened — currency dropdown tappedcurrency_changed (from_currency, to_currency, invoice_total) — merchant switched currencycurrency_auto_detected (country_code, detected_currency, merchant_accepts: boolean) — system suggested currency based on business locationinvoice_number_displayed (format, next_number) — invoice number showninvoice_number_copied — merchant copied to clipboarddue_date_chip_clicked (chip_label: "Net 15"|"Net 30"|"Net 60"|"Custom") — merchant selected a preset or customdue_date_custom_picker_opened — date picker modal showndue_date_selected (due_date, days_from_today) — merchant picked a datedue_date_warning_shown — "no due date set" warning banner displayeddue_date_warning_dismissed — merchant closed warningline_item_added (position, source: manual|catalogue|template) — line item added to invoiceline_item_description_focused (position) — merchant clicked on description fieldline_item_description_changed (position, description_length) — merchant typed descriptionline_item_qty_focused (position) — merchant clicked qty fieldline_item_qty_changed (position, new_qty, previous_qty) — merchant updated quantityline_item_rate_focused (position) — merchant clicked rate/price fieldline_item_rate_changed (position, new_rate, previous_rate, currency) — merchant updated rateline_item_tax_expanded (position, has_tax_previously: boolean) — merchant opened tax/discount optionsline_item_tax_rate_selected (position, tax_rate_percent) — merchant chose tax rate (may be from preset or custom)line_item_discount_applied (position, discount_type: fixed|percent, discount_amount) — discount added to line itemline_item_total_recalculated (position, old_total, new_total) — total recalculated on qty/rate/tax changeline_item_deleted (position, description) — merchant removed line itemline_item_duplicate_clicked (position) — merchant duplicated line itemadd_line_item_button_clicked — merchant tapped "Add item" buttonadd_from_catalogue_clicked — merchant tapped "Use from catalogue/services"catalogue_search_performed (search_term, result_count) — merchant searched saved productscatalogue_item_selected (product_id, product_name, pre_filled_fields: list) — merchant selected from catalogueinvoice_summary_updated (subtotal, tax_total, discount_total, final_total) — totals recalculatedinvoice_summary_panel_viewed — merchant scrolled to or focused on summaryinvoice_total_changed (previous_total, new_total, change_reason) — total changed (could be due to item add/remove, qty, rate, tax, discount)preview_panel_opened (preview_type) — merchant opened preview panelpreview_tab_clicked (tab: pdf|email|payment_page) — merchant switched preview tabspreview_updated (total_time_to_update_ms) — preview re-rendered (live as merchant edits)preview_download_clicked — merchant initiated preview PDF downloadpreview_panel_closed — merchant closed previewpayment_methods_section_viewed — payment methods accordion visiblepayment_method_toggled (method: card|bank_transfer|paypal|..., new_state: on|off) — merchant enabled/disabled payment methodpayment_method_expanded (method) — merchant tapped payment method to see detailspayment_fee_shown (method, fee_type: percentage|fixed, fee_amount) — fee displayedpayment_method_validation_error (method, error_type) — payment config error shown (e.g. no payment method selected)payment_link_generated (payment_link_url) — payment page link createdadvanced_settings_expanded — merchant opened "Advanced" or "Business details" sectionadvanced_settings_collapsed — merchant closed sectionbusiness_name_changed (new_name) — merchant edited business namebusiness_vat_changed (new_vat) — merchant edited VAT numberbusiness_address_changed (new_address) — merchant edited business addressbusiness_details_validation_error (field, error_type) — validation error on business fieldinvoice_discount_expanded — merchant opened invoice-level discount sectioninvoice_discount_type_selected (discount_type: fixed|percent) — merchant chose discount typeinvoice_discount_applied (discount_amount, discount_type, new_total) — invoice-level discount appliedinvoice_discount_removed — merchant cleared discountauto_save_triggered (change_type, time_since_last_save_ms) — background auto-save firedauto_save_completed (save_duration_ms, data_size_bytes) — save succeededauto_save_failed (error_type) — auto-save failed (network error, auth timeout)draft_status_indicator_shown — "Draft · Saved" indicator displayeddraft_status_indicator_hidden — indicator hidden (successful save confirmed)confirmation_modal_opened (client_name, invoice_total, due_date) — pre-send modal displayedconfirmation_modal_details_reviewed — merchant reviewed modal contentsconfirmation_modal_edited_clicked — merchant tapped "Go back and edit"confirmation_modal_confirmed — merchant approved and proceeded to deliveryconfirmation_modal_save_draft_clicked — merchant chose "Save as draft" from modaldraft_save_initiated (trigger: manual_button|nav_away|timeout) — draft save starteddraft_saved (save_duration_ms, invoice_id) — draft created/updated successfullydraft_save_failed (error_type) — draft save faileddraft_discard_prompted — "Keep draft or discard?" confirmation showndraft_discard_confirmed — merchant chose "Discard"draft_keep_confirmed — merchant chose "Keep as draft"invoice_editor_back_clicked — merchant tapped back buttoninvoice_editor_nav_away (from_section, unsaved_changes: boolean) — merchant navigated awayinvoice_editor_abandoned (time_in_editor_ms, completed_sections: list) — merchant dropped off without saving---
The merchant has prior work context — a completed job, an active contract, or a project — and wants to generate an invoice from it. Most fields are pre-populated, so the flow is about reviewing and adjusting rather than filling in from scratch.
graph TD
A{Entry point} --> B[From job/project list]
A --> C[From contract dashboard]
A --> D[From 'New Invoice' +
select source]
B --> E[Select completed job
or uninvoiced project]
C --> F[Select active contract
with billing period]
D --> G{Source picker:
job, contract, or blank}
G -->|Job/project| E
G -->|Contract| F
G -->|Blank| H[→ Journey 1:
New from scratch]
E --> I[Auto-populate:
client, line items,
amounts from job]:::track
F --> J[Auto-calculate:
working days, rates,
amounts from contract terms]:::track
I --> K[Single-page editor loads
with pre-filled data]
J --> K
K --> L{Review client details}
L -->|Correct| M[Keep as-is]
L -->|Update needed| N[Edit inline —
address, currency, etc.]:::assumed
N --> M
M --> O{Review line items}
O -->|All correct| P[Keep pre-filled items]
O -->|Adjust amounts| Q[Edit qty, rate,
or description]
O -->|Remove items| R[Delete uninvoiced items
not yet ready to bill]:::assumed
O -->|Add items| S[Add manual items
on top of pre-filled]:::assumed
Q --> T{More adjustments?}
R --> T
S --> T
T -->|Yes| O
T -->|No| P
P --> U{Partial invoice?}:::assumed
U -->|Invoice all| V[Full amount from source]
U -->|Invoice subset| W[Select which items /
amount to bill now]:::assumed
W --> X[Remaining flagged as
uninvoiced for next time]:::assumed
V --> Y[Running total updates]
X --> Y
Y --> Z[Configure tax / discount
if not inherited from source]:::assumed
Z --> AA[Live preview]:::track
AA --> BB[Configure payment +
delivery — same as Journey 1]:::track
BB --> CC[Success screen]:::track
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
invoice_from_source_started — merchant chose "from existing context" optionsource_picker_opened — source type selection modal shownsource_type_selected (source_type: job|contract|blank) — merchant chose source typeinvoice_from_job_started — merchant selected job/project sourceinvoice_from_contract_started — merchant selected contract sourceinvoice_from_blank_started — merchant chose blank (redirect to Journey 1)job_list_opened — completed jobs list displayedjob_selected (job_id, client_name, job_status, uninvoiced_amount) — merchant selected a jobcontract_list_opened — active contracts list displayedcontract_selected (contract_id, client_name, billing_period, contract_rate) — merchant selected a contractcontract_billing_period_picker_opened — period selector displayedcontract_period_selected (period_start_date, period_end_date, period_type: weekly|monthly|quarterly) — merchant chose period to invoiceauto_populate_started (source_type, source_id) — pre-fill process initiatedauto_populate_completed (client_populated: boolean, items_count, subtotal, tax_total) — pre-fill finishedauto_populate_failed (error_type, source_id) — pre-fill failed (data missing, service error)client_auto_populated (client_id, client_name) — client auto-filledline_items_auto_populated (items_count, total_amount) — line items pulled from sourcetax_inherited_from_source (tax_rate, tax_total) — tax carried over from sourcediscount_inherited_from_source (discount_type, discount_amount) — discount carried oversource_data_reviewed (items_count, changes_made: boolean) — merchant reviewed auto-populated datapre_filled_item_kept (position, item_id, item_description) — merchant accepted pre-filled itempre_filled_item_modified (position, item_id, field_changed: description|qty|rate, previous_value, new_value) — merchant edited pre-filled itempre_filled_item_deleted (position, item_id, item_description) — merchant removed pre-filled itempre_filled_item_duplicated (position, item_id) — merchant duplicated pre-filled itemmanual_item_added_to_source_items (position, description) — merchant added new item alongside pre-filled itemspre_filled_client_kept — merchant accepted auto-populated clientpre_filled_client_modified (field: name|email|address, previous_value, new_value) — merchant edited auto-populated client detailspartial_invoice_mode_enabled — merchant chose to bill subset of itemspartial_invoice_items_selected (items_selected_count, items_total_count, selected_subtotal, full_subtotal) — merchant selected items to invoiceuninvoiced_balance_calculated (uninvoiced_amount, uninvoiced_items_count) — remaining balance calculated for next invoicepartial_invoice_created (invoice_total, uninvoiced_balance) — partial invoice confirmed and proceedinginvoice_linked_to_source (source_type, source_id) — invoice marked as linked to job/contract (for future reference)source_marked_partially_invoiced (source_id, remaining_uninvoiced_amount) — source updated with uninvoiced balancesource_invoice_preview_opened — merchant opened previewsource_invoice_payment_config_opened — merchant configured paymentsource_invoice_delivery_selected (delivery_channel) — merchant chose delivery channelsource_invoice_sent (source_type, source_id, partial_invoice: boolean) — invoice sent (tagged with source)---
The merchant uploads an existing document — a PDF, photo, or screenshot — and AI extracts the invoice details. The merchant reviews, corrects, and sends. This flow (inspired by Wise) replaces manual data entry with verification, but requires trust-building through transparency about what the AI extracted vs. what it guessed. The "Upload (AI extract)" entry point is surfaced as a prominent yellow-tinted button with an "AI" badge inside the line-items section of the editor, making it discoverable mid-flow, not just at the very start.
graph TD
A[Merchant taps 'New Invoice'] --> B{Creation method}
B -->|Manual| C[→ Journey 1]
B -->|From job/contract| D[→ Journey 2]
B -->|Upload document| E[Upload screen]
E --> F{File type}
F -->|PDF| G[Upload PDF]
F -->|Image / photo| H[Upload or take photo]:::track
F -->|Screenshot| I[Paste or upload screenshot]
G --> J[AI extraction service
processes document]:::track
H --> J
I --> J
J --> K{Extraction quality}
K -->|High confidence
all fields extracted| L[Pre-fill editor with
all extracted data]:::track
K -->|Partial extraction
some fields uncertain| M[Pre-fill known fields,
highlight uncertain ones]:::assumed
K -->|Extraction failed| N[Show error:
'Could not read this document']:::assumed
L --> O[Show AI disclaimer:
'Extracted by AI — please review']:::track
M --> O
N --> P{Retry options}:::assumed
P -->|Try different file| E
P -->|Enter manually| C
P -->|Cancel| Q[Return to dashboard]
O --> R{Merchant reviews
extracted data}
R --> S{Client correct?}
R --> T{Items correct?}
R --> U{Amounts correct?}
S --> W{Field correct?}
T --> W
U --> W
W -->|Yes| X[Keep as-is]
W -->|No / uncertain| Y[Edit inline]:::track
X --> Z{All fields reviewed?}
Y --> Z
Z -->|No| R
Z -->|Yes| AA[Merchant confirms
extracted invoice]:::track
AA --> BB[Editor loads with
confirmed data —
same as Journey 1 Step 5+]
BB --> CC[Preview → Payment →
Delivery → Success]:::track
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
ai_upload_screen_viewed — upload screen displayedai_processing_screen_viewed — animated "Extracting invoice details..." shownai_review_screen_viewed — extracted data review screen displayedai_disclaimer_shown (confidence_level) — AI transparency banner displayedai_upload_started — merchant tapped "Upload document" buttonai_upload_file_picker_opened — file chooser dialog shownai_upload_camera_option_shown — "Take a photo" option displayedai_upload_camera_clicked — merchant tapped camera buttonai_upload_paste_option_clicked — merchant pasted screenshot (keyboard)ai_file_selected (file_type: pdf|image|screenshot, file_size_bytes, file_format) — file chosenai_file_upload_started (file_type, file_size_bytes) — upload beganai_file_upload_progress (bytes_uploaded, total_bytes, percent_complete) — upload in progress (fire every 500ms)ai_file_upload_completed (file_type, file_size_bytes, upload_duration_ms) — upload finishedai_file_upload_failed (error_type: network|size_exceeded|unsupported_format|timeout, file_type) — upload failedai_file_validation_error (validation_error: file_type_unsupported|size_exceeds_limit|corrupted) — client-side validation failedai_file_upload_retry_clicked — merchant tapped "Try another file"ai_extraction_initiated (file_type, file_size_bytes) — processing startedai_extraction_in_progress (elapsed_time_ms) — extraction ongoing (fire at 2s, 5s, 10s markers for long processing)ai_extraction_completed (confidence_level: high|partial|failed, fields_extracted_count, processing_time_ms) — extraction finishedai_extraction_failed (error_type: unsupported_format|low_quality|service_error|timeout, processing_time_ms) — extraction failedai_confidence_tier_assigned (confidence_level, high_confidence_fields, partial_confidence_fields, failed_fields) — confidence breakdown calculatedai_review_started (confidence_level, total_fields) — merchant began reviewing extracted dataai_field_section_viewed (section: client|items|amounts|dates) — merchant scrolled to a sectionai_field_focused (field_name, confidence: high|partial|failed, extracted_value) — merchant tapped on a fieldai_field_confidence_badge_clicked (field_name, confidence_level) — merchant clicked confidence indicatorai_field_accepted (field_name, confidence: high|partial|failed) — merchant confirmed field is correct (no edit)ai_field_edited (field_name, confidence_was, extracted_value, new_value) — merchant corrected fieldai_field_validation_error (field_name, error_type) — field validation failed after editai_field_validation_passed (field_name) — field passed validation after correctionai_field_blur (field_name, final_value) — merchant left fieldai_client_section_complete (client_name, client_email, confidence_level) — all client fields reviewedai_items_section_complete (items_count, total_amount) — all item fields reviewedai_amounts_section_complete (subtotal, tax, discount, total) — all amount fields reviewedai_dates_section_complete (invoice_date, due_date) — all date fields reviewedai_high_confidence_fields_count — number of high-confidence extractionsai_partial_confidence_fields_count — number of fields needing reviewai_failed_fields_count — number of unextracted fieldsai_field_correction_rate (field_name, correction_needed: boolean) — per-field correction necessityai_extraction_failed_modal_shown (error_message) — failure screen displayedai_extraction_retry_clicked — merchant tapped "Try another file"ai_extraction_manual_fallback_clicked — merchant tapped "Enter manually"ai_extraction_cancelled — merchant cancelled and returned to dashboardai_review_completed (fields_corrected_count, fields_accepted_count, review_duration_ms) — merchant finished reviewingai_extraction_confirmed (confidence_level, fields_corrected_count) — merchant approved and proceeding to editorai_extraction_abandoned (fields_reviewed_count, review_duration_ms, reason: timeout|nav_away|explicit) — merchant dropped off during reviewai_extracted_invoice_editor_opened (fields_extracted: list, source: ai_upload) — editor loaded with extracted dataai_extracted_editor_preview_opened — merchant opened preview on AI-extracted invoiceai_extracted_payment_config_opened — merchant configured paymentai_extracted_delivery_selected (delivery_channel) — merchant chose deliveryai_extracted_invoice_sent (confidence_level, corrections_made: boolean, delivery_channel) — invoice sent (tagged with AI source)---
A merchant invoices the same client regularly. The flow leverages auto-complete, saved items, and optionally previous invoice templates to minimize repetitive data entry. This is a variation of Journey 1 where most friction is removed by memory and defaults.
graph TD
A[Merchant taps 'New Invoice'] --> B[Editor loads with
smart defaults]
B --> C[Start typing client
name or email]
C --> D[Auto-complete suggests
matching contacts]:::track
D --> E[Select returning client]
E --> F[Auto-fill: billing address,
currency, language,
preferred payment method]:::track
F --> G{Use previous invoice
as template?}:::assumed
G -->|Yes| H[Load line items from
most recent invoice
for this client]:::track
G -->|No| I[Start with blank
line items]
H --> J{Review pre-loaded items}
J -->|Adjust amounts / dates| K[Edit line items]
J -->|All correct| L[Keep as-is]
K --> L
I --> M[Add line items
— manual or catalogue]
M --> L
L --> N[Running total updates]
N --> O{Tax / discount
inherited from template?}:::assumed
O -->|Yes| P[Review inherited rates]
O -->|No| Q[Configure inline]
P --> R[Preview + Payment +
Delivery — same as Journey 1]
Q --> R
R --> S[Success screen]:::track
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
client_autocomplete_field_focused — merchant clicked on client fieldclient_autocomplete_search_started (search_term) — merchant began typingclient_autocomplete_results_shown (result_count, has_recent: boolean) — suggestions displayedclient_autocomplete_result_hovered (client_id, client_name) — merchant hovered over suggestion (desktop)client_autocomplete_selected (client_id, client_name, matched_by: name|email, is_returning_customer: boolean) — merchant selected a clientclient_autocomplete_search_abandoned — merchant cleared search without selectingclient_autofill_initiated (client_id, client_name) — auto-fill process startedclient_autofill_completed (client_name, client_email, billing_address, currency, language, preferred_payment_method) — client details pre-populatedclient_autofill_failed (error_type) — auto-fill failed (data missing, service error)client_autofill_partially_completed (fields_filled: list, fields_missing: list) — some fields missingtemplate_suggestion_shown (template_id, template_age_days, previous_invoice_number, previous_total) — template prompt appearedtemplate_suggestion_accepted — merchant tapped "Use as template"template_suggestion_declined — merchant tapped "Start fresh"template_suggestion_dismissed — merchant closed prompt without choosingtemplate_load_initiated (template_id, template_age_days) — template fetch startedtemplate_load_completed (items_count, subtotal, tax_total, discount_total) — template loadedtemplate_load_failed (error_type) — template loading failedtemplate_items_viewed (items_count) — merchant reviewed template itemstemplate_item_kept (position, item_id) — merchant accepted template itemtemplate_item_modified (position, item_id, field_changed: description|qty|rate|tax|discount) — merchant edited template itemtemplate_item_deleted (position, item_id) — merchant removed template itemtemplate_item_added (position, source: manual|catalogue) — merchant added new item to templatetemplate_total_recalculated (old_total, new_total, reason: item_change|qty_change|rate_change|tax_change|discount_change) — total updatedtemplate_inherited_tax_reviewed (tax_rate, applies_to_all: boolean) — merchant reviewed inherited taxtemplate_inherited_discount_reviewed (discount_type, discount_amount) — merchant reviewed inherited discountrepeat_customer_detected (client_id, client_name, previous_invoice_count, previous_total_amount) — system identified returning customerrepeat_customer_metric_displayed (previous_invoice_count, total_invoiced_amount) — merchant shown customer historytemplate_suggestion_confidence (confidence_score) — system's confidence that template is relevant (0-100)repeat_customer_invoice_preview_opened — merchant opened previewrepeat_customer_payment_config_opened — merchant configured paymentrepeat_customer_delivery_selected (delivery_channel) — merchant chose deliveryrepeat_customer_invoice_sent (template_used: boolean, items_modified: boolean, delivery_channel) — invoice sent---
A merchant starts an invoice but isn't ready to send. They save it as a draft and return later to finish and send. This journey covers the save, resume, and edit cycle.
graph TD
A{Entry point} --> B[Mid-edit: merchant
navigates away]
A --> C[Merchant taps
'Save as Draft']
A --> D[Auto-save triggers
in background]:::assumed
B --> E{Unsaved changes?}:::assumed
E -->|Yes| F[Prompt: save draft
or discard?]:::assumed
E -->|No| G[Exit editor cleanly]
F -->|Save| H[Invoice saved to drafts]:::track
F -->|Discard| I[Changes lost,
return to dashboard]:::assumed
C --> H
D --> H
H --> J[Draft badge visible
with timestamp]:::track
K[Later: merchant opens
invoice dashboard] --> L[Drafts section visible
with count badge]:::track
L --> M[Select a draft]
M --> N[Editor loads with
all saved data intact]:::track
N --> O{Resume editing}
O --> P[Add / edit line items]
O --> Q[Update client details]
O --> R[Change payment config]
P --> S{Ready to send?}
Q --> S
R --> S
S -->|Yes| T[Confirmation modal +
delivery — same as Journey 1]:::track
S -->|Not yet| U[Save draft again]
U --> H
S -->|Delete draft| V{Confirm delete?}:::assumed
V -->|Yes| W[Draft permanently deleted]:::track
V -->|No| N
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
auto_save_enabled — auto-save feature active on this draftauto_save_interval_started (interval_ms) — auto-save timer started (e.g. every 10 seconds)auto_save_triggered (time_since_last_save_ms, change_type: field|item|amount) — auto-save firedauto_save_in_progress — save request sent to serverauto_save_completed (save_duration_ms, invoice_id, data_size_bytes) — auto-save succeededauto_save_failed (error_type: network|auth_timeout|server_error, save_duration_ms) — auto-save failedauto_save_retry_scheduled (retry_delay_ms) — retrying after failuredraft_status_updated (status: saved|unsaved|saving|failed) — status indicator updatedunsaved_changes_detected (change_type: field|item, field_name) — change registeredunsaved_changes_count_incremented (unsaved_change_count) — tracking number of changes since last saveunsaved_changes_warned (unsaved_change_count) — user warned before navigation (if no auto-save)save_draft_button_clicked — merchant tapped "Save draft" buttondraft_save_initiated (trigger: manual_button|nav_away|app_close) — save starteddraft_save_in_progress — save request sentdraft_save_completed (invoice_id, save_duration_ms, invoice_status: draft) — save succeededdraft_save_failed (error_type, error_message) — save faileddraft_save_retry_clicked — merchant tapped retry after failureeditor_nav_away_with_changes (unsaved_change_count, time_in_editor_ms) — merchant tried to leave with changesunsaved_changes_confirmation_shown (unsaved_change_count) — "Save or discard?" modal appearedunsaved_changes_save_clicked — merchant chose "Save draft"unsaved_changes_discard_clicked — merchant chose "Discard changes"unsaved_changes_cancel_clicked — merchant cancelled navigationdrafts_section_viewed (draft_count) — drafts section displayed in dashboarddrafts_filter_clicked — merchant filtered invoice list to drafts onlydrafts_count_badge_shown (draft_count) — count badge displayeddraft_row_clicked (draft_id, age_days) — merchant selected a draft from listdraft_preview_hovered (draft_id) — merchant hovered over draft row (shows preview tooltip)draft_load_initiated (draft_id, age_days) — draft load starteddraft_load_completed (draft_id, load_duration_ms, data_size_bytes) — draft loaded into editordraft_load_failed (error_type) — draft load failed (data corrupted, not found, auth error)draft_editor_opened (draft_id, age_days, last_edited_time_ago_minutes) — editor opened with draft datadraft_conflict_detected — draft data conflicts with server version (e.g. another device edited it)draft_conflict_resolution_modal_shown — conflict resolution UI appeareddraft_version_selected (version: local|server) — merchant chose which version to keepdraft_edit_resumed (draft_id) — merchant made first change to resumed draftdraft_field_changed (field_name, previous_value, new_value) — merchant edited a fielddraft_items_modified (items_added: count, items_deleted: count, items_edited: count) — items changeddraft_total_changed (previous_total, new_total) — total updated while editingdraft_send_initiated (draft_id, age_days) — merchant tapped "Send" on a draftdraft_sent (draft_id, age_days, delivery_channel) — draft finalized and sent (conversion event)draft_delete_clicked (draft_id) — merchant tapped "Delete draft"draft_delete_confirmation_shown (draft_id) — "Confirm delete?" modal appeareddraft_delete_confirmed (draft_id, age_days) — merchant confirmed deletiondraft_delete_cancelled — merchant cancelled deletiondraft_permanently_deleted (draft_id) — draft removed from systemdraft_duplicate_clicked (draft_id) — merchant tapped "Duplicate draft"draft_duplicated (original_draft_id, new_draft_id) — draft copieddraft_expiration_warning_shown (draft_id, days_until_expiry) — merchant warned that draft will expire soondraft_expired (draft_id, age_days) — draft auto-deleted due to age (if applicable)draft_archived (draft_id, age_days) — draft moved to archive (if applicable)---
After an invoice is finalized, the merchant chooses how to deliver it. This journey focuses on the delivery decision and the channel-specific flows — it's the tail end of every other journey.
graph TD
A[Invoice finalized —
confirmation modal] --> B{Select delivery channel}
B -->|Email| C[Pre-fill recipient email
from client record]
C --> D{Customize email?}
D -->|Yes| E[Edit subject line +
message body]:::assumed
D -->|No| F[Use default template
with dynamic subject]
E --> G[Send email with
invoice attached + payment link]:::track
F --> G
B -->|WhatsApp — 'Popular'| WA1[Pre-fill phone number
from client record]:::track
WA1 --> WA2{Number on file?}
WA2 -->|Yes| WA3[Preview WhatsApp message
with invoice # + amount +
payment link]:::track
WA2 -->|No| WA4[Enter WhatsApp number]
WA4 --> WA3
WA3 --> WA5[Send via WhatsApp Business API]:::track
B -->|Shareable link| H[Generate unique
payment link URL]:::track
H --> I[Copy to clipboard +
show QR code option]:::assumed
I --> J{Share via}:::assumed
J -->|Copy link| K[Merchant pastes
link manually]
J -->|QR code| L[Display QR code
for in-person use]:::track
B -->|SMS| M[Pre-fill phone number
from client record]:::assumed
M --> N{Number on file?}:::assumed
N -->|Yes| O[Send SMS with
payment link]:::track
N -->|No| P[Enter phone number]
P --> O
B -->|PDF download| Q[Generate PDF]:::track
Q --> R[Download to device]
R --> S[Merchant distributes
manually — print, attach, etc.]
B -->|Schedule send| T[Pick date and time]
T --> U{Delivery channel
for scheduled send}:::assumed
U -->|Email| V[Queue email
for scheduled time]:::track
U -->|WhatsApp| VW[Queue WhatsApp
for scheduled time]:::track
U -->|SMS| W[Queue SMS
for scheduled time]:::track
G --> X[Success screen]:::track
WA5 --> X
K --> X
L --> X
O --> X
R --> X
V --> X
VW --> X
W --> X
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
delivery_modal_opened (available_channels: list) — delivery option selection modal displayeddelivery_channel_hovered (channel) — merchant hovered over delivery option (desktop)delivery_channel_selected (channel: email|sms|whatsapp|link|pdf|scheduled, channel_count_available) — merchant chose channeldelivery_channel_unselected (channel) — merchant deselected a channel (if multi-select available)delivery_channel_icon_clicked (channel) — merchant clicked channel help/info iconemail_delivery_selected (recipient_email_on_file: boolean) — merchant chose emailemail_recipient_prefilled (recipient_email) — email auto-populated from client recordemail_recipient_field_focused — merchant clicked recipient fieldemail_recipient_changed (previous_email, new_email) — merchant edited recipient emailemail_recipient_validation_error (error_type: invalid_format) — validation failedemail_recipient_added (recipient_email) — valid email enteredemail_template_preview_opened — merchant opened template previewemail_subject_focused — merchant clicked subject lineemail_subject_changed (new_subject) — merchant edited subjectemail_subject_restored_to_default — merchant reset to default subjectemail_body_focused — merchant clicked message bodyemail_body_changed (char_count) — merchant edited body (fire on blur, with length)email_body_restored_to_default — merchant reset to default bodyemail_customization_preview_updated — preview re-rendered on customizationemail_sending_initiated (recipient_email, customized: boolean) — send startedemail_sending_in_progress (elapsed_time_ms) — sending (fire at 2s, 5s markers if slow)email_sent_successfully (recipient_email, send_duration_ms) — email deliveredemail_send_failed (error_type: invalid_recipient|service_error|auth_error, error_message) — send failedemail_send_retry_clicked — merchant tapped retry after failureemail_attachment_included (attachment_type: pdf|..) — attachment included with emailemail_delivery_receipt_requested (receipt_type: read|delivery) — merchant enabled delivery receipt (if available)sms_delivery_selected (recipient_phone_on_file: boolean) — merchant chose SMSsms_recipient_prefilled (recipient_phone) — phone auto-populated from client recordsms_recipient_field_opened — SMS recipient modal/field openedsms_recipient_changed (previous_phone, new_phone) — merchant edited phone numbersms_recipient_validation_error (error_type: invalid_format|invalid_country) — validation failedsms_recipient_confirmed (recipient_phone) — valid phone enteredsms_preview_shown (sms_preview_text, link_included: boolean) — SMS preview displayedsms_sending_initiated (recipient_phone) — send startedsms_sending_in_progress — sendingsms_sent_successfully (recipient_phone, send_duration_ms) — SMS deliveredsms_send_failed (error_type: invalid_recipient|no_balance|service_error, error_message) — send failedsms_send_retry_clicked — merchant tapped retrywhatsapp_delivery_selected (recipient_phone_on_file: boolean) — merchant chose WhatsAppwhatsapp_recipient_prefilled (recipient_phone) — phone auto-populatedwhatsapp_recipient_field_opened — WhatsApp recipient modal/field openedwhatsapp_recipient_changed (previous_phone, new_phone) — merchant edited phone numberwhatsapp_recipient_validation_error (error_type) — validation failedwhatsapp_recipient_confirmed (recipient_phone) — valid phone enteredwhatsapp_message_preview_shown (message_preview_text, fields_included: list) — message preview displayedwhatsapp_message_customized (customization_type: text_edited) — merchant edited message (if editable)whatsapp_sending_initiated (recipient_phone) — send startedwhatsapp_sending_in_progress — sendingwhatsapp_sent_successfully (recipient_phone, send_duration_ms) — WhatsApp message deliveredwhatsapp_send_failed (error_type: not_on_whatsapp|phone_unverified|service_error) — send failedwhatsapp_send_retry_clicked — merchant tapped retrywhatsapp_message_content (invoice_number_included: boolean, amount_included: boolean, payment_link_included: boolean, due_date_included: boolean) — message content compositionshareable_link_selected — merchant chose "Shareable link" optionshareable_link_generation_initiated — link generation startedshareable_link_generated (link_url, link_id) — unique link createdshareable_link_generation_failed (error_type) — generation failedshareable_link_displayed (link_url) — link shown to merchantshareable_link_copy_clicked — merchant tapped "Copy to clipboard"shareable_link_copied (link_url) — link copied to clipboardshareable_link_copy_failed (error_type) — copy failedshareable_link_qr_code_requested — merchant tapped "Show QR code"shareable_link_qr_code_generated (qr_code_size, format) — QR code createdshareable_link_qr_code_displayed — QR code shown on screenshareable_link_qr_code_download_clicked — merchant tapped "Download QR code"shareable_link_qr_code_downloaded (format) — QR code image downloadedshareable_link_qr_code_print_clicked — merchant tapped "Print"shareable_link_share_opened — native share sheet opened (iOS/Android)shareable_link_share_method_used (share_method: copy|whatsapp|email|sms|other) — merchant shared via OS methodpdf_download_initiated (invoice_id, file_format: a4|letter, language) — PDF generation startedpdf_download_in_progress (elapsed_time_ms) — generating (fire at 2s, 5s markers if slow)pdf_generation_completed (file_size_bytes, generation_time_ms) — PDF createdpdf_generation_failed (error_type: rendering_error|timeout|service_error) — generation failedpdf_download_started (file_size_bytes, file_name) — download initiatedpdf_download_progress (bytes_downloaded, total_bytes, percent_complete) — download in progresspdf_download_completed (file_size_bytes, download_duration_ms, destination: device_downloads) — download finishedpdf_download_failed (error_type: network_error|disk_full|permissions) — download failedpdf_print_clicked — merchant tapped "Print" optionpdf_printed (pages_printed) — PDF sent to printerscheduled_send_selected — merchant chose "Schedule send"scheduled_send_datetime_picker_opened — date/time picker modal appearedscheduled_send_date_selected (scheduled_date, days_from_now) — merchant chose datescheduled_send_time_selected (scheduled_time, timezone) — merchant chose timescheduled_send_datetime_confirmed (scheduled_datetime, days_from_now) — date/time confirmedscheduled_send_channel_picker_opened — channel selection appeared (for scheduled send)scheduled_send_channel_selected (channel: email|sms|whatsapp|link) — merchant chose channel for scheduled deliveryscheduled_send_queued (scheduled_datetime, delivery_channel, invoice_id) — scheduled send queued successfullyscheduled_send_queue_failed (error_type) — queueing failedscheduled_send_preview_shown (scheduled_datetime, delivery_channel) — preview displayedscheduled_send_edit_clicked (scheduled_send_id) — merchant edited scheduled send before it firedscheduled_send_cancelled (scheduled_send_id, time_until_scheduled_send_minutes) — merchant cancelled scheduled sendscheduled_send_reminder_set (remind_before_minutes) — merchant opted to be reminded before sendmulti_channel_send_initiated (channels_selected: list) — merchant chose to send via multiple channelsmulti_channel_send_completed (channels_sent: list, overall_duration_ms) — all sends finishedmulti_channel_send_partial_failure (successful_channels: list, failed_channels: list) — some channels faileddelivery_confirmation_modal_opened (channel, recipient_address) — pre-send confirmation displayeddelivery_confirmation_reviewed — merchant reviewed detailsdelivery_confirmation_confirmed — merchant approved final senddelivery_confirmation_edited — merchant tapped "Edit" to change settingsdelivery_success_screen_shown (channel, recipient_address) — success notification displayeddelivery_success_action_clicked (action: duplicate|reminder|recurring|dashboard) — merchant tapped post-send actiondelivery_tracking_enabled (tracking_type: opens|clicks|payment) — merchant opted into delivery trackingdelivery_notification_enabled — merchant opted to receive notifications on recipient actions---
After sending the first invoice, the system prompts the merchant to set up automations — payment reminders, recurring reissue, and autopilot collection. Crucially, recurring (reissue on schedule) and autopilot (auto-collect on due date) are presented as complementary primitives under a unified "Set & forget — reissue and auto-collect" section. When both are enabled, the merchant has created a true subscription. When only recurring is on, the UI nudges them toward adding autopilot for the flywheel. And when the system detects the same customer being invoiced repeatedly, it surfaces a merchant-facing insight card inviting the customer to save a card on their next payment page — closing the flywheel from the recipient side.
graph TD
A[Success screen after
invoice sent] --> B{Automation prompts}
B --> C[Set up payment reminders?]
B --> AUTO[Set & forget:
reissue + auto-collect]
B --> F[Done — return to dashboard]
C --> G{Reminder config}
G --> H[Before due date:
3 days, 1 day, day-of]
G --> I[After overdue:
1 day, 7 days, 14 days]
G --> HC[Channel: Email, SMS,
WhatsApp, or all channels]
H --> J[Save reminder schedule]:::track
I --> J
HC --> J
AUTO --> D[Toggle: Make recurring]
AUTO --> E[Toggle: Autopilot payments]
D --> K{Recurring config}
K --> L[Frequency: weekly,
monthly, quarterly, custom]
L --> M[End condition: never,
after N invoices, on date]
M --> N{Auto-send or
draft for review?}
N -->|Auto-send| O[Recurring invoice
sends automatically]:::track
N -->|Draft| P[Recurring draft created
for manual review each cycle]:::track
O --> STATE{Also enable
autopilot?}
P --> STATE
STATE -->|Not yet| NUDGE[Inline nudge:
'Turn this into a true subscription —
pair with Autopilot below']:::track
STATE -->|Yes| E
E --> Q{Autopilot config}
Q --> R[Select payment method
on file: card, DD, VRP]
R --> S{Charge timing}
S -->|On due date| U[Charge on exact due date]
S -->|Smart — skip weekends| T[Charge on Friday
if due date is weekend]
T --> FH[Failure handling:
retry in 3 days, notify, or both]
U --> FH
FH --> V[Save autopilot config]:::track
V --> FLYWHEEL{Both recurring
AND autopilot on?}
NUDGE --> W
FLYWHEEL -->|Yes| SUBSCRIPTION[🎉 Subscription banner:
'You've turned this into a subscription —
Teya will issue AND auto-charge']:::track
FLYWHEEL -->|No| W
SUBSCRIPTION --> W
J --> W{Set up more automations?}
W -->|Yes| B
W -->|No| X[Return to invoice dashboard
with automation badges visible]:::track
F --> X
classDef assumed fill:#fff3cd,stroke:#ffc107
classDef track fill:#d4edda,stroke:#28a745
post_send_prompts_shown (prompt_type: reminders|recurring|autopilot) — automation prompts displayedreminder_section_viewed — reminders card visiblereminder_toggle_clicked — merchant tapped "Enable reminders" togglereminder_config_opened (reminder_toggle_state: on|off) — reminder config panel openedreminder_schedule_option_selected (timing_type: before_due|after_overdue) — merchant chose timing strategyreminder_before_due_selected (days_before: 3|1|0) — merchant chose pre-due reminder timingreminder_before_due_customized (custom_days: number) — merchant set custom days-before valuereminder_after_overdue_selected (days_after: 1|7|14) — merchant chose post-due reminder timingreminder_after_overdue_customized (custom_days: number) — merchant set custom days-after valuereminder_channel_selected (channels: email|sms|whatsapp|combination) — merchant chose notification channel(s)reminder_channel_toggled (channel, new_state: on|off) — merchant enabled/disabled specific channelreminder_schedule_preview_shown (reminder_timeline: list) — timeline of reminders displayed (e.g. "3 days before, 1 day before, 7 days after overdue")reminder_config_saved (reminder_schedule: list, channels: list, invoice_id) — reminders configured and savedreminder_config_abandoned — merchant closed config without savingrecurring_section_viewed — recurring card visiblerecurring_toggle_clicked (current_state: off) — merchant tapped "Enable recurring" togglerecurring_config_opened (recurring_toggle_state: on|off) — recurring config panel openedrecurring_frequency_selected (frequency: weekly|biweekly|monthly|quarterly|custom) — merchant chose reissue frequencyrecurring_frequency_custom_entered (custom_frequency_days: number) — merchant entered custom frequencyrecurring_frequency_preview_shown (next_issue_date, subsequent_dates: list) — timeline of future invoices shownrecurring_end_condition_selected (condition_type: never|after_count|on_date) — merchant chose end conditionrecurring_end_count_entered (invoice_count: number) — merchant set "after N invoices" thresholdrecurring_end_date_selected (end_date, recurrences_until_date: number) — merchant chose end daterecurring_send_mode_selected (mode: auto_send|draft_for_review) — merchant chose auto-send vs. draftrecurring_preview_shown (schedule: list) — full recurring schedule displayedrecurring_config_saved (frequency, end_condition, send_mode, invoice_id) — recurring configured and savedrecurring_nudge_shown (message_type: "pair with autopilot") — nudge to add autopilot displayedrecurring_nudge_dismissed — merchant closed nudge without actingrecurring_nudge_converted — merchant clicked "Enable autopilot" from nudgerecurring_config_abandoned — merchant closed config without savingautopilot_section_viewed — autopilot card visibleautopilot_info_tooltip_clicked — merchant clicked help/info icon for autopilotautopilot_toggle_clicked (current_state: off) — merchant tapped "Enable autopilot" toggleautopilot_config_opened (autopilot_toggle_state: on|off) — autopilot config panel openedautopilot_payment_method_selection_opened — payment method picker displayedautopilot_payment_method_available (available_methods: list) — available payment methods shownautopilot_payment_method_selected (method: card|direct_debit|vrp|other, method_token: masked) — merchant chose payment methodautopilot_payment_method_validation_error (error_type: no_method_on_file|unsupported_method) — validation failedautopilot_charge_timing_selected (timing_type: on_due_date|smart_weekend) — merchant chose charge timingautopilot_smart_timing_explained — merchant viewed "skip weekends" explanationautopilot_smart_timing_enabled (skip_weekends: boolean) — smart timing enabledautopilot_failure_handling_selected (handling_type: retry|notify|retry_and_notify) — merchant chose failure responseautopilot_retry_delay_selected (retry_days: 3) — merchant set retry delayautopilot_notification_enabled (notification_type: merchant|recipient|both) — merchant opted into notificationsautopilot_payment_preview_shown (expected_charge_date, payment_method, amount) — charge preview displayedautopilot_mandate_terms_shown — terms and conditions for mandate displayed (compliance)autopilot_mandate_accepted — merchant reviewed and acceptedautopilot_config_saved (payment_method, charge_timing, failure_handling, invoice_id) — autopilot configuredautopilot_config_abandoned — merchant closed config without savingsubscription_state_reached (invoice_id, frequency, charge_timing) — HEADLINE METRIC: both recurring and autopilot enabledsubscription_success_banner_shown (message: "You've turned this into a subscription — Teya will issue AND auto-charge") — celebration banner displayedsubscription_banner_action_clicked (action: view_scheduled|configure_reminders) — merchant interacted with bannersubscription_badge_displayed_on_invoice (invoice_id) — subscription badge shown on invoice detail/listsubscription_lifecycle_state_changed (previous_state, new_state: pending_first_charge|active|paused|ended) — subscription state changedrepeat_customer_insight_card_shown (customer_name, invoice_count, timeframe_days) — merchant-facing flywheel card displayedrepeat_customer_card_action_clicked (action: queue_autopilot_invite|dismiss) — merchant interacted with cardautopilot_invite_queued_for_recipient (customer_id, invoice_id) — invite queued for next payment pageautopilot_invite_queued_confirmation_shown — confirmation message displayedrecipient_payment_page_loaded_with_autopilot_invite (customer_id, invoice_id) — payment page shown to recipient with autopilot optionrecipient_autopilot_prompt_shown — autopilot save-card prompt appeared on payment pagerecipient_autopilot_card_saved (mandate_id, payment_method, invoice_id) — RECIPIENT-SIDE FLYWHEEL CONVERSION: recipient saved card and authorized mandaterecipient_autopilot_declined (invoice_id) — recipient declined autopilot promptrecipient_autopilot_reminded_next_cycle (customer_id) — system will re-prompt on next invoicescheduled_invoices_filter_clicked — merchant filtered to Scheduled invoicesscheduled_invoices_view_opened (scheduled_invoice_count, upcoming_invoices_by_date: list) — scheduled view displayedscheduled_invoice_row_clicked (scheduled_invoice_id, scheduled_date, recurrence_info) — merchant selected scheduled invoicescheduled_invoice_detail_opened (scheduled_invoice_id, source_type: recurring|one_time_scheduled) — detail page shownscheduled_invoice_edit_clicked (scheduled_invoice_id, time_until_send_hours) — merchant tapped "Edit"scheduled_invoice_preview_clicked (scheduled_invoice_id) — merchant opened previewscheduled_invoice_reschedule_clicked (scheduled_invoice_id, current_datetime, proposed_datetime) — merchant tapped "Reschedule"scheduled_invoice_new_datetime_selected (scheduled_invoice_id, new_datetime, days_postponed: number) — merchant set new timescheduled_invoice_rescheduled (scheduled_invoice_id, original_datetime, new_datetime) — reschedule confirmedscheduled_invoice_cancel_clicked (scheduled_invoice_id, time_until_send_hours) — merchant tapped "Cancel send"scheduled_invoice_cancel_confirmation_shown — "Confirm cancel?" displayedscheduled_invoice_cancelled (scheduled_invoice_id, scheduled_datetime) — send cancelledscheduled_invoice_send_now_clicked (scheduled_invoice_id) — merchant tapped "Send now"scheduled_invoice_sent_immediately (scheduled_invoice_id, delivery_channel) — invoice sent ahead of schedulescheduled_invoice_automation_badge_shown (automation_type: recurring|scheduled_send) — badge displayed on scheduled invoicescheduled_invoice_issued_successfully (scheduled_invoice_id, actual_send_datetime, scheduled_datetime, was_on_time: boolean) — scheduled invoice issuedscheduled_invoice_issue_failed (scheduled_invoice_id, error_type, error_message) — automatic issue failedscheduled_invoice_retry_queued (scheduled_invoice_id, retry_datetime) — retry scheduled after failureautomation_prompt_bundle_shown (prompt_count, automation_types: list) — all automation prompts displayed post-sendautomation_prompt_section_expanded (prompt_type) — merchant expanded a prompt cardautomation_prompt_section_collapsed (prompt_type) — merchant collapsed a prompt cardautomation_prompt_info_clicked (prompt_type) — merchant clicked help/info iconautomation_prompt_dismissed (prompt_type) — merchant closed prompt without configuringautomation_prompt_configured (prompt_type, configuration: dict) — prompt configuredautomation_all_prompts_completed (prompts_configured: list) — all prompts processedautomation_prompts_skipped_all — merchant clicked "Done" without configuring any automationautomation_dashboard_return (automation_configured_count, automation_types: list) — merchant returned to dashboardautomation_badge_displayed (invoice_id, automation_types: list) — badge showing active automations visible on invoice listautomation_badge_clicked (invoice_id, automation_type) — merchant tapped badge for detailsautomation_badge_detail_opened (invoice_id, automation_type, config: dict) — automation detail popup shown---
The invoice list is the merchant's home base for all invoicing activity. It surfaces every invoice across its full lifecycle — from scheduled and draft, through sent, viewed, and paid, to overdue — and gives the merchant a single place to triage, filter, and drill in.
flowchart TD
Start([Merchant opens Invoices tab]) --> Landing[Invoice list landing page]
Landing --> Summary[Summary bar:
Outstanding · Overdue · Paid this month]
Landing --> Filters[Filter chips:
All · Scheduled · Draft · Sent · Viewed · Paid · Overdue]
Landing --> Search[Search by client, number, or amount]
Landing --> NewBtn[+ New invoice CTA]
Filters --> List[Filtered invoice list
grouped by status]
List --> ScheduledGroup[Scheduled · upcoming
clock icon + days until send]
List --> DraftGroup[Drafts · needs review]
List --> ActiveGroup[Sent / Viewed / Overdue]
List --> PaidGroup[Paid · recent]
ScheduledGroup --> Row[Invoice row:
client · number · amount · status pill · date]
DraftGroup --> Row
ActiveGroup --> Row
PaidGroup --> Row
Row --> Detail[Invoice detail page]
Row --> QuickActions[Row actions:
Remind · Duplicate · Cancel · Mark paid]
NewBtn --> Editor[Invoice editor]
Detail --> End([Merchant takes action])
QuickActions --> End
Editor --> End
invoice_list_opened — dashboard/list page loadedinvoice_list_rendered (invoice_count, rendering_time_ms) — list fully renderedinvoice_list_screen_viewed — list page came into view (mobile tab switch or nav)summary_bar_displayed (outstanding_total, outstanding_count, overdue_count, overdue_total, paid_this_month_total) — summary metrics shownsummary_outstanding_clicked (outstanding_total, outstanding_count) — merchant tapped Outstanding metricsummary_overdue_clicked (overdue_count, overdue_total) — merchant tapped Overdue metricsummary_paid_this_month_clicked (paid_total, invoice_count) — merchant tapped Paid this month metricsummary_metric_filter_applied (metric_type, resulting_filter) — clicking metric filtered the listfilter_chips_displayed (available_filters: list, current_filter: string) — filter row shownfilter_chip_clicked (filter_value: all|scheduled|draft|sent|viewed|paid|overdue|cancelled, result_count) — merchant selected filterfilter_count_badge_shown (filter_value, count) — badge shown on filter chipfilter_results_updated (previous_count, new_count, filter_value) — list re-filteredfilter_empty_state_shown (filter_value) — no results shown for filterfilter_multi_select_available — if applicable, multi-filter capability shownfilter_clear_all_clicked — merchant tapped "Clear all filters"search_field_focused — merchant clicked on search inputsearch_query_entered (search_term, search_term_length) — merchant typed querysearch_autocomplete_suggestions_shown (suggestion_count, suggestion_types: client_names|invoice_numbers|amounts) — suggestions displayedsearch_performed (search_term, result_count, search_duration_ms) — search executedsearch_results_displayed (result_count, search_term) — results renderedsearch_result_clicked (result_type, result_id) — merchant selected a search resultsearch_cleared — merchant cleared search and returned to full listsearch_no_results_shown (search_term) — no results for queryinvoice_row_viewed (invoice_id, invoice_status, invoice_age_days) — row scrolled into viewinvoice_row_clicked (invoice_id, invoice_status, time_on_row_seconds) — merchant tapped invoice rowinvoice_row_hovered (invoice_id) — merchant hovered over row (desktop, shows preview/actions)invoice_row_quick_preview_shown (invoice_id) — quick tooltip/popover shown on hoverinvoice_row_status_pill_clicked (invoice_id, status) — merchant clicked status indicatorinvoice_row_menu_opened (invoice_id) — overflow menu expandedinvoice_row_menu_closed — overflow menu closedquick_action_menu_opened (invoice_id, available_actions: list) — action menu displayedquick_action_remind_clicked (invoice_id, status) — merchant tapped "Remind" / "Send reminder"quick_action_duplicate_clicked (invoice_id) — merchant tapped "Duplicate"quick_action_cancel_clicked (invoice_id, status) — merchant tapped "Cancel"quick_action_mark_paid_clicked (invoice_id) — merchant tapped "Mark as paid"quick_action_edit_clicked (invoice_id, status) — merchant tapped "Edit"quick_action_delete_clicked (invoice_id, status) — merchant tapped "Delete"quick_action_share_clicked (invoice_id) — merchant tapped "Share"quick_action_download_clicked (invoice_id) — merchant tapped "Download PDF"status_group_header_viewed (status_group: scheduled|draft|sent_viewed|overdue|paid|cancelled) — section header visiblestatus_group_expanded (status_group, invoice_count) — section expanded (if collapsible)status_group_collapsed (status_group) — section collapsedstatus_group_empty_state_shown (status_group) — "No {{status}} invoices" message shownscheduled_group_upcoming_badge_shown (days_until_next_send) — "Upcoming · 2 scheduled for tomorrow" badgenew_invoice_button_clicked (entry_point: fab|header_button) — merchant tapped "New invoice"new_invoice_menu_shown (options: blank|from_template|from_job|from_contract|ai_upload) — creation method menu appeared (if available)new_invoice_method_selected (method: blank|from_template|from_job|from_contract|ai_upload) — merchant chose methodai_upload_quick_access_shown — AI upload button visible in headerai_upload_quick_access_clicked — merchant tapped AI upload shortcutai_upload_initiated_from_list — AI upload started from list screeninvoice_list_pagination_shown (total_pages, current_page) — pagination controls displayed (if applicable)invoice_list_page_changed (from_page, to_page, invoices_per_page) — merchant went to next/previous pageinvoice_list_infinite_scroll_triggered (items_loaded_so_far, total_items) — more items loaded on scrollinvoice_list_reached_end (total_loaded_items) — merchant scrolled to end of listinvoice_list_refresh_clicked — merchant tapped refresh buttoninvoice_list_refreshing (elapsed_time_ms) — refresh in progressinvoice_list_refreshed (refresh_duration_ms, invoices_updated: count) — refresh completedinvoice_list_auto_refreshed (trigger: periodic|app_foreground|notification) — automatic refresh occurredinvoice_list_sync_conflict_detected — local list conflicts with serverinvoice_list_empty_state_shown — list is empty (first time or after filter)invoice_list_empty_state_action_clicked (action: create_first_invoice|browse_templates|ai_upload) — merchant interacted with empty state CTA---
The merchant opens a single invoice to review, share, remind, or take action. The detail page surfaces the full invoice data, client information, payment status, delivery history, and quick actions (remind, duplicate, share, cancel, mark paid, recurring/autopilot config).
invoice_detail_opened (invoice_id, invoice_status, invoice_age_days) — invoice detail page loadedinvoice_detail_rendered (invoice_id, rendering_time_ms) — page fully renderedinvoice_detail_scrolled (scroll_position_percent) — merchant scrolled (fire on 25%, 50%, 75%, 100%)invoice_header_displayed (invoice_number, client_name, invoice_status, invoice_total) — header showninvoice_status_pill_displayed (status: draft|scheduled|sent|viewed|paid|overdue|cancelled) — status indicator showninvoice_status_changed (old_status, new_status) — status changed (e.g. sent → viewed → paid)invoice_total_displayed (total_amount, currency, tax_breakdown: list) — total and breakdown showninvoice_payment_status_displayed (paid_amount, outstanding_amount, payment_method_if_paid) — payment status showninvoice_due_date_displayed (due_date, days_until_due) — due date shown (with indicator if overdue)invoice_dates_summary_displayed (invoice_date, due_date, reminder_dates) — key dates showninvoice_client_section_displayed (client_name, client_email, client_address) — client info showninvoice_client_avatar_clicked (client_id, client_name) — merchant tapped client avatarinvoice_client_name_clicked (client_id, client_name) — merchant tapped client name (navigates to client profile)invoice_client_email_clicked (client_email) — merchant tapped email (opens mail client or action sheet)invoice_client_details_edit_clicked — merchant tapped "Edit client"invoice_client_details_updated (field_changed: name|email|address) — client details edited inlineinvoice_line_items_section_displayed (items_count) — line items showninvoice_line_item_expanded (item_position) — line item expanded for detailsinvoice_line_item_tax_breakdown_shown (item_position, tax_rate, tax_amount) — tax details displayedinvoice_line_item_discount_shown (item_position, discount_type, discount_amount) — discount showninvoice_payment_methods_displayed (accepted_methods: list) — payment method badges showninvoice_payment_link_displayed (payment_link_url) — hosted payment page link showninvoice_payment_link_copied (payment_link_url) — merchant copied linkinvoice_payment_link_qr_displayed — QR code shown for payment linkinvoice_payment_link_qr_downloaded — merchant downloaded QR codeinvoice_payment_history_displayed (payment_count) — payment transaction list showninvoice_payment_record_viewed (payment_id, payment_date, payment_amount, payment_method) — payment details viewedinvoice_delivery_history_displayed (delivery_count, deliveries: list) — delivery timeline showninvoice_delivery_record_viewed (delivery_id, delivery_method, delivery_time, recipient_address) — single delivery details viewedinvoice_delivery_status_shown (delivery_id, status: sent|delivered|opened|bounced) — delivery status indicatorinvoice_open_tracking_displayed (open_count, first_open_time, last_open_time) — email open tracking showninvoice_link_click_tracking_displayed (click_count) — link click tracking showninvoice_reminder_history_displayed (reminder_count, reminders_sent: list) — reminders sent showninvoice_reminder_record_viewed (reminder_id, reminder_time, reminder_channel) — reminder details viewedinvoice_action_bar_displayed (available_actions: list) — action buttons shown at bottom (or top, depending on device)invoice_action_remind_clicked (invoice_id, status) — merchant tapped "Remind"invoice_remind_options_shown (reminder_options: list) — remind method picker displayedinvoice_action_duplicate_clicked (invoice_id) — merchant tapped "Duplicate"invoice_duplicate_confirmation_shown — "Create duplicate invoice?" modal showninvoice_duplicated (original_invoice_id, new_invoice_id) — invoice duplicatedinvoice_action_share_clicked (invoice_id) — merchant tapped "Share"invoice_share_sheet_opened (available_methods: list) — share options displayedinvoice_share_method_selected (share_method: email|link|sms|whatsapp|print) — merchant chose methodinvoice_action_download_pdf_clicked (invoice_id) — merchant tapped "Download"invoice_pdf_generated (invoice_id, file_size_bytes, generation_time_ms) — PDF createdinvoice_pdf_downloaded (invoice_id, file_size_bytes) — PDF downloadedinvoice_action_edit_clicked (invoice_id, status) — merchant tapped "Edit"invoice_action_cancel_clicked (invoice_id, status) — merchant tapped "Cancel"invoice_cancel_confirmation_shown — "Cancel invoice?" modal showninvoice_cancelled (invoice_id) — invoice cancelledinvoice_action_mark_paid_clicked (invoice_id, status) — merchant tapped "Mark as paid"invoice_mark_paid_options_shown (payment_methods: list) — payment method selector showninvoice_mark_paid_confirmed (invoice_id, payment_method) — invoice marked paidinvoice_action_menu_opened — overflow menu expandedinvoice_action_menu_closed — overflow menu collapsedinvoice_action_whatsapp_clicked (invoice_id) — merchant tapped WhatsApp actioninvoice_action_print_clicked (invoice_id) — merchant tapped "Print"invoice_automations_displayed (automations: list) — active automations shown (reminders, recurring, autopilot badges)invoice_reminders_status_shown (reminder_schedule: list, next_reminder_date) — reminder config displayedinvoice_reminders_edit_clicked (invoice_id) — merchant tapped "Edit reminders"invoice_reminders_configuration_changed (new_schedule: list) — reminders updatedinvoice_recurring_status_shown (frequency, end_condition, next_issue_date, send_mode) — recurring config displayedinvoice_recurring_edit_clicked (invoice_id) — merchant tapped "Edit recurring"invoice_recurring_configuration_changed (new_frequency, new_end_condition) — recurring updatedinvoice_recurring_pause_clicked (invoice_id) — merchant paused recurringinvoice_recurring_paused (invoice_id, pause_until_date) — recurring pausedinvoice_recurring_resume_clicked (invoice_id) — merchant resumed recurringinvoice_autopilot_status_shown (payment_method, charge_timing, failure_handling, next_charge_date) — autopilot config displayedinvoice_autopilot_edit_clicked (invoice_id) — merchant tapped "Edit autopilot"invoice_autopilot_configuration_changed (new_payment_method, new_charge_timing) — autopilot updatedinvoice_autopilot_pause_clicked (invoice_id) — merchant paused autopilotinvoice_autopilot_paused (invoice_id) — autopilot pausedinvoice_automation_remove_clicked (automation_type, invoice_id) — merchant removed automationinvoice_automation_removed (automation_type, invoice_id) — automation deletedinvoice_repeat_customer_insight_shown (customer_id, customer_name, invoice_count) — repeat-customer insight card showninvoice_repeat_customer_action_clicked (action: queue_autopilot_invite|dismiss) — merchant interacted with insightinvoice_recipient_autopilot_readiness_shown (customer_id, payment_methods_on_file: count) — recipient has payment method on file (prompt to enable autopilot)invoice_recipient_autopilot_invite_queued (customer_id, invoice_id) — merchant opted to queue autopilot invite for recipientinvoice_related_invoices_section_shown (customer_id, related_invoice_count) — other invoices for this customer showninvoice_related_invoice_clicked (related_invoice_id, customer_id) — merchant navigated to related invoiceinvoice_export_clicked (export_format: pdf|json|csv) — merchant tapped exportinvoice_exported (invoice_id, export_format, file_size_bytes) — invoice exportedinvoice_integration_available_shown (integration_type: accounting|erp|crm) — integration suggestion showninvoice_integration_clicked (integration_type) — merchant opened integration dialoginvoice_detail_back_clicked — merchant tapped back buttoninvoice_detail_exited (time_on_page_seconds) — merchant navigated awayinvoice_detail_tab_switched (from_tab, to_tab) — merchant switched tabs (if tabbed interface)---
session_started (session_id, user_id, app_version, platform: web|ios|android, device_type) — session initiatedsession_ended (session_id, session_duration_seconds, event_count) — session ended (idle, logout, app close)session_idle_timeout_warning_shown (time_remaining_seconds) — inactivity warning displayedsession_idle_timeout_extended — merchant tapped "Keep me signed in"session_idle_timeout_expired — merchant was logged out due to inactivityuser_logged_in (user_id, login_method: email|oauth|sso, time_since_last_login_days) — user authenticateduser_logged_out (user_id, session_duration_seconds) — user logged out explicitlynavigation_tab_clicked (tab: invoices|settings|help|account) — merchant tapped bottom tab or top navnavigation_menu_opened — navigation menu/drawer openednavigation_menu_closed — navigation menu closedpage_transition (from_page, to_page, transition_type: push|modal|tab) — page changeddeep_link_opened (deep_link_url, page_destination) — deep link was followedhelp_icon_clicked (page, context) — merchant tapped help iconhelp_menu_opened — help menu appearedhelp_article_viewed (article_id, article_title, category) — merchant read help articlehelp_article_search_performed (search_term, result_count) — merchant searched helpcontextual_tooltip_shown (tooltip_id, page, feature) — tooltip displayedcontextual_tooltip_dismissed (tooltip_id) — merchant closed tooltipcontextual_tooltip_action_clicked (tooltip_id, action) — merchant tapped action in tooltipfeature_discovery_nudge_shown (feature: ai_upload|recurring|autopilot|...) — nudge displayed for new/underused featurefeature_discovery_nudge_dismissed (feature) — merchant closed nudgefeature_discovery_nudge_converted (feature, next_action: try_feature|learn_more|dismiss) — merchant took actionin_app_message_shown (message_id, message_type: announcement|promotion|alert) — in-app message displayedin_app_message_action_clicked (message_id, action) — merchant tapped CTAin_app_message_dismissed (message_id) — merchant closed messageonboarding_tutorial_started — merchant started guided tutorialonboarding_tutorial_step_completed (step_number, step_name) — tutorial step finishedonboarding_tutorial_completed — full tutorial completedonboarding_tutorial_abandoned (completed_steps: count, abandoned_at_step) — merchant quit tutorial earlyerror_displayed (error_code, error_type, error_message, page) — error shown to merchanterror_dismissed (error_code) — merchant closed errorerror_retry_clicked (error_code) — merchant tapped retry after errorapi_error_occurred (error_code, endpoint, http_status, error_message) — API call failed (backend event, may be logged server-side)validation_error_shown (error_type, field_name, page) — form validation failednetwork_error_detected (error_type: timeout|connection_lost|offline) — network issue detectedoffline_mode_entered — device went offlineoffline_mode_exited — device came back onlineapp_crash_detected (crash_id, error_type, error_message, stack_trace) — app crashed (session/analytic error boundary)error_boundary_triggered (error_type, page) — React error boundary caught errorclient_side_warning_logged (warning_type, warning_message) — client-side warning (console.warn equivalent)page_load_time (page, time_to_interactive_ms, first_contentful_paint_ms) — page load performanceapi_response_time (endpoint, method, response_time_ms, data_size_bytes) — API performancefile_upload_time (file_type, file_size_bytes, upload_time_ms) — upload durationpdf_generation_time (invoice_id, generation_time_ms) — PDF creation durationai_extraction_time (file_type, file_size_bytes, processing_time_ms, confidence_level) — AI processing durationform_submission_time (form_type, submission_time_ms) — form completion durationfeature_flag_evaluated (flag_name, flag_value: on|off, experiment_id) — feature flag check occurredfeature_flag_exposed (flag_name, flag_value, experiment_id, variant) — merchant exposed to variantab_test_assigned (test_id, test_name, variant, variant_description) — merchant assigned to A/B test variantab_test_variant_viewed (test_id, variant, page, time_on_variant_seconds) — variant experiencedab_test_metric_recorded (test_id, variant, metric_type, metric_value) — test metric collectedpermission_requested (permission_type: camera|contacts|location) — OS permission requestedpermission_granted (permission_type, by_user: boolean) — permission approvedpermission_denied (permission_type) — permission deniedanalytics_consent_requested — privacy/analytics consent dialog shownanalytics_consent_given (consent_type: analytics|marketing) — merchant opted inanalytics_consent_withdrawn — merchant revoked consentterms_displayed — terms of service shownterms_accepted — merchant agreed to termsprivacy_policy_opened — merchant read privacy policyfeature_used (feature_name, feature_context) — generic feature usage eventuser_preference_changed (preference_type, old_value, new_value) — merchant changed settinguser_setting_opened (settings_page) — settings page viewedcurrency_preference_changed (old_currency, new_currency, scope: merchant_default|invoice_specific) — currency preference updatedlanguage_preference_changed (old_language, new_language) — language preference updatedtimezone_preference_changed (old_timezone, new_timezone) — timezone preference updatednotification_preference_changed (notification_type, enabled: boolean) — notification setting toggledinvoice_shared (share_method: email|link|sms|whatsapp|print, invoice_id) — invoice shared via methodshared_link_generated (link_id, invoice_id, link_scope: merchant|recipient) — share link createdshared_link_opened_by_recipient (link_id, recipient_user_agent) — shared link accessedshared_link_expired (link_id) — share link expiredsocial_media_share_clicked (platform) — merchant shared to social (if applicable)feedback_sent (feedback_type, feedback_text, screenshot_included: boolean) — merchant submitted feedbackfeedback_reaction_given (feedback_id, reaction: helpful|not_helpful) — feedback was usefulinvoice_created (invoice_id, creation_method: manual|ai|job|contract|template, template_id) — new invoice created (backend event)invoice_updated (invoice_id, fields_changed: list) — invoice modifiedinvoice_sent (invoice_id, delivery_channel, recipient_email, scheduled: boolean) — invoice delivered (backend event)invoice_reminder_scheduled (invoice_id, reminder_type, reminder_datetime) — reminder queued (backend event)invoice_paid_partially (invoice_id, paid_amount, outstanding_amount, payment_method) — partial payment received (backend event)invoice_paid_fully (invoice_id, total_paid, payment_method, settlement_status) — invoice paid in full (backend event)invoice_overdue (invoice_id, days_overdue) — invoice passed due date (backend event, may trigger notifications)invoice_marked_unpaid (invoice_id, reason) — merchant reset paid status (backend event)recurring_invoice_issued (recurring_id, issued_invoice_id, issue_datetime) — recurring invoice auto-generated (backend event)recurring_invoice_failed (recurring_id, error_type, error_message, retry_scheduled: boolean) — recurring auto-issue failed (backend event)autopilot_charge_attempted (autopilot_id, invoice_id, charge_amount, charge_datetime) — autopilot initiated charge (backend event)autopilot_charge_succeeded (autopilot_id, invoice_id, charge_amount, settlement_reference) — autopilot collected payment (backend event)autopilot_charge_failed (autopilot_id, invoice_id, error_type, error_message, retry_scheduled: boolean) — autopilot charge declined (backend event)recipient_opened_link (invoice_id, recipient_id, link_open_datetime, recipient_user_agent) — recipient clicked payment link (backend event from payment page analytics)recipient_viewed_invoice (invoice_id, recipient_id, view_datetime) — recipient viewed invoice (backend event, may be tracked via email open or link click)recipient_autopilot_accepted (autopilot_invite_id, customer_id, mandate_id, payment_method) — recipient saved card and enrolled in autopilot (backend event, HEADLINE RECIPIENT-SIDE METRIC)mandate_created (mandate_id, customer_id, payment_method, mandate_type) — payment mandate authorized (backend event)mandate_failed (mandate_id, customer_id, error_type, error_message) — mandate authorization failed (backend event)payment_reconciliation_completed (invoice_id, reconciliation_status: matched|pending|unmatched) — payment matched to invoice (backend event)template_created (template_id, template_source: from_invoice|from_scratch, creator_id) — invoice template saved (backend event)template_used (template_id, new_invoice_id, created_by: merchant|system) — template applied (backend event)client_created (client_id, created_via: manual|ai_extraction|import) — new client added (backend event)client_auto_suggested (client_id, source: history|autocomplete) — client suggested to merchant (backend event)---