25. Finance Management
Pixally CRM☑️ Billing > Invoices Tab
Finances Billing module - Invoices Tab FRD
1. Module Overview
- Module Name: Billing > Invoices Tab
- Purpose: The Invoices Tab within the Billing submodule serves as the central hub for managing all client invoices across the agency. It provides a comprehensive view of invoice statuses, payment schedules, and associated transactions, and enables agency owners to track payment collection progress on a per-project basis.
- Business Goal: Enable agency owners to efficiently manage client billing by providing visibility into invoice statuses, payment schedules, and financial health. The module ensures streamlined payment collection, accurate financial tracking per project, and seamless integration with external accounting systems (QuickBooks) to maintain financial integrity and reduce administrative overhead.
2. User Roles & Permissions
Refer - Click Here
3. User Flow
Navigation Path: Sidebar → Finances → Billing → Invoices Tab
Primary User Flow - Viewing and Managing Invoices:
- Access Billing Module: User navigates to the Finances section and selects Billing.
- Land on Invoices Tab: System displays the Invoices tab as default with "All" sub-tab selected.
- View Invoice List: User sees a table of active invoices sorted by next payment date (overdue first).
- Filter by Brand: User selects brand from the dropdown to filter invoices.
- Search: User enters search terms to find specific invoices.
- Expand Invoice Details: User clicks the expand arrow to view transactions inline.
- Perform Actions: User accesses the three-dot menu for View Details, Download PDF, or Deactivate.
- View Deactivated: User switches to the Deactivated sub-tab to reactivate invoices.
Alternative Flow - Empty State Handling:
- User navigates to the Billing module.
- System checks prerequisites (Stripe, Brands, Projects, Invoices).
- If missing, the system displays an appropriate empty state with action prompts.
- User follows guided actions to complete setup.
4. Functional Logic
4.1 Empty State Management
The system performs a structured, priority-based empty state evaluation to ensure all required prerequisites are completed before the user can access the Billing → Invoices tab.
Only one empty state is displayed at a time based on the highest applicable condition.
Priority Order of Empty State Checks
4.1.1 No Brands Created (Highest Priority)
- Condition: The user has not created any brand under the agency.
- System Behavior:
- Displays an empty state with the message: “Create a brand to organize your projects and billing.”
- Shows a CTA button: “Setup Brand”
- CTA Action: Opens the brand creation workflow (Brand Setup wizard → Step 1).
4.1.2 No Stripe Account Connected
- Condition: Brands exist, but the user has not connected a Stripe account for payment processing.
- System Behavior:
- Displays an empty state with the message: “Connect your Stripe account to start collecting payments.”
- Shows a CTA button: “Connect Stripe”
- CTA Action: Redirects the user to: Settings → Business & Payment Details → Stripe Connection
4.1.3 No Projects Created
- Condition: At least one brand exists and Stripe is connected, but the user has not created any projects.
- System Behavior:
- Displays an empty state with the message: “Create a project to begin invoicing clients.”
- Shows a CTA button: “Create Project”
- CTA Action: Opens the project creation workflow (Project → Create New).
4.1.4 No Invoices Created
- Condition: Brands exist, Stripe is connected, and at least one project exists, but no invoices have been created.
- System Behavior:
- Displays an empty state with the message: “No invoices found. Invoices appear when proposals are accepted or created manually.”
- Shows a CTA button: “Go to Projects”
- CTA Action: Navigates to the Projects module.
Business Rules
- The system evaluates empty states in strict priority order (4.1.1 → 4.1.2 → 4.1.3 → 4.1.4). Only the highest applicable empty state is shown.
- If no brand exists, all subsequent checks are skipped.
- When any empty state is active:
- The Brand Filter dropdown is disabled.
- The invoice list table remains hidden.
- When all prerequisites are satisfied, the invoice list becomes visible.
4.2 Invoice List Display
Default Sort Order:
- Primary: Overdue invoices appear first.
- Secondary: Next payment date ascending (nearest first).
- Tertiary: Invoice ID descending (newest first).
Pagination:
- Default: 10 rows per page
- Options: 10, 25, 50, 100
- Display: "1-10 of X" format
- Persists when switching between All/Deactivated tabs
4.3 Invoice Status Logic
Invoice status is automatically calculated based on the collective status of all associated transactions.
Status
Trigger Condition
Unpaid
All transactions "Unpaid" and none overdue
Partially Paid
At least one "Paid" AND at least one "Unpaid"/"Processing" (no overdue)
Paid
All transactions "Paid"
Overdue
At least one transaction "Overdue" (due date passed without payment)
Partially Refunded
At least one transaction refunded but not all
Refunded
All paid transactions fully refunded
Deactivated
Manually deactivated by admin
Status Priority Rules:
- Deactivated overrides all other statuses.
- Overdue takes precedence over Partially Paid or Unpaid.
- Refunded only applies when ALL collected payments returned.
- Status updates in real-time as transaction statuses change.
4.4 Invoice-to-Transaction Grouping
Relationship:
Each invoice has a one-to-many relationship with transactions. Every scheduled payment creates a corresponding transaction.
Expand/Collapse Behavior:
- Collapsed (Default): Only invoice row visible with summary.
- Expanded: All transactions displayed inline below invoice.
- Visual: Down arrow collapsed, Up arrow expanded.
- Transaction Display: Indented rows with Payment Date, Amount, Status, Actions.
Transaction Status Badges:
- Paid: Green badge
- Unpaid: Orange/Yellow badge
- Processing: Blue badge (ACH 4-5 days)
- Overdue: Red badge
- Failed: Dark Red badge
- Refunded: Gray badge
4.5 Payment Schedule Logic
Automatic Invoice Creation (from Proposal):
- When proposal accepted, system automatically generates invoice.
- Invoice inherits exact payment schedule from proposal (same dates, amounts, installments).
- Each scheduled payment becomes a transaction.
- Invoice automatically linked to same project as proposal.
Payment Schedule Rules:
- Minimum 1 scheduled payment per invoice.
- No maximum limit on installments.
- Only fixed-split payments supported (no custom partial amounts).
- Sum of payments must equal total invoice amount.
- Admin can adjust schedule after creation (dates, split amounts).
Next Payment Date Calculation:
- System identifies earliest "Unpaid" or "Overdue" transaction.
- If overdue exists, earliest overdue date displayed.
- If no unpaid transactions remain, displays "-" or "Complete."
- Format: "Mon DD, YYYY" (e.g., "Oct 5, 2024").
4.6 Filtering and Search Functionality
Brand Filtering:
- Location: Top right dropdown labeled "All Brands."
- Options: "All Brands" (default) + all active brands.
- Behavior: Filters to invoices for projects under selected brand.
- Persistence: Persists only within current tab; switching to Transactions resets it.
- Update: Table refreshes immediately on selection.
Search Functionality:
- Location: Search bar next to brand filter.
- Searchable Fields:
- Invoice ID (e.g., "#INV00004")
- Client name (partial match)
- Project name (partial match)
- Type: Case-insensitive, partial match (contains).
- Real-time: Results filter as user types (300ms debounce).
- Clear: X button to clear search field.
4.7 Invoice Deactivation and Reactivation
Deactivation Eligibility:
- Can deactivate: Unpaid, Partially Paid, or Overdue invoices.
- Cannot deactivate: Paid, Refunded, Partially Refunded, or invoices with "Processing" transactions.
- Reason: Prevents financial inconsistencies during active payments.
Impact of Deactivation:
- Payment Collection Blocked: No payments can be collected.
- Transactions Hidden: All transactions hidden from Transactions tab.
- No Workflow Blocking: Other workflows function normally.
- Tab Movement: Invoice moves to Deactivated tab.
- Status Update: Status changes to "Deactivated."
- Audit Trail: Action logged with timestamp and user.
- Statuses Preserved: Transaction statuses remain unchanged internally.
Reactivation Logic:
- Access: "Reactivate" button in Deactivated tab.
- Data Restoration: All data restores exactly as before.
- Status Recalculation: Status recalculated (may become Overdue).
- Transactions Visible: Transactions reappear in Transactions tab.
- Invoice Returns: Returns to All tab.
- Audit Trail: Reactivation action logged.
4.8 Invoice Actions Menu
Actions in All Tab:
- View Details: Opens detailed view with Invoice ID, Client info, Line items, Payment schedule, Transaction history.
- Download PDF: Generates branded PDF with line items, taxes, payment schedule. File: "Invoice_[ID]_[Client].pdf"
- Deactivate Invoice: Confirmation dialog required. Disabled if Processing transactions exist.
Actions in Deactivated Tab:
- View Details
- Download PDF
- Reactivate Invoice
4.9 Project Linking Logic
Core Rules:
- Every invoice belongs to exactly one project (mandatory).
- Transactions inherit the same project as their invoice.
- Project's client automatically becomes invoice owner.
- Projects under brands establish filtering structure.
Project Determines:
- Client association
- Brand association (for filtering)
- Visibility and access permissions
- Revenue attribution
Multi-Project Clients:
- Single client can have multiple projects (Wedding, Engagement, etc.).
- Each project generates separate invoice(s).
- Billing records maintained per project, not aggregated.
- Client appears multiple times with different projects.
4.10 Impact on Other Modules
Dashboard:
- Outstanding invoices count reflects active invoices only.
- Revenue tracking includes only Paid transactions.
- Overdue alerts display prominently.
QuickBooks Sync:
- CRITICAL: Only "Paid" transactions sync to QuickBooks.
- Unpaid, Processing, Failed, Overdue NOT synced.
- Refunds trigger reversal entries.
- Deactivated invoice transactions excluded.
Profit & Loss:
- Revenue includes only Paid transactions.
- Refunds appear as adjustments.
- Project-level profitability tied to payments.
Proposals Module:
- Accepted proposals auto-generate invoices.
- Payment schedule inherited.
- Proposal status updates to "Accepted."
Client Portal:
- Clients view invoices and payment history.
- Deactivated invoices hidden from client view.
- Payment buttons disabled for deactivated/paid invoices.
5. Field Details & Validations
Table Structure:
Column
Data Displayed
Sorting
Expand/Collapse
Arrow icon for transaction list
Not sortable
Next Payment Date
Date of next scheduled payment
Sortable (Default: ascending, overdue first)
Invoice ID
Unique identifier (#INV00004)
Sortable
Client
Client avatar and full name
Sortable (alphabetically)
Amount
Total invoice amount
Sortable (numerical)
Payments
Total scheduled payments count
Sortable (numerical)
Status
Invoice status badge
Not sortable
Project
Associated project name
Sortable (alphabetically)
Actions
Three-dot menu
Not sortable
5.1 Invoice List Table Fields
Field Name
Type
Format
Validation
Next Payment Date
Date
"Mon DD, YYYY"
System-calculated, read-only
Invoice ID
Auto-generated
"#INVXXXXX"
Unique, sequential, immutable
Client Name
Text + Avatar
"[Avatar] Full Name"
Inherited from project, required
Amount
Currency
"$X,XXX.XX"
Must be > $0, two decimals
Payments Count
Integer
Number (e.g., "3")
Minimum 1, no maximum
Status Badge
Badge
Colored badge with text
System-calculated, read-only
Project Name
Text
Full project name
Required, immutable link
5.2 Search and Filter Fields
Field
Type
Format
Validation
Search Bar
Text Input
Placeholder text
No character limit, 300ms debounce
Brand Filter
Dropdown
Default: "All Brands"
Single selection
Rows Per Page
Dropdown
Default: "10"
Options: 10, 25, 50, 100
6. Error Message Handling
Scenario
Trigger
Message
Type
No Search Results
Query returns zero matches
"No invoices found matching your search criteria."
Info
Deactivate Blocked
Processing transaction exists
"Cannot deactivate. Payments are processing."
Error
Deactivate Confirm
User clicks Deactivate
"Are you sure? Payments cannot be collected until reactivated."
Warning
Deactivate Success
Successful deactivation
"Invoice #INVXXXXX deactivated successfully."
Success
Reactivate Success
Successful reactivation
"Invoice reactivated. Payments can now be collected."
Success
PDF Download Fail
Generation fails
"Failed to generate PDF. Please try again."
Error
Network Error
API request fails
"Unable to load. Check your connection."
Error
Stripe Not Connected
No Stripe account
"Connect Stripe to start collecting payments."
Info
7. Edge Cases & Special Scenarios
Scenario
Expected Behavior
All transactions Processing
Status shows "Partially Paid". Deactivation blocked.
Transaction becomes Overdue while deactivated
Updates internally. On reactivation, invoice shows Overdue.
Client has invoices across multiple brands
Brand filter shows only invoices for selected brand's projects.
Partial refund on transaction
Invoice becomes "Partially Refunded". QuickBooks receives reversal.
Search for deactivated invoice in All tab
Returns no results. User must switch to Deactivated tab.
Project deletion with existing invoice
Blocked if unpaid invoices exist.
Very long client/project name
Truncated with ellipsis. Full name on hover.
Invoice has 100+ transactions
Virtualized list with scroll for performance.
Brand is deleted
Invoices remain visible via "All Brands". Brand removed from dropdown.
8. Acceptance Criteria
Core Functionality:
- Users can view all active invoices in sortable, paginated table.
- Invoice status auto-calculates based on transaction statuses.
- Users can expand/collapse invoices to view transactions inline.
- Brand filtering works correctly for projects under selected brand.
- Search returns results for Invoice ID, Client name, or Project name.
Deactivation/Reactivation:
- Users can deactivate Unpaid, Partially Paid, or Overdue invoices.
- Deactivation blocked for Processing transactions.
- Deactivated invoices appear only in Deactivated tab.
- Reactivation restores all data and recalculates status.
- Audit trail logs all deactivation/reactivation actions.
Integration:
- Only Paid transactions sync to QuickBooks.
- Dashboard widgets reflect accurate counts and statuses.
- Project linking maintains data integrity across modules.
9. Dependencies
Module/System
Type
Impact if Unavailable
Stripe Payment Gateway
Integration
Cannot collect payments. Empty state displayed.
Projects Module
Data Dependency
Cannot create/link invoices. Project names may fail.
Clients Module
Data Dependency
Client info unavailable. No names/avatars.
Proposals Module
Integration
Auto-generation from proposals fails.
QuickBooks Integration
Integration
Paid transactions not synced. Manual reconciliation needed.
Authentication Service
Security
Users cannot access module.
Audit Trail Service
Service
Actions not logged. Compliance compromised.
10. References
Design Files:
- Figma/Sketch link - [To be added]
Deprecated—--------------
4. Field Details & Validations
Field Name
Type
Required
Validation Rules
Next Payment Date
Date
Yes
Must be a valid date format, auto-calculated from the package schedule, the breakdown of the split payment will shuffle, and the nearest payment date will be at the top
Invoice ID
Alpha numeric
Yes
Auto-generated: "INV" + sequential number for main invoice, append "-1", "-2" etc. for split payments
Client Name
Text
Yes
Client’s profile image with the client name from the client module
Amount
Currency
Yes
Must be a positive number, formatted to 2 decimal places. The 1st row will consist of the sum of the total invoice value autopopulated from the package selected
Payment Splits
Number
No
An integer showing the total number of payment splits based on the package’s payment terms (shown in the primary row).
Each line split displays the split amount” status row by row.
Payment Status
Text
Yes
Values: Unpaid, Processing, Paid, Overdue, Failed, Refund
“Deactivated” status
Payment Status
only visible in the
Text
Conditional(only visible in the deactivated tab )
“Deactivated” status on the primary row for the deactivated invoices,
Reactivate tab
CTA
Conditional(only visible in the deactivated tab )
It can reactivate and move the invoice to the “All” sub-tab of invoices
Project Name
Text
Yes
Links to the associated project
5. Success Message Handling
Validation Scenario
Success Message
Invoice PDF downloaded
"Invoice PDF downloaded successfully."
Invoice link copied
"Invoice link copied to clipboard."
Invoice deactivated
"Invoice has been deactivated successfully."
Invoice reactivated
"Invoice has been reactivated successfully."
6. Error Message Handling
Field
Validation Scenario
Error Message
General
Network connection failed
"Unable to load invoices. Please check your connection and try again."
General
Server timeout
"Request timed out. Please refresh and try again."
Invoice Actions
PDF generation failed
"Unable to generate PDF. Please try again later."
Invoice Actions
Print job failed
"Unable to print invoice. Please check the printer connection."
Brand Filter
No results found
"No invoices found for the selected brand."
Deactivation
Action failed
"Unable to deactivate invoice. Please try again."
Reactivation
Action failed
"Unable to reactivate invoice. Please try again."
8. Edge Cases
Scenario
Expected Behavior
Payment status changes from Paid to Refund
System maintains payment history, updates current status, and preserves previous status in the invoice record
Large number of payment splits (>10)
System handles gracefully with scroll or pagination within the expanded view
Brand filter returns no results
Display an empty state with clear messaging and an option to clear the filter
PDF generation for large invoices
System shows loading indicator, generates PDF asynchronously
11. Dependencies
Module/System
Impact if Unavailable
Packages Module
Cannot auto-generate invoices if there are no proposals
Project Management
Cannot link invoices to projects, PM role restrictions fail
Client Management
Cannot display client information and profiles
Payment Gateway
Cannot process payment status updates
Proposal System
Cannot auto-generate invoices from signed proposals
12. References
☑️ Billing > Transactions Tab
Functional Requirements Document (FRD) - Transactions Tab
1. Module Overview
- Module Name: Billing → Transactions Tab
- Purpose: The Transactions tab provides a centralized, status-driven view of all payment schedule items (transactions) across client invoices. It enables agency owners and financial administrators to monitor payment lifecycles, track failed payments, manage overdue collections, process refunds, and maintain QuickBooks synchronization from a single interface.
- Business Goal: To give agencies complete visibility and control over their payment collection pipeline, reduce revenue leakage through proactive overdue management, streamline refund processing, and ensure accurate financial record-keeping across integrated accounting systems.
2. User Roles & Permissions
Refer- Click Here
3. User Flow
Navigation Path: Main Menu → Finances → Billing → Transactions Tab
Step-by-Step Flow:
- User clicks "Finances" in the left navigation menu, which expands to show sub-options.
- User clicks "Billing" to access the Billing module.
- System displays the Billing page with two primary tabs: "Invoices" and "Transactions."
- User clicks the "Transactions" button (highlighted/active state).
- System displays the Transactions view with six sub-tabs: Unpaid, Processing, Paid, Overdue, Failed, Refunds.
- By default, system loads the "Unpaid" sub-tab showing all unpaid transactions.
- User can switch between sub-tabs to view transactions filtered by status.
- User can apply additional filters using the Brand dropdown, search bar, or Filters panel.
- User can sort columns by clicking column headers.
- User can perform actions via the Actions menu (three-dot icon) on each transaction row.
- For specific sub-tabs (Overdue), user can click dedicated action buttons (Remind) directly in the row.
Alternative Flows:
- Direct Navigation via URL: User can access specific sub-tabs directly via URL parameters
- Cross-Module Navigation: User clicks on Invoice ID in the transaction row to navigate to the Invoice detail view.
- Filter-First Approach: User opens the Filters panel first, applies filters, then browses sub-tabs with filters persisted.
4. Functional Logic
4.1 Page Layout & Common Elements
Overview: The Transactions tab shares a consistent layout across all six sub-tabs while adapting specific columns and actions based on transaction status.
Common Header Elements:
- Page Title: "Billing" (persistent across Invoices and Transactions tabs)
- Tab Switcher: Two buttons - "Invoices" (outline style) and "Transactions" (filled/active style)
- Brand Dropdown: Single-select dropdown defaulting to "All Brands," positioned top-right
- Search Bar: Text input for searching across Invoice ID, Client name, and Project name
- Filter Icon: Opens the Filters slideout panel
Sub-Tab Navigation:
- Horizontal tab bar with six status tabs: Unpaid | Processing | Paid | Overdue | Failed | Refunds
- Active tab displays with underline indicator
- Tab badges showing count of transactions (optional based on configuration)
Common Table Structure:
- Sortable column headers (indicated by ↓ icon)
- Client column displays avatar + full name
- Amount column shows dollar value with "X of Y" indicator (e.g., "1 of 2" for payment schedule position)
- Status column displays colored badge (varies by sub-tab)
- Project column shows linked project name
- Actions column contains three-dot menu for row actions
Pagination:
- "Rows per page" dropdown: Options 10, 25, 50, 100
- Default: 25 rows per page
- Page indicator: "1-4 of 4" format
- Previous/Next navigation arrows
Empty State (No Transactions Exist): When there are no transactions in the system at all (not just filtered results), the Transactions tab displays:
- Centered illustration/icon representing transactions or payments
- Heading: "No transactions yet"
- Subtext: "Transactions will appear here once you create invoices with payment schedules"
- Call-to-action button: "Create Invoice" (links to Invoice creation flow)
This empty state appears when the agency has not yet created any invoices with payment schedules. Once invoices are created, individual sub-tabs will show their own status-specific empty states.
4.2 Unpaid Sub-Tab
Overview: Displays all transactions that have not yet been paid and are not yet overdue.
Entry Criteria: Transaction status = "Unpaid" AND payment_due_date ≥ current_date
Displayed Columns:
- Payment Date (sortable) - The scheduled payment due date
- Invoice ID (sortable) - Format: #INVXXXXX
- Client (sortable) - Avatar + Full Name
- Amount (sortable) - Dollar amount + payment schedule position
- Status (sortable) - "Unpaid" badge (gray/neutral color)
- Project (sortable) - Project name
- Actions - Three-dot menu
Default Sort: Payment Date ascending (earliest due dates first)
Available Actions (Three-dot menu):
- View Details → Opens transaction/invoice detail view
- Copy Invoice Link → Copies client payment portal URL to clipboard
- Download PDF → Downloads invoice PDF
- Print Invoice → Opens print dialog for invoice
- Mark as Paid → Opens manual payment recording dialog
Business Rules:
- Transactions automatically move to Overdue sub-tab when payment_due_date < current_date (scheduled job runs at midnight in agency's timezone).
- Transactions move to Processing when client initiates payment via Stripe.
- Transactions from deactivated invoices are hidden from this view.
- Display shows only active invoice transactions.
Empty State:
- Message: "No unpaid transactions"
- Subtext: "All scheduled payments have been processed or are not yet due"
4.3 Processing Sub-Tab
Overview: Displays transactions where payment has been initiated but not yet confirmed by Stripe (ACH transfers, 3D Secure authentication pending).
Entry Criteria: Transaction status = "Processing"
Displayed Columns:
- Payment Date (sortable) - Original scheduled payment due date
- Charged (sortable) - Date and time payment was initiated (Format: "January 20, 2025" + "5:48 PM")
- Invoice ID (sortable) - Format: #INVXXXXX
- Client (sortable) - Avatar + Full Name
- Amount (sortable) - Dollar amount + payment schedule position
- Status (sortable) - "Processing" badge (yellow/amber color)
- Project (sortable) - Project name
- Actions - Three-dot menu
Default Sort: Charged date descending (most recent first)
Available Actions (Three-dot menu):
- View Details → Opens transaction detail view
- Copy Invoice Link → Copies payment URL to clipboard
- Download PDF → Downloads invoice PDF
- Print Invoice → Opens print dialog
Business Rules:
- Status transitions via Stripe webhooks only (no manual intervention).
- Processing → Paid: When Stripe confirms successful payment
- Processing → Failed: When Stripe returns failure
- Typical processing duration: ACH (3-5 business days), 3D Secure (minutes to hours).
- System stores timestamp when payment enters Processing state.
- These are one-time payments; system will not automatically retry failed payments.
Empty State:
- Message: "No payments currently processing"
- Subtext: "Payments typically process within 3-5 business days for ACH transfers"
4.4 Paid Sub-Tab
Overview: Displays all successfully completed transactions with payment confirmation, fee details, and QuickBooks sync status.
Entry Criteria: Transaction status = "Paid"
Displayed Columns:
- Payment Date (sortable) - Original scheduled payment due date
- Deposited (sortable) - Date and time payment was confirmed (Format: "January 20, 2025" + "5:48 PM")
- Invoice ID (sortable) - Format: #INVXXXXX
- Client (sortable) - Avatar + Full Name
- Amount (sortable) - Dollar amount + info icon (ⓘ) + payment schedule position
- Status (sortable) - "Paid" badge (green color)
- QuickBooks Icon - Sync status indicator
- Project (sortable) - Project name
- Actions - Three-dot menu
Amount Info Tooltip (on ⓘ hover):
- Transaction Method: [Credit Card / ACH Transfer / Manual – Cash / Manual – Bank Transfer / etc.]
- Amount: $XXX.XX
- Fee: $XX.XX (Stripe + Pixally platform fee, only for online payments)
QuickBooks Sync Status Icons:
- Green QB icon: Successfully synced
- Gray QB icon with red cross: Sync failed (manual retry available)
- No icon: QuickBooks integration not enabled
Default Sort: Deposited date descending (most recent first)
Available Actions (Three-dot menu):
- View Details → Opens transaction detail view
- Sync with QuickBooks → Manual sync trigger (shown only if sync failed or pending)
- Copy Invoice Link → Copies payment confirmation URL
- Download PDF → Downloads receipt/invoice PDF
- Print Invoice → Opens print dialog
- Refund → Opens refund initiation dialog
Business Rules:
- Paid transactions trigger automatic QuickBooks sync immediately when integration is enabled.
- Timestamp stored when payment is confirmed.
- Payment method and transaction fees stored for reporting.
- Paid transactions can only transition to Refunded or Partially Refunded status.
- Manual payments marked as "Manual – [Method]" in transaction method field.
- Only one refund allowed per transaction (full or partial).
Empty State:
- Message: "No paid transactions yet"
- Subtext: "Completed payments will appear here with their receipt details"
4.5 Overdue Sub-Tab
Overview: Displays transactions where the payment due date has passed without successful payment, enabling proactive collection management.
Entry Criteria: (Transaction status = "Unpaid" OR Transaction status = "Failed") AND payment_due_date < current_date
Displayed Columns:
- Payment Date (sortable) - Original scheduled payment due date (past date)
- Invoice ID (sortable) - Format: #INVXXXXX
- Client (sortable) - Avatar + Full Name
- Amount (sortable) - Dollar amount + payment schedule position
- Status (sortable) - "Overdue" badge (red/coral color)
- Project (sortable) - Project name
- Remind Button - Dedicated action button
- Actions - Three-dot menu
Remind Button Behavior:
Normal State (clickable):
- Button text: "Remind"
- Tooltip on hover: "No reminders sent" OR "Reminders sent: X \n Last Reminded: [Date/Time]"
- Click action: Sends reminder email immediately
Disabled State (within 24h cooldown):
- Button text: "Remind" (grayed out)
- Tooltip on hover: "Reminders sent: X \n Last Reminded: [Date/Time] \n ⓘ You will be able to send next reminder after 24h after last one."
- No click action available
Default Sort: Payment Date ascending (oldest overdue first)
Available Actions (Three-dot menu):
- View Details → Opens transaction detail view
- Send Payment Link → Emails payment link to client
- Copy Invoice Link → Copies payment URL to clipboard
- Download PDF → Downloads invoice PDF
- Print Invoice → Opens print dialog
- Mark as Paid → Opens manual payment recording dialog
Business Rules:
- System automatically moves transactions to Overdue via scheduled job (runs at midnight in agency's timezone).
- Both Unpaid and Failed transactions appear here if overdue.
- Reminder cooldown: Minimum 24 hours between reminders per transaction.
- No maximum limit on reminder count.
- Each reminder increments reminder_count and updates last_reminded_at timestamp.
- Reminder email uses system-wide template containing: Invoice details, amount due, days overdue, payment link.
- All reminder actions logged in audit trail with user and timestamp.
Empty State:
- Message: "No overdue transactions"
- Subtext: "Great! All payments are current or have been collected"
4.6 Failed Sub-Tab
Overview: Displays transactions where payment processing failed, showing failure reasons from Stripe for troubleshooting and retry.
Entry Criteria: Transaction status = "Failed"
Displayed Columns:
- Payment Date (sortable) - Original scheduled payment due date
- Failed Date (sortable) - Date and time of failure + Failure Reason (Format: "January 20, 2025" + "Card Declined")
- Invoice ID (sortable) - Format: #INVXXXXX
- Client (sortable) - Avatar + Full Name
- Amount (sortable) - Dollar amount + payment schedule position
- Status (sortable) - "Failed" badge (red color with border)
- Project (sortable) - Project name
- Actions - Three-dot menu
Failure Reasons (from Stripe):
- Card Declined
- Invalid Card Details
- Insufficient Funds
- Payment Blocked
- Expired Card
- Authentication Failed
- Network Error
- Processing Error
Default Sort: Failed Date descending (most recent failures first)
Available Actions (Three-dot menu):
- View Details → Opens transaction detail view with full error information
- Notify Client → Sends failure notification email with reason and retry instructions
- Send Payment Link → Sends new payment link for retry
- Copy Invoice Link → Copies payment URL to clipboard
- Download PDF → Downloads invoice PDF
- Print Invoice → Opens print dialog
Business Rules:
- Failure reason stored directly from Stripe webhook response.
- Failed transactions that pass their due date also appear in Overdue sub-tab.
- Failed timestamp and failure reason stored for each failure.
- Client can retry payment via sent link, which creates new Processing transaction.
- Multiple failure attempts tracked in transaction history.
- Transaction remains in Failed tab until client retries and status changes to Processing or Paid.
- System does not automatically retry failed payments (one-time payment model).
Empty State:
- Message: "No failed transactions"
- Subtext: "All payment attempts have been successful"
4.7 Refunds Sub-Tab
Overview: Displays transactions that have been fully or partially refunded, with refund amounts and reasons.
Entry Criteria: Transaction status = "Refunded" OR Transaction status = "Partially Refunded"
Displayed Columns:
- Payment Date (sortable) - Original scheduled payment due date
- Invoice ID (sortable) - Format: #INVXXXXX
- Client (sortable) - Avatar + Full Name
- Amount (sortable) - Net amount after refund (with strikethrough for original if different) + refund info icon
- Status (sortable) - "Refunded" badge (purple color) OR "Partially Refunded" badge
- QuickBooks Icon - Refund sync status (with circular arrow indicator)
- Project (sortable) - Project name
- Actions - Three-dot menu
Amount Display Logic:
- Full Refund: Shows refunded amount (e.g., "$100.00")
- Partial Refund: Shows net amount (e.g., "$80.00" with tooltip showing original $100.00, refunded $20.00)
Refund Info Tooltip (on amount hover):
- Original Amount: $XXX.XX
- Refunded Amount: $XX.XX
- Net Paid Amount: $XXX.XX (for partial refunds)
- Refund Reason: [User-entered reason text]
QuickBooks Refund Indicator:
- Circular arrow icon showing refund has been synced to QuickBooks
- Gray icon with red cross if sync failed
Default Sort: Payment Date descending (most recent refunds first)
Available Actions (Three-dot menu):
- View Details → Opens refund transaction detail view
- Sync with QuickBooks → Manual sync for failed refund sync
- Download PDF → Downloads refund receipt
- Print Receipt → Opens print dialog for refund receipt
Business Rules:
- Refunds can only be initiated from Paid transactions.
- Partial refunds require amount ≤ original paid amount.
- Refund reason is required (free text field).
- Only one refund allowed per transaction (no subsequent refunds on partially refunded transactions).
- Refunds processed through Stripe API for online payments.
- Manual payment refunds require manual tracking only.
- System stores: original_amount, refunded_amount, net_paid_amount, refund_reason, refunded_at.
- All refund actions logged in audit trail with user and timestamp.
Empty State:
- Message: "No refunded transactions"
- Subtext: "Refund history will appear here when refunds are processed"
4.8 Transaction Status Lifecycle
Overview: Defines all valid status transitions and the triggers that cause them.
Status Values:
- Unpaid - Initial state, awaiting payment
- Processing - Payment initiated, awaiting confirmation
- Paid - Payment successfully completed
- Overdue - Payment due date passed (Unpaid or Failed)
- Failed - Payment attempt unsuccessful
- Refunded - Full refund processed
- Partially Refunded - Partial refund processed
Transition Matrix:
From Status
To Status
Trigger
Automation
Unpaid
Processing
Client initiates payment via Stripe
Automatic (Stripe webhook)
Unpaid
Paid
User marks as paid manually
Manual action
Unpaid
Overdue
Payment due date passes
Automatic (scheduled job at midnight in agency timezone)
Processing
Paid
Stripe confirms payment
Automatic (Stripe webhook)
Processing
Failed
Stripe returns failure
Automatic (Stripe webhook)
Failed
Processing
Client retries payment
Automatic (Stripe webhook)
Failed
Paid
User marks as paid manually
Manual action
Failed
Overdue
Already past due date
Display logic (appears in both tabs)
Paid
Refunded
User initiates full refund
Manual action + Stripe API
Paid
Partially Refunded
User initiates partial refund
Manual action + Stripe API
Overdue
Processing
Client initiates late payment
Automatic (Stripe webhook)
Overdue
Paid
User marks as paid manually
Manual action
Invalid Transitions:
- Processing → Unpaid (cannot reverse payment initiation)
- Paid → Unpaid (cannot unpay completed payment)
- Refunded → Paid (cannot unrefund)
- Partially Refunded → Paid (refund is permanent)
- Partially Refunded → Refunded (only one refund allowed per transaction)
- Any status → Processing (only Stripe can set this)
4.9 Stripe Integration & Webhook Processing
Overview: All online payments are processed through Stripe, with transaction statuses updated via webhooks.
Transaction Creation:
- When an invoice is created with a payment schedule, the system creates individual transaction records for each scheduled payment.
- Each transaction is linked to: Invoice ID, Project ID, Client ID, Brand ID.
- Initial status: Unpaid
- Payment amount and due date set from invoice payment schedule.
- Each transaction shows independently based on its own status (e.g., for invoice with 3 payments, one could be Paid while others remain Unpaid).
Stripe Payment Flow:
- Payment Initiation:
- Client clicks payment link in email or client portal.
- System creates Stripe PaymentIntent with transaction metadata.
- Transaction status → Processing.
- Data Synchronized from Stripe:
- Transaction ID (Stripe PaymentIntent ID)
- Payment method type (card, ach_debit)
- Last 4 digits of payment method
- Processing fees (Stripe fees + Pixally platform fee)
- Failure codes and decline reasons
- Refund transaction IDs
Fee Calculation:
- Stripe fee: Standard Stripe rates (e.g., 2.9% + $0.30 for cards)
- Pixally platform fee: Configurable percentage (set at account level)
- Total fee stored
- Displayed in the Paid tab amount tooltip
4.10 Reminder Logic (Overdue Management)
Overview: Enables systematic follow-up on overdue payments with email reminders and tracking.
Reminder Initiation:
- User clicks "Remind" button on overdue transaction row.
- System checks cooldown period (24-hour minimum).
- If allowed, sends reminder email immediately.
Reminder Email Content (System-Wide Template):
- Subject: "Payment Reminder: Invoice #[INVOICE_ID] - [PROJECT_NAME]"
- Body includes:
- Client name greeting
- Invoice number and project name
- Original payment due date
- Number of days overdue
- Amount due
- Direct payment link (secure, pre-authenticated)
- Agency contact information
- Professional, non-aggressive tone
Tracking Data:
- Reminder Count: Integer tracking total reminders sent
- Last Reminded at: Timestamp of most recent reminder
- Stored at transaction level
- History log maintained for audit purposes (accessible to admin users)
- Audit trail records: user who sent reminder, timestamp, client email
Cooldown Logic:
- Minimum 24 hours between reminders.
- Calculation: current_time - last_reminded_at ≥ 24 hours.
- If within cooldown: Button disabled, tooltip shows countdown.
- No maximum limit on reminders (agency discretion).
- Exactly at 24-hour mark, button becomes enabled.
Reminder Button States:
- Never Reminded: Enabled, tooltip "No reminders sent"
- Reminded + Cooldown Expired: Enabled, tooltip shows history
- Reminded + Within Cooldown: Disabled, tooltip shows restriction message
4.11 Refund Processing Logic
Overview: Supports both full and partial refunds with complete audit trail and accounting integration.
Refund Initiation Points:
- Transactions → Paid tab → Actions menu → Refund
- Invoice detail view → Transaction section → Refund action
Full Refund Process:
- User clicks "Refund" from Paid transaction.
- System displays refund dialog:
- Original amount: $XXX.XX (read-only)
- Refund amount: [pre-filled with full amount]
- Refund reason: [required text field]
- Confirm/Cancel buttons
- User enters reason and confirms.
- For online payments: System calls Stripe Refund API.
- For manual payments: System records refund locally only.
- Transaction status → Refunded.
- Refund data stored: original_amount, refunded_amount = original_amount, net_paid_amount = 0, refund_reason, refunded_at.
- QuickBooks sync triggered immediately (if enabled).
- Audit trail records: user, timestamp, amounts, reason.
Partial Refund Process:
- Same initiation as full refund.
- User modifies refund amount to less than original.
- Validation: Refund amount must be > 0 and ≤ original amount.
- Transaction status → Partially Refunded.
- Only one refund allowed - cannot add more refunds to a partially refunded transaction.
Invoice Impact:
- Full Refund of All Transactions: Invoice status → Refunded.
- Partial Refund (invoice still fully paid): Invoice status remains Paid, displays "Refunded $X" indicator.
- Partial Refund (creating outstanding balance): Invoice status updates based on remaining balance rules.
QuickBooks Sync:
- Full refunds create credit memo in QuickBooks.
- Partial refunds adjust payment record with memo.
- Sync happens immediately upon refund processing.
- Failed sync shows error indicator, allows manual retry.
- Refund reason synced as memo/note field.
4.12 Manual Payment Recording
Overview: Allows agencies to record offline payments (cash, check, bank transfer) that occur outside Stripe.
Initiation:
- From Unpaid or Overdue transaction → Actions → "Mark as Paid"
Manual Payment Dialog:
- Payment Method dropdown:
- Manual – Cash
- Manual – Check
- Manual – Bank Transfer
- Manual – Wire Transfer
- Manual – Other
- Payment Date: Date picker (defaults to current date)
- Reference Number: Optional text field (check number, wire reference, etc.)
- Notes: Optional text field for additional context
- Confirm/Cancel buttons
Processing:
- User fills out dialog and confirms.
- Transaction status → Paid.
- Payment method stored as selected option.
- No fees calculated (no Stripe processing).
- Reference number and notes stored for audit.
- QuickBooks sync triggered immediately with manual payment type.
- Audit trail records: user, timestamp, payment details.
Display in Paid Tab:
- Amount tooltip shows "Transaction Method: Manual – [Method]"
- Fee field shows "$0.00" or "N/A"
- Reference number visible in transaction detail view
Restrictions:
- Only users with appropriate permissions can mark as paid.
- Cannot be reversed once marked (must process as refund if needed).
- Payment date cannot be in the future.
- Audit log records user who marked payment and timestamp.
4.13 QuickBooks Synchronization
Overview: Automatically syncs paid transactions and refunds to QuickBooks Online immediately when integration is enabled.
Auto-Sync Triggers:
- Transaction status changes to Paid (payment received) - synced immediately.
- Refund is processed (full or partial) - synced immediately.
Sync Data Mapping:
- Transaction → QuickBooks Payment
- Invoice linkage maintained
- Payment method recorded
- Fees recorded as expenses (optional configuration)
- Refund → QuickBooks Credit Memo or Payment Adjustment
Sync Status Indicators:
In Paid Tab:
- ✅ Green QB icon: Successfully synced, click shows sync timestamp
- ❌ Gray QB icon with red cross: Sync failed
- No icon: QuickBooks not integrated
In Refunds Tab:
- 🔄 Circular arrow icon: Refund synced
- ❌ Red cross: Refund sync failed
Failed Sync Handling:
- System attempts sync immediately upon status change.
- If fails (network error, QB API error, auth issue), mark as failed.
- Error details logged for troubleshooting.
- User sees failed indicator in Actions column.
- Actions menu shows "Sync with QuickBooks" option.
- User clicks to retry sync manually.
- On success, icon updates to success state.
Error Scenarios:
- Authentication expired: Prompt to re-authenticate QB connection
- Duplicate transaction: Skip with warning logged
- QB API timeout: Retry with exponential backoff
- Data mapping error: Log specific field issue for support
4.14 Filters Panel
Overview: Comprehensive filtering system that applies across all sub-tabs.
Filter Panel Access:
- Click filter icon (funnel) in top-right header area.
- Panel slides out from right side.
- Filters persist when switching between sub-tabs.
Available Filters:
- Date Issued:
- Type: Date picker
- Format: Calendar popup with date selection
- Filters on invoice issue date
- Clear button to reset
- Payment Due Date:
- Type: Date picker
- Format: Calendar popup with date selection
- Filters on transaction payment due date
- Clear button to reset
- Brand:
- Type: Single-select dropdown
- Default: "All Brands"
- Options: List of all brands in account
- Filters transactions by brand association
- Amount:
- Type: Range slider with min/max inputs
- Format: Min ()[input]—Max() [input] — Max ( )[input]—Max() [input]
- Visual slider for quick adjustment
- Scale markers shown below slider
- Filters transactions within dollar range
- Client:
- Type: Multi-select with search
- Search box for client name lookup (minimum 2 characters)
- Scrollable list with checkboxes
- Client avatars displayed next to names
- Filters to show only selected clients
- Project:
- Type: Multi-select with search
- Search box for project name lookup (minimum 2 characters)
- Scrollable list with checkboxes
- Filters to show only selected projects
Filter Actions:
- Reset Icon (↻): Top-right of panel, clears all filters
- Apply Button: Applies selected filters (if separate apply needed)
- Auto-Apply: Filters may apply in real-time as changed (configuration option)
Filter Persistence:
- Filters remain active when switching sub-tabs.
- Filter state shown via "Active Filters" indicator.
- Filters reset on page refresh (session-based).
- Clear all option removes all active filters.
4.15 Sorting Logic
Overview: Enables column-based sorting with persistence across sub-tab navigation.
Sortable Columns (varies by sub-tab):
- Payment Date
- Charged / Deposited / Failed Date (status-specific)
- Invoice ID
- Client
- Amount
- Status
- Project
Sort Behavior:
- Click column header to sort ascending.
- Click again to sort descending.
- Sort indicator (↓) shows current sort column and direction.
- Only one column sorted at a time.
- Default sort varies by sub-tab (defined in each sub-tab section).
Sort Persistence:
- Sort order maintained when switching sub-tabs.
- Reset to default when page is refreshed.
- Sort state not saved in user preferences (session-only).
Sort Logic for Data Types:
- Dates: Chronological/reverse chronological
- Text (Client, Project, Invoice ID): Alphabetical A-Z / Z-A
- Amount: Numeric low-high / high-low
- Status: Alphabetical by status name
4.16 Search Functionality
Overview: Global search bar for quick transaction lookup.
Search Scope:
- Invoice ID (exact and partial match)
- Client Name (partial match, case-insensitive)
- Project Name (partial match, case-insensitive)
Search Behavior:
- Real-time filtering as user types (debounced 300ms).
- Minimum 2 characters required to trigger search.
- Searches within currently active sub-tab only.
- Combined with other active filters.
- Clear button (X) to reset search.
Search Results Display:
- Table updates to show only matching transactions.
- Row count updates in pagination.
- "No results found" empty state if no matches.
4.17 Project/Client/Brand Linkage
Overview: Every transaction maintains hierarchical relationships for organizational context.
Data Hierarchy:
Brand
└─ Client
└─ Project
└─ Invoice
└─ Transaction (Payment Schedule Item)
Navigation Capabilities:
- Click Invoice ID → Navigate to Invoice detail view
- Click Project name → Navigate to Project detail view
- Click Client name → Navigate to Client profile (optional)
- All navigation opens in same window (back button functional)
Filtering by Linkage:
- Brand dropdown filters all transactions by brand.
- Filters panel allows Client and Project multi-select.
- Hierarchical filtering: Selecting client shows only their projects in Project filter.
4.18 Interaction with Invoices Module
Overview: Transactions are integral to invoice lifecycle, with bidirectional impact on statuses and totals.
Invoice Status Impact from Transactions:
Transaction Status Change
Invoice Status Impact
All transactions Paid
Invoice → Paid
All transactions Refunded
Invoice → Refunded
Some transactions Paid, some Unpaid
Invoice → Partially Paid
Partial refund on Paid invoice (no outstanding)
Invoice remains Paid, shows "Refunded $X"
Transaction becomes Overdue
Invoice may show "Overdue" indicator
Invoice Total Calculations:
- Invoice total = Sum of all transaction amounts.
- Paid amount = Sum of Paid transaction amounts - Refunded amounts.
- Outstanding = Invoice total - Paid amount.
- Refunded indicator = Sum of all refunded amounts.
Deactivated Invoice Behavior:
- When invoice is deactivated (soft delete), all its transactions are hidden from Transactions tab.
- Transactions are not deleted, just filtered from view.
- Reactivating invoice makes transactions visible again.
- Deactivated invoice transactions don't count in totals/reports.
Cross-Module Actions:
- Refund initiated from Invoice detail → Updates Transaction status in Transactions tab.
- Payment marked as paid from Transactions tab → Updates Invoice status and amounts.
- Invoice edited (schedule changed) → Transactions updated accordingly (with restrictions on Paid transactions).
4.19 Email & Notification Triggers
Overview: System-generated emails triggered by transaction events.
Email Types:
- Overdue Reminder Email:
- Trigger: User clicks "Remind" button
- Recipient: Client primary email
- Template: System-wide (not customizable per brand)
- Content: Invoice details, amount due, days overdue, payment link
- Throttle: 24-hour minimum between sends
- Failed Payment Notification:
- Trigger: User clicks "Notify Client" from Failed tab
- Recipient: Client primary email
- Content: Failure reason, retry instructions, payment link
- No automatic sending (user-initiated only)
- Payment Link Resend:
- Trigger: User clicks "Send Payment Link"
- Recipient: Client primary email
- Content: Original payment link with invoice details
- Available from: Failed and Overdue tabs
- Refund Confirmation:
- Trigger: Refund successfully processed
- Recipient: Client primary email (optional, configurable)
- Content: Refund amount, reason, updated invoice balance
- Automatic if email notifications enabled
Notification Logging:
- All sent emails logged with timestamp.
- Delivery status tracked (sent, delivered, bounced, opened).
- Accessible in transaction detail view and audit trail.
- Audit trail accessible to admin users.
4.20 Audit Trail
Overview: Comprehensive logging of all user actions on transactions for accountability and compliance.
Logged Actions:
- Mark as Paid (manual payment recording)
- Refund initiation (full or partial)
- Reminder sent
- QuickBooks sync attempts (manual retries)
- Status changes (with source: manual vs webhook)
Audit Entry Data:
- Timestamp (UTC with timezone conversion for display)
- User ID and name who performed action
- Action type
- Previous value (if applicable)
- New value
- Additional context (e.g., refund reason, payment method)
- IP address (optional for security)
Access:
- Visible to admin users in transaction detail view
- Exportable for compliance reporting
- Retained according to data retention policy (configurable)
5. Field Details & Validations
5.1 Transaction Table Fields
Field Name
Field Type
Display Format
Validation Rules
Payment Date
Date Display
"January 20, 2025"
Required, valid date
Charged (Processing)
DateTime Display
"January 20, 2025" + "5:48 PM"
Required when status = Processing
Deposited (Paid)
DateTime Display
"January 20, 2025" + "5:48 PM"
Required when status = Paid
Failed Date (Failed)
DateTime + Text
"January 20, 2025" + "Card Declined"
Required when status = Failed
Invoice ID
Text Link
"#INV00004"
Required, format #INV[5 digits], clickable
Client
Avatar + Text
[Avatar] "Judy Whales"
Required, display name from Client record
Amount
Currency + Info
"$250.00" + ⓘ + "1 of 2"
Required, positive decimal, two decimal places
Status
Badge
Colored badge with status text
Required, must be valid status value
Project
Text Link
"Jadon & Monika Wedding"
Required, from linked Project record
Actions
Icon Menu
Three-dot vertical menu
System-generated based on status
Remind Button
Button
"Remind" text button
Only on Overdue tab, respects cooldown
QuickBooks Icon
Icon
QB logo with status indicator
Only on Paid/Refunds tabs when QB integrated
5.2 Manual Payment Dialog Fields
Field Name
Field Type
Display Format
Validation Rules
Payment Method
Dropdown
Single-select list
Required, must select from predefined options
Payment Date
Date Picker
"mm/dd/yyyy" with calendar
Required, cannot be future date
Reference Number
Text Input
Alphanumeric text
Optional, max 50 characters
Notes
Text Area
Multi-line text
Optional, max 500 characters
5.3 Refund Dialog Fields
Field Name
Field Type
Display Format
Validation Rules
Original Amount
Read-only Text
"$250.00"
Display only, non-editable
Refund Amount
Currency Input
"$" + numeric input
Required, > 0, ≤ original amount, two decimal places
Refund Reason
Text Area
Multi-line text
Required, min 10 characters, max 500 characters
5.4 Filter Panel Fields
Field Name
Field Type
Display Format
Validation Rules
Date Issued
Date Picker
Calendar with "Select Date" placeholder
Optional, valid date
Payment Due Date
Date Picker
Calendar with "Select Date" placeholder
Optional, valid date
Brand
Dropdown
"All Brands" default, single-select
Optional, valid brand from list
Amount Min
Number Input
Dollar amount with slider
Optional, ≥ 0, ≤ Max value
Amount Max
Number Input
Dollar amount with slider
Optional, ≥ Min value
Client
Multi-select with Search
Checkboxes with avatars and names
Optional, valid clients from list, min 2 chars for search
Project
Multi-select with Search
Checkboxes with project names
Optional, valid projects from list, min 2 chars for search
6. Error Messages & Notifications
Field/Action
Validation Scenario
Error/Success Message
Type
Refund Amount
Exceeds original amount
"Refund amount cannot exceed the original payment of $[amount]"
Error
Refund Amount
Zero or negative
"Please enter a valid refund amount greater than $0"
Error
Refund Reason
Empty or too short
"Please provide a refund reason (minimum 10 characters)"
Error
Refund Processing
Stripe API error
"Refund could not be processed. Please try again or contact support."
Error
Refund Success
Successful refund
"Refund of $[amount] has been processed successfully"
Success
QuickBooks Sync
Authentication failed
"QuickBooks authentication expired. Please reconnect your QuickBooks account."
Error
QuickBooks Sync
Sync failed
"Failed to sync transaction to QuickBooks. Click to retry."
Error
QuickBooks Sync
Sync successful
"Transaction synced to QuickBooks successfully"
Success
Manual Payment
Future date selected
"Payment date cannot be in the future"
Error
Manual Payment
No method selected
"Please select a payment method"
Error
Manual Payment Success
Payment recorded
"Payment of $[amount] has been recorded successfully"
Success
Reminder
Within 24h cooldown
"You will be able to send next reminder after 24h after last one."
Info (tooltip)
Reminder
Client has no email
"Client email address not configured"
Error
Reminder Sent
Email dispatched
"Reminder email sent to [client email]"
Success
Reminder Failed
Email delivery failed
"Failed to send reminder. Please check client email address."
Error
Search
No results
"No transactions found matching '[search term]'"
Info
Search
Too few characters
"Please enter at least 2 characters to search"
Info
Filter
No results
"No transactions match the selected filters"
Info
Network Error
Connection lost
"Connection lost. Please check your internet and try again."
Error
Stripe Webhook
Processing error
"Payment status update pending. Please refresh in a few minutes."
Warning
7. Edge Cases & Special Scenarios
Scenario
Expected Behavior
Transaction becomes overdue during user session
Transaction remains in Unpaid tab until midnight scheduled job runs; real-time update not required
Client pays while transaction is in Processing state
Stripe webhook updates status; if user viewing Processing tab, refresh shows transaction moved to Paid
Multiple refunds on same transaction
System prevents - once Refunded/Partially Refunded, no further refunds allowed
Partial refund equals full amount
System treats as full refund, status → Refunded
QuickBooks disconnected after paid transaction
Transaction marked as "sync failed", manual retry available after QB reconnected
Invoice deactivated with Processing transactions
Processing transactions hidden; if payment completes via Stripe, transaction updated but remains hidden until invoice reactivated
Reminder sent exactly 24h ago
Button becomes enabled; edge case at 24:00:00 mark should enable
Client has no email address
Remind button shows error: "Client email address not configured", button disabled
Zero-amount transaction (rare)
Display as "$0.00", all actions available except refund
Currency mismatch
System enforces single currency per account; edge case handled by validation at invoice creation
Duplicate webhook received
Idempotency key prevents duplicate status changes; webhook logged but no action taken
User closes browser during refund processing
Refund continues server-side; status updated on next page load
Filter returns > 10,000 results
Pagination handles efficiently; warning shown if export attempted
Browser timezone differs from server
All times displayed in user's local timezone (converted from UTC storage)
Refund processed but Stripe reverses it
Rare scenario - would require manual correction; audit log maintained
Payment method changes during Processing
Not possible - method locked when PaymentIntent created
Client account deleted with outstanding transactions
Transactions remain viewable; client shows as "[Deleted Client]"
Project deleted with transactions
Transactions remain; project shows as "[Deleted Project]"
Brand deleted/deactivated
Brand filter excludes; existing transactions remain but may be filtered out
Failed transaction retried successfully
Transaction moves from Failed tab to Processing, then to Paid; original failure history preserved in audit trail
Search with 1 character
No search performed; tooltip shows "Please enter at least 2 characters to search"
8. Test Cases Reference
9. Acceptance Criteria
- Users can view transactions filtered by status across six sub-tabs, with each tab displaying appropriate columns and actions.
- System automatically updates transaction status based on Stripe webhook events without manual intervention.
- Users can send overdue reminders with 24-hour cooldown enforcement, and system tracks reminder count and last sent timestamp.
- Users can process full and partial refunds with required reason, and system allows only one refund per transaction.
- Users can mark transactions as paid manually with payment method selection, and system records offline payment details.
- Filters panel allows multi-criteria filtering by date, brand, amount range, client, and project, with filters persisting across sub-tabs.
- Column sorting functions correctly for all sortable fields, with sort order maintained during sub-tab navigation.
- Search functionality requires minimum 2 characters and returns real-time results matching invoice ID, client name, or project name.
- QuickBooks integration automatically syncs paid transactions and refunds immediately upon status change, with failed sync indicator and manual retry option.
- Transactions from deactivated invoices are hidden from all views and become visible upon reactivation.
- All error messages display appropriately for validation failures, network errors, and integration issues.
- Empty states provide clear messaging when no transactions exist for selected status or filter combination.
- Pagination correctly handles large datasets with configurable rows per page (10, 25, 50, 100).
- Overdue status transitions occur automatically via scheduled job running at midnight in agency's timezone.
- All user actions (mark as paid, refund, reminder sent, QB sync retries) are logged in audit trail accessible to admin users.
- Failed transactions remain in Failed tab until client retries and status changes to Processing or Paid.
10. Dependencies
Module/System
Dependency Type
Impact if Unavailable
Stripe Payment Gateway
Integration
Online payments cannot be processed, webhook updates fail, no automatic status transitions
QuickBooks Online API
Integration
Automatic accounting sync fails, manual recording required, potential reconciliation issues
Invoices Module
Data Dependency
Cannot create transactions without invoices, invoice-transaction linkage broken
Client Management Module
Data Dependency
Cannot display client information, reminders fail without client email
Projects Module
Data Dependency
Cannot display project information, filtering by project unavailable
Brands Module
Data Dependency
Brand filtering unavailable, transaction-brand association broken
Email Service (SendGrid/SES)
Service Dependency
Reminder emails fail to send, payment notifications not delivered
Authentication Service
Security Dependency
Users cannot access module, permission checks fail
Database Service
Infrastructure
Complete module failure, no data retrieval or updates
Cron/Scheduler Service
Service Dependency
Overdue status transitions don't occur automatically at midnight
Audit Logging Service
Service Dependency
User actions not tracked, compliance issues
11. References
- Design Files: Figma/Sketch link - [Provided screenshots cover UI specifications]
Deprecated —---------------------------------
4. Status-Specific Field Details & Validations
4.1 Unpaid Status Tab Fields
Field Name
Type
Validation Rules
Payment Date
Date
Valid date format, the payment date is fetched from the package
Invoice ID
Text
Format: INV + number + sequence (e.g., INV0004, INV0004-1)
Unique identifier for transaction
Client
Text with Profile
Links to client profile, displays name with profile image
The client who signed the package will be displayed here
Amount
Currency with Split Info
Positive number, with
Payment amount with split details shows installment notation (e.g., "2 of 3")
Status
Static Text
Always displays "Unpaid"
Project
Text
Links to the associated project
Actions
Kebab Menu
View Details, Copy Invoice Link, Download PDF, Print Invoice
4.2 Processing Status Tab Fields
Field Name
Type
Validation Rules
Payment Date
Date
Original payment due date
Valid date format, original due date
Charged Date
DateTime
Auto-populated by Stripe when payment is initiated
Invoice ID
Text
Format: INV + number + sequence (e.g., INV0004-1)
Unique identifier for transaction
Client
Text with Profile
Links to client profile, displays name with profile image
The client who signed the package will be displayed here
Amount
Currency with Split Info
Positive number, shows installment notation (e.g., "1 of 2")
Status
Static Text
Always displays "Processing"
Project
Text
Links to the associated project
Actions
Kebab Menu
View Details, Copy Invoice Link, Download PDF, Print Invoice
4.3 Paid Status Tab Fields
Field Name
Type
Validation Rules
Payment Date
Date
Original payment due date
Valid date format, original due date
Deposited Date
DateTime
Date payment received in the agency account
Auto-updated by Stripe, manually adjustable
Invoice ID
Text
Format: INV + number + sequence (e.g., INV0004-2)
Unique identifier for transaction
Client
Text with Profile
Links to client profile, displays name with profile image
Primary client who signs the proposal
Amount
Currency with Hover Details
Positive number, detailed split info on hover
Payment amount with detailed breakdown
On the tooltip, details like payment method, amount, and free can be seen
Stripe and Pixally Fees
QuickBooks Sync
Icon
Synchronization status with QuickBooks
Green tick (synced) or red cross (not synced)
Can be manually synced via action in the kebab menu, in case it is not automatically synced
Status
Static Text
Always displays "Paid"
Project
Text
Links to the associated project
Actions
Kebab Menu
View Details, Sync with QuickBooks (if not synced), Copy Invoice Link, Download PDF, Print Invoice, Refund
4.4 Overdue Status Tab Fields
Field Name
Type
Validation Rules
Payment Date
Date
Original payment due date
Valid date format, original due date
Invoice ID
Text
Format: INV + number + sequence (e.g., INV0004-3)
Client
Text with Profile
Links to client profile, displays name with profile image
Amount
Currency
Outstanding payment amount
Positive number, payment amount due
Status
Static Text
Always displays "Overdue"
Project
Text
Links to the associated project
Reminder
Button with Hover Info
Send a reminder email to the client
Shows reminder count and last sent date on hover
Actions
Kebab Menu
View Details, Copy Invoice Link, Download PDF, Print Invoice
4.5 Failed Status Tab Fields
Field Name
Type
Validation Rules
Payment Date
Date
Original payment due date
Valid date format, original due date
Failed Date
DateTime with Reason
Date and reason for payment failure
Auto-populated by Stripe with failure reason
Invoice ID
Text
Unique identifier for transaction
Format: INV + number + sequence (e.g., INV0004-1)
Client
Text with Profile
Links to client profile, displays name with profile image
Amount
Currency with Split Status
Payment amount with split details
A positive number shows split information
Status
Static Text
Always displays "Failed"
Project
Text
Links to the associated project
Actions
Kebab Menu
View Details, Copy Invoice Link, Download PDF, Print Invoice
4.6 Refunds Status Tab Fields
Field Name
Type
Validation Rules
Payment Date
Date
Original payment due date
Valid date format, original due date
Invoice ID
Text
Unique identifier for transaction
Format: INV + number + sequence (e.g., INV0004-2)
Client
Text with Profile
Links to client profile, displays name with profile image
Amount
Currency
Full refund amount
Positive number, refunded amount
Status
Static Text
Always displays "Refunded"
Project
Text
Links to associated project
Actions
Kebab Menu
View Details, Copy Invoice Link, Download PDF, Print Invoice
5. Success Message Handling
Validation Scenario
Success Message
Reminder email sent successfully
"Payment reminder sent successfully."
QuickBooks synchronization completed- manual
"Transaction synced with QuickBooks successfully."
Refund processing completed
"Refund processed successfully."
Invoice link copied
"Transaction invoice link copied to clipboard."
6. Error Message Handling
Field
Validation Scenario
Error Message
QuickBooks Integration
Sync connection failed
"QuickBooks synchronization failed. Please check integration settings and try again"
QuickBooks Integration
Authentication expired
"QuickBooks authentication expired. Please reconnect your account"
Refund Processing
Refund processing failed
"Unable to process refund. Please contact payment support or try again later."
Refund Processing
Transaction not eligible
"This transaction is not eligible for refund. Please contact support."
Status Management
Invalid status transition
"Invalid status change. Please verify the transaction's current status."
Filter Validations
Invalid date range
"End date must be after start date"
Filter Validations
Invalid amount range
"The maximum amount must be greater than the minimum amount."
8. Edge Cases
Scenario
Expected Behavior
Client initiates multiple failed payment attempts
Each failure attempt is tracked with a separate failed date and reason, and final successful payment updates to Paid status with complete failure history preserved
QuickBooks sync repeatedly fails for a specific transaction
Red cross indicator persists, manual retry available indefinitely, sync status does not affect other transaction functionality
Multiple reminder emails sent within short timeframe
All reminders tracked and sent without frequency restrictions, complete communication history maintained
Manual status change from Unpaid directly to Paid
Status updates immediately, deposited date field becomes available for manual entry, and bypasses normal processing flow
Refund initiated for the transaction with pending QuickBooks sync
Refund processes normally, sync status transfers to the refunded transaction record
Large volume of transactions exceeding pagination limits
System maintains filter state across all pages, and pagination applies to filtered results
Client retries failed payment multiple times before success
All failure attempts are preserved in the transaction history, and successful payment updates the existing transaction rather than creating a duplicate
Network interruption during transaction status update
System provides clear error messaging, allows immediate retry, and maintains data consistency
11. Dependencies
Module/System
Impact if Unavailable
Stripe Payment Gateway
Cannot process payments, status updates fail, no failure notifications
QuickBooks Integration
Sync functionality unavailable, accounting reconciliation fails
Email Service Provider
Reminder emails cannot be sent, client failure notifications fail
Billing Module
Cannot access invoice data, transaction creation fails
Project Management Module
Cannot link transactions to projects, PM access restrictions fail
Client Management Module
Cannot display client information, reminder email delivery fails
Authentication System
Role-based access control fails, user permissions cannot be enforced
12. References
- Figma
☑️ Contractor Invoices
Functional Requirements Document (FRD) - Contractor Invoices Module
Document Version: 1.1
Created Date: December 23, 2025
Last Updated: July 14, 2026
Module Location: Finances → Contractor Invoices
1. Module Overview
Module Name: Contractor Invoices
Purpose: The Contractor Invoices module enables agency owners and admins to view, manage, and process payments for invoices submitted by contractors for work completed on specific project events. Contractors upload invoices through the Contractor Portal, and agencies can pay via Stripe, ACH bank transfer, or record manual offline payments.
Business Goals:
-
Streamline contractor payment workflows by centralizing all invoice management in one location.
-
Provide real-time visibility into invoice statuses across Unpaid, Overdue, Processing, Paid, and Failed states.
-
Enable flexible payment options through online ACH transfers and manual payment recording.
-
Track discrepancies between agreed contractor fees and invoiced amounts to prevent overpayments.
-
Automatically identify overdue invoices based on contractor-set due dates to ensure timely payments.
-
Synchronize contractor payments with QuickBooks as expenses for accurate financial reporting.
-
Provide transparent fee breakdown for online payments to help agencies understand total costs.
-
Reduce payment processing time and improve contractor satisfaction through timely payments.
2. User Roles & Permissions
Role
View Invoices
Pay (Stripe ACH)
Mark as Paid
Retry Payment
View Invoice PDF
Download Invoice
Sync QuickBooks
Agency Owner
✅
✅
✅
✅
✅
✅
✅
Agency Admin
✅
❌
✅
❌
✅
✅
✅
Role Descriptions:
-
Agency Owner: Has full access to all contractor invoice functionalities including initiating online ACH payments via Stripe, retrying failed payments, marking invoices as paid manually, viewing and downloading invoice PDFs, and triggering QuickBooks sync.
-
Agency Admin: Can view all contractor invoices, mark invoices as paid manually using offline payment methods, view and download invoice PDFs, and trigger QuickBooks sync. Agency Admins cannot initiate online ACH payouts or retry failed payments.
3. User Flow
3.1 The user navigates to the Finances section from the left sidebar menu and clicks on Contractor Invoices.
3.2 The system loads the Contractor Invoices module and displays the Unpaid tab by default with all unpaid and overdue invoices listed.
3.3 If no invoices have been submitted by contractors, the system displays an empty state with the message "No contractor invoices yet" and secondary text "The Invoices will appear here once the contractors submit invoices."
3.4 The user can switch between Unpaid, Processing, Paid, and Failed tabs by clicking on the respective tab headers.
3.5 The system displays the invoice list for the selected tab with columns appropriate to that tab's context.
3.6 The user observes invoices with "Overdue" status badge (red) in the Unpaid tab for invoices whose due date has passed without payment.
3.7 The user clicks the expand arrow on any invoice row to view the Expected Contractor Payment details including the agreed fee, total amount invoiced, and any discrepancy.
3.8 The system expands the row inline and displays the Expected Contractor Payment amount, Amount Invoiced by Contractor, and Discrepancy (if applicable).
3.9 The user clicks the filter icon to open the Filters panel.
3.10 The system displays the Filters panel with Date Issued, Brand, Contractor, and Project filter options.
3.11 The user selects filter values and the system immediately filters the invoice list based on the selected criteria.
3.12 The user clicks the "Pay" button on an unpaid or overdue invoice row (Agency Owner only).
3.13 The system opens the "Pay Contractor" modal displaying contractor details, project name, issue date, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), an editable Amount field pre-filled with the invoice amount, and the Stripe fee breakdown.
3.14 The system displays the fee breakdown showing the Amount (payment to contractor), Fee (Stripe transaction fee), and implied total that the agency will be charged.
3.15 If the agency has not connected their Stripe account or added a payment method, the system displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button.
3.16 If the contractor has not set up their bank account, the system displays a message "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."
3.17 If both agency and contractor payment methods are configured, the system displays the agency's linked bank account details with account name and last 4 digits.
3.18 The user reviews the payment details including the Stripe fee, optionally modifies the amount (which triggers fee recalculation), and clicks "Pay Contractor" to initiate the ACH transfer.
3.19 The system initiates the Stripe ACH payout and moves the invoice from Unpaid/Overdue to Processing status.
3.20 The user clicks the "Mark as Paid" button on an unpaid or overdue invoice row.
3.21 The system opens the "Mark as Paid" modal with confirmation text "You are about to mark this invoice as paid. Do you want to continue?", contractor details, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), editable Amount field, Payment Method dropdown, and optional Note field.
3.22 The system does not display any fee breakdown in the Mark as Paid modal since manual payments do not incur Stripe fees.
3.23 The user selects a payment method from the dropdown (Cash, Check, Zelle, PayPal, Venmo, Google Pay, or Apple Pay), optionally enters a note, and clicks "Mark as Paid".
3.24 The system moves the invoice directly from Unpaid/Overdue to Paid status and records the manual payment details.
3.25 The user clicks the "View Invoice" button on any invoice row.
3.26 The system opens a PDF viewer popup displaying the uploaded invoice document with Print, Download, and zoom controls.
3.27 The user clicks the 3-dot overflow menu on any invoice row.
3.28 The system displays menu options: View Invoice, Sync with QuickBooks (if not synced or sync failed), and Download Invoice.
3.29 The user clicks "Retry Payment" icon on a failed invoice row (Agency Owner only).
3.30 The system initiates a new ACH payout attempt and moves the invoice from Failed back to Processing status.
3.31 The system receives a Stripe webhook confirming successful payout and moves the invoice from Processing to Paid status.
3.32 The system receives a Stripe webhook indicating payout failure and moves the invoice from Processing to Failed status, storing the failure reason.
3.33 The user clicks on a Project name link in the invoice list.
3.34 The system navigates the user to the Project details page.
3.35 The user enters a search term in the search bar.
3.36 The system filters the invoice list to show invoices matching the search term against Contractor Name, Project Name, or Amount.
3.37 The user clicks a column header to sort the invoice list.
3.38 The system sorts the invoice list by the selected column in ascending or descending order.
3.39 The user hovers over the info icon (ⓘ) next to the amount in the Paid tab to view the fee breakdown.
3.40 The system displays a tooltip showing Transaction Method, Amount paid to contractor, and Fee charged by Stripe.
3.41 The user clicks the QuickBooks sync icon on a Paid invoice.
3.42 The system displays a tooltip showing the sync status ("Synced: [Date] at [Time]", "Not synced yet. Press QuickBooks icon to sync this transaction.", or "Sync failed. Press to retry.").
3.43 If sync is pending or failed, the user clicks the icon and the system initiates a sync to QuickBooks.
3.44 The system creates or updates the corresponding expense entry in QuickBooks upon successful sync.
4. Functional Logic
4.1 Navigation & Entry Points
-
The Contractor Invoices module is accessible from the left sidebar under Finances → Contractor Invoices.
-
The module can also be accessed contextually from Project details or Event details pages where contractor invoice links may be present.
-
When the user navigates to the module, the system loads the Unpaid tab by default.
-
The system displays a Brand dropdown filter in the header set to "All Brands" by default.
-
The system displays a search bar in the header for quick invoice lookup.
-
The system displays a filter icon button that opens the advanced Filters panel.
4.2 Empty State Logic
-
If no invoices have been submitted by contractors across the entire system, the system displays the message "No invoices yet" with secondary text "The Invoices will appear here once the contractors submit invoices."
-
Empty states are displayed only after data loading is complete to prevent UI flicker.
-
Filters remain accessible during empty states to allow users to adjust filter criteria.
4.3 Tab-Level Empty States
-
If invoices exist in the system but the Unpaid tab has no entries, the system displays "No unpaid invoices found."
-
If the Processing tab has no entries, the system displays "No invoices are currently processing."
-
If the Paid tab has no entries, the system displays "No paid invoices found."
-
If the Failed tab has no entries, the system displays "No failed invoices found."
4.4 Filter-Induced Empty State
-
If the user applies filters that return zero results, the system displays the message "No invoices match your selected filters." with a "Clear Filters" CTA.
-
Clicking "Clear Filters" resets all filter values to their defaults and refreshes the invoice list.
4.5 Invoice Status Definitions
-
Unpaid: The invoice has been uploaded by the contractor, the due date has not yet passed, and no payment attempt has been initiated (no ACH payout, no manual "Mark as Paid").
-
Overdue: The invoice has been uploaded by the contractor, the due date set by the contractor has passed, and no payment has been processed or initiated. Overdue invoices are displayed within the Unpaid tab with a red "Overdue" status badge.
-
Processing: A Stripe ACH payout has been initiated to the contractor's bank account and final confirmation is pending from Stripe (typically 3-5 business days).
-
Paid: The ACH payout was successfully completed based on Stripe webhook confirmation, OR the agency used "Mark as Paid" to record a manual offline payment.
-
Failed: The ACH payout failed due to a bank or Stripe error such as insufficient funds, blocked transaction, or invalid account details.
4.6 Overdue Status Logic
-
The contractor sets the due date when uploading an invoice through the Contractor Portal.
-
The system automatically monitors all unpaid invoices and compares the current date against each invoice's due date.
-
When the current date exceeds the invoice's due date and the invoice has not been paid or is not in Processing status, the system automatically changes the invoice status from Unpaid to Overdue.
-
The Overdue status change is performed by a background scheduled task that runs daily.
-
Overdue invoices are displayed within the Unpaid tab alongside Unpaid invoices, distinguished by a red "Overdue" badge.
-
There is no separate tab or filter specifically for Overdue invoices; they appear mixed with Unpaid invoices in the Unpaid tab.
-
When an agency owner receives a notification that an invoice has become overdue, they can take action to pay the contractor promptly.
-
Overdue invoices can be paid using either the "Pay" (Stripe ACH) or "Mark as Paid" (manual) methods, following the same flows as Unpaid invoices.
4.7 Status Transitions
-
Unpaid → Overdue: Occurs automatically when the current date exceeds the invoice's due date and no payment has been initiated.
-
Unpaid → Processing: Occurs when the agency owner clicks "Pay" and confirms the online ACH payment via Stripe.
-
Unpaid → Paid: Occurs when an agency user clicks "Mark as Paid" and confirms a manual offline payment method.
-
Overdue → Processing: Occurs when the agency owner clicks "Pay" on an overdue invoice and confirms the online ACH payment via Stripe.
-
Overdue → Paid: Occurs when an agency user clicks "Mark as Paid" on an overdue invoice and confirms a manual offline payment method.
-
Processing → Paid: Occurs when Stripe webhook confirms successful ACH payout completion.
-
Processing → Failed: Occurs when Stripe webhook returns a failure response.
-
Failed → Processing: Occurs when the agency owner uses "Retry Payment" to initiate a new payout attempt for the same invoice.
-
No other status transitions are permitted by the system.
4.8 List View & Tab Structure
4.8.1 Unpaid Tab Columns
-
Contractor (with avatar and name). A green checkmark badge appears on the avatar when the contractor has completed Stripe payout setup; hovering the badge shows the tooltip “Stripe setup complete.” No badge is shown when setup is incomplete (see Section 4.28).
-
Issued (date the invoice was submitted)
-
Due Date (date set by contractor for payment)
-
Status (displays "Unpaid" or "Overdue" badge; Overdue is displayed in red)
-
Project (project name with event name and event color dot below)
-
Amount (invoice amount in currency format)
-
Actions (Pay, Mark as Paid, View Invoice buttons, 3-dot menu)
4.8.2 Processing Tab Columns
-
Contractor (with avatar and name). A green checkmark badge appears on the avatar when the contractor has completed Stripe payout setup; hovering the badge shows the tooltip “Stripe setup complete.” No badge is shown when setup is incomplete (see Section 4.28).
-
Issued (date the invoice was submitted)
-
Paid (date the payment was initiated)
-
Paid Amount (the amount paid to the contractor, shown with an info icon (ⓘ) that displays the fee breakdown on hover — see Section 4.15)
-
Payment Method (displays "Bank Transfer" for ACH or manual method name)
-
Status (always displays "Processing" badge)
-
Project (project name with event name and event color dot below)
-
Actions (View Invoice button, 3-dot menu)
4.8.3 Paid Tab Columns
-
Contractor (with avatar and name). A green checkmark badge appears on the avatar when the contractor has completed Stripe payout setup; hovering the badge shows the tooltip “Stripe setup complete.” No badge is shown when setup is incomplete (see Section 4.28).
-
Issued (date the invoice was submitted)
-
Paid (date the payment was completed)
-
Payment Method (displays "Bank Transfer" for ACH or manual method name)
-
Status (always displays "Paid" badge)
-
Project (project name with event name and event color dot below)
-
Paid Amount (the amount paid to the contractor, shown with an info icon (ⓘ) that displays the fee breakdown on hover — see Section 4.15)
-
QuickBooks Sync Icon (displays sync status)
-
Actions (View Invoice button, QuickBooks Sync, 3-dot menu)
4.8.4 Failed Tab Columns
-
Contractor (with avatar and name). The Stripe setup badge is not displayed on the Failed tab (see Section 4.28).
-
Issued (date the invoice was submitted)
-
Failed Date (date and failure reason below)
-
Payment Method (displays "Bank Transfer" or last attempted method)
-
Status (always displays "Failed" badge in red)
-
Project (project name with event name and event color dot below)
-
Actions (View Invoice, Retry Payment icon, 3-dot menu)
4.9 Expandable Row Logic
-
Each invoice row in the Unpaid tab has an expand/collapse arrow on the left side.
-
When the user clicks the expand arrow, the row expands inline to display additional payment context.
-
The expanded section displays: Expected Contractor Payment (the agreed contractor fee for the event), Amount Invoiced by Contractor (cumulative total of all invoices submitted by this contractor for this event), and Discrepancy (if applicable) showing the difference when invoiced amount exceeds the expected payment.
-
The discrepancy value is displayed only when the Amount Invoiced exceeds the Expected Contractor Payment.
-
Clicking the expand arrow again collapses the row back to its default state.
4.10 Contractor Fee Tracking & Overage Warning
-
Each contractor has an agreed fee per event that is set when the agency assigns the contractor to the event.
-
The system tracks the cumulative total of all invoices submitted by a contractor for a specific event.
-
The system does NOT block invoices that exceed the assigned contractor fee.
-
When the total invoiced amount exceeds the assigned contractor fee, the system displays the discrepancy amount in the expanded row view.
-
The discrepancy warning is also displayed in the Pay Contractor modal and Mark as Paid modal to alert the agency before processing payment.
-
The agency can proceed with payment even when a discrepancy exists, as there may be valid reasons such as scope changes or extended event duration.
4.11 Pay Contractor Modal (Online Payment)
-
The Pay Contractor modal opens when an Agency Owner clicks the "Pay" button on an unpaid or overdue invoice.
-
The modal header displays "Pay Contractor" with a close (X) button.
-
The Contractor section displays the contractor's avatar, name, linked project name, and issue date.
-
A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.
-
The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.
-
When the contractor has submitted more than one invoice for the same contractor and event/project, the modal displays an itemized breakdown listing all of those invoices instead of a single amount.
-
The specific invoice on which the action was clicked is pinned to the top of the breakdown list regardless of its own status; the remaining invoices are listed below it sorted by status in the order Unpaid → Processing → Failed → Paid.
-
Each row in the breakdown shows the invoice description, invoice number, issued date, status badge, a “View” link to open that invoice’s PDF, and the invoice amount. A Total Invoiced value (with invoice count) and the Discrepancy (if applicable) are shown below the list.
-
The Amount field is pre-filled with the sum of all non-Paid invoices (Unpaid, Processing, and Failed) shown in the breakdown — not the full total invoiced and not only the pinned invoice. Invoices already in Paid status are displayed in the breakdown for context but are excluded from the default payable amount to prevent accidental duplicate payment. The field remains editable to allow partial payments or manual adjustment.
-
If the contractor has only a single invoice for the event/project, the modal displays that single invoice inline with no breakdown list, and the Amount field is pre-filled with that invoice’s amount (unchanged behavior).
-
The system fetches the current Stripe ACH transaction fee percentage dynamically from the Stripe API when the modal opens.
-
The modal displays a fee breakdown section showing: Amount (the payment that will be sent to the contractor), and Fee (the Stripe transaction fee that the agency will bear).
-
The total amount the agency will be charged equals the Amount plus the Fee.
-
When the user edits the Amount field, the system automatically recalculates the Stripe Fee in real-time based on the new amount.
-
If the contractor has not set up their bank account, the modal displays "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account." and the Pay Contractor button is disabled.
-
If the agency has not set up their payment method, the modal displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button that redirects to Stripe Financial Connections.
-
If both payment methods are configured, the modal displays the agency's connected bank account with company name and last 4 digits of the account number, along with an edit icon to change the payment method.
-
The Cancel button closes the modal without any changes.
-
The Pay Contractor button should validate that both the agency and contractor payment methods are configured and the amount field has a valid value.
-
Clicking Pay Contractor initiates the Stripe ACH payout (charging the agency the Amount plus Fee) and closes the modal.
-
The contractor receives the full Amount; the Fee is deducted from the agency's payment.
4.12 Stripe Transaction Fee Logic
-
For all online payments via Stripe ACH, the agency bears the Stripe transaction fees.
-
The Stripe fee percentage is fetched dynamically from the Stripe API and may vary (e.g., 1.8% for ACH).
-
The fee is calculated as: Fee = Amount × (Stripe Fee Percentage / 100).
-
The total charge to the agency is: Total = Amount + Fee.
-
Example: If Amount = $100.00 and Stripe Fee = 1.8%, then Fee = $1.80 and Total = $101.80.
-
The fee breakdown is displayed in the Pay Contractor modal before payment initiation.
-
The fee breakdown is visible in the Paid tab via an info icon (ⓘ) tooltip showing Transaction Method, Amount, and Fee.
-
The fee breakdown is also included in transaction history reports.
-
Stripe fees are only charged when a payment is successful; failed payment attempts do not incur fees.
-
When retrying a failed payment, the Stripe fee will be charged only if the retry attempt is successful.
-
Manual payments recorded via "Mark as Paid" do not incur any Stripe fees.
4.13 Mark as Paid Modal (Manual Payment)
-
The Mark as Paid modal opens when an agency user clicks the "Mark as Paid" button on an unpaid or overdue invoice.
-
The modal header displays "Mark as Paid" with a close (X) button.
-
The modal displays confirmation text: "You are about to mark this invoice as paid. Do you want to continue?"
-
The Contractor section displays the contractor's avatar, name, linked project name, and issue date.
-
A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.
-
The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.
-
When the contractor has submitted more than one invoice for the same contractor and event/project, the modal displays an itemized breakdown listing all of those invoices instead of a single amount.
-
The specific invoice on which the action was clicked is pinned to the top of the breakdown list regardless of its own status; the remaining invoices are listed below it sorted by status in the order Unpaid → Processing → Failed → Paid.
-
Each row in the breakdown shows the invoice description, invoice number, issued date, status badge, a “View” link to open that invoice’s PDF, and the invoice amount. A Total Invoiced value (with invoice count) and the Discrepancy (if applicable) are shown below the list.
-
The Amount field is pre-filled with the sum of all non-Paid invoices (Unpaid, Processing, and Failed) shown in the breakdown; invoices already in Paid status are shown for context but excluded from the default amount to prevent accidental duplicate payment. The field remains editable.
-
If the contractor has only a single invoice for the event/project, the modal displays that single invoice inline with no breakdown list, and the Amount field is pre-filled with that invoice’s amount (unchanged behavior).
-
No fee breakdown is displayed since manual payments do not incur Stripe fees.
-
The Payment Method dropdown is required and contains options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay.
-
The Note field is optional and allows the agency to record internal notes about the payment (maximum 1000 characters).
-
The Note field content is visible only to agency owner and team members, not to the contractor.
-
The Cancel button closes the modal without any changes.
-
The Mark as Paid button should validate that a payment method is selected and the amount field has a valid value.
-
Clicking Mark as Paid records the manual payment, moves the invoice to Paid status, and closes the modal.
4.14 View Invoice Functionality
-
Clicking the "View Invoice" button opens a full-screen PDF viewer popup.
-
The popup header displays the invoice filename in the format "[Contractor Name] - [Project Name] ([Issue Date]).pdf".
-
The popup header includes Print, Download, zoom out (-), zoom percentage dropdown, and zoom in (+) controls.
-
A back arrow in the top-left allows the user to close the popup and return to the invoice list.
-
The PDF viewer displays the contractor-uploaded invoice document.
4.15 Paid Amount Column & Fee Breakdown Tooltip (Processing & Paid Tabs)
-
A “Paid Amount” column appears on both the Processing and Paid tabs, showing the amount paid to the contractor with an info icon (ⓘ) next to it. This column is additive and does not replace the Paid (date) column.
-
Hovering over the info icon displays a tooltip with the fee breakdown.
-
For online payments (Stripe ACH / Bank Transfer), the tooltip shows: Paid Amount (the payment sent to the contractor), Stripe Fees (the Stripe transaction fee), and Net Paid (the total cost to the agency, equal to Paid Amount plus Stripe Fees).
-
For manual payments (Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay), the tooltip shows only the Transaction Method and Paid Amount; the Stripe Fees and Net Paid lines are omitted because no Stripe fee is charged.
-
The Paid Amount column and its tooltip behave identically on the Processing and Paid tabs for consistency.
-
The tooltip also displays the installment information if applicable (e.g., "1 of 2").
4.16 Failed Payment & Retry Logic
-
When an ACH payout fails, the system stores the failure reason received from Stripe.
-
The Failed tab displays the failure date and failure reason below each failed invoice (e.g., "Card Declined", "Invalid Card Details", "Insufficient Funds", "Payment Blocked").
-
The Retry Payment action is available only to Agency Owners.
-
Clicking the Retry Payment icon initiates a new Stripe ACH payout attempt for the same invoice.
-
Upon retry, the invoice status changes from Failed to Processing.
-
Stripe fees are not charged for failed payment attempts; fees are only charged if the retry is successful.
-
The subsequent Stripe webhook will determine whether the invoice moves to Paid or back to Failed.
4.17 Invoice Payment Status Icon
-
When a contractor's invoice is paid or marked as paid by the agency, the invoice payment status icon reflects the updated status
-
The invoice icon visually indicates the payment status of a contractor's invoice
-
The icon fill state updates automatically when the agency marks payments
-
**Icon States:
** -
**Unpaid
**-
Icon appears empty (outline only)
-
No payment has been made against the invoice
-
-
**Partial Payment
**-
Icon appears half-filled
-
Agency has made a partial payment
-
Remaining balance is pending
-
-
**Fully Paid
**-
Icon appears completely filled
-
Full invoice amount has been paid by the agency
-
-
**Modules Impacted:
**-
Calendar List View - Invoice icon displayed alongside each event entry
-
Event Details > Contractors Tab - Invoice icon shown for each assigned contractor
-
Project Listing - Invoice icon visible in the project list view
-
Event Listing - Invoice icon displayed for each event row
-
Contractor Portal > Event Listing
-
Contractor Portal > Event Details> Contractor’s tab
-
4.18 Filters Panel Logic
-
The Filters panel is accessed by clicking the filter icon in the header.
-
A refresh icon at the top of the panel resets all filters to default values.
-
Date Issued Filter: A date picker allowing the user to select a specific date or date range.
-
Brand Filter: A single-select dropdown defaulting to "All Brands" that filters invoices by the brand associated with the project.
-
Contractor Filter: A multi-select list with search functionality allowing the user to select one or more contractors.
-
Project Filter: A multi-select list with search functionality allowing the user to select one or more projects.
-
When a Brand is selected, the Project filter list is scoped to show only projects belonging to that brand.
-
When a Brand is selected, the Contractor filter list is scoped to show only contractors assigned to events within that brand.
-
Filters apply across all four status tabs (Unpaid, Processing, Paid, Failed).
-
Filter selections persist when switching between status tabs until manually cleared.
-
Applying filters immediately refreshes the invoice list without requiring a separate "Apply" action.
-
There is no dedicated filter for Overdue status; Overdue invoices are viewed within the Unpaid tab.
4.19 Search Functionality
-
The search bar in the header allows quick lookup of invoices.
-
Search matches against Contractor Name, Project Name, and Amount.
-
Search results are displayed in real-time as the user types.
-
Search works in conjunction with applied filters.
-
Clearing the search field restores the full filtered list.
4.20 Sorting Logic
-
All column headers with a down arrow (↓) are sortable.
-
Clicking a sortable column header sorts the list by that column in ascending order.
-
Clicking the same column header again toggles to descending order.
-
Sortable columns include: Contractor, Issued, Due Date (Unpaid tab), Paid (where applicable), Payment Method (where applicable), Status, Project, Amount.
-
Default sort order is by Issued date in descending order (most recent first).
-
Sorting preferences persist while navigating between tabs within the same session.
4.21 Pagination Logic
-
The invoice list supports pagination with a "Rows per page" dropdown (default: 10).
-
Available options for rows per page are: 10, 25, 50.
-
The pagination footer displays the current range (e.g., "1-4 of 4") and navigation arrows.
-
Pagination state resets when switching tabs or applying new filters.
4.22 Project & Event Linkage
-
Every Contractor Invoice is mandatorily linked to a specific Event.
-
Every Event is mandatorily linked to a Project.
-
Every Project is mandatorily linked to a Brand.
-
The Project column displays the project name with the event name and event color dot displayed below.
-
Clicking on the Project name navigates the user to the Project details page.
-
Multiple invoices can exist for the same contractor and event combination.
4.23 3-Dot Overflow Menu Actions
-
View Invoice: Opens the PDF viewer popup to display the uploaded invoice document.
-
Sync with QuickBooks: Displayed only if the invoice is not synced or sync has failed; triggers a manual sync to QuickBooks.
-
Download Invoice: Downloads the invoice PDF to the user's device.
4.24 QuickBooks Integration
-
Contractor payments (both online ACH and manual) sync to QuickBooks as expenses.
-
When an invoice status becomes Paid, the system creates or updates the corresponding expense entry in QuickBooks.
-
The QuickBooks sync icon displays one of three states: Synced successfully, Sync failed, Sync pending.
-
Hovering over the sync icon displays a tooltip with status details (e.g., "Synced: Aug 20, 2025 at 7:00pm" or "Not synced yet. Press QuickBooks icon to sync this transaction.").
-
If sync fails, the user can click the icon to manually retry the sync.
-
Data mapping: Contractor maps to Vendor in QuickBooks, Project maps to Class/Job, payment amount maps to expense amount, and Stripe fee (if applicable) is recorded separately or as part of the expense.
-
If the agency has not connected their QuickBooks account, the sync icon is not displayed.
4.25 Stripe Connect Integration
-
Pixally maintains a master Stripe account with both agencies and contractors as connected accounts.
-
When an agency invites a contractor to Pixally for the first time, the system creates a Stripe Connect account for the contractor under Pixally's master account.
-
Contractors complete the Stripe onboarding process only once, even if invited by multiple agencies.
-
Each agency that wants to pay a contractor must set up a customer profile and payment method within the contractor's Stripe account.
-
If a contractor is already associated with another agency on Pixally, they do not need to complete onboarding again.
-
For ACH payouts to succeed, both the agency's funding bank account and the contractor's payout bank account must be configured in Stripe.
4.26 Notifications & Emails
-
Payment Success (to Contractor): When a contractor payment is successfully processed (either via ACH or marked as paid manually), the system sends an email notification and an in-app notification to the contractor confirming the payment.
-
Payment Failed (to Agency Owner): When an ACH payout fails, the system sends an email notification to the agency owner with the failure reason.
-
New Invoice Submitted (to Agency): When a contractor submits a new invoice, the system sends an in-app notification to agency users.
-
Invoice Overdue (to Agency Owner): When an invoice's due date passes and the invoice becomes Overdue, the system sends a notification to the agency owner alerting them of the overdue invoice.
-
Invoice Overage Warning: The warning is displayed only in the UI (Pay Contractor modal and Mark as Paid modal) when the agency attempts to pay an invoice that exceeds the expected contractor fee; no email notification is sent for overage.
4.27 Audit Trail
-
The system maintains an audit trail for all payment-related actions.
-
Logged actions include: Invoice submitted, Invoice became overdue, Payment initiated, Payment completed, Payment failed, Payment retried, Invoice marked as paid, QuickBooks sync attempted, QuickBooks sync completed, QuickBooks sync failed.
-
Each audit entry captures the action timestamp, user who performed the action, and relevant details including fee information for online payments.
4.28 Contractor Stripe Setup Indicator
-
Purpose: give agency owners and admins at-a-glance visibility into which contractors have completed their Stripe payout setup, without opening the Pay Contractor modal.
-
A small green checkmark badge is overlaid on the contractor’s avatar in the list view.
-
On hover, the badge shows the tooltip “Stripe setup complete.”
-
The badge appears only when the contractor’s Stripe payout setup is complete. When setup is incomplete, no badge is shown — the absence of the badge implies incomplete setup, and no separate “not set up” icon or state is used.
-
The badge is displayed on the Unpaid, Processing, and Paid tabs only.
-
The badge is not displayed on the Failed tab.
-
The badge appears strictly on the main list-view rows (the Contractor column avatar). It does not appear on the contractor avatar inside the Pay Contractor modal, the Mark as Paid modal, or the Filters panel contractor list.
-
The indicator is informational only and does not gate or restrict any action; Pay and Mark as Paid remain governed by the existing payment-method validation logic (see Section 4.11 and Section 5).
-
If a contractor completes Stripe setup after invoices already exist, the badge appears on the next data refresh across the applicable tabs (Unpaid, Processing, Paid). If a contractor’s setup later becomes invalid or disconnected, the badge is removed on the next data refresh.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Contractor Name
Text (Display)
Read-only; pulled from contractor profile
Contractor Avatar
Image (Display)
Read-only; pulled from contractor profile
Issued Date
Date (Display)
Read-only; set when contractor submits invoice; Format: MMM D, YYYY
Due Date
Date (Display)
Read-only; set by contractor when uploading invoice; Format: MMM D, YYYY
Paid Date
Date (Display)
Read-only; set when payment completes; Format: MMM D, YYYY
Failed Date
Date (Display)
Read-only; set when payment fails; Format: Month D, YYYY
Status
Badge (Display)
Read-only; system-managed; Values: Unpaid (default), Overdue (red), Processing, Paid, Failed (red)
Project Name
Text (Link)
Read-only; clickable to navigate to project details
Event Name
Text (Display)
Read-only; displayed with event color dot below project name
Invoice Amount
Currency (Display)
Read-only; set by contractor; Format: $X,XXX.XX
Expected Contractor Payment
Currency (Display)
Read-only; pulled from contractor assignment on event
Amount Invoiced by Contractor
Currency (Display)
Read-only; cumulative sum of all invoices for contractor-event
Discrepancy
Currency (Display)
Read-only; calculated as (Amount Invoiced - Expected Payment) when positive
Payment Amount
Currency (Input)
Required; Numeric only; Must be greater than $0.00; Pre-filled with the sum of non-Paid invoices in the breakdown (Unpaid, Processing, Failed) when multiple invoices exist, otherwise the single invoice amount; editable; Format: $X,XXX.XX
Stripe Fee
Currency (Display)
Read-only; calculated dynamically as Amount × Stripe Fee Percentage; Format: $X.XX
Stripe Fee Percentage
Percentage (System)
Fetched dynamically from Stripe API; typically 1.8% for ACH
Total Charge
Currency (Display)
Read-only; calculated as Payment Amount + Stripe Fee; Format: $X,XXX.XX
Payment Method (Manual)
Dropdown (Select)
Required for Mark as Paid; Options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay
Note
Text Area (Input)
Optional; Maximum 1000 characters; Internal use only
Failure Reason
Text (Display)
Read-only; populated from Stripe webhook response
QuickBooks Sync Status
Icon (Display)
Read-only; States: Synced, Failed, Pending
Search Query
Text (Input)
Optional; Matches against Contractor Name, Project Name, Amount
Date Issued Filter
Date Picker
Optional; Accepts single date or date range
Brand Filter
Dropdown (Single-select)
Optional; Default: All Brands
Contractor Filter
Multi-select List
Optional; Searchable; Multiple selections allowed
Project Filter
Multi-select List
Optional; Searchable; Scoped to selected brand
6. Success Message Handling
Operation
Success Message
Trigger Condition
Post-Success Action
Pay Contractor (ACH)
"Payment initiated successfully. The contractor will receive funds within 3-5 business days."
User clicks "Pay Contractor" and ACH payout is initiated
Modal closes; Invoice moves to Processing tab; List refreshes
Mark as Paid
"Invoice marked as paid successfully."
User clicks "Mark as Paid" with valid payment method selected
Modal closes; Invoice moves to Paid tab; List refreshes
Retry Payment
"Payment retry initiated. Processing will complete within 3-5 business days."
User clicks Retry Payment icon on failed invoice
Invoice moves to Processing tab; List refreshes
QuickBooks Sync
"Successfully synced with QuickBooks."
Manual or automatic sync completes successfully
Sync icon updates to "Synced" state; Tooltip shows sync timestamp
Download Invoice
"Invoice downloaded successfully."
User clicks Download Invoice from 3-dot menu
PDF file downloads to user's device
Filters Applied
(No toast message - list updates silently)
User selects filter values
Invoice list refreshes to show filtered results
Filters Cleared
"Filters cleared."
User clicks "Clear Filters" or refresh icon
All filters reset to defaults; List shows all invoices for current tab
7. Error Message Handling
Error Scenario
Error Message
Trigger Condition
Required Action
Agency Payment Method Not Set Up
"No payment method set up. To pay your contractor, you'll need to add a payment method first."
Agency clicks Pay but has not connected Stripe or added payment method
Click "Add Payment Method" to configure Stripe Financial Connections
Contractor Bank Account Not Set Up
"You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."
Agency clicks Pay but contractor has not completed Stripe onboarding
Contact contractor to complete bank account setup in Contractor Portal
Payment Amount Invalid
"Please enter a valid payment amount greater than $0.00."
User enters zero, negative, or non-numeric value in Amount field
Enter a valid positive numeric amount
Payment Amount Exceeds Limit
"Payment amount exceeds the maximum allowed limit."
User enters amount exceeding Stripe ACH limit
Enter an amount within the allowed limit
Payment Method Required
"Please select a payment method to continue."
User clicks Mark as Paid without selecting payment method
Select a payment method from the dropdown
Stripe Fee Fetch Failed
"Unable to calculate transaction fees. Please try again."
System fails to fetch Stripe fee percentage from API
Close modal and try again; Contact support if issue persists
ACH Payout Failed - Insufficient Funds
"Payment failed: Insufficient funds in the source account."
Stripe webhook returns insufficient funds error
Verify agency bank account balance and retry payment
ACH Payout Failed - Invalid Account
"Payment failed: Invalid bank account details."
Stripe webhook returns invalid account error
Contractor must update bank account details
ACH Payout Failed - Account Blocked
"Payment failed: The recipient's bank account is blocked."
Stripe webhook returns blocked account error
Contractor must resolve issue with their bank
ACH Payout Failed - Card Declined
"Payment failed: Card declined by the bank."
Stripe webhook returns card declined error
Verify payment details and retry
QuickBooks Sync Failed
"Failed to sync with QuickBooks. Click to retry."
QuickBooks API returns error during sync
Click sync icon to retry; If persistent, verify QuickBooks connection
QuickBooks Not Connected
"Connect your QuickBooks account to sync contractor payments."
User attempts sync but QuickBooks is not connected
Navigate to Settings → Integrations to connect QuickBooks
Search No Results
"No invoices found matching your search."
Search query returns no matching invoices
Modify search term or clear search
Filter No Results
"No invoices match your selected filters."
Applied filters return zero results
Adjust filter criteria or click "Clear Filters"
Note Exceeds Character Limit
"Note cannot exceed 1000 characters."
User enters more than 1000 characters in Note field
Reduce note content to 1000 characters or less
Network Error
"Unable to complete the request. Please check your connection and try again."
Network connectivity issue during any operation
Check internet connection and retry the action
Session Expired
"Your session has expired. Please log in again."
User session times out during operation
Log in again to continue
8. Edge Cases
Edge Case
System Behavior
Contractor submits multiple invoices for the same event
The system accepts all invoices and displays them as separate line items; Amount Invoiced by Contractor shows cumulative total. When Pay or Mark as Paid is clicked, the modal lists all invoices for that contractor-event with the selected invoice pinned on top and the remaining invoices sorted by status, and the Amount field defaults to the sum of the non-Paid invoices only (already-Paid invoices are shown for context but excluded to prevent duplicate payment).
Total invoiced amount exceeds agreed contractor fee
The system displays a discrepancy warning but does not block payment; Agency can proceed with payment
Agency attempts to pay more than invoice amount
The system allows overpayment as the Amount field is editable; Stripe fee is calculated on the new amount
Agency pays partial amount
The system processes the partial payment with fee calculated on partial amount; Invoice status changes based on payment flow; Original invoice amount remains unchanged for reference
Invoice due date passes without payment
System automatically changes status from Unpaid to Overdue; Agency owner receives notification
Invoice due date is set to past date by contractor
System immediately marks invoice as Overdue upon submission
Payment initiated on same day as due date
Invoice remains Unpaid (not Overdue) until end of due date; If payment processing extends past due date, status depends on payment completion
Stripe webhook delayed beyond 5 business days
Invoice remains in Processing status until webhook is received; No timeout mechanism auto-fails the payment
Stripe webhook received out of order
The system processes webhooks based on event timestamp, not receipt order
Stripe fee percentage changes during modal session
Fee is calculated at time of payment initiation using the rate fetched when modal opened; Real-time rate changes don't affect in-progress modals
User switches tabs while payment is processing
The invoice correctly appears in Processing tab; Original tab updates upon return
User applies filters then switches tabs
Filter selections persist across tab switches within the same session
Brand with no projects is selected in filter
Project filter shows empty list; Contractor filter shows empty list
Contractor is removed from event after submitting invoice
Existing invoices remain visible and can still be paid; New invoices cannot be submitted
Project is deactivated after invoice submission
Existing invoices remain visible and can still be processed; Project name displays with deactivated indicator
Multiple users attempt to pay same invoice simultaneously
First successful payment request is processed; Subsequent attempts fail with "Invoice already processing" error
QuickBooks sync fails due to disconnection
Sync icon shows failed state; User can reconnect QuickBooks and retry sync
Agency disconnects Stripe account with invoices in Processing
Processing invoices continue through Stripe; New payments cannot be initiated until reconnection
Contractor has multiple bank accounts
The system uses the default payout bank account set in contractor's Stripe Connect account
PDF invoice file is corrupted or cannot be rendered
System displays error "Unable to load invoice. Please contact support." with option to download file directly
User opens Pay modal for invoice that was just paid by another user
Modal displays current status and refreshes; Shows message "This invoice has already been paid."
Internet disconnects during payment confirmation
System displays network error; User should check Processing tab to verify if payment was initiated
Note field contains special characters
System accepts all UTF-8 characters including emojis; Properly escapes for storage
Amount field receives paste with currency symbol
System strips non-numeric characters except decimal point; Validates resulting number; Recalculates fee
Stripe API unavailable when fetching fee
Modal displays error message; Pay Contractor button disabled until fee can be fetched
9. Acceptance Criteria
9.1 Navigation & Access
-
Users can access Contractor Invoices from Finances menu in left sidebar.
-
Unpaid tab is displayed by default when module loads.
-
All four status tabs (Unpaid, Processing, Paid, Failed) are visible and clickable.
-
Brand dropdown filter defaults to "All Brands" and shows all brands the user has access to.
9.2 Empty States
-
System displays "No contractor invoices yet" with secondary text when no invoices exist.
-
Tab-level empty states display when no invoices exist for specific status.
-
Filter-induced empty state displays with Clear Filters option when filters return no results.
9.3 Invoice List Display
-
Invoice rows display correct columns for each tab type.
-
Unpaid tab displays both Unpaid and Overdue invoices with appropriate status badges.
-
Overdue status is displayed with a red badge.
-
Due Date column is visible in the Unpaid tab.
-
Expandable rows show Expected Contractor Payment, Amount Invoiced, and Discrepancy.
-
Project column shows project name with event name and color dot below.
-
Status badges display correct color and text for each status.
-
Pagination controls work correctly with configurable rows per page.
9.4 Overdue Logic
-
Invoices automatically transition from Unpaid to Overdue when due date passes.
-
Agency owner receives notification when invoice becomes overdue.
-
Overdue invoices can be paid via Pay or Mark as Paid methods.
-
Overdue invoices appear within the Unpaid tab (no separate tab).
9.5 Pay Contractor Flow
-
Pay button is visible only to Agency Owners.
-
Pay Contractor modal displays all required information fields including fee breakdown.
-
Stripe fee is fetched dynamically and displayed in the modal.
-
Fee recalculates automatically when Amount field is edited.
-
Modal shows appropriate message when agency payment method is not configured.
-
Modal shows appropriate message when contractor bank account is not configured.
-
Amount field is pre-filled and editable.
-
Pay Contractor button initiates Stripe ACH payout with total charge (Amount + Fee).
-
Invoice moves to Processing status after successful payment initiation.
9.6 Mark as Paid Flow
-
Mark as Paid button is visible to both Agency Owners and Agency Admins.
-
Modal displays a confirmation message and all required fields.
-
No fee breakdown is displayed for manual payments.
-
Payment Method dropdown shows all seven options (Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay).
-
Note field accepts up to 1000 characters.
-
Invoice moves directly to Paid status after confirmation.
9.7 Paid Tab Fee Display
-
Paid invoices from online payments display info icon (ⓘ) next to amount.
-
Hovering over info icon shows tooltip with Transaction Method, Amount, and Fee.
-
Manually paid invoices do not display info icon.
9.8 Failed Payment & Retry
-
Failed invoices display failure date and reason.
-
Retry Payment icon is visible only to Agency Owners.
-
Retry initiates new ACH payout attempt.
-
Stripe fees are only charged on successful retry.
-
Invoice moves to Processing status after retry initiation.
9.9 Filters & Search
-
All filter types function correctly (Date, Brand, Contractor, Project).
-
Project filter scopes to selected Brand.
-
Contractor filter scopes to selected Brand.
-
Filters persist across tab switches.
-
Search matches against Contractor Name, Project Name, and Amount.
-
Clear Filters resets all filters to defaults.
9.10 Sorting
-
All designated columns are sortable including Due Date in Unpaid tab.
-
Sort order toggles between ascending and descending.
-
Sort preferences persist within session.
9.11 QuickBooks Integration
-
Sync icon displays correct state (Synced, Failed, Pending).
-
Tooltip shows sync status details on hover.
-
Manual sync triggers successfully when clicked.
-
Paid invoices sync to QuickBooks as expenses.
9.12 Notifications
-
Contractor receives email and in-app notification on successful payment.
-
Agency owner receives email notification on failed payment.
-
Agency receives in-app notification when new invoice is submitted.
-
Agency owner receives notification when invoice becomes overdue.
9.13 View & Download Invoice
-
View Invoice opens PDF viewer popup.
-
PDF viewer has Print, Download, and zoom controls.
-
Download Invoice downloads PDF file to user's device.
10. Manual Test Cases
Test cases are documented in a separate Excel file for import into test management tools.
Refer: <u>Click Here</u>
11. Dependencies
Dependency Type
Dependency Name
Description
Impact if Unavailable
Internal Module
Brands
Brand creation and management
Invoices cannot be linked to projects/events
Internal Module
Projects
Project creation and linking
Invoices cannot be associated with projects
Internal Module
Events
Event creation within projects
Invoices cannot be linked to specific events
Internal Module
Contractor Management
Contractor profiles and event assignment
Cannot assign contractors or receive invoices
Internal Module
Contractor Portal
Interface for contractors to submit invoices with due dates
Invoices cannot be created by contractors
External Service
Stripe Connect
Payment processing for ACH payouts
Online payments cannot be processed; Mark as Paid still available
External Service
Stripe Financial Connections
Bank account linking for agencies
Agencies cannot add payment methods for ACH
External Service
Stripe Webhooks
Payment status updates
Payment status stuck in Processing; Manual verification required
External Service
Stripe Pricing API
Dynamic fee percentage retrieval
Fee cannot be calculated; Online payment blocked until resolved
External Service
QuickBooks API
Expense synchronization
Expense entries not created; Manual accounting required
Configuration
Agency Stripe Account
Agency's connected Stripe account
Cannot initiate ACH payments
Configuration
Contractor Stripe Account
Contractor's Stripe Connect account
Cannot receive ACH payments
Configuration
Agency Payment Method
Linked bank account for fund source
Cannot initiate ACH payments
Configuration
Contractor Bank Account
Linked bank account for payout
Cannot receive ACH payments
Background Service
Overdue Status Scheduler
Daily job to update invoice statuses
Invoices won't auto-transition to Overdue
12. References
Please refer- <u>Click Here</u>
View detail invoice
Functional Requirements Document (FRD) — Invoice Details View
1. Module Overview
-
Module Name: Billing → Invoice Details View
-
Purpose: The Invoice Details View provides a complete, single-screen representation of an individual invoice — including line items, taxes, discounts, payment schedule, payment activity, payout activity, refund activity, and contextual metadata (client, project, brand). It is the central interface for viewing, editing, sharing, refunding, deactivating, or deleting an invoice and for tracking the lifecycle of every scheduled payment within it.
-
Business Goal: Give agency owners and financial administrators a single source of truth for every invoice in the system. Reduce errors caused by stale or partial information by surfacing real-time payment and payout state, enable controlled in-place edits that preserve financial integrity once payments are collected, and centralize all invoice-level actions (edit, share, refund, deactivate, delete) into one auditable surface.
2. User Roles & Permissions
Refer — Click Here
3. User Flow
Navigation Paths:
There are two entry points to the Invoice Details View:
Path A — From Billing:
- User clicks "Finances" in the left navigation menu.
- User clicks "Billing."
- System displays the Billing page with the Invoices tab active by default.
- User locates the desired invoice row and clicks the three-dot Actions menu.
- User clicks "View Details."
- System opens the Invoice Details View for the selected invoice.
Path B — From Project:
- User navigates to a project from the Projects module.
- User opens the Invoice section/tab within the project.
- User clicks "View Invoice" on a specific invoice.
- System navigates the user to the Invoice Details View for that invoice (deep-linked).
Primary User Flow (after landing on Invoice Details View):
- User reviews invoice header (Invoice ID + status badge).
- User reviews the Items section (line items, optional groupings, quantity, unit, price, per-item tax toggle).
- User reviews calculated summary (Subtotal, Discount, Tax, Total Amount).
- User reviews Payment Terms and the schedule of payments with their individual statuses.
- User reviews the right-side Details panel (Net Total, Gross Total, Paid, Unpaid, Issued On, Next Payment, From, Bill To, Project & Event, Activity).
- User uses the Activity payment selector to inspect Payment, Payout, and Refund activity for a specific scheduled payment.
- User clicks "Actions" to perform any invoice-level action (Copy Invoice Link, Edit Invoice, Download PDF, Print Invoice, Refund, Deactivate Invoice, Delete Invoice).
Alternative Flows:
- Edit Mode Entry: User clicks Actions → Edit Invoice → System navigates to the Invoice Editor where the "Actions" button is replaced by "Update & Notify Client."
- Back Navigation: User clicks the back arrow next to the invoice ID to return to the Billing → Invoices list (or to the originating project if Path B was used).
- Send Reminder: For invoices with an unpaid next payment, user clicks "Send Reminder" in the Activity panel to send a reminder email immediately (governed by the 24-hour cooldown rule defined in the Transactions FRD).
4. Functional Logic
4.1 Page Layout & Empty State
Overview: The Invoice Details View is rendered as a two-column layout with a persistent header. There is no empty state for the page itself — if no invoice exists at the URL/ID, the system shows a "404 — Page not found" state with a CTA to return to Billing.
Header (top bar):
- Back arrow (←)
- Page title: "Invoice Details: #INVXXXXX"
- Status badge (right of title) — see Section 4.2
- "Actions" dropdown button (right-aligned) — see Section 4.10
- In Edit mode: the "Actions" button is replaced by "Update & Notify Client" — see Section 4.12
Left Column — Invoice Body :
- Items section (with line items, grouping headers, per-item tax toggle)
- Subtotal, Add Discount, Tax, Total Amount summary block
- Payment Terms section (schedule table with Amount, Due Date, Payment Date, Payment ID, Status, row actions in edit mode)
Right Column — Details Panel :
- Details card (Net Total, Gross Total, Paid, Unpaid, Issued On, Next Payment, From, Bill To)
- Project & Event card (Project link, Event and Date, Brand)
- Activity card (Payment selector + activity timelines + Send Reminder CTA)
Default State on Load: Read-only view with the most recent or upcoming scheduled payment auto-selected in the Activity selector.
Invoice-Not-Found State:
- Heading: "Invoice not found"
- Subtext: "This invoice may have been deleted or you may not have access to it."
- CTA: "Back to Billing"
4.2 Invoice Status Display (Header Badge)
Overview: The status badge next to the Invoice ID communicates the current consolidated state of the invoice. It is derived from the underlying transaction states (per the logic defined in the Invoices Tab FRD) and is mapped to a compact display label.
Status Badge Mapping:
Underlying Invoice Status
Display Badge
Unpaid
In Progress
Partially Paid
In Progress
Overdue
In Progress
Paid
Paid
Partially Refunded
In progress
Refunded
Refund
Deactivated
Deactivated
Business Rules:
- The badge is read-only and system-calculated.
- The badge updates in real time as underlying transactions transition state via Stripe webhooks or manual actions.
- The badge controls which Actions are available (see Section 4.10) and whether the invoice body is editable (see Section 4.18).
- Overdue is surfaced primarily at the payment-row level inside Payment Terms; at the invoice level, an overdue invoice shows "In Progress" with the affected payment row showing an "Overdue" status pill.
4.3 Items Section
Overview: Displays all line items grouped logically (e.g., Wedding, Rehearsal Dinner, Instagram Photo as standalone). Each line item shows description, optional sub-bullets, quantity, unit, price, and a per-item tax toggle.
Per-Item Fields Displayed:
- Item Name (text)
- Description / sub-bullets (text list — e.g., "10 hours of photoshooting", "Basic Retouch", "1 Photographer")
- Qty (numeric, optional display)
- Unit (text, optional display — e.g., hours, sessions)
- Price (currency, e.g., "$450")
- Tax Toggle (per item — when ON, this item's price is included in the tax base)
Grouping Headers:
- Items can be visually grouped under a section header (e.g., "WEDDING," "REHEARSAL DINNER").
- Grouping is set during invoice creation and is preserved here in read-only display.
"Add New Item" Link:
- Visible only in Edit mode (Section 4.12). In read-only view this control is hidden.
- In Edit mode (Mode A), clicking "Add New Item" opens an inline new-item row.
- In Edit mode (Mode B), it adds a new line item that will generate additional unpaid balance.
Business Rules:
- In read-only view, items are not editable.
- When an invoice is fully Paid, items are locked even in edit mode (Edit Invoice is not available for Paid status — see Section 4.10).
- When an invoice is Partially Paid, line items that correspond to already-collected payments are locked and visually indicated; new items can still be added.
- Tax toggle reflects the saved state and is not interactive in read-only mode.
4.4 Subtotal, Discount, Tax, Total Amount
Overview: Auto-calculated summary block beneath the Items section.
Fields:
- Subtotal — Sum of all line item prices (Qty × Unit Price summed across items). Read-only, system-calculated.
- Add Discount — Link/control to apply or edit a discount. Visible as "Add Discount" if no discount is applied, else shows discount value (e.g., "−$50.00") with an edit affordance in Edit mode.
- Tax — Displays as "X% Tax" or "$X Tax" (Fixed mode) or "Auto-Tax" (Stripe Tax mode). Shows "0.0% Tax" when no tax has been configured. Tax amount displayed on the right (e.g., "$42.50").
- Total Amount — Subtotal − Discount + Tax = Total Amount. Read-only, system-calculated, bold styling.
Pencil/Edit Icons:
- The pencil icon next to Tax and the Add Discount control are visible only in Edit mode. In read-only view these controls are hidden.
Calculation Logic:
- Subtotal = Σ (item.qty × item.unit_price) for all items.
- Taxable Subtotal = Σ (item.qty × item.unit_price) for items where tax_toggle = true.
- Tax Amount depends on tax type (see Section 4.5).
- Discount is subtracted from Subtotal before tax (when tax is percentage-based, tax applies to discounted subtotal). When tax is Fixed, discount and tax are independent.
- Total Amount = Subtotal − Discount + Tax. Cannot be negative; see validation in Section 5.
4.5 Edit Tax Modal
Overview: Triggered from the pencil icon next to the Tax row in Edit mode. Allows the user to set or change the tax mechanism for the invoice.
Modal Title: "Edit Tax"
Tax Type Selector (Three Tabs):
- Percentage — User enters a percentage value (e.g., "8.5"). Tax = Taxable Subtotal × (percentage / 100).
- Fixed — User enters a flat dollar amount (e.g., "$100"). Tax = entered amount, regardless of taxable subtotal. Not distributed across items.
- Auto-Tax Calculation — Powered by Stripe Tax. Automatically applies sales tax based on client location, product/service category, and other Stripe Tax inputs. Requires Stripe Tax to be enabled at the account level.
Field Behavior:
- Amount Field:
- In Percentage mode: numeric input with "%" suffix indicator.
- In Fixed mode: numeric input with "$" suffix indicator.
- In Auto-Tax Calculation mode: amount field is hidden; an info card explains the behavior.
Auto-Tax Calculation Info Card Copy: "Auto-Tax Calculation powered by Stripe helps you apply sales tax automatically based on your client's location, product type, or service category — no manual input needed. While it's a helpful starting point and often accurate, we're not accountants and can't guarantee its correctness. Ultimately, it's your responsibility to ensure the right amount of tax is collected and remitted."
Auto-Tax Availability:
- If Stripe Tax is not enabled on the connected Stripe account, the "Auto-Tax Calc..." tab is rendered disabled with a tooltip: "Enable Stripe Tax in your Stripe dashboard to use Auto-Tax Calculation."
- The other two tabs (Percentage, Fixed) remain available.
Modal Buttons:
- Remove Tax (secondary, left) — Sets tax to 0/none on the invoice. Closes the modal. Visible only when a tax is already configured.
- Cancel (secondary, right) — Discards changes, closes modal.
- Save (primary, right) — Validates and applies the tax. Closes the modal.
Business Rules:
- The tax mechanism is invoice-level (one tax setting per invoice).
- The per-item Tax toggle controls which items are included in the tax base; the modal does not control that.
- Tax can be edited on Unpaid, Partially Paid, and Overdue invoices.
- Tax editing is disabled when invoice is Paid, Partially Refunded, Refunded, or Deactivated.
- Changing tax recalculates totals immediately on Save. Already-paid transaction amounts are not affected; the recalculated Total only impacts the unpaid balance and future transactions (see Section 4.18).
4.6 Add / Edit Discount
Overview: Allows applying a discount that reduces the invoice subtotal.
Trigger: "Add Discount" link in Edit mode (link converts to discount value with pencil affordance once applied).
Discount Behavior:
- Discount can be entered as a fixed dollar amount and percentage based.
- Discount is subtracted from Subtotal before tax (for Percentage tax mode).
- Discount can be removed/edited in Edit mode while invoice is Unpaid, Partially Paid, or Overdue.
Business Rules:
- Discount value cannot make the Total Amount negative. Validation prevents Save if Subtotal − Discount + Tax < 0.
- On a Partially Paid invoice, discount edits can reduce only the unpaid balance; they cannot retroactively reduce already-collected payments. If the new Total would be less than the already-paid amount, Save is blocked with a validation message.
4.7 Payment Terms Section
Overview: Displays the schedule of payments derived from the invoice — when and how the client pays.
Section Header Elements:
- Title: "Payment Terms"
- Subtitle: "Specify when and how you will be paid"
- Save as Preset (button, Edit mode only) — Saves the current payment schedule as a reusable preset.
- Apply Preset (dropdown, Edit mode only) — Applies an existing preset to the current invoice's schedule.
Table Columns:
Column
Description
Amount
Dollar amount of this scheduled payment
Due Date
Scheduled payment due date
Payment Date
Actual date payment was completed (blank for unpaid rows)
Payment ID
Stripe payment identifier once charged (blank for unpaid rows)
Status
Row-level transaction status pill (Paid, Processing, Overdue, Failed, Unpaid, Due)
Row Actions (Edit mode only)
Edit (pencil) and Delete (trash) icons
Row-Level Status Pills:
Status
Pill Color
Meaning
Paid
Green
Payment confirmed by Stripe (or marked paid manually)
Processing
Blue/Cyan
Payment initiated, awaiting Stripe confirmation
Overdue
Red/Coral
Due date passed without successful payment
Failed
Red outline
Stripe returned a failure
Unpaid
Gray
Scheduled, due date not yet reached
Due
Yellow/Amber
Currently due (today or imminently — UI emphasis variant of Unpaid)
Add Payment Link:
- Visible only in Edit mode.
- Clicking adds a new payment row at the bottom of the schedule with empty Amount and Due Date inputs.
Business Rules:
- In read-only view, the table is purely informational; no row actions are visible.
- In Edit mode:
- Paid, Processing, and Failed rows are locked — pencil and trash icons are disabled with a tooltip ("Cannot edit a payment that has been processed").
- Unpaid and Overdue rows are editable (amount, due date) and deletable.
- The sum of all payment row amounts must equal Total Amount on Save. If not, validation blocks Save with a clear message.
- The Payment ID column auto-populates from Stripe once the payment is initiated/completed.
- The Payment Date column auto-populates from Stripe on successful payment.
4.8 Details Panel (Right Column)
Overview: Snapshot of invoice metadata, financial summary, and relationships.
Details Card Fields:
Field
Description
Net Total
Invoice total before any refunds, equal to Total Amount
Gross Total
Invoice total including any post-issuance changes (typically same as Net Total unless adjusted)
Paid
Total amount collected to date (sum of Paid transaction amounts)
Unpaid
Remaining balance (Net Total − Paid). Displayed in red/coral when > 0
Issued On
Date the invoice was first published/sent
Next Payment
Due date of the next upcoming scheduled payment (or "—" if all paid)
From
Agency information block (name, email, business name)
Bill To
Client information block (name, email)
Project & Event Card Fields:
Field
Description
Project
Project name with a "Project Details" link/button to navigate to the project
Event and Date
Event name and date (e.g., "Wedding (Sat, October 5, 2024)")
Brand
Brand under which the invoice was issued
Business Rules:
- All fields are read-only on the Details Panel.
- Project Details link navigates to the Projects module → project page.
- Client name in Bill To is a link to the Client profile (if Client Management module supports it).
- Paid and Unpaid values update in real time as transaction statuses change.
4.9 Activity Section
Overview: Granular, per-payment activity log showing the full lifecycle of each scheduled payment across three categories — Payment, Payout, and Refund. The Activity section is scoped to the payment selected in the dropdown.
Activity Payment Selector:
- Dropdown at the top of the Activity card (e.g., "Payment 2: Sep 20, 2025").
- Lists all scheduled payments in chronological order with their date.
- Default selection: the most recent payment with activity, or the next upcoming payment if no activity yet exists.
- Switching the selection swaps the displayed timelines.
Three Timeline Sections (rendered conditionally — only shown if at least one event exists in that category):
4.9.1 Payment Activity Timeline
Displays the full lifecycle of payment attempts for the selected scheduled payment, including retries.
States (in chronological order, retries reset the cycle):
State
Color
Description / Trigger
Initiated
Blue
Client started a payment attempt (Stripe PaymentIntent created)
Requires Action
Amber
3D Secure authentication requested
Processing
Purple
Shown for ACH / bank account payments awaiting clearance
Failed
Red
Card declined or other failure — customer retried, cycle restarts from Initiated
Successful
Green (filled)
Payment confirmed by Stripe
Header Right-Aligned Info: Card type and last 4 (e.g., "Card · Visa •••• 4242").
Display Rules:
- Full retry history is preserved — each cycle appended in chronological order.
- A horizontal divider separates retry cycles for visual clarity.
- The currently-active state (latest) is displayed with a filled dot; prior states use outlined dots.
4.9.2 Payout Activity Timeline
Displays the lifecycle of funds moving from Stripe to the agency's connected bank account for the selected payment.
States:
State
Color
Description / Trigger
Payout Initiated
Blue
Triggered by payout.created Stripe webhook
Deposit In Progress
Amber
Triggered by payout.updated with status: in_transit
Deposited
Green (filled)
Triggered by payout.paid
Deposit Failed
Red
Shown only when payout.failed is received
Header Right-Aligned Info: Wallet → Bank reference (e.g., "Wallet → Bank •••• 6789").
Display Rules:
- Payout Activity is shown only after the corresponding Payment Activity reaches "Successful."
- If a payout fails, the system surfaces the failure but does not automatically retry — the failure flows in via Stripe webhook only.
4.9.3 Refund Activity Timeline
Displays the lifecycle of refunds initiated against the selected payment.
States (Partial and Full refund flows shown in chronological order):
State
Color
Description / Trigger
Partial Refund In Progress
Amber
Refund initiated for an amount less than the full payment
Partial Refund Failed
Red
Stripe returned failure on the partial refund
Partially Refunded
Green (filled)
Partial refund successfully returned to client
Refund In Progress
Amber
Full refund initiated
Refund Failed
Red
Stripe returned failure on the full refund
Refunded
Green (filled)
Full refund successfully returned
Header Right-Aligned Info: "Initiated by agency."
Display Rules:
- Refund Activity is rendered only if at least one refund has been initiated for the selected payment.
- All refund attempts (in-progress, failed, successful) are preserved for audit and visibility.
4.9.4 Send Reminder CTA
Below the timelines, the "Send Reminder" button is visible when:
- The selected payment is in Unpaid, Overdue, or Failed state.
- The 24-hour reminder cooldown (per Transactions FRD §4.10) has elapsed.
Disabled with tooltip when within cooldown: "You will be able to send the next reminder 24h after the last one."
4.10 Actions Menu (Status-Driven)
Overview: The Actions dropdown in the header surfaces all invoice-level actions. Available actions vary by invoice status. Destructive actions ("Deactivate Invoice", "Delete Invoice") are visually distinguished (red text).
Action Availability Matrix:
Action
Unpaid (In Progress)
Partially Paid (In Progress)
Overdue (In Progress)
Paid
Partially Refunded (Refund)
Refunded (Refund)
Deactivated
Copy Invoice Link
✓
✓
✓
✓
✓
✓
✗
Edit Invoice
✓
✓
✓
✗
✗
✗
✗
Download PDF
✓
✓
✓
✓
✓
✓
✓
Print Invoice
✓
✓
✓
✓
✓
✓
✓
Refund
✗
✓
✓ (if any paid txn exists)
✓
✓
✗
✗
Deactivate Invoice
✓
✓
✓
✗
✗
✗
✗
Delete Invoice
✓ (if no payment history)
✗
✓ (if no payment history)
✗
✗
✗
✓ (if no payment history)
Action-Specific Rules:
- Copy Invoice Link: Hidden for Deactivated invoices because the link is invalidated on deactivation.
- Edit Invoice: Hidden for Paid, Partially Refunded, Refunded, and Deactivated invoices. Available for Partially Paid with restricted scope (see Section 4.12 Mode B).
- Refund: Only available when at least one underlying transaction is in Paid state (i.e., there are funds to refund). Hidden for Refunded (no remaining refundable balance) and Deactivated.
- Deactivate Invoice: Hidden for Paid (deactivation is meant to stop future collection — irrelevant when fully paid).
- Delete Invoice: Allowed only when zero payments have been collected (no transactions in Processing, Paid, Failed, or Refunded state). Available for Unpaid and Deactivated invoices that have no payment history.
4.11 Copy Invoice Link (Share Link Modal)
Overview: Generates and shares a tokenized link that, when opened by an authenticated client associated with the project, renders the invoice and allows payment.
Modal Title: "Share Link"
Modal Copy: "This link can be shared with all clients associated with this project."
Modal Body:
- Public Link label
- Read-only text input pre-filled with the tokenized URL (e.g., https://www.pixally.com/document/v2?token=a79d963c593584b7906aa7bc1387...)
- Copy Link button (right of the input) — copies the URL to clipboard, shows toast "Invoice link copied to clipboard."
Modal Footer:
- Done (primary) — closes the modal.
Business Rules:
- The link is token-based and requires client authentication (client must be logged in as a recipient associated with this project).
- When the authenticated client opens the link, they see the invoice in client-portal mode and can pay outstanding scheduled payments.
- The link is invalidated when the invoice is Deactivated or Deleted. Opening a stale link displays an error page: "This invoice is no longer available."
- No time-based expiry — the link remains valid as long as the invoice is active.
- The link is consistent across multiple "Copy Invoice Link" actions (it's the same token, not regenerated each time).
4.12 Edit Invoice Flow
Overview: Edit Invoice takes the user from the read-only Invoice Details View to the Invoice Editor — the same builder UI used during invoice creation (Image 15 layout). The editor is gated by an editability mode that depends on the invoice's current state.
Entry Point: Actions → Edit Invoice.
Editor Header Differences vs. Detail View:
- The "Actions" button in the top-right is replaced by an "Update & Notify Client" button.
- The back arrow remains and triggers the unsaved-changes check (see below).
4.12.1 Mode A — Full Edit (Unpaid invoice with no payment history)
Eligibility: Invoice status = Unpaid AND no transactions have ever entered Processing, Paid, Failed, or Refunded state.
Editable Surface:
- All line items (add, edit, delete, reorder)
- Quantity, Unit, Price for each item
- Per-item Tax toggle
- Tax (type and amount via Edit Tax modal)
- Discount (add, edit, remove)
- Payment Terms (add, edit, delete rows; change amounts and due dates)
- Save as Preset / Apply Preset for payment terms
Save Behavior: On "Update & Notify Client," all transactions are regenerated from the new payment schedule, the invoice version increments, and the client is sent an updated email notification.
4.12.2 Mode B — Restricted Edit (Partially Paid or Overdue invoice)
Eligibility: Invoice status = Partially Paid OR Overdue AND at least one transaction has been Paid/Processing/Failed/Refunded.
Locked Elements (visually indicated, non-interactive):
- Line items that correspond to already-collected payments
- Payment Terms rows with status Paid, Processing, or Failed (pencil and trash icons disabled with tooltip)
- Already-collected payment amounts
Editable Elements:
- Tax (type and amount — applies to recalculation of unpaid balance only)
- Discount (add, edit, remove — cannot make Total Amount less than already-paid sum)
- New line items can be added (which generate additional unpaid balance / new payment rows)
- Unpaid and Overdue payment rows (amount, due date)
- New payment rows can be added via "Add Payment"
Validation on Save:
- New Total Amount ≥ Sum of already-paid amounts — otherwise Save is blocked.
- Sum of Payment Term row amounts = Total Amount — otherwise Save is blocked.
- Total Amount > 0 — otherwise Save is blocked.
Save Behavior: Only unpaid/new transactions are regenerated; existing Paid/Processing/Failed transactions are preserved unchanged. The client is sent an updated email notification.
4.12.3 Update & Notify Client Button
Button States:
- Disabled (default on entry): No changes have been made. Tooltip: "Make a change to update this invoice."
- Enabled: At least one field has been modified vs. the saved version.
Click Behavior:
- System validates all fields and constraints (see Section 5 and Section 6).
- If valid, system saves changes, regenerates affected transactions, and directly sends an email notification to the client with a link to the updated invoice. No additional confirmation step.
- On success, system returns the user to the Invoice Details View (now reflecting the saved changes) with a success toast: "Invoice updated and client notified."
Autosave:
- Changes are autosaved as draft as the user edits (debounced).
- The "Changes applied to file" modal explicitly references this autosave: "Your changes were saved automatically."
4.12.4 Unsaved Changes — Back Navigation Modal
Trigger: While in Edit mode, user clicks the back arrow (or attempts to navigate away) with unsaved changes that have not yet been published via "Update & Notify Client."
Modal Title: "Changes applied to file"
Modal Body:
- "Your changes were saved automatically."
- Warning callout (icon + yellow background): "Updating will publish the latest version and send your client an email notification. Otherwise they'll still see the previous one."
Modal Buttons:
- Exit without updating (secondary) — User leaves the editor; draft remains saved internally but client is not notified and continues to see the previous published version.
- Update & Notify Client (primary) — Equivalent to clicking the header CTA: publishes and notifies, then exits.
Business Rules:
- The draft is preserved across sessions. The next time the user opens Edit Invoice, the draft state is restored.
- Drafts do not affect the read-only Invoice Details View shown to the agency or the client; both continue to see the last published version until "Update & Notify Client" is clicked.
- If the invoice is deactivated or deleted while a draft exists, the draft is discarded.
4.13 Download PDF
Overview: Generates a PDF representation of the invoice and triggers a download.
Behavior:
- On click, system generates the latest published version of the invoice as a PDF.
- PDF includes: header (logo, invoice ID, status), line items with grouping, totals, payment terms, agency and client info, payment IDs for paid transactions.
- Download begins automatically; filename format: Invoice_#INVXXXXX.pdf.
Business Rules:
- Available across all statuses including Deactivated (for record-keeping).
- PDF generation is asynchronous; a loading indicator displays during generation.
- On failure, user sees the PDF failure error message (Section 6).
4.14 Print Invoice
Overview: Opens the browser's print dialog with a print-optimized rendering of the invoice.
Behavior:
- On click, system opens a print-friendly view in a new tab/dialog.
- Print stylesheet hides navigation, action buttons, and interactive controls.
- Available across all statuses.
4.15 Refund Flow
Overview: Initiates a refund of a paid amount back to the client through Stripe. Funds are returned to the original payment method.
Trigger: Actions → Refund.
Modal Title: "Refund Invoice"
Modal Top Note (yellow callout): "Note: When you issue a refund, the processing fees from the original payment are not returned by Stripe. The refunded amount will come out of your balance in full."
Modal Body Copy: "We'll send the money back to {ClientName} via Stripe, directly to the original payment method. Enter the amount and an optional note. Refunds typically take 5–10 business days to appear in the client's account."
Modal Fields:
- Amount (currency input)
- Pre-filled with a default suggested value or left blank.
- Helper text below: "Up to ${maxRefund} available to refund."
- maxRefund = sum of paid amounts − sum of already-refunded amounts across all transactions on this invoice.
- Note (multi-line text area, optional)
- Free-form internal note (e.g., "Refunding the overpayment by customer").
Modal Buttons:
- Cancel (secondary)
- Process Refund (primary)
Business Rules:
- If the connected Stripe account does not have sufficient balance for the refund, Stripe returns an error; system surfaces the failure message.
- Refund amount can be partial or full (up to maxRefund).
- Multiple partial refunds are allowed on the same invoice as long as cumulative refunded amount ≤ total paid amount.
- On success:
- Stripe initiates the refund (state: Refund In Progress or Partial Refund In Progress in the Refund Activity timeline).
- Invoice status updates: Paid → Partially Refunded (if partial) or Refunded (if full), Partially Refunded → Refunded if cumulative refunds now cover all paid amounts.
- Refund Activity timeline reflects the new state.
- If multiple paid transactions exist, the system applies the refund against transactions in chronological order (oldest first) unless future logic dictates otherwise.
- Refunds are logged in the audit trail with user, timestamp, amount, and note.
4.16 Deactivate Invoice Flow
Overview: Marks the invoice as inactive — prevents the client from making any further payments and locks the invoice from edits.
Trigger: Actions → Deactivate Invoice.
Modal Title: "Deactivate Invoice"
Modal Warning Banner (yellow): "Warning: Deactivating This Invoice Will Stop All Payments."
Modal Body Copy:
"Before deactivating this invoice, please make sure you've issued any necessary refunds manually. Deactivating an invoice will:
- Prevent the client from making any future payments
- Stop all automated reminders
- Lock the invoice from further editing unless reactivated
Refunds are not processed automatically. If any amount needs to be returned to the client, please complete the refund through your payment processor before deactivating."
Modal Buttons:
- Cancel (secondary)
- Yes, Deactivate Invoice (primary, destructive styling)
Business Rules:
- Deactivation is not allowed when any transaction is in Processing state (the existing block from the Invoices Tab FRD applies). System shows the error: "Cannot deactivate. Payments are processing."
- On success:
- Invoice status → Deactivated.
- All unpaid/overdue scheduled payments are halted (no further reminders, no payment portal access).
- Public invoice link is invalidated.
- Client can no longer view or pay the invoice via the link.
- Invoice moves to the "Deactivated" tab in the Billing → Invoices list.
- Audit trail logs the deactivation event (user, timestamp).
4.17 Delete Invoice Flow
Overview: Permanently removes the invoice and all associated data. Allowed only when no payments have been collected.
Trigger: Actions → Delete Invoice.
Modal Title: "Delete Invoice"
Modal Body Copy:
"This action will permanently delete the invoice and all associated data, including:
- Line items
- Payment terms
- History and activity logs
This cannot be undone."
Modal Warning Banner (yellow): "If any payments have been made toward this invoice, you must void or deactivate it instead to preserve financial records. Invoices with payments cannot be deleted."
Modal Buttons:
- Cancel (secondary)
- Yes, Delete Invoice (primary, destructive styling)
Business Rules:
- Delete is allowed only when zero transactions on this invoice have ever been in Processing, Paid, Failed, or Refunded state.
- If any payment history exists, the "Yes, Delete Invoice" button is disabled and a tooltip explains why; alternatively, the action is hidden from the Actions menu entirely (per Section 4.10).
- On success:
- Invoice and all associated data are removed from active storage.
- The public link is invalidated.
- The deletion is logged in the audit trail (user, timestamp, invoice ID) for compliance, even though the underlying record is removed.
- User is redirected to the Billing → Invoices list with a success toast: "Invoice deleted successfully."
4.18 Read-Only vs. Editable State Logic
Overview: The Invoice Details View has a strict separation between read-only display and the Edit mode (Invoice Editor). The page itself is always read-only. Inline controls such as the Tax pencil, Discount edit, "Add New Item," "Add Payment," and row-level pencil/trash icons appear only in Edit mode.
State Determination on Page Load:
- System fetches the invoice and computes its consolidated status (per Invoices Tab FRD §4.3).
- System renders the page in read-only mode by default.
- If the user clicks Actions → Edit Invoice (and the action is allowed per Section 4.10), system navigates to the Invoice Editor in Mode A or Mode B based on payment history.
Locking Rules in Edit Mode (Mode B specifically):
Element
Locked When
Line item (any field)
The item is fully covered by collected payments
Payment row (amount, due date, delete)
Row status is Paid, Processing, or Failed
Total Amount reduction below paid sum
Always blocked — cannot make Net Total less than already-collected funds
Currency
Always locked (currency is fixed per brand/project)
Tax & Discount on Partial Payment:
- Editing tax recalculates Total. The new Total must remain ≥ already-paid amount.
- Editing discount recalculates Total. The new Total must remain ≥ already-paid amount AND > 0.
- If the user attempts a change that would violate either rule, Save is blocked with a specific error (see Section 6).
4.19 Impact
Cross-Module and Downstream Impact of Actions on the Invoice Details View:
- **Edit Invoice → Update & Notify Client:
**- Triggers regeneration of unpaid transactions in the Billing → Transactions tab.
- Sends an email notification to the client via the Email Service Provider.
- Updates the Next Payment Date displayed in the Invoices list.
- Logs the event in the audit trail.
- QuickBooks: only paid transactions remain synced; unpaid-side edits do not trigger sync.
- **Refund:
**- Triggers Stripe refund API.
- Updates underlying transaction(s) to Refunded or Partially Refunded.
- Updates invoice-level status accordingly.
- Updates Refund Activity timeline.
- QuickBooks: pushes a reversal entry for the refunded amount (per Transactions FRD).
- Updates Paid and Unpaid amounts in the Details panel.
- **Deactivate:
**- Marks invoice as Deactivated.
- Moves invoice to the Deactivated sub-tab in the Billing → Invoices list.
- Invalidates the public link.
- Removes the invoice from the client portal.
- Stops automated reminders.
- Does not affect already-paid transactions or their QuickBooks sync state.
- **Delete:
**- Permanently removes the invoice record.
- Removes the invoice from the Billing → Invoices list (All and Deactivated sub-tabs).
- Invalidates the public link.
- Logs the deletion in the audit trail.
- **Copy Invoice Link:
**- No state change on the invoice. Audit trail optionally logs the action.
5. Field Details & Validations
5.1 Header Fields
Field
Type
Format
Validation
Invoice ID
Auto-generated
"#INVXXXXX"
Read-only, unique, immutable
Status Badge
System-calculated
Colored pill (see §4.2)
Read-only
5.2 Items Section Fields
Field
Type
Format
Validation
Item Name
Text
Free text
Required, max 200 chars
Description
Multi-line text
Free text (bulleted)
Optional
Qty
Numeric
Positive integer or decimal
Must be > 0
Unit
Text
Free text (e.g., "hours")
Optional
Unit Price
Currency
"$X,XXX.XX"
Must be ≥ 0, two decimals
Per-Item Tax Toggle
Boolean
On/Off
Default: Off
5.3 Summary Fields
Field
Type
Format
Validation
Subtotal
Currency
"$X,XXX.XX"
System-calculated, read-only
Discount
Currency
"−$X,XXX.XX"
Optional; ≥ 0; ≤ Subtotal + Tax
Tax (Percentage)
Numeric
"X.X %"
≥ 0; max 100
Tax (Fixed)
Currency
"$X,XXX.XX"
≥ 0
Tax (Auto-Tax)
System-calculated
"$X,XXX.XX"
Pulled from Stripe Tax
Total Amount
Currency
"$X,XXX.XX"
System-calculated; must be > 0 on Save in Edit mode
5.4 Payment Terms Fields
Field
Type
Format
Validation
Amount
Currency
"$X,XXX.XX"
> 0; row-level. Sum of all rows must = Total Amount
Due Date
Date
"Mon DD, YYYY"
Valid date; must be ≥ Issued On date
Payment Date
Date
"Mon DD, YYYY"
Read-only; auto-populated from Stripe on payment
Payment ID
Text
Stripe ID format
Read-only; auto-populated from Stripe
Status
System pill
See §4.7 status pill table
Read-only
5.5 Details Panel Fields
Field
Type
Format
Validation
Net Total
Currency
"$X,XXX.XX"
Read-only, equals Total Amount
Gross Total
Currency
"$X,XXX.XX"
Read-only
Paid
Currency
"$X,XXX.XX"
Read-only, sum of paid transactions
Unpaid
Currency
"$X,XXX.XX"
Read-only, Net Total − Paid
Issued On
Date
"Mon DD, YYYY"
Read-only
Next Payment
Date
"Mon DD, YYYY" or "—"
Read-only
From
Text block
Multi-line
Read-only
Bill To
Text block
Multi-line
Read-only
Project
Text + Link
Project name
Read-only link
Event and Date
Text
Free text
Read-only
Brand
Text
Brand name
Read-only
5.6 Edit Tax Modal Fields
Field
Type
Format
Validation
Tax Type
Segmented tabs
Percentage / Fixed / Auto-Tax Calc
One required selection
Amount (Percentage)
Numeric
"%" suffix
≥ 0; ≤ 100; up to 2 decimals
Amount (Fixed)
Currency
"$" suffix
≥ 0; up to 2 decimals
Amount (Auto-Tax)
N/A
Not user-editable
Hidden; Stripe-driven
5.7 Refund Modal Fields
Field
Type
Format
Validation
Amount
Currency
"$" prefix
> 0; ≤ maxRefund; up to 2 decimals
Note
Text area
Free text
Optional; max 500 chars
5.8 Share Link Modal Fields
Field
Type
Format
Validation
Public Link
Read-only text
Tokenized URL
Read-only; copy-only
6. Error Message Handling
Scenario
Trigger
Message
Type
Invoice not found
URL or ID invalid
"Invoice not found. It may have been deleted or you don't have access."
Error
Network failure on load
API timeout
"Unable to load invoice. Please check your connection and try again."
Error
Edit blocked — Paid status
User somehow accesses Edit
"Paid invoices cannot be edited."
Error
Edit Save — total below paid sum
Mode B Save
"Total Amount cannot be less than the amount already collected (${paidSum})."
Error
Edit Save — payment rows don't sum to Total
Mode B Save
"Payment Terms total (${rowSum}) must equal the Invoice Total (${total})."
Error
Edit Save — Total ≤ 0
Mode A or B Save
"Invoice Total must be greater than $0."
Error
Edit Save — Discount exceeds Subtotal + Tax
Discount input
"Discount cannot make the Total Amount negative."
Error
Tax Save — Percentage out of range
Edit Tax modal
"Tax percentage must be between 0 and 100."
Error
Tax Save — Fixed amount invalid
Edit Tax modal
"Tax amount must be a positive number."
Error
Auto-Tax disabled
Auto-Tax tab clicked while Stripe Tax off
"Enable Stripe Tax in your Stripe dashboard to use Auto-Tax Calculation."
Tooltip
Refund — amount exceeds max
Process Refund click
"Refund amount cannot exceed the available refund balance (${maxRefund})."
Error
Refund — Stripe failure
Process Refund click
"Unable to process refund. Please try again or contact support."
Error
Refund — insufficient Stripe balance
Process Refund click
"Your Stripe balance is insufficient for this refund. Please top up and try again."
Error
Deactivate blocked — Processing payment
Deactivate confirm
"Cannot deactivate. Payments are processing."
Error
Delete blocked — payment history exists
Delete confirm
"Invoices with payment history cannot be deleted. Please deactivate instead."
Error
Copy link copy failure
Browser permission
"Unable to copy link. Please copy it manually."
Error
PDF generation failure
Download PDF click
"Unable to generate PDF. Please try again."
Error
Print dialog failure
Print Invoice click
"Unable to open print dialog. Please check your browser settings."
Error
Reminder cooldown active
Send Reminder click
"You will be able to send the next reminder 24h after the last one."
Tooltip
Edit conflict — last write wins
Concurrent edit detected
"Another user has updated this invoice. Your latest save has been applied."
Warning
Update & Notify — email send failure
Save in Edit mode
"Invoice updated, but we couldn't send the notification email. Please retry from Actions."
Warning
Stale share link opened by client
Client clicks invalidated link
"This invoice is no longer available."
Info (client-facing)
Success Messages:
Scenario
Message
Invoice link copied
"Invoice link copied to clipboard."
Invoice updated and client notified
"Invoice updated and client notified."
Tax updated
"Tax updated successfully."
Discount applied
"Discount applied successfully."
Refund processed
"Refund initiated. The amount will appear in the client's account in 5–10 business days."
Invoice deactivated
"Invoice #INVXXXXX deactivated successfully."
Invoice deleted
"Invoice deleted successfully."
PDF downloaded
"Invoice PDF downloaded successfully."
Reminder sent
"Payment reminder sent successfully."
7. Edge Cases
Scenario
Expected Behavior
Invoice has no payment schedule yet (draft)
Page renders normally; Payment Terms section shows "Add Payment" prompt in Edit mode; Activity section shows no timelines.
Activity selector shows a payment with no activity yet
Timelines render as empty (or hidden); only the selector and Send Reminder (if applicable) are visible.
User selects a payment in Activity that has been deleted in Edit mode
Selector falls back to the next available payment; previously-selected payment is removed from the dropdown.
Invoice status changes while user is viewing (e.g., client just paid)
Page updates in real time (websocket/polling); status badge, Paid/Unpaid totals, and Payment Terms row update without full reload.
Two users edit the same invoice concurrently
Last-write-wins. The user whose save lands second sees the warning "Another user has updated this invoice. Your latest save has been applied." Their changes overwrite the prior save.
User tries to edit tax on a fully Paid invoice
Edit Invoice action is hidden entirely; tax cannot be modified post-full-payment.
User tries to delete a payment row that is Paid
Trash icon is disabled with tooltip "Cannot delete a payment that has been processed."
Discount makes Total = 0
Save blocked: "Invoice Total must be greater than $0."
Refund amount equals full paid balance
Invoice status transitions to Refunded; subsequent Refund action is hidden.
Multiple partial refunds across the same payment
Each refund attempt logged in the Refund Activity timeline; cumulative refunded amount tracked; further refunds blocked once cumulative = paid total.
Auto-Tax Calculation returns a different value on recalculation
Tax field updates automatically; user notified via toast "Tax recalculated by Stripe Tax."
Stripe Tax becomes disabled after an invoice was configured with Auto-Tax
The saved tax value is preserved on the invoice; in Edit mode, the Auto-Tax tab is disabled and the user must choose Percentage or Fixed to make changes.
Client tries to pay an invoice that has just been deactivated
Public link returns "This invoice is no longer available." Any in-flight payment attempt is allowed to complete (Stripe will not cancel mid-flight), and the resulting transaction is recorded.
Invoice has 50+ payment rows
Payment Terms table renders with scroll; no virtualization required at this scale.
Activity timeline has very long retry history
Timeline scrolls vertically within its card; dividers separate retry cycles.
User exits edit mode via browser back button (not in-app back arrow)
Browser-native "Leave site?" prompt is triggered; draft remains saved (autosaved) so user can resume later.
User opens Edit Invoice with an existing draft
Editor restores the draft state with a banner: "You have unpublished changes. Update & Notify Client when ready."
Invoice deletion happens while user has it open in another tab
The other tab shows "Invoice not found" on next interaction.
Brand or Project linked to the invoice is deleted
Invoice remains intact; the Project/Brand link in the Details panel shows "—" or "Deleted Project."
Send Reminder click while the next payment becomes Paid mid-action
System validates state at click time; if already Paid, returns "This payment has already been collected."
Refund initiated while a payout for that payment is still In Progress
Refund is queued at Stripe level (per Stripe behavior); state shown as Refund In Progress until Stripe processes.
User attempts to add a payment row that would push schedule beyond Total Amount
Validation on Save: "Payment Terms total exceeds Invoice Total."
User changes tax type from Percentage to Fixed (or vice versa)
Amount field resets; new value required before Save can be enabled.
8. Acceptance Criteria
Core Functionality:
- Users can open the Invoice Details View from both the Billing module and from within a Project.
- The status badge correctly maps invoice status to the four display states (In Progress, Paid, Refund, Deactivated).
- All read-only fields (Items, Summary, Payment Terms, Details, Activity) render accurately based on real-time data.
Activity Section:
- The Activity selector defaults to the most recent or next upcoming payment.
- Switching the selector swaps the three timeline sections correctly.
- Payment, Payout, and Refund timelines render only when at least one event exists in that category.
- Retry cycles in Payment Activity are preserved and visually separated.
Actions:
- The Actions menu shows exactly the actions permitted by the invoice's current status (per §4.10 matrix).
- Destructive actions (Deactivate, Delete) are visually distinguished.
Edit Flow:
- Edit Invoice from Actions navigates to the Invoice Editor in Mode A or Mode B based on payment history.
- In edit mode, "Actions" is replaced by "Update & Notify Client."
- "Update & Notify Client" is disabled until at least one field is changed.
- Back navigation with unsaved changes triggers the "Changes applied to file" modal.
- "Update & Notify Client" sends the client an email directly on click.
- Mode B correctly locks paid line items and paid payment rows.
- Save is blocked when Total would fall below already-paid sum.
Modals:
- Copy Invoice Link modal shows a tokenized link and copy-to-clipboard works.
- Refund modal validates amount against maxRefund and submits to Stripe.
- Deactivate modal blocks deactivation when a Processing payment exists.
- Delete modal blocks deletion when payment history exists.
- Edit Tax modal supports Percentage, Fixed, and Auto-Tax Calculation modes with correct field visibility.
Real-Time and Audit:
- Status changes from upstream events (Stripe webhooks, manual marking) reflect immediately in the view.
- All actions (edit, refund, deactivate, delete, reminder sent) are logged in the audit trail with user and timestamp.
Integrations:
- Stripe refunds, webhooks, and Stripe Tax (when enabled) function correctly through the view.
- QuickBooks sync state is preserved across edits (only paid transactions sync; refunds push reversals).
- Client notification emails are sent on Update & Notify Client.
9. Dependencies
Module/System
Type
Impact if Unavailable
Billing → Invoices Tab
Data Dependency
Cannot reach Invoice Details via Path A; cannot return on back navigation.
Billing → Transactions Tab
Data Dependency
Transaction data and statuses cannot be displayed; Activity timelines render empty.
Projects Module
Data Dependency
Path B navigation broken; Project Details link non-functional; Project/Event card shows "—".
Clients Module
Data Dependency
Bill To block and refund recipient name cannot be displayed.
Brands Module
Data Dependency
Brand label in Project & Event card cannot be displayed.
Stripe Payment Gateway
Integration
Payment/Payout activity timelines cannot update; Refund cannot be processed.
Stripe Tax
Integration
Auto-Tax Calculation option disabled with tooltip.
QuickBooks Integration
Integration
Sync indicators on Paid transactions unavailable; refund reversals not pushed.
Email Service Provider
Integration
"Update & Notify Client" cannot send notification email; reminder emails fail.
Authentication Service
Security
User cannot access the page; client cannot open public link.
Audit Trail Service
Service
Actions not logged; compliance impacted.
PDF Generation Service
Service
Download PDF fails with error.
File Storage / CDN
Service
Avatars, logos, and other assets fail to render.
10. References
Invoices
Refer - Click Here
Deprecated
Functional Requirements Document (FRD) - Paid Invoice Detail View
1. Overview
Paid Invoice Detail View
Purpose: Display a comprehensive read-only view of paid invoices with limited action capabilities
Business Goal: Provide complete invoice information for reference and enable essential post-payment actions
2. User Roles & Permissions
Role
Access Level
Agency Owner
Full access to all paid invoice details and actions
Admin
Full access to all paid invoice details and actions
Project Manager
Access only to paid invoices for assigned projects
3. User Flow
- User navigates to the paid invoice from the billing list or the direct link
- System displays read-only invoice detail view
- User reviews invoice information and payment history
- User can perform limited actions: Download PDF, Print, Copy Link, and Refund.
- The system maintains an audit trail of actions performed
4. Display Sections
4.1 Invoice Header
Field
Type
Description
Invoice Number
Text
Format: #INV00004
Status Badge
Visual Indicator
Green "Paid" badge
Action CTA
Action Button
Copy invoice link, download PDF, Print invoice, Refund
4.2 Items Section (Read-Only)
Field
Description
Service Description
Item name and details
Quantity
Service quantity
Unit Price
Price Unit
Package Line item listing
Event-wise details of the line items
A La Carte item Listing
Ad on items/events’ listing
Subtotal
Sum of all line items and add-ons
Tax Percentage
Applied tax rate (only applies if not 0)
Tax Amount
Calculated tax amount(only applies if not 0)
Total Amount
Final invoice total
4.3 Payment Terms Section (Read-Only)
Field
Description
Payment Amount
Individual payment amount
Due Date
Original payment due date as per the package or manual added
Payment Date
Actual payment completion date
Payment ID
Unique payment reference- auto-fetched from
Payment Status
"Paid" status indicator
4.4 Right Sidebar Information
Invoice Details
- Net Total - This is the amount after deductions (like taxes, insurance, or other withholdings).
- Gross Total - This is the total amount before any deductions.
- Paid- Money already received or settled.
- Unpaid-Money that is still outstanding (not yet received or settled). In case of a paid document the unpaid amount will be by default zero
- Issued on - date of invoice issued
Action CTA:
- Copy invoice link: Creates a shareable link to the invoice
- Download PDF : Lets you save the invoice as a PDF file on your computer.
- Print Invoice: Sends the invoice to your printer for a paper copy.
- Refund: will move the invoice to the refund tab.
Project & Event Panel:
- Project name and link
- Event details and dates
- Brand association
Activity Panel:
- Payment timeline
- Status change history
- User action logs
5. Success Messages
Action
Success Message
PDF Download
"Invoice PDF downloaded successfully."
Copy Link
"Invoice link copied to clipboard"
6. Error Messages
Scenario
Error Message
PDF Generation Failed
"Unable to generate PDF. Please try again"
Refund Process Failed
"Unable to process refund. Please contact support"
7. Functional Logic
Read-Only Enforcement
- All invoice data is displayed as non-editable text
- No form fields or input controls available
- Financial calculations are displayed but not modifiable
Action Restrictions
- Refund and actions limited to Owner/Admin roles
- PM users can only view invoices for assigned projects
- All actions maintain an audit trail
Data Display Rules
- Currency values formatted with proper symbols and decimals
- Dates displayed in consistent format (MMM DD, YYYY)
- Payment status clearly indicated with visual cues
8. Acceptance Criteria
- Invoice displays all line items, totals, and payment information in read-only format
- Payment history shows a complete transaction timeline
- All monetary values are formatted consistently with currency symbols
- Limited actions (Download, Print, Copy Link, Refund) function correctly
- The activity timeline shows chronological payment and status progression
- Visual status indicators clearly show "Paid" state throughout the interface
9. Dependencies
System
Dependency Type
Impact if Unavailable
Billing Module
Data Source
Cannot display invoice information
Payment Processing
Status Data
Payment history unavailable
Project Management
Reference Data
Project details cannot be displayed
PDF Generation Service
File Export
Download PDF functionality fails
Functional Requirements Document (FRD) - Invoice details
1. Overview
Purpose: Comprehensive invoice viewing, editing, and management interface with line item modifications, payment term adjustments, and status tracking capabilities
Business Goal: Provide complete invoice lifecycle management with flexible editing, automated calculations, payment processing integration, and comprehensive audit tracking
2. User Roles & Permissions
Role
Description
Key Permissions
Agency Owner
Business owner with full financial control
Full access: view, edit, delete, refund, activate/deactivate all invoices, manage payment terms, tax settings
Admin
System administrator with operational control
Full access: view, edit, delete, refund, activate/deactivate all invoices, manage payment terms, tax settings
Project Manager (PM)
Project-specific management role
Limited access: view invoices for assigned projects only, edit/delete permissions are available but no refund access is with the PM
3. Invoice Status Management
3.1 Client-to-Agency Invoice Statuses
Status
Description
Trigger
Editable
Unpaid
Payment not yet initiated
Manual/Default
Yes
Processing
Payment initiated, pending completion
Stripe automatic
No
Paid
Payment successfully completed
Stripe automatic
No
Overdue
Payment is past due date
Automatic (date-based)
Yes
Failed
Payment processing failed
Stripe automatic
No
Refunded
Payment refunded to client
Manual/Stripe
Yes
3.2 Agency-to-Contractor Invoice Statuses
Status
Description
Trigger
Editable
Unpaid
Payment has not yet been made to the contractor
Default
Yes
Processing
Payment initiated to the contractor
Stripe automatic
No
Paid
Payment completed to the contractor
Stripe automatic
No
Failed
Payment to the contractor failed
Stripe automatic
Yes
4. User Flow
Primary Flow - Invoice Detail Management:
- Invoice Access: User navigates to the invoice detail from the billing list or a direct link
- Status Review: User views current invoice status and financial summary
- Content Management: User reviews/edits line items, applies discounts, and manages tax settings
- Payment Terms: User modifies payment schedules, adds new payment terms
- Actions Execution: User performs available actions based on invoice status and permissions
- Activity Tracking: System logs all changes and updates in the activity timeline
5. Field Details & Validations
5.1 Invoice Header Information
Field Name
Required
Validation Rules
Description
Invoice Number
Yes
Auto-generated, format: #INV00004
Unique invoice identifier
Status Badge
Yes
Auto-updated based on payment status
Current invoice status display
Actions Button
Yes
Role-based action availability
Available actions menu
5.2 Financial Summary Fields
Field Name
Type
Required
Validation Rules
Gross Total
Currency
Yes
Calculated from line items, the full invoice amount before deductions.
Net Total
Currency
Yes
The total amount due after all deductions (e.g., taxes, discounts).
Paid Amount
Currency
Yes
Sum of completed payments
The invoice marked as settled, either automatically when payment is processed or manually.
Unpaid Amount
Currency
Yes
Invoice not yet settled; may become overdue after the due date.
Issued On
Date
Yes
Date of the invoice issused
Next Payment
Date
Yes
Date of next payment if there is any
From
Name and email ID
Yes
From the billing name and the email ID
Bill To
Name and email ID
Yes
To the billing name and the email ID
5.3 Line Item Fields
Field Name
Type
Required
Validation Rules
Description
Item Name
Text
Yes
From the package catalogue or custom entry
Service/product description
Quantity
Number
Yes
Must be > 0, decimal allowed
Item quantity
Unit Price
Currency
Yes
Must be > 0
Price per unit
Line Total
Currency
Yes
Calculated: Quantity × Unit Price
Total for line item
Tax Toggle
Boolean
No
Per-item tax application
Tax inclusion for specific item
Item Description
Text
No
Optional detailed description
Additional item details
5.4 Payment Terms Fields
Field Name
Type
Required
Validation Rules
Description
Payment Amount
Currency
Yes
Must be > 0, total must equal Net Total
Individual payment amount
Due Date
Date
Yes
Cannot be past date for new payments
Payment due date
Payment Date
Date
Conditional
Set when payment is completed
Actual payment date
Payment ID
Text
Conditional
Auto-generated for completed payments
Payment reference
Payment Status
Text
Yes
Unpaid/Processing/Paid/Failed/Overdue
Current payment status
5.5 Contact Information, Project & event details and Activity
Field Name
Required
Validation Rules
Description
Project Name
Yes
Links to the project management module
Associated project
Event Date
Yes
Primary event date from the project
Event scheduling information
Brand
Yes
Brand association
Brand identification
Payment activity
Yes
All the payment status flow will be there
Send Reminder
Conditional
Send an email reminder for the client to pay the overdue invoice
6. Popup Specifications
6.1 Add Payment Popup
Field Name
Type
Required
Validation Rules
Description
Date Type
Dropdown
Yes
Smart Date, Custom Date options
Payment date calculation method
Days Before
Number
Conditional
1-365 days
Days before project date
Payment Type
Radio Buttons
Yes
Custom, Percentage, Equal Payment
Payment calculation method
Custom Amount
Currency
Conditional
Must be > 0 when Custom selected
Specific payment amount
Percentage
Percentage
Conditional
1-100% when Percentage selected
Percentage of total amount
6.2 Edit Discount Popup
Field Name
Type
Required
Validation Rules
Description
Discount Type
Radio Buttons
Yes
Percentage or Fixed amount
Discount calculation method
Amount
Number
Yes
Must be > 0, percentage ≤ 100%
Discount value
Remove Discount
Button
No
Removes all applied discounts
Discount removal option
6.3 Apply Tax Popup
Field Name
Type
Required
Validation Rules
Description
Tax Type
Radio Buttons
Yes
Percentage, Fixed, Auto-Tax Calculation
Tax calculation method
Amount
Number
Conditional
Must be ≥ 0
Tax rate or fixed amount
Auto-Tax Calc
Selection
Conditional
Based on client location and service type
Automatic tax calculation
6.4 Delete Invoice Popup
Field Name
Type
Required
Validation Rules
Description
Warning Message
Text
Yes
"This action will permanently delete the invoice and all associated data"
Deletion warning
Data Impact List
Text
Yes
Line items, Payment terms, History and activity logs
What will be deleted
Payment Warning
Text
Conditional
Shown if payments exist
Warning about paid invoices
Confirmation
Button
Yes
"Yes, Delete Invoice"
Deletion confirmation
6.5 Deactivate Invoice Popup
Field Name
Type
Required
Validation Rules
Description
Warning Message
Text
Yes
"Warning: Deactivating This Invoice Will Stop All Payments"
Deactivation warning
Impact Description
Text
Yes
Lists effects of deactivation
Consequences explanation
Refund Notice
Text
Yes
Manual refund requirement notice
Refund process information
Confirmation
Button
Yes
"Yes, Deactivate Invoice"
Deactivation confirmation
6.6 Refund Invoice Popup
Field Name
Type
Required
Validation Rules
Description
Refund Notice
Text
Yes
Processing fee and timing information
Refund process details
Recipient
Text
Yes
Client name for refund
Refund recipient
Amount
Currency
Yes
Must be ≤ total refundable amount
Refund amount
Available Amount
Text
Yes
Shows maximum refundable amount
Refund limit display
Note
Text Area
No
Optional refund reason
Refund explanation
7. Success Message Handling
Validation Scenario
Success Message
Invoice updated successfully
"Invoice has been updated successfully."
Payment term added
"Payment term added successfully."
Discount applied
"Discount applied successfully."
Tax settings updated
"Tax settings updated successfully."
Payment processed
"Payment processed successfully."
Invoice deactivated
"Invoice has been deactivated successfully."
Invoice deleted
"Invoice has been deleted permanently."
Refund processed
"Refund of $[amount] initiated successfully."
8. Error Message Handling
Field
Validation Scenario
Error Message
Payment Terms
Invalid payment distribution
"Payment terms must equal invoice total amount"
Discount
Discount exceeds invoice total
"Discount cannot exceed invoice total amount"
Date Validation
Invalid due date
"Due date cannot be in the past"
Amount Validation
Invalid payment amount
"Payment amount must be greater than $0"
System Integration
Stripe connection failure
"Payment processing unavailable. Please try again later"
9. Functional Logic
Invoice Editing Rules
- Paid Invoice Restrictions: Once any payment is completed, invoice cannot be edited
- Line Item Modifications: Adding/editing line items automatically recalculates totals and adjusts unpaid payment terms proportionally
- Tax Toggle Logic: Tax can be applied/removed to entire invoice or individual line items, automatically recalculating totals
- Discount Application: Only one discount can be applied per invoice, either percentage-based or fixed amount
Payment Term Management
- Automatic Adjustment: When invoice total changes, unpaid payment terms adjust proportionally while maintaining paid amounts
- Overpayment Handling: If line item changes result in paid amount exceeding new total, system displays warning and requires manual refund processing
- Payment Addition: New payment terms can be added, automatically redistributing unpaid amounts across all payment dates
- Date Validation: Payment due dates cannot be set in the past for new payment terms
Tax Calculation Logic
- Auto-Tax Calculation: System automatically applies correct tax based on client location and service type when enabled
- Manual Override: Users can override automatic tax calculations with custom rates or fixed amounts
- Line Item Tax: Tax can be applied at individual line item level or invoice level
- Tax Toggle: Tax can be completely removed from invoice, updating all calculations accordingly
Activity Tracking Logic
- Comprehensive Logging: All invoice actions logged with timestamps: creation, editing, payments, status changes, user actions
- User Attribution: Every activity entry includes user identification and role information
- Permanent History: Activity logs maintained indefinitely for audit and compliance purposes
- Real-Time Updates: Activity timeline updates immediately when actions are performed
Integration Logic
- Stripe Integration: All payment processing, status updates, and refunds handled through Stripe API
- Project Module Integration: Project details link directly to project management module
- Package Catalog Integration: Line item additions pull from existing package and A La Carte catalogs
- Preset System: Payment term presets can be saved and applied across multiple invoices
10. Edge Cases
Scenario
Expected Behavior
Overpayment due to line item reduction
Display warning message, require manual refund processing before allowing changes
Multiple simultaneous edits
Last save wins, notify users of conflicts, provide option to refresh and retry
Payment processing during invoice edit
Lock invoice editing until payment processing completes
Discount exceeding invoice total
Prevent application, show validation error, suggest maximum discount amount
Tax toggle on individual items with invoice-level tax
Item-level tax takes precedence, calculate accordingly
Payment term deletion with existing payments
Prevent deletion of payment terms with completed payments
Preset application over existing payment terms
Replace existing unpaid terms, preserve paid terms, recalculate totals
Network interruption during save
Auto-save draft changes, restore on reconnection, validate data integrity
Client location change affecting auto-tax
Prompt user to recalculate tax, apply new rates if confirmed
Large invoice with many line items
Implement pagination for line items, maintain performance
Concurrent payment and refund processing
Queue operations, process sequentially, update status accordingly
Invoice deletion with partial payments
Prevent deletion, require deactivation instead, provide refund guidance
11. Test Cases
12. Acceptance Criteria
- Role-Based Access Control: PM users can only view invoices for assigned projects, Owner/Admin have full edit access
- Status Management: Invoice statuses update automatically via Stripe integration and manually as appropriate
- Line Item Flexibility: Users can add, edit, and remove line items with automatic total recalculation
- Tax Management: Tax toggle works at invoice and line item levels with accurate calculations
- Payment Term Control: Payment terms can be added, modified, and adjusted with proper validation
- Discount Functionality: Single discount application per invoice with percentage or fixed amount options
- Edit Restrictions: Paid invoices cannot be edited, appropriate restrictions enforced
- Overpayment Protection: System prevents line item changes that would create overpayment situations
- Integration Reliability: Stripe integration handles all payment processing and status updates
- Activity Tracking: Complete audit trail maintained for all invoice actions and changes
- Preset Management: Payment term presets can be saved and applied efficiently
- Action Availability: All actions (edit, delete, refund, etc.) available based on invoice status and user permissions
- Data Validation: All financial calculations accurate and validated before saving
- Error Handling: Comprehensive error messaging for validation failures and system issues
- Performance: Interface remains responsive with large invoices and multiple line items
13. Dependencies
Module/System
Dependency Type
Impact if Unavailable
Stripe Payment Gateway
Critical Integration
Payment processing, status updates, and refunds fail
Package Management
Data Dependency
Cannot add line items from package catalog
Project Management
Reference Dependency
Project details link non-functional, project association fails
Authentication System
Security Dependency
Role-based access control fails
Billing Module
Parent Dependency
Cannot access invoice data or navigate back to billing list
Activity Logging System
Audit Dependency
Activity tracking fails, compliance issues
Tax Calculation Service
Functional Dependency
Auto-tax calculation unavailable
Email Service
Communication Dependency
Invoice notifications and reminders fail
14. Future Enhancements
14.1 Advanced Features
- Version Control: Track invoice versions and allow rollback to previous versions
- Approval Workflow: Multi-level approval process for large invoice modifications
- Bulk Operations: Batch invoice operations for multiple invoices
- Template Management: Custom invoice templates with branding
14.2 Integration Expansions
- Multi-Currency Support: Handle international clients with currency conversion
- Advanced Tax Management: Complex tax scenarios with multiple jurisdictions
- Document Management: Attach supporting documents and contracts to invoices
- API Access: RESTful API for third-party integrations and custom reporting
15. References
- Figma
Expense
Finance Management — Expenses Management Module (FRD)
1. Module Overview
Module Name: Expenses Management Module (Sub-module within Finance Management)
Purpose: Record, manage, and track all outgoing monetary expenses of the company with COGS/OPEX classification, brand and project association, contractor/editor payee tracking, and automated QuickBooks integration.
Business Goal: Provide centralized expense management with an OPEX-vs-COGS tabbed view, detailed categorization, project-linked cost attribution (COGS), contractor and editor payment tracking, and per-row QuickBooks sync visibility.
2. User Roles & Permissions
Role
Add
Edit
Delete
View
Agency Owner
Any expense (COGS or OPEX)
Any expense
Any expense — except Stripe/ACH-paid entries, which are never deletable
All expenses
Admin
Any expense (COGS or OPEX)
Any expense
Only entries they added themselves (never Stripe/ACH-paid)
All expenses
Project Manager (PM)
COGS only, for assigned projects (cannot add OPEX)
Only entries they created themselves, within assigned projects
Only entries they created themselves, within assigned projects (never Stripe/ACH-paid)
Own assigned-project expenses; can view OPEX read-only
Note (flagged for confirmation): Admin permissions are intentionally asymmetric — Admin can edit any expense but can delete only their own manual entries. Confirm this is intended and not meant to be symmetric.
Note: "Project owner" in stakeholder notes is treated as the Project Manager (PM) role.
3. User Flow
Primary Flow — Expense Management
- Module Access: User navigates to Finance Management → Expenses.
- Tab Selection: User lands on the All tab by default and can switch between All | OPEX | COGS (each showing a live count).
- Expense Listing: System displays the expense table. On All and COGS, columns are Date, Amount, Category (with a COGS/OPEX badge), Brand, Project, Payee, Notes, and Action. On OPEX, the Project and Payee columns are hidden.
- Filter Application: User applies filters (brand, date range, price range, notes/category search) and, on the All and COGS tabs only, the "Only show amount paid to Contractor" toggle. Filters and search persist when switching tabs.
- Expense Actions: Based on permissions, the user can add, edit, or delete expenses, and manually re-sync an entry with QuickBooks.
- QuickBooks Integration: When the integration is on the plan and connected, every expense syncs to QuickBooks by default and each row shows a Synced / Not synced indicator with manual re-sync from the kebab. The indicator is hidden when the integration isn't on the plan and greyed when on plan but not connected (see §4.11, §10.1).
Secondary Flow — Add New Expense
- Add Expense: User clicks the "Add Expense" button (available from every tab).
- Type Selection: The expense type defaults to OPEX from all tabs. Agency Owner and Admin can switch to COGS. Project Managers are offered COGS only (they cannot create OPEX), so COGS is pre-selected for them.
- Category Selection: User selects from the predefined category list for the chosen type.
- Form Completion: User fills the required fields. For COGS, brand is required and project is auto-fetched when the entry originates from a project, or optional when added manually. OPEX has no project field.
- Payee Selection (COGS): For payee-based COGS categories (e.g., Contractor), the user selects the relevant contractor; the selected name appears in the Payee column.
- Submission: System validates data and creates the expense record.
- Auto-Sync: System syncs the new expense to QuickBooks by default.
Tertiary Flow — Delete / Void
- Delete Attempt: A permitted user clicks the delete icon on a deletable row (Stripe/ACH-paid entries show a greyed-out, non-clickable delete icon).
- Local Deletion: The entry is hard-deleted from the CRM (row disappears, excluded from all totals).
- QuickBooks Void: If the entry was synced, it is voided in QuickBooks. If QuickBooks is not connected (or the entry was never synced), no QuickBooks action occurs.
- Source Reversion: If the entry was an editor payment (from Post Production) or a manually marked-as-paid contractor payment, deleting it reverts the source status back to unpaid.
Quaternary Flow — QuickBooks Sync Management
- Auto-Sync: The system syncs new/modified expenses to QuickBooks by default.
- Sync Indicator: When connected, each row shows Synced (green) or Not synced (grey); hidden when the integration isn't on the plan; greyed for all rows when on plan but not connected (see §10.1).
- Manual Re-Sync: When connected, the user opens the row's kebab (three-dot) menu and selects "Sync with QuickBooks" to sync a Not-synced entry.
4. Functional Logic
4.1 Empty State (Initial Behavior)
- When no rows match the current tab, search, filters, brand, or toggle — or when no expenses exist at all — the table area shows a single global empty-state message (see Section 6). The filter/search/tab controls and the toolbar "Add Expense" button remain visible and enabled at all times.
- The empty state never blocks adding an expense; permitted users can always add from the toolbar.
4.2 Expense Tabs (All | OPEX | COGS)
- Three tabs group expenses by type: All, OPEX, COGS. Each tab displays a live count of its records.
- All is the default tab and shows every expense; rows carry a COGS/OPEX badge in the Category cell, and OPEX rows render "–" in the Project and Payee columns.
- OPEX and COGS tabs constrain the list to that type. Search, brand filter, price/date filters, and (where applicable) the contractor toggle operate within the active tab's scope and persist across tab switches.
- Selecting a tab does not clear active filters or search terms; they re-apply within the new tab's scope.
4.3 Expense Type & Category Logic
- COGS and Editor/Contractor placement: Contractor payments and editor payments are COGS (moved from OPEX). COGS categories include Contractor plus production-related categories such as Second Shooter, Editing Services, Equipment Rental, and Album & Print Production.
- OPEX scope: OPEX now covers operating costs only (e.g., Business Insurance, Legal Fees, Utilities, CRM / Project Management Software, Studio Lease, Paid Advertising, Bank / Payment Processor Fees). OPEX no longer has a contractor field.
- Type→Category filtering: Selecting COGS shows only COGS categories; selecting OPEX shows only OPEX categories.
- Contractor category logic: When a payee-based COGS category (e.g., Contractor) is selected, the contractor/payee selection becomes required.
4.4 Table Columns & Behavior
- All & COGS tabs: Date, Amount, Category (with COGS/OPEX badge), Brand, Project, Payee, Notes, Action.
- OPEX tab: Date, Amount, Category, Brand, Notes, Action — the Project and Payee columns are hidden entirely (not blank).
- Project column: Clickable — navigates through to the linked project. Present on All & COGS; "–" for OPEX rows shown on the All tab.
- Payee column: A single generic column showing the contractor/editor/vendor name where one applies; blank ("–") when there is no named payee. Plain text, not clickable (for now).
- Action column: Contains the QuickBooks sync indicator (Synced / Not synced — hidden entirely when QuickBooks integration is not on the subscription plan; see §4.11 and §10.1), an edit icon, a delete icon, and a kebab (three-dot) menu with "View Details" and "Sync with QuickBooks."
4.5 Project Assignment Logic
- Project applies to COGS only. When a COGS entry originates from a project, the project is auto-fetched and populated on every such entry; when added manually, the project field is optional.
- PM scoping: PMs can only select/add against their assigned projects. Because OPEX has no project to scope by, PMs cannot add OPEX (they may view OPEX read-only).
- Agency Owner and Admin can leave the manual COGS project field empty for company-wide costs.
4.6 Payee Logic (Contractor vs. Editor)
- Contractors and editors are distinct entities, both surfaced through the single Payee column.
- Contractor payments: Paid directly via Stripe/ACH, or manually marked as paid. Stripe/ACH-paid contractor entries are non-deletable; manually marked-as-paid contractor entries are deletable.
- Editor payments: Editors cannot be paid directly from the system; they are marked as paid from Post Production, which creates the expense entry. Such entries are deletable, and deletion reverts the editor to unpaid in Post Production.
- Failed payments never create an expense entry, so there is no failed-payment row to handle.
4.7 Add Expense & Type Pre-selection
- The Add Expense action is available from every tab; on submission it defaults the expense type to OPEX regardless of the active tab.
- Agency Owner and Admin may switch the type to COGS in the form.
- Project Managers are offered COGS only (they cannot create OPEX), so COGS is pre-selected and OPEX is unavailable for them.
4.8 Brand Association Logic
- All expenses can be associated with any brand or "All Brands," with no type-based brand restrictions.
- The list defaults to "All Brands" unless the user selects a specific brand; the brand filter is available on every tab.
4.9 Delete Logic & Rules
- Non-deletable: Stripe/ACH-paid entries can never be deleted; their delete icon is greyed out and non-clickable, with an explanatory tooltip.
- Deletable: Any COGS or OPEX entry that was manually marked as paid (or otherwise not paid through Stripe/ACH) can be deleted, subject to role permissions.
- Local behavior: Deletion is a hard delete in the CRM — the row disappears and is excluded from all totals and rollups.
- QuickBooks behavior: If the entry was synced, deletion voids it in QuickBooks. If QuickBooks is not connected (or the entry was never synced), no QuickBooks action is taken.
- Source reversion: Deleting an editor payment reverts it to unpaid in Post Production; deleting a manually marked-as-paid contractor payment reverts the paid status at its source.
- Role scope: Agency Owner can delete any (deletable) entry. Admin and PM can delete only entries they added themselves (PM further limited to assigned projects). System-generated entries (editor payments from Post Production, project-fetched contractor entries) are therefore deletable only by the Agency Owner.
4.10 Edit Logic
- Role scope: Agency Owner and Admin can edit any expense; PMs can edit only entries they created themselves within their assigned projects.
- Stripe/ACH-paid entries are editable (delete is the only locked action for them); edits propagate to QuickBooks.
4.11 QuickBooks Integration & Sync Indicator Logic
- Icon visibility (plan-gated): The sync indicator appears only when QuickBooks integration is part of the account's subscription plan. If the integration is not on the plan, the icon is hidden entirely for every row.
- Connection state (when the integration is on the plan):
- On plan but not connected (never integrated) → the icon shows for all rows but is greyed / Not synced (nothing can sync yet).
- Connected → the icon reflects each entry's sync status: green "Synced" once the entry has synced, greyed "Not synced" until it has.
- Previously connected, then disconnected → the icon reverts to greyed / Not synced for all rows until QuickBooks is reconnected.
- Sync by default: When connected, every expense — including manually added ones — syncs to QuickBooks by default.
- Edits sync / Delete voids: When connected, editing an expense (including a Stripe/ACH-paid one) updates the corresponding QuickBooks record, and deleting a synced expense voids it (see 4.9).
- Manual re-sync: When connected, a Not-synced entry can be re-synced from the row's kebab menu via "Sync with QuickBooks." When not connected — or when the integration is not on the plan — manual re-sync is unavailable.
4.12 Price Range Filter Logic
- System-derived Min/Max: The system calculates the minimum from the lowest expense amount and the maximum from the highest, updating dynamically as the dataset changes.
- User interaction: The user drags the range slider between the system-defined Min and Max to filter the list.
- Display: The Min ($) and Max ($) labels above the slider are informational, read-only values reflecting the current dataset range.
- Removal of Event Types Filter: The Event Types dropdown has been removed from the filter panel.
4.13 Impact
- Accounting sync: Creates and edits propagate to QuickBooks by default; deletes void the synced record, keeping external accounting aligned. If QuickBooks is disconnected, entries simply carry no QuickBooks record.
- Financial classification: Moving contractor and editor costs into COGS changes how those amounts roll into COGS-vs-OPEX reporting and profitability views, so tab/type accuracy directly affects those figures.
- Cross-module status: Deleting an editor or manually-paid contractor payment reverts the paid status at its source (Post Production / contractor record), so Finance deletions have downstream effects.
- Brand & project rollups: Project-linked COGS attributes costs to the correct project and brand; hard-deleted entries drop out of those rollups immediately.
5. Field Details & Validations
5.1 Expense Form Fields
Field Name
Required
Validation Rules
Date
Yes
The date of payment.
Amount
Yes
Total amount paid. Must be numeric and > 0, formatted to 2 decimal places.
Category
Yes
The category the payment was made in (scoped to the selected type).
Payee
Conditional
Required for payee-based COGS categories (e.g., Contractor); shows the contractor/editor/vendor name.
Notes
Yes
Maximum 250 characters.
QuickBooks sync indicator
Conditional
Shown only when QuickBooks integration is on the subscription plan. States: green "Synced" / greyed "Not synced" (greyed for all rows when on plan but not connected or later disconnected). Re-sync via the row kebab when connected. See §10.1.
Actions
Yes
Sync indicator, edit, delete, and kebab ("View Details", "Sync with QuickBooks").
5.2 COGS (Cost of Goods Sold) Form Fields
Field Group
Details
Select Category
Drop-down auto-populated with COGS values (Contractor, Second Shooter, Editing Services, Equipment Rental, Album & Print Production, etc.).
Select Brand
Drop-down; brand values auto-populate. Required.
Select Project
Auto-fetched when the entry originates from a project; optional when added manually.
Select Contractor / Payee
Required for payee-based categories (e.g., Contractor); populates the Payee column.
Date
Date picker.
Amount
Numeric value only.
Notes (Optional)
Text field.
5.3 OPEX (Operating Expenses) Form Fields
Field Group
Details
Select Brand
Drop-down; brand values auto-populate.
Select Category
Drop-down auto-populated with OPEX values (Business Insurance, Legal Fees, Utilities, CRM / Project Management Software, Studio Lease, Paid Advertising, Bank / Payment Processor Fees, etc.).
Date
Date picker.
Amount
Numeric value only.
Notes
Text field.
Removed from OPEX: the Select Contractor field and any project field. Contractors/editors are now COGS.
5.4 Table Columns by Tab
Column
All
COGS
OPEX
Date
✓
✓
✓
Amount
✓
✓
✓
Category (with COGS/OPEX badge)
✓
✓
✓
Brand
✓
✓
✓
Project (clickable)
✓ ("–" for OPEX rows)
✓
Hidden
Payee (plain text)
✓ ("–" when none)
✓
Hidden
Notes
✓
✓
✓
Action (sync / edit / delete / kebab)
✓
✓
✓
5.5 Filter & Toolbar Fields
Field Name
Type
Rules / Availability
Tabs (All / OPEX / COGS)
Tab control
Default All; live counts; filters/search persist across tabs.
Contractor Toggle
Toggle Switch
"Only show amount paid to Contractor." Shown on All and COGS tabs only; hidden on OPEX.
Brand Filter
Dropdown
Filter by brand; "All Brands" default. Available on all tabs.
Date Filter
Date Range
Start date ≤ end date; valid date format.
Price Range
Number Range
Filter by amount range (Min $0 – Max $200+); system-derived min/max.
Notes/Category Search
Text Input
Real-time search within notes and categories, scoped to the active tab.
6. Empty State Handling
All empty conditions render a single global message (informational, not an error). Controls and the toolbar "Add Expense" button remain available.
Message: "No expenses match these filters." Sub-text: "Try widening the date range, or clear the filters to see everything."
Trigger scenarios (all show the message above):
- Notes/category search returns no matching results.
- Applied filters (date range, price range, brand) return no matching results.
- "Only show amount paid to Contractor" toggle returns no data.
- Selected brand has no expense records.
- Active tab (OPEX or COGS) has no records.
- No expense records exist in the system.
7. Success Message Handling
Scenario
Success Message
Expense created successfully
"Expense has been added successfully."
Expense updated successfully
"Expense details have been updated successfully."
Expense deleted successfully
"Expense has been deleted successfully."
Expense deleted while synced
"Expense has been deleted and voided in QuickBooks."
Manual re-sync successful
"Expense has been synced with QuickBooks."
8. Error Message Handling
Field / Action
Scenario
Message
Expense Type
Not selected
"Please select expense type (COGS or OPEX)."
Category
Not selected
"Please select a category."
Brand
Not selected
"Please select a brand."
Project
Not selected (when required on a project-originated COGS entry)
"Please select a project from your assigned projects."
Payee / Contractor
Not selected when required
"Please select a contractor for this expense."
Date
Invalid or empty
"Please select a valid date."
Amount
Invalid or ≤ 0
"Please enter a valid expense amount greater than $0."
Amount
Non-numeric
"Please enter a valid numeric amount."
Notes
Exceeds 250 characters
"Notes cannot exceed 250 characters."
Delete (blocked)
Stripe/ACH-paid entry
Delete icon greyed out with tooltip: "Stripe-paid entries can't be deleted."
9. Edge Cases
Scenario
Expected Behavior
Delete a Stripe/ACH-paid entry
Not permitted; delete icon greyed out with tooltip. Entry remains editable.
Delete a synced entry
Hard-delete locally; void the corresponding record in QuickBooks.
Delete when QuickBooks disconnected / entry never synced
Hard-delete locally; no QuickBooks action.
Delete an editor payment (from Post Production)
Reverts the editor to unpaid in Post Production.
Delete a manually marked-as-paid contractor payment
Reverts the paid status at its source.
Admin/PM attempts to delete a system-generated entry they didn't add
Not permitted; only the Agency Owner can delete system-generated entries.
PM attempts to add OPEX
Not permitted; OPEX is unavailable in Add Expense for PMs (they may view OPEX read-only).
Category selection with no matching contractor
If a contractor is required but none are available, show "No contractors available."
Switching tabs with active filters/search
Filters and search persist and re-apply within the new tab's scope.
QuickBooks integration not on the subscription plan
Sync indicator is hidden on every row; no sync/void occurs; kebab "Sync with QuickBooks" is unavailable.
On plan but QuickBooks not connected (never integrated)
Indicator shown greyed "Not synced" on all rows; manual re-sync unavailable until connected.
QuickBooks previously connected, then disconnected
Indicator reverts to greyed "Not synced" on all rows; entries stop syncing/voiding until reconnected.
10. QuickBooks Integration Specifications
10.1 Sync Indicator States (plan- and connection-gated)
Subscription / Connection State
Icon Visibility
Icon State
Notes
QuickBooks integration not on the subscription plan
Hidden — no icon on any row
—
The Action column shows no sync indicator at all.
On plan, not connected (never integrated)
Shown
Greyed "Not synced" (all rows)
Nothing syncs until QuickBooks is connected.
On plan, connected — entry has synced
Shown
Green "Synced"
Entry is synchronized with QuickBooks.
On plan, connected — entry not yet synced
Shown
Greyed "Not synced"
Re-sync via the row kebab → "Sync with QuickBooks."
On plan, previously connected then disconnected
Shown
Greyed "Not synced" (all rows)
Reconnect QuickBooks to resume syncing.
10.2 Sync Behavior
- When connected, every expense (including manual) syncs to QuickBooks by default.
- When connected, edits update the QuickBooks record; deletes void the QuickBooks record.
- When the integration is not on the plan, no sync indicator is shown and no QuickBooks records are created, updated, or voided.
- When on the plan but not connected (never integrated, or later disconnected), the indicator shows greyed "Not synced," manual re-sync is unavailable, and no records are created or voided until reconnected.
11. Acceptance Criteria
- Tabs: All | OPEX | COGS render with live counts; All is default; filters/search persist across tabs and scope to the active tab.
- Columns: Project and Payee appear on All & COGS and are hidden on OPEX; Project is clickable to the project; Payee is plain text; OPEX rows on the All tab show "–" for Project/Payee.
- Reclassification: Contractor and editor costs are COGS; OPEX has no contractor/project fields.
- Add Expense: Defaults to OPEX from all tabs for Owner/Admin; PMs are offered COGS only.
- Project logic: Project auto-fetches for project-originated COGS entries and is optional for manual COGS; PMs cannot add OPEX.
- Delete rules: Stripe/ACH-paid entries are non-deletable (greyed icon + tooltip); manually paid entries are deletable; deletion is a local hard delete and voids the entry in QuickBooks when synced; deletion reverts the source (Post Production / contractor) to unpaid.
- Permissions: Owner deletes any deletable entry; Admin/PM delete only their own manual entries (PM within assigned projects); Owner/Admin edit any entry; PM edits own within assigned projects.
- Sync indicator: Hidden when QuickBooks integration is not on the subscription plan; greyed "Not synced" when on plan but not connected (or later disconnected); green "Synced" / greyed "Not synced" per entry when connected. Manual re-sync from the kebab is available only when connected; every expense syncs by default when connected.
- Empty state: A single global message appears for all empty/no-result conditions with controls remaining accessible.
- Validation: Required-field validations and messages work as specified.
12. Dependencies
Module / System
Impact if Unavailable
Brands Management
Cannot associate/filter expenses by brand.
Contractor Management
Cannot select contractors for COGS payee categories.
Project Management
Cannot auto-fetch/assign projects to COGS; PM project scoping fails.
Post Production
Editor payments (marked as paid) cannot flow in; delete-to-unpaid reversion cannot reflect.
Stripe / ACH Payment Processing
Direct contractor payments cannot be processed; non-deletable rule cannot be enforced.
QuickBooks Integration
Sync/void unavailable; manual reconciliation required.
Authentication System
Role-based add/edit/delete permissions cannot be enforced.
13. References
- Figma
- UI reference screenshots (All / OPEX / COGS tab states) provided by the product team.
Open Items (to confirm)
- Add Expense pre-selection (TBD → proposed resolved): Defaults to OPEX from all tabs; for PMs (no OPEX), COGS is pre-selected. Confirm this reconciliation.
- Admin edit/delete asymmetry: Admin edits any but deletes only own — confirm intended.
Quickbooks
Refer - Click Here
☑️ Profit and Loss
Functional Requirements Document (FRD) - Profit and Loss Module
1. Module Overview
Module Name: Profit and Loss Module (Sub-module within Finance Management)
Purpose: Provide comprehensive financial insights by tracking income, expenses, and profit trends across different time periods with visual analytics and detailed reporting capabilities
Business Goal: Enable data-driven financial decision making, monitor business performance trends, and provide stakeholders with clear visibility into agency profitability and financial health
2. User Roles & Permissions
Role
Description
Key Permissions
Agency Owner
Business owner with full financial oversight
Full access to all financial data, can view/configure filters, export reports Excel, and print summaries
Admin
System administrator with financial access
Full access to all financial data, can view/configure filters, export reports Excel, and print summaries
Project Manager (PM)
Project-specific management role
Limited access to financial data only for assigned projects, project-specific profit/loss calculations, and restricted export capabilities
3. User Flow
Primary Flow - Financial Analytics Review:
- Module Access: User navigates to Finance Management → Profit and Loss
- Time Period Selection: User selects date filter from preset options or custom range (defaults to "Last Month")
- Analytics Review: System displays Profit & Loss analytics with KPI cards (Profit, Income, Expenses) and trend chart
- Chart Interaction: User can click on chart points to view detailed breakdowns for specific time periods
- Summary Analysis: User scrolls to view the detailed Summary section with project-level breakdowns
- Data Export: User can print a summary or export data in Excel formats
- Project Drill-down: User can expand/collapse individual project details in the summary section
Secondary Flow - Custom Date Range Selection:
- Custom Range Selection: User clicks "Custom Range" from the date filter dropdown
- Calendar Interface: Dual calendar picker opens, showing start and end date selection
- Date Validation: System validates selected date range and updates analytics
- Data Refresh: All charts, KPIs, and summary data refresh based on the selected period
Tertiary Flow - Project-Specific Analysis (PM Users):
- Restricted Access: PM users see only assigned project financial data
- Project Filtering: The System automatically filters all financial metrics to assigned projects only
- Limited Export: PM users have restricted export capabilities for assigned project data only
4. Field Details & Validations
4.1 Date Filter Configuration
Field Name
Type
Required
Validation Rules
Description
Time Filter
Dropdown
Yes
Must select from preset options or valid custom range
Date period for financial analysis
Custom Start Date
Date
Conditional
Must be valid past date, cannot be a future date
Start date for custom range selection
Custom End Date
Date
Conditional
Must be ≥ start date, cannot be a future date
End date for custom range selection
Preset Filter Options:
- Custom Range: Pick any start and end date you want.
- Today: Shows only today’s data.
- This Week to Date: From the start of this week up to today.
- This Month to Date: From the start of this month up to today.
- This Quarter to Date: From the start of this quarter (3-month period) up to today.
- This Year to Date: From January 1 (or start of the financial year) up to today.
- Last Week: Data from the full previous week.
- Last Month (Default): Data from the full previous month.
- Last Quarter: Data from the full previous quarter.
- Last Year: Data from the full previous year.
4.2 Financial KPI Fields
Field Name
Type
Required
Validation Rules
Description
Calculation Source
Total Profit
Currency
Yes
Calculated field, can be negative
Net profit for selected period
Income - Total Expenses
Total Income
Currency
Yes
Must be ≥ 0, sum of all incoming revenue
All incoming money from clients
Client Payments (Billing Module)
Total Expenses
Currency
Yes
Must be ≥ 0, sum of all outgoing costs
All outgoing money flow
Contractor Payments + COGS + OPEX
Profit Percentage Change
Percentage
Conditional
Comparison with same period last year
Year-over-year profit change
Current Period vs Previous Year
Income Percentage Change
Percentage
Conditional
Comparison with same period last year
Year-over-year income change
Current Period vs Previous Year
Expense Percentage Change
Percentage
Conditional
Comparison with same period last year
Year-over-year expense change
Current Period vs Previous Year
**4.3 Summary Breakdown
**
Category
Definition
Total Income
Money earned from business activities (excluding sales tax). With breakdown entries supporting the sum total figure
Cost of Goods Sold (COGS)
Direct costs of making or delivering what was sold.
With breakdown entries supporting the sum total figure
Gross Profit
Income left after subtracting COGS.
With breakdown entries supporting the sum total figure
Total Expenses
All other business costs, not including COGS.
With breakdown entries supporting the sum total figure
Net Profit (Loss)
Final result after subtracting expenses from gross profit.
With breakdown entries supporting the sum total figure
Categories can expand/collapse → first row = total, inside rows = details.
Totals and breakdowns depend on the date filter selected.
Output can be exported/printed in Excel in the same format.
5. Success Message Handling
Validation Scenario
Success Message
Excel export completed
"Financial data exported successfully."
6. Error Message Handling
Field
Validation Scenario
Error Message
Date Selection
Future date selected
"Cannot select future dates for financial reporting."
Date Range
End date before start date
"End date must be after start date."
Data Loading
No financial data for the selected period
"No financial data available for the selected period."
7. Functional Logic
Financial Calculation Engine
- Profit Calculation: Total Income - Total Expenses (including contractor payments, COGS, and operational expenses)
- Year-over-Year Comparison: Compare the selected period with the same period in previous year, display "N/A" if no previous year data exists
- Project-Level Calculations: Individual project profit/loss calculated from project-specific income and allocated expenses
- Real-Time Updates: Financial data updated via batch processing every hour when source data changes
- Currency Precision: All financial calculations maintained to 2 decimal places with proper rounding
Chart Visualization Logic
- Time Granularity Adjustment: Chart automatically adjusts granularity based on selected time period (daily for weeks, weekly for months, monthly for quarters/years)
- Multi-Metric Display: Users can toggle between Profit only (default) or Profit + Income + Expenses view
- Interactive Data Points: Clicking chart points reveals detailed financial breakdown for specific time periods
- Trend Analysis: Chart displays trend lines for selected metrics with appropriate scaling and formatting
- Performance Optimization: Loading indicators displayed for datasets exceeding 500 data points
Data Source Integration
- Income Sources: All incoming money from clients via Billing/Client Invoices module
- Expense Sources:
- Contractor payments from Contractor Invoices module
- Cost of Goods Sold from direct project expenses
- Operational expenses from Expenses module
- Data Synchronization: Data refreshes on page refresh to maintain current financial information
- Data Validation: Cross-module validation to ensure financial data consistency
Access Control and Filtering
- Role-Based Data Access: PM users see only financial data for assigned projects
- Project-Specific Calculations: PM role calculations limited to the assigned project scope
- Full Company View: Agency Owner and Admin see aggregated company-wide financial data
- Dynamic Filtering: All charts, KPIs, and summaries automatically filter based on user permissions
8. Edge Cases
Scenario
Expected Behavior
No financial data for the selected period
Display "No data available" message with option to select a different period
Year-over-year comparison with no previous year data
Show "N/A" instead of percentage change to avoid misleading metrics
Very large dataset (2+ years of daily data)
Implement pagination for the summary section (50+ projects), show loading indicators, and warn the user of a large export
Custom date range exceeding the maximum recommended period
Display a warning message about the potential performance impact
Export process interrupted or failed
Provide a retry option with a detailed error message
9. Chart and Visualization Specifications
9.1 Main Financial Trend Chart
Feature
Specification
Description
Chart Type
Multi-line chart
Primary visualization for financial trends
Default View
Profit line only
Single metric view for clarity
Toggle Option
Profit + Income + Expenses
Three-line view for comprehensive analysis
Interactive Points
Click for detailed breakdown
Drill-down capability for specific periods
Y-Axis
Currency formatting
Proper dollar formatting with appropriate scaling
X-Axis
Time period labels
Clear date/time labels based on granularity
Color Scheme
Profit (Blue), Income (Green), Expenses (Red)
Consistent color coding across interface
9.2 KPI Cards Layout
Metric
Features
Profit
Amount, percentage change, trend indicator
Income
Amount, percentage change, trend indicator
Expenses
Amount, percentage change, trend indicator
10. Test Cases
11. Acceptance Criteria
- Role-Based Access Control: PM users restricted to assigned project financial data only, Owner/Admin sees full company financials
- Date Filter Functionality: All preset options and custom date ranges work correctly with proper validation
- Financial Calculation Accuracy: Profit = Income - Expenses calculations are accurate across all time periods and user roles
- Year-over-Year Comparisons: Percentage changes calculated correctly, "N/A" displayed when no previous year data exists
- Chart Visualization: An Interactive chart displays financial trends with appropriate granularity and user interaction capabilities
- Summary Section: Project-level breakdown with expand/collapse functionality and pagination for large datasets
- Export Capabilities: Excel export formats work correctly with summary data only (no chart visualization)
- Print Functionality: Professional print layout generates correctly formatted financial summaries
- Performance Optimization: Loading indicators and pagination implemented for large datasets (50+ projects, 500+ data points)
- Error Handling: Appropriate error messages for missing data, validation failures, and system errors
- Data Integration: Real-time financial data from Billing, Contractor Invoices, and Expenses modules
- Mobile Responsiveness: Interface adapts correctly to different screen sizes while maintaining functionality
- Data Persistence: Selected filters and preferences maintained during user session
- Security Compliance: Financial data access properly restricted based on user roles and permissions
14. Dependencies
Module/System
Dependency Type
Impact if Unavailable
Billing/Client Invoices Module
Critical Data Dependency
Cannot calculate income; profit calculations are incomplete
Contractor Invoices Module
Critical Data Dependency
Cannot calculate contractor expenses, profit calculations inaccurate
Expenses Module
Critical Data Dependency
Cannot calculate operational expenses, missing COGS and OPEX data
Project Management Module
Data Dependency
Cannot provide project-level breakdowns, PM role restrictions fail
Authentication System
Security Dependency
Role-based access control fails, data security compromised
15. References
- Profit and Loss tab Figma
Taxes
Note: Need to confirm with the client
Functional Requirements Document (FRD) - Taxes Sub module
1. Module Overview
Module Name: Taxes Module (Sub-module within Finance Management)
Purpose: Generate country-specific tax reporting documents based on agency income and contractor payment data for compliance and filing purposes
Business Goal: Provide automated tax compliance reporting, streamline tax document preparation, and ensure accurate financial data for tax filing requirements across supported countries
2. User Roles & Permissions
Role
Description
Key Permissions
Agency Owner
Business owner with full financial oversight
Full access to all tax reports, can view/download reports, configure country settings, access sales tax reports
Admin
System administrator with financial access
Full access to all tax reports, can view/download reports, configure country settings, access sales tax reports
Project Manager (PM)
Project-specific management role
No Access - Tax reports are restricted to Owner and Admin roles only
3. User Flow
Primary Flow - Tax Report Generation:
- Module Access: User (Owner/Admin) navigates to Finance Management → Taxes
- Country Selection: System auto-detects country (currently US, expanding to Canada), user can manually change selection
- Year Selection: System defaults to the current year; user can select different tax years from the dropdown
- Report Generation: The System automatically generates a year-to-date tax report using contractor payment data
- Download Action: User clicks "Download Report" to generate a CSV file with 1099-NEC support data
Secondary Flow - Sales Tax Report Access:
- Sales Tax Navigation: User clicks "View Sales Tax Reports" button
- Reports Module Redirect: System navigates to Reports module, Sales Tax Report section
- Detailed Analysis: User accesses comprehensive sales tax calculations and breakdowns
4. Field Details & Validations
4.1 Tax Report Configuration Fields
Field Name
Type
Required
Validation Rules
Description
Country Selection
Dropdown
Yes
Values: United States, Canada (future expansion)
Country for tax reporting compliance
Tax Year
Dropdown
Yes
Current year default, historical years available
Year for which tax report is generated
Report Type
Static
Yes
Automatically determined by country selection
Type of tax document (1099-NEC for US)
4.2 Contractor Tax Data Fields (Auto-populated from Contractor Profiles)
Field
Description
Contractor Name
Full name,
autopopulated from the system
Contractor Email
Optional, for reference
autopopulated from the system
Contractor Address
If collected
autopopulated from the system
Contractor Tax ID (TIN/SSN)
autopopulated from the system
Total Paid (USD)
For the tax year, autopopulated from the system
First & Last Payment Date
Useful for an activity timeline
Autopopulated from the system
**
5. Success Message Handling**
Validation Scenario
Success Message
Tax report downloaded successfully
"Your tax report has been downloaded successfully."
6. Error Message Handling
Field
Validation Scenario
Error Message
Report Generation
Report generation system failure
"Unable to generate tax report. Please try again later."
Data Validation
Missing critical contractor information
"Some contractor profiles are missing required tax information. Reports may be incomplete."
Year Selection
Invalid year selected
"Please select a valid tax year."
File Download
Download failure
"Unable to download report file. Please check your connection and try again."
7. Functional Logic
Data Aggregation Logic
- Contractor Payment Calculation: System aggregates all payments made to each contractor during the selected tax year from the Contractor Invoices module.
- Income Calculation: Total agency income calculated from all client payments received during the selected tax year.
- Year-to-Date Reporting: For the current year, the report includes data from January 1st through the download date.
- Historical Reporting: For previous years, the report includes complete calendar year data
- Missing Data Handling: Fields with missing contractor information display "--" in generated reports
Country-Specific Compliance
- United States: Generates 1099-NEC support report format with required contractor information
- Canada (Future): Will support Canadian tax compliance formats when implemented
- Auto-Detection: The System automatically detects the agency country based on profile settings
- Manual Override: Users can manually select a different country for specific reporting needs
Report Generation Process
- Real-Time Data: Reports generated using the most current data available at the time of download
- Multiple Downloads: Users can download the same report multiple times without restrictions
- Data Persistence: Generated reports remain accessible and downloadable indefinitely
- Format Specification: 1099-NEC support reports generated in CSV format for easy import into tax software
Access Control and Security
- Role Restriction: Only Agency Owner and Admin roles can access tax module
- PM Exclusion: Project Managers have no access to any tax reporting functionality
- Data Retention: All tax data and reports stored permanently in system
- No Audit Trail: System does not track download history or user access patterns
8. Edge Cases
Scenario
Expected Behavior
Contractor profile missing required tax information
Report generation continues, missing fields display "--", user receives warning message
No contractor payments made in selected year
Report shows "No data available" message, empty report can still be downloaded
Selected year has no client income data
Agency income fields show $0.00, contractor data still displayed if available
Report generation fails due to system error
User receives error message "Unable to generate tax report. Please try again later"
User selects future year for reporting
System prevents selection, shows validation error for invalid year
Large number of contractors causing performance issues
System maintains functionality, may show loading indicator for extended processing time
Contractor deleted after payments made
Contractor data preserved in tax reports using historical payment records
Multiple currencies in payment data
All amounts converted to USD for reporting purposes
Partial year reporting for first year of operation
Report includes only actual operating period data with appropriate date ranges
User attempts to access without proper permissions
System shows access denied message, redirects to dashboard
9. Report Format Specifications
9.1 1099-NEC Support Report (CSV Format)
Column Name
Data Type
Description
Source
Contractor_Name
Text
Full legal name
Contractor Profile
Contractor_Email
Text
Email address or "--"
Contractor Profile
Contractor_Address
Text
Complete mailing address or "--"
Contractor Profile
Tax_ID
Text
TIN/SSN or "--"
Contractor Profile
Total_Paid_USD
Number
Total payments in selected year
Payment History
First_Payment_Date
Date
First payment date (MM/DD/YYYY)
Payment History
Last_Payment_Date
Date
Last payment date (MM/DD/YYYY)
Payment History
Reporting_Year
Number
Tax year (YYYY)
User Selection
Report_Generated_Date
Date
Download date (MM/DD/YYYY)
System Generated
10. Test Cases
11. Acceptance Criteria
- Access Control: Only Agency Owner and Admin users can access the Taxes module; PM users receive an access denied message
- Country Support: System supports United States tax reporting with CSV format 1099-NEC support reports
- Year Selection: Current year selected by default, historical years available in dropdown
- Data Aggregation: Reports accurately aggregate all contractor payments and agency income for the selected year
- Missing Data Handling: Reports generate successfully even with incomplete contractor information, showing "--" for missing fields
- Download Functionality: Users can download CSV reports multiple times without restrictions
- Sales Tax Integration: "View Sales Tax Reports" button successfully navigates to Reports module
- Error Handling: Appropriate error messages for report generation failures, access violations, and data issues
- Report Format: CSV reports include all required fields for tax compliance purposes
12. Dependencies
Module/System
Impact if Unavailable
Contractor Invoices Module
Cannot calculate contractor payments, reports incomplete or unavailable
Client Invoices/Billing Module
Cannot calculate agency income, financial summaries incomplete
Contractor Profiles
Cannot populate contractor information, tax compliance data missing
Reports Module
Sales Tax Reports link non-functional, reduces user workflow efficiency
Authentication System
Access control fails, unauthorized users may access tax data
13. References
- Figma design
Deprecated Versions
Contractor Invoices_Deprecated
Functional Requirements Document (FRD) - Contractor Invoices
1. Module Overview
- Module Name: Contractor Invoices
- Purpose: The Contractor Invoices module enables agency owners and admins to manage, review, and process payments for invoices submitted by contractors for work completed on project events. It provides a centralized view of all contractor invoices across multiple status states, supports both online payments via Stripe ACH and manual payment recording, and integrates with QuickBooks for expense tracking.
- Business Goal: Streamline the contractor payment workflow by providing real-time visibility into invoice statuses, enabling secure online payments through Stripe ACH bank transfers, supporting flexible manual payment recording for offline methods, and maintaining accurate financial records through QuickBooks integration. This module ensures contractors are paid accurately and on time while giving agencies complete control over their outgoing payments.
2. User Roles & Permissions
Refer- Click Here
Note: Agency Admins cannot initiate online ACH payments or retry failed payments. Only Agency Owners have these capabilities.
3. User Flow
3.1 Navigation Path
Primary Navigation: Finances → Contractor Invoices
Alternative Entry Points:
- From Project Detail → View contractor invoices for that project
- From Event Detail → View contractor invoices for that event
- From Dashboard notifications (if implemented)
3.2 Primary User Flow - Viewing Invoices
- User navigates to Contractor Invoices
- System loads the Contractor Invoices page
- System checks for prerequisites (brands, projects, events, contractor assignments)
- If prerequisites missing, display appropriate empty state with CTA
- If prerequisites met but no invoices, display "No contractor invoices yet" message
- If invoices exist, display Unpaid tab by default with invoice list
- User views invoice list
- System displays invoices in tabular format with columns specific to the active tab
- Each row shows contractor avatar, name, issued date, status, project, amount, and available actions
- User can sort by clicking column headers
- User can filter using the Filters panel (funnel icon)
- User switches between status tabs
- System updates the list to show only invoices matching the selected status
- Columns adjust based on tab requirements
- Filters persist across tab switches
- Sorting preferences maintained within session
3.3 User Flow - Online Payment (Agency Owner Only)
- User clicks "Pay" button on Unpaid invoice
- System opens "Pay Contractor" modal
- Modal displays contractor info, project, issue date, and amount (editable)
- System checks if agency has configured funding bank account
- If agency bank account NOT configured:
- Modal shows "No payment method set up" message
- Display "Add Payment Method" button
- "Pay Contractor" button is disabled
- User clicks "Add Payment Method" → redirected to Agency Settings → Finances
- If agency bank account IS configured:
- Modal shows bank account info (e.g., "Emma Taylor Company - Bank account ending in 6021")
- "Pay Contractor" button is enabled
- System checks if contractor has payout bank account configured
- If NOT configured: Display warning message "Contractor has not set up their bank account for payouts"
- Payment cannot proceed until contractor adds bank details
- User confirms payment
- User can adjust amount if needed (editable field)
- User clicks "Pay Contractor"
- System initiates Stripe ACH payout
- Invoice status changes: Unpaid → Processing
- Invoice moves to Processing tab
- Success message displayed
- Payment processing completes
- Stripe webhook received
- If successful: Status changes Processing → Paid, moves to Paid tab, QB sync triggered
- If failed: Status changes Processing → Failed, moves to Failed tab with failure reason
3.4 User Flow - Manual Payment (Mark as Paid)
- User clicks "Mark as Paid" button on Unpaid invoice
- System opens "Mark as Paid" modal
- Modal displays confirmation message: "You are about to mark this invoice as paid. Do you want to continue?"
- User fills in payment details
- Amount field (pre-filled with invoice amount, editable)
- Payment Method dropdown (required): Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay, Other
- Note field (optional): Text area for internal notes
- User confirms action
- User clicks "Mark as Paid"
- System validates required fields
- Invoice status changes: Unpaid → Paid
- Invoice moves to Paid tab immediately
- QuickBooks sync triggered
- Success message displayed
3.5 User Flow - Retry Failed Payment (Agency Owner Only)
- User views Failed tab
- System displays failed invoices with failure reasons from Stripe
- Each row shows failure date and specific reason (e.g., "Card Declined", "Insufficient Funds")
- User clicks Retry Payment icon
- System initiates new Stripe ACH payout attempt
- Invoice status changes: Failed → Processing
- Invoice moves to Processing tab
- System awaits new webhook response
- Retry result
- If successful: Processing → Paid
- If failed again: Processing → Failed with new failure reason
3.6 User Flow - View Invoice Details
- User clicks "View Invoice" button
- System opens PDF viewer in modal/overlay
- Modal displays invoice PDF with contractor name, project, and date in header
- Print and Download buttons available in top right
- Zoom controls available (+, -, percentage dropdown)
- Back arrow to close modal
- User downloads invoice
- User clicks "Download" button
- PDF file downloads to user's device
- Filename format: "[Contractor Name] - [Project Name] ([Issue Date]).pdf"
4. Functional Logic
4.1 Empty State Logic (Hierarchical Empty State Priority)
The Contractor Invoices module depends on a complete hierarchy of data. Empty states are displayed based on priority order, showing only the highest-priority missing prerequisite.
Priority Order:
Priority
Condition
Message
CTA Button
Action
1
No Brands exist
"Create a brand to manage contractor invoices."
Create Brand
Navigate to Brand creation
2
No Projects exist
"Create a project to start tracking contractor work and invoices."
Create Project
Navigate to Project creation
3
No Events exist
"Create an event to allow contractors to upload invoices."
Create Event
Navigate to Event creation
4
No Contractors Assigned
"No contractors are assigned to any events yet."
Assign Contractor
Navigate to Event → Contractor assignment
5
No Invoices Uploaded
"No contractor invoices yet."
None
Subtext: "Contractors will appear here once they submit invoices for event work."
Display Rules:
- Check conditions in priority order
- Display only the first unmet condition
- Empty states appear only after data fully loads (no loading flicker)
- Filters remain accessible even during empty states
- Pagination does not create false empty states
4.1.1 Tab-Level Empty States
When invoices exist but specific tabs have no entries:
Tab
Message
Unpaid
"No unpaid contractor invoices."
Processing
"No invoices are currently processing."
Paid
"No paid invoices yet."
Failed
"No failed invoices found."
4.1.2 Filter-Induced Empty State
When active filters return zero results:
- Message: "No invoices match your selected filters."
- CTA: "Clear Filters" button
- Action: Resets all filters to default state
4.2 Status Definitions & Lifecycle
Invoice Statuses:
Status
Definition
Unpaid
Invoice uploaded by contractor; no payment attempt initiated (no ACH payout, no manual mark as paid)
Processing
Stripe ACH payout initiated; awaiting final confirmation from Stripe
Paid
ACH payout successfully completed (confirmed by Stripe webhook) OR Agency manually marked as paid with offline method
Failed
ACH payout failed due to bank/Stripe error
Status Transitions:
UNPAID ─────┬──────────────────► PROCESSING ─────┬──────► PAID
│ (Pay button - ▲ │ (Stripe webhook
│ Stripe ACH) │ │ success)
│ │ │
│ │ └──────► FAILED
│ │ (Stripe webhook
│ │ failure)
│ │ │
│ └──────────────────────────────┘
│ (Retry Payment)
│
└──────────────────────────────────────────────────► PAID
(Mark as Paid - manual payment)
Transition Rules:
- Unpaid → Processing
- Trigger: Agency Owner clicks "Pay" and confirms (Stripe ACH initiated)
- System action: Create Stripe payout request, update status, move to Processing tab
- Unpaid → Paid
- Trigger: Agency Owner/Admin clicks "Mark as Paid" and confirms
- System action: Update status with payment method and note, move to Paid tab, trigger QB sync
- Processing → Paid
- Trigger: Stripe webhook confirms successful ACH payout
- System action: Update status, move to Paid tab, trigger QB sync
- Processing → Failed
- Trigger: Stripe webhook returns failure
- System action: Update status with failure reason, move to Failed tab
- Failed → Processing
- Trigger: Agency Owner clicks "Retry Payment"
- System action: Create new Stripe payout request, update status, move to Processing tab
4.3 Invoice-Event-Project Relationship
Data Hierarchy:
Brand
└── Project
└── Event
└── Contractor Assignment (with agreed fee)
└── Contractor Invoice(s)
Relationship Rules:
- Every Contractor Invoice MUST be linked to exactly one Event
- Each Event belongs to exactly one Project
- Each Project belongs to exactly one Brand
- A contractor can have multiple invoices for the same event (partial billing)
- A contractor can be assigned to multiple events within the same project
- Multiple contractors can be assigned to the same event
4.4 Contractor Fee Tracking & Overage Warning
Fee Tracking Logic:
Each contractor has an agreed fee per event (set during contractor assignment). The system tracks the cumulative total of all invoices submitted by that contractor for that specific event.
Calculation:
Total Invoiced = SUM(all invoice amounts for contractor + event combination)
Assigned Fee = Contractor's agreed fee for that event
Overage = Total Invoiced - Assigned Fee (when positive)
Overage Warning Rules:
- System does NOT block invoices that exceed the assigned fee
- When Total Invoiced > Assigned Fee:
- Display warning icon (⚠️) next to the amount in list view
- Show tooltip on hover: "Total invoiced (X) exceeds assigned contractor fee (X) exceeds assigned contractor fee ( X) exceeds assigned contractor fee (Y)"
- Display warning banner in "Pay Contractor" modal
- Notify both agency owner and contractor (optional notification)
- Warning appears in:
- Amount column in list view (warning icon)
- "Pay Contractor" modal (warning banner with details)
- Valid reasons for overage (not an error):
- Scope increased after initial agreement
- Event duration extended
- Additional services requested
- Negotiated change orders
4.5 Tab-Specific Column Configuration
Unpaid Tab:
Column
Sortable
Description
Contractor
Yes
Avatar + full name
Issued
Yes
Date invoice was submitted
Status
Yes
"Unpaid" badge
Project
Yes
Project name (clickable)
Amount
Yes
Invoice amount in USD
Actions
No
Pay, Mark as Paid, View Invoice, More (⋮)
Processing Tab:
Column
Sortable
Description
Contractor
Yes
Avatar + full name
Issued
Yes
Date invoice was submitted
Paid
Yes
Date payment was initiated
Payment Method
Yes
"Bank Transfer" (ACH)
Status
Yes
"Processing" badge
Project
Yes
Project name (clickable)
Actions
No
View Invoice, More (⋮)
Paid Tab:
Column
Sortable
Description
Contractor
Yes
Avatar + full name
Issued
Yes
Date invoice was submitted
Paid
Yes
Date payment completed
Payment Method
Yes
Bank Transfer, Cash, Check, etc.
Status
Yes
"Paid" badge
QuickBooks
No
Sync status icon (see 4.8)
Project
Yes
Project name (clickable)
Actions
No
View Invoice, More (⋮)
Failed Tab:
Column
Sortable
Description
Contractor
Yes
Avatar + full name
Issued
Yes
Date invoice was submitted
Failed Date
Yes
Date + failure reason (e.g., "January 20, 2025 - Card Declined")
Payment Method
Yes
"Bank Transfer" (ACH)
Status
Yes
"Failed" badge
Project
Yes
Project name (clickable)
Actions
No
View Invoice, Retry Payment icon, More (⋮)
4.6 Filtering Logic
Filter Panel Components:
- Date Issued (Date Picker)
- Select date or date range
- Filters invoices by submission date
- Brand (Single-Select Dropdown)
- Options: "All Brands" + list of agency brands
- Selecting a brand filters the Project list to show only projects under that brand
- Contractor (Multi-Select with Search)
- Searchable list of all contractors
- Select one or multiple contractors
- Real-time search filtering
- Project (Multi-Select with Search)
- Searchable list of projects
- Scoped to selected Brand (if brand filter active)
- Select one or multiple projects
Filter Behavior Rules:
- Filters apply across ALL four status tabs
- Filters persist when switching between tabs until manually cleared
- Reset button (↻) clears all filters
- Brand filter scopes Project dropdown options
- Multiple filter conditions use AND logic
- Filter-induced empty state shows: "No invoices match your selected filters" with "Clear Filters" CTA
4.7 Sorting Logic
Default Sort: Issued Date (descending - newest first)
Sortable Columns:
- Contractor (alphabetical)
- Issued Date (chronological)
- Paid Date (chronological) - Processing/Paid/Failed tabs
- Failed Date (chronological) - Failed tab only
- Payment Method (alphabetical)
- Status (alphabetical)
- Project (alphabetical)
- Amount (numerical)
Sort Behavior:
- Click column header to sort ascending
- Click again to sort descending
- Sort indicator arrow shows direction (↓ or ↑)
- Sorting preferences persist within session
- Sorting maintained when switching between tabs
4.8 Pagination
Configuration:
- Rows per page options: 10, 25, 50, 100
- Default: 10 rows per page
- Page indicator format: "1-4 of 4"
- Navigation: Previous (‹) and Next (›) arrows
Behavior:
- Pagination resets to page 1 when filters change
- Pagination maintained when sorting changes
- Each tab maintains its own pagination state
4.9 QuickBooks Integration
Sync Trigger: When invoice status changes to "Paid"
Sync Behavior:
- Automatic sync initiated immediately upon status change to Paid
- Creates expense entry in QuickBooks
- Both online (ACH) and manual payments sync
Sync Status Icons (Paid Tab):
Icon State
Meaning
Visual
Green Checkmark
Successfully synced to QuickBooks
✓ (green)
Grey/Loading
Sync in progress or pending
○ (grey)
Red Warning
Sync failed - requires attention
⚠ (red)
Failed Sync Handling:
- Display red warning icon in QB column
- Show error details on hover
- Three-dot menu includes "Sync with QuickBooks" option for manual retry
- Admin can manually trigger resync
Mapping:
- Contractor → Vendor in QuickBooks
- Project → Class/Job (if configured)
- Invoice Amount → Expense Amount
- Payment Date → Transaction Date
- Payment Method → Payment Type
4.10 Three-Dot Menu Actions
Unpaid Tab:
- View Details (opens invoice detail view)
- Download PDF
- Sync with QuickBooks (disabled/hidden)
Processing Tab:
- View Details
- Download PDF
Paid Tab:
- View Details
- Download PDF
- Sync with QuickBooks (manual retry if needed)
Failed Tab:
- View Details
- Download PDF
4.11 Search Functionality
Global Search Bar:
- Located in page header
- Placeholder: "Search..."
- Minimum 2 characters to initiate search
- Real-time filtering as user types
Searchable Fields:
- Contractor name
- Project name
- Invoice amount
- Any other relevant text fields
Search Behavior:
- Searches within current tab only
- Respects active filters
- Results update dynamically
- Clear search to show all invoices (within filters)
5. Field Details & Validations
5.1 Pay Contractor Modal
Field Name
Field Type
Display Format
Validation Rules
Contractor Info
Display Only
Avatar + Name + Project + Issue Date
Read-only
View Invoice Link
Button
Text link
Opens PDF viewer
Amount
Currency Input
"$X,XXX.XX"
Required, numeric, positive value, pre-filled with invoice amount but editable
Payment Method Display
Display Only
Bank icon + Company Name + "Bank account ending in XXXX"
Shows only if agency bank configured
No Payment Method Warning
Alert Box
"No payment method set up" message
Shows only if agency bank NOT configured
Modal Actions:
- Cancel: Closes modal without action
- Pay Contractor: Initiates ACH payment (disabled if no payment method)
- Add Payment Method: Redirects to Agency Settings (shown when no payment method)
5.2 Mark as Paid Modal
Field Name
Field Type
Display Format
Validation Rules
Amount
Currency Input
"$X,XXX.XX"
Required, numeric, positive value, pre-filled with invoice amount but editable
Payment Method
Dropdown
Single selection
Required, options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay, Other
Note
Text Area
Multi-line text
Optional, max 500 characters, internal only (not visible to contractor)
Modal Actions:
- Cancel: Closes modal without action
- Mark as Paid: Updates status to Paid immediately
5.3 PDF Viewer Modal
Field Name
Field Type
Display Format
Validation Rules
Header Title
Display Only
"[Contractor] - [Project] ([Date]).pdf"
Read-only
Print Button
Button
Icon + "Print"
Opens system print dialog
Download Button
Button
Icon + "Download"
Downloads PDF file
Zoom Controls
Control Group
"-" button, percentage dropdown, "+" button
Range: 25% - 400%, default 65%
Page Indicator
Display Only
"Page X/Y"
Shows current page of multi-page PDFs
Back Arrow
Button
"←" icon
Closes modal/overlay
6. Error Messages & Notifications
6.1 Payment Flow Errors
Scenario
Error Message
Type
Display Location
Agency bank not configured
"No payment method set up. To pay your contractor, you'll need to add a payment method first."
Warning
Pay Contractor modal
Contractor bank not configured
"Contractor has not set up their bank account for payouts. Please notify the contractor to add their bank details."
Warning
Pay Contractor modal
Amount field empty
"Please enter an amount"
Error
Below Amount field
Amount is zero or negative
"Amount must be greater than $0"
Error
Below Amount field
Amount exceeds invoice
"Payment amount exceeds the invoice amount. Are you sure?"
Warning
Pay Contractor modal (confirmation)
Payment initiation failed
"Unable to initiate payment. Please try again."
Error
Toast notification
Stripe connection error
"Payment service temporarily unavailable. Please try again later."
Error
Toast notification
6.2 Mark as Paid Errors
Scenario
Error Message
Type
Display Location
Payment method not selected
"Please select a payment method"
Error
Below Payment Method field
Amount field empty
"Please enter an amount"
Error
Below Amount field
Amount is zero or negative
"Amount must be greater than $0"
Error
Below Amount field
Note exceeds character limit
"Note cannot exceed 500 characters"
Error
Below Note field
6.3 Stripe Failure Reasons (Failed Tab)
Stripe Error
Display Message
account_closed
"Bank Account Closed"
insufficient_funds
"Insufficient Funds"
invalid_account_number
"Invalid Account Number"
bank_account_restricted
"Bank Account Restricted"
debit_not_authorized
"Debit Not Authorized"
card_declined
"Card Declined"
invalid_card_details
"Invalid Card Details"
payment_blocked
"Payment Blocked"
generic_decline
"Payment Declined"
6.4 Success Notifications
Action
Success Message
Type
Payment initiated
"Payment initiated successfully. Status updated to Processing."
Toast (success)
Payment completed
"Payment completed successfully."
Toast (success)
Mark as paid
"Invoice marked as paid successfully."
Toast (success)
Retry payment initiated
"Payment retry initiated. Status updated to Processing."
Toast (success)
QuickBooks sync success
"Invoice synced to QuickBooks successfully."
Toast (success)
6.5 Warning Notifications
Scenario
Warning Message
Display Location
Invoice overage
"Warning: Total invoiced amount (X)exceedsassignedcontractorfee(X) exceeds assigned contractor fee (
X)exceedsassignedcontractorfee(Y) for this event."
Pay Contractor modal + List view tooltip
QuickBooks sync failed
"Failed to sync with QuickBooks. Click to retry."
QB column icon tooltip
7. Edge Cases & Special Scenarios
Scenario
Expected Behavior
Contractor uploads invoice while agency viewing list
New invoice appears on next page refresh or real-time update (if implemented)
Multiple invoices for same contractor-event
All invoices display separately in list; system tracks cumulative total for overage warning
Payment initiated but webhook delayed
Invoice remains in Processing tab; status updates when webhook received
Stripe webhook received out of order
System processes based on timestamp; latest status wins
Agency pays more than invoice amount
System allows (editable amount field); logs actual payment amount
Agency pays less than invoice amount
System allows (editable amount field); partial payment recorded
Contractor deletes bank account after invoice submission
Payment attempt fails; displays "Contractor bank account not available" error
Concurrent payment attempts (race condition)
First successful request wins; subsequent attempts blocked
Invoice PDF file corrupted or missing
Display error message: "Unable to load invoice. Please contact support."
QuickBooks disconnected
Sync fails; warning icon displayed; manual retry available when reconnected
Network connection lost during payment
Display error; payment status remains unchanged; user can retry
Browser closed during payment processing
Payment continues server-side; status updates via webhook
Filters return partial matches
Display only invoices matching ALL filter criteria (AND logic)
User switches tabs rapidly
Cancel pending requests; load data for active tab only
Large dataset (1000+ invoices)
Implement server-side pagination; load only visible page
Contractor assigned to event but later unassigned
Existing invoices remain; no new invoices can be created
Project or Event deleted
Invoices remain for historical record; display "Deleted Project/Event" indicator
Same contractor, same event, same amount, same date
System allows (valid scenario for multiple submissions); each has unique invoice_id
8. Acceptance Criteria
- Users can navigate to Contractor Invoices via Finances menu and view invoices organized in four status tabs (Unpaid, Processing, Paid, Failed)
- System displays appropriate empty state based on hierarchical priority when prerequisites are missing (no brands → no projects → no events → no contractors assigned → no invoices)
- Agency Owner can initiate online payment via Stripe ACH for unpaid invoices when both agency and contractor bank accounts are configured
- System transitions invoice status from Unpaid to Processing when ACH payment is initiated
- System automatically updates status from Processing to Paid or Failed based on Stripe webhook response
- Agency Owner and Admin can mark invoices as paid manually with payment method selection and optional note
- Agency Owner can retry failed payments, which transitions status from Failed back to Processing
- Filters persist across tab switches and can be combined (Date Issued, Brand, Contractor, Project)
- Sorting is available on all tabs for relevant columns and preferences persist within session
- System displays warning when total invoiced amount exceeds contractor's assigned fee for the event
- Invoice PDF viewer opens in modal with print and download functionality
- QuickBooks sync triggers automatically when invoice status changes to Paid
- Three-dot menu provides contextual actions based on invoice status (View Details, Download PDF, Sync with QuickBooks)
- All form validations display appropriate error messages before submission is allowed
- Status transitions occur automatically based on defined business rules with no manual intervention required
9. Dependencies
Module/System
Dependency Type
Impact if Unavailable
Stripe Payment Gateway
Integration
Cannot process online ACH payments; manual payment still functional
Contractor Portal
Service Dependency
Contractors cannot upload invoices; existing invoices remain accessible
Event Management
Data Dependency
Cannot link invoices to events; core functionality broken
Project Management
Data Dependency
Cannot associate invoices with projects; filtering by project fails
Brand Management
Data Dependency
Cannot filter by brand; brand hierarchy broken
QuickBooks Online
Integration
Expense sync fails; financial tracking incomplete
User Authentication
Security Dependency
Cannot verify user permissions; module inaccessible
Contractor Management
Data Dependency
Cannot display contractor information; assignment data unavailable
Agency Settings (Finances)
Configuration Dependency
Cannot configure agency bank account for payouts
File Storage Service
Service Dependency
Cannot store or retrieve invoice PDFs
Notification Service
Service Dependency
Email/in-app notifications for overage warnings fail
10. References
- Design:
Deprecated —--------------------
4. Status-Specific Field Details & Validations
4.1 Unpaid Status Tab Fields
Field Name
Type
Validation Rules
Contractor
Text with Profile
The contractor who submitted the invoice
Links to contractor profile, displays name with profile image
Issued Date
Date
Date the invoice was issued by the contractor. Must be a valid date format, representing the submission date of the invoice.
Status
Static Text
Always displays "Unpaid"
Project
Text
Links to the associated project
Pay CTA
Button
Initiate payment to the contractor
Opens payment popup, requires payment method setup
Mark as Paid CTA
Button
Manually mark the payment as completed
Opens manual payment confirmation pop-up- with fields of amount, payment method,a nd note to be added
View Invoice CTA
Button
Opens invoice details view
Actions
Kebab Menu
Sync to QuickBooks, Copy Invoice Link, Download PDF, Print Invoice
4.2 Processing Status Tab Fields
Field Name
Type
Validation Rules
Contractor
Text with Profile
The contractor who submitted the invoice
Links to contractor profile, displays name with profile image
Issued Date
Date
Date the invoice was issued by the contractor
Valid date format, original invoice date
Paid Date
Date
Valid date format, date payment was initiated
Payment Method
Text
Method used for payment processing
Values: Bank Transfer, Credit Card, ACH
Status
Static Text
Always displays "Processing"
Project
Text
Links to the associated project
View Invoice CTA
Button
Opens invoice details view
Actions
Kebab Menu
Sync to QuickBooks, Copy Invoice Link, Download PDF, Print Invoice
4.3 Paid Status Tab Fields
Field Name
Type
Required
Validation Rules
Contractor
Text with Profile
Yes
The contractor who submitted the invoice
Links to contractor profile, displays name with profile image
Issued Date
Date
Yes
Date the invoice was issued by the contractor
Valid date format, original invoice date
Paid Date
Date
Yes
Date payment was successfully completed
Valid date format, date payment
Payment Method
Text
Yes
Method used for payment completion
Values: Bank Transfer, Credit Card, ACH, Cash
Status
Static Text
Yes
Always displays "Paid"
Comment
Text
Conditional
Appears when payment is manually marked as paid
Project
Text
Yes
Links to the associated project
View Invoice CTA
Button
Yes
Opens invoice details view with download button
QuickBooks Sync
Icon
Yes
Auto or manual synchronization with QuickBooks
Green tick (auto-synced) or clickable icon (manual sync needed)
Actions
Kebab Menu
Yes
Sync to QuickBooks (if auto sync fails), Copy Invoice Link, Download PDF, Print Invoice
4.4 Failed Status Tab Fields
Field Name
Type
Validation Rules
Contractor
Text with Profile
The contractor who submitted the invoice & payment failed
Links to contractor profile, displays name with profile image
Issued Date
Date
Date the invoice was issued by the contractor
Valid date format, original invoice date
Failed Date
DateTime with Reason
Auto-populated by Stripe with a detailed failure reason
Payment Method
Text
Method attempted for payment
Values: Bank Transfer, Credit Card, ACH
Status
Static Text
Always displays "Failed"
Project
Text
Links to the associated project
View Invoice CTA
Button
Opens invoice details view
Retry Payment CTA
Button
Retry payment processing
Opens payment popup for retry attempt
Actions
Kebab Menu
Sync to QuickBooks, Copy Invoice Link, Download PDF, Print Invoice
5. Popup Specifications
5.1 Pay Contractor Popup
Field Name
Type
Required
Validation Rules
Contractor Info
Display
Yes
Shows contractor name, profile image, project, and issued date
Amount
Currency
Yes
Pre-filled from invoice, editable, must be positive
Payment Method Selection
Dropdown/Cards
Yes
Shows available payment methods or sets up payment methods
View Invoice Link
Button
No
Opens invoice in new view
Add Payment Method Button
Button
Conditional
Set up the payment gateway
Appears when no payment method is configured
Cancel Button
Button
Yes
Cancel the payment process
Closes pop-up without action
Pay Contractor Button
Button
Yes
Initiates payment processing
5.2 Mark as Paid Popup
Field Name
Type
Required
Validation Rules
Confirmation Message
Text
Yes
"You are about to mark this invoice as paid. Do you want to continue?"
Amount
Currency
Yes
Pre-filled from invoice, editable, must be positive
Payment Method
Dropdown
Yes
Method used for manual payment
Values: Cash, Bank Transfer, Credit Card, ACH
Note
Text Area
No
Optional additional information
Cancel Button
Button
Yes
Closes pop-up without action
Mark as Paid Button
Button
Yes
Confirms manual payment marking
6. Filter Specifications
6.1 Contractor Invoices Filter Panel
Field Name
Type
Description
Date Issued
Date
Filter by invoice issue date
Brand Filter
Multi-select Dropdown
Filter by project or contractor brand
Contractor Search and multi-select
Text with multi-select value
Search and select specific contractors
Project Search and
Multi select
Text with multi select value
Search and select specific projects
7. Success Message Handling
Validation Scenario
Success Message
Payment successfully initiated
"Payment initiated successfully"
Payment marked as paid manually
"Invoice marked as paid successfully"
QuickBooks sync completed
"Invoice synced with QuickBooks successfully."
Payment method added
"Payment method added successfully."
Invoice PDF downloaded
"Invoice downloaded successfully."
Invoice link copied
"Invoice link copied to clipboard."
Print job initiated
"Invoice sent to printer successfully."
Payment retry initiated
"Payment retry initiated successfully."
8. Error Message Handling
Field
Validation Scenario
Error Message
Payment Processing
Payment gateway connection failed
"Payment processing failed. Please check your payment method and try again."
Payment Processing
Insufficient funds or payment declined
"Payment declined. Please verify payment method details and try again."
Payment Method Setup
Setup failed
"Unable to set up payment method. Please contact support."
General
Network connection failed
"Unable to load contractor invoices. Please check your connection and try again."
General
Server timeout
"Request timed out. Please refresh the page and try again."
Filter Validations
Invalid date range
"End date must be after start date."
Filter Validations
No matching results
"No contractor invoices match the selected filter criteria."
PDF Generation
PDF creation failed
"Unable to generate invoice PDF. Please try again later."
10. Edge Cases
Scenario
Expected Behavior
Partial payment processing through Pay CTA
System processes partial amount as entered, remaining balance stays in Unpaid status for future payment
Payment remains in Processing status for an extended period
Status remains in Processing indefinitely until Stripe provides success or failure response, no automatic timeout
Manual Mark as Paid with backdated information
System accepts any date entered without validation restrictions, records manual entry in audit trail
QuickBooks sync failure for paid invoice
Manual sync option remains available indefinitely, sync status shows red cross until successful completion
View Invoice clicked from any status
Opens invoice details in new page with download button available for PDF generation
Contractor name search with partial text
Real-time search displays matching contractor names only, no company name or email matching
Project-specific user access preventing concurrent actions
System design ensures project-specific users cannot create conflicts, access restricted by project assignment
Payment processing with no contractor notifications
System completes all payment processes without sending any automated notifications to contractors
Payment method setup required for new users
System blocks access to financial functionality until payment method configured, enforced on first access
11. Test Cases
13. Dependencies
Module/System
Dependency Type
Impact if Unavailable
Stripe Payment Gateway
Critical Integration
Cannot process payments, no payment status updates, payment processing fails
QuickBooks Integration
Accounting Integration
Sync functionality unavailable, manual accounting reconciliation required
Project Management Module
Data Dependency
Cannot link invoices to projects, project-based filtering fails
Contractor Management Module
Data Dependency
Cannot display contractor information, contractor filtering unavailable
24 Dec Contractor Invoices
Functional Requirements Document (FRD) - Contractor Invoices Module
Document Version: 1.0
Created Date: December 23, 2025
Module Location: Finances → Contractor Invoices
1. Module Overview
Module Name: Contractor Invoices
Purpose: The Contractor Invoices module enables agency owners and admins to view, manage, and process payments for invoices submitted by contractors for work completed on specific project events. Contractors upload invoices through the Contractor Portal, and agencies can pay via Stripe, ACH bank transfer or record manual offline payments.
Business Goals:
- Streamline contractor payment workflows by centralizing all invoice management in one location.
- Provide real-time visibility into invoice statuses across Unpaid, Processing, Paid, and Failed states.
- Enable flexible payment options through online ACH transfers and manual payment recording.
- Track discrepancies between agreed contractor fees and invoiced amounts to prevent overpayments.
- Synchronize contractor payments with QuickBooks as expenses for accurate financial reporting.
- Reduce payment processing time and improve contractor satisfaction through timely payments.
2. User Roles & Permissions
Role
View Invoices
Pay (Stripe ACH)
Mark as Paid
Retry Payment
View Invoice PDF
Download Invoice
Sync QuickBooks
Agency Owner
✅
✅
✅
✅
✅
✅
✅
Agency Admin
✅
❌
✅
❌
✅
✅
✅
Role Descriptions:
-
Agency Owner: Has full access to all contractor invoice functionalities, including initiating online ACH payments via Stripe, retrying failed payments, marking invoices as paid manually, viewing and downloading invoice PDFs, and triggering QuickBooks sync.
-
Agency Admin: Can view all contractor invoices, mark invoices as paid manually using offline payment methods, view and download invoice PDFs, and trigger QuickBooks sync. Agency Admins cannot initiate online ACH payouts or retry failed payments.
3. User Flow
3.1 The user navigates to the Finances section from the left sidebar menu and clicks on Contractor Invoices.
3.2 The system loads the Contractor Invoices module and displays the Unpaid tab by default, with all unpaid and overdue invoices listed.
3.3 If no invoices have been submitted by the contractors, the system displays an empty state with the message "No contractor invoices yet." and secondary text "The invoices will appear here once the contractors submit invoices for event work."
3.4 The user can switch between Unpaid, Processing, Paid, and Failed tabs by clicking on the respective tab headers.
3.5 The system displays the invoice list for the selected tab with columns appropriate to that tab's context.
3.6 The user clicks the expand arrow on any invoice row to view the Expected Contractor Payment details including the Event Price, total amount invoiced, and any discrepancy.
3.7 The system expands the row inline and displays the Expected Contractor Payment amount, Amount Invoiced by Contractor, and Discrepancy (if applicable).
3.8 The user clicks the filter icon to open the Filters panel.
3.9 The system displays the Filters panel with Date Issued, Brand, Contractor, and Project filter options.
3.10 The user selects filter values and the system immediately filters the invoice list based on the selected criteria.
3.11 The user clicks the "Pay" button on an unpaid invoice row (Agency Owner only).
3.12 The system opens the "Pay Contractor" modal displaying contractor details, project name, issue date, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), and an editable Amount field pre-filled with the invoice amount.
3.13 If the agency has not connected their Stripe account or added a payment method, the system displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button.
3.14 If the contractor has not set up their bank account, the system displays a message "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."
3.15 If both agency and contractor payment methods are configured, the system displays the agency's linked bank account details with account name and last 4 digits.
3.16 The user reviews the payment details, optionally modifies the amount, and clicks "Pay Contractor" to initiate the ACH transfer.
3.17 The system initiates the Stripe ACH payout and moves the invoice from Unpaid to Processing status.
3.18 The user clicks the "Mark as Paid" button on an unpaid invoice row.
3.19 The system opens the "Mark as Paid" modal with confirmation text "You are about to mark this invoice as paid. Do you want to continue?", contractor details, Expected Contractor Payment, Amount Invoiced by Contractor, Discrepancy (if applicable), editable Amount field, Payment Method dropdown, and optional Note field.
3.20 The user selects a payment method from the dropdown (Cash, Check, Zelle, PayPal, Venmo, Google Pay, or Apple Pay), optionally enters a note, and clicks "Mark as Paid".
3.21 The system moves the invoice directly from Unpaid to Paid status and records the manual payment details.
3.22 The user clicks the "View Invoice" button on any invoice row.
3.23 The system opens a PDF viewer popup displaying the uploaded invoice document with Print, Download, and zoom controls.
3.24 The user clicks the 3-dot overflow menu on any invoice row.
3.25 The system displays menu options: View Invoice, Sync with QuickBooks (if not synced or sync failed), and Download Invoice.
3.26 The user clicks "Retry Payment" icon on a failed invoice row (Agency Owner only).
3.27 The system initiates a new ACH payout attempt and moves the invoice from Failed back to Processing status.
3.28 The system receives a Stripe webhook confirming successful payout and moves the invoice from Processing to Paid status.
3.29 The system receives a Stripe webhook indicating payout failure and moves the invoice from Processing to Failed status, storing the failure reason.
3.30 The user clicks on a Project name link in the invoice list.
3.31 The system navigates the user to the Project details page.
3.32 The user enters a search term in the search bar.
3.33 The system filters the invoice list to show invoices matching the search term against Contractor Name, Project Name, or Amount.
3.34 The user clicks a column header to sort the invoice list.
3.35 The system sorts the invoice list by the selected column in ascending or descending order.
3.36 The user clicks the QuickBooks sync icon on a Paid invoice.
3.37 The system displays a tooltip showing the sync status ("Synced: [Date] at [Time]", "Not synced yet. Press QuickBooks icon to sync this transaction.", or "Sync failed. Press to retry.").
3.38 If sync is pending or failed, the user clicks the icon and the system initiates a sync to QuickBooks.
3.39 The system creates or updates the corresponding expense entry in QuickBooks upon successful sync.
4. Functional Logic
4.1 Navigation & Entry Points
- The Contractor Invoices module is accessible from the left sidebar under Finances → Contractor Invoices.
- The module can also be accessed contextually from Project details or Event details pages, where contractor invoice links may be present.
- When the user navigates to the module, the system loads the Unpaid tab by default.
- The system displays a Brand dropdown filter in the header set to "All Brands" by default.
- The system displays a search bar in the header for quick invoice lookup.
- The system displays a filter icon button that opens the advanced Filters panel.
4.2 Empty State Logic
- The system evaluates empty states in a hierarchical priority order to display the most relevant message.
- No Invoices: If no invoices have been submitted by the contractors, the system displays the message "No contractor invoices yet" with secondary text "The Invoices will appear here once the contractors submit invoices."
- Empty states are displayed only after data loading is complete to prevent UI flicker.
- Filters remain accessible during empty states to allow users to adjust filter criteria.
4.3 Tab-Level Empty States
- If invoices exist in the system but the Unpaid tab has no entries, the system displays "No unpaid contractor invoices."
- If the Processing tab has no entries, the system displays "No invoices are currently processing."
- If the Paid tab has no entries, the system displays "No paid invoices yet."
- If the Failed tab has no entries, the system displays "No failed invoices found."
4.4 Filter-Induced Empty State
- If the user applies filters that return zero results, the system displays the message "No invoices match your selected filters." with a "Clear Filters" CTA.
- Clicking "Clear Filters" resets all filter values to their defaults and refreshes the invoice list.
4.5 Invoice Status Definitions
- Unpaid: The invoice has been uploaded by the contractor, but no payment attempt has been initiated (no ACH payout, no manual "Mark as Paid").
- Overdue: Displays the invoices where the payment due date has passed without successful payment.
- Processing: A Stripe ACH payout has been initiated to the contractor's bank account, and final confirmation is pending from Stripe (typically 3-5 business days).
- Paid: The ACH payout was successfully completed based on Stripe webhook confirmation, OR the agency used "Mark as Paid" to record a manual offline payment.
- Failed: The ACH payout failed due to a bank or Stripe error, such as insufficient funds, a blocked transaction, or invalid account details.
4.6 Status Transitions
- Unpaid → Processing: Occurs when the agency owner clicks "Pay" and confirms the online ACH payment via Stripe.
- Unpaid → Paid: Occurs when an agency user clicks "Mark as Paid" and confirms a manual offline payment method.
- Processing → Paid: Occurs when Stripe webhook confirms successful ACH payout completion.
- Processing → Failed: Occurs when Stripe webhook returns a failure response.
- Failed → Processing: Occurs when the agency owner uses "Retry Payment" to initiate a new payout attempt for the same invoice.
- No other status transitions are permitted by the system.
4.7 List View & Tab Structure
4.7.1 Unpaid Tab Columns
- Contractor (with avatar and name)
- Issued (date the invoice was submitted)
- Status (always displays "Unpaid" badge)
- Project (project name with event name and event color dot below)
- Amount (invoice amount in currency format)
- Actions (Pay, Mark as Paid, View Invoice buttons, 3-dot menu)
4.7.2 Processing Tab Columns
- Contractor (with avatar and name)
- Issued (date the invoice was submitted)
- Paid (date the payment was initiated)
- Payment Method (displays "Bank Transfer" for ACH or manual method name)
- Status (always displays "Processing" badge)
- Project (project name with event name and event color dot below)
- Actions (View Invoice button, 3-dot menu)
4.7.3 Paid Tab Columns
- Contractor (with avatar and name)
- Issued (date the invoice was submitted)
- Paid (date the payment was completed)
- Payment Method (displays "Bank Transfer" for ACH or manual method name)
- Status (always displays "Paid" badge)
- Project (project name with event name and event color dot below)
- QuickBooks Sync Icon (displays sync status)
- Actions (View Invoice button, 3-dot menu)
4.7.4 Failed Tab Columns
- Contractor (with avatar and name)
- Issued (date the invoice was submitted)
- Failed Date (date and failure reason below)
- Payment Method (displays "Bank Transfer" or last attempted method)
- Status (always displays "Failed" badge in red)
- Project (project name with event name and event color dot below)
- Actions (View Invoice, Retry Payment icon, 3-dot menu)
4.8 Expandable Row Logic
- Each invoice row in the Unpaid tab has an expand/collapse arrow on the left side.
- When the user clicks the expand arrow, the row expands inline to display additional payment context.
- The expanded section displays: Expected Contractor Payment (the agreed contractor fee for the event), Amount Invoiced by Contractor (cumulative total of all invoices submitted by this contractor for this event), and Discrepancy (if applicable) showing the difference when the invoiced amount exceeds the expected payment.
- The discrepancy value is displayed only when the Amount Invoiced exceeds the Expected Contractor Payment.
- Clicking the expand arrow again collapses the row back to its default state.
4.9 Contractor Fee Tracking & Overage Warning
- Each contractor has an agreed fee per event that is set when the agency assigns the contractor to the event.
- The system tracks the cumulative total of all invoices submitted by a contractor for a specific event.
- The system does NOT block invoices that exceed the assigned contractor fee.
- When the total invoiced amount exceeds the assigned contractor fee, the system displays the discrepancy amount in the expanded row view.
- The discrepancy warning is also displayed in the Pay Contractor modal and Mark as Paid modal to alert the agency before processing payment.
- The agency can proceed with payment even when a discrepancy exists, as there may be valid reasons such as scope changes or extended event duration.
4.10 Pay Contractor Modal (Online Payment)
- The Pay Contractor modal opens when an Agency Owner clicks the "Pay" button on an unpaid invoice.
- The modal header displays "Pay Contractor" with a close (X) button.
- The Contractor section displays the contractor's avatar, name, linked project name, and issue date.
- A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.
- The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.
- The Amount field is pre-filled with the invoice amount but is editable to allow partial payments.
- If the contractor has not set up their bank account, the modal displays "You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account." and the Pay Contractor button is disabled.
- If the agency has not set up their payment method, the modal displays "No payment method set up" with the message "To pay your contractor, you'll need to add a payment method first." and an "Add Payment Method" button that redirects to Stripe Financial Connections.
- If both payment methods are configured, the modal displays the agency's connected bank account with company name and last 4 digits of the account number, along with an edit icon to change the payment method.
- The Cancel button closes the modal without any changes.
- The Pay Contractor button is enabled only when both agency and contractor payment methods are configured and the amount field has a valid value.
- Clicking Pay Contractor initiates the Stripe ACH payout and closes the modal.
4.11 Mark as Paid Modal (Manual Payment)
- The Mark as Paid modal opens when an agency user clicks the "Mark as Paid" button on an unpaid invoice.
- The modal header displays "Mark as Paid" with a close (X) button.
- The modal displays confirmation text: "You are about to mark this invoice as paid. Do you want to continue?"
- The Contractor section displays the contractor's avatar, name, linked project name, and issue date.
- A "View Invoice" link is displayed to allow the user to view the PDF without closing the modal.
- The modal displays Expected Contractor Payment, Amount Invoiced by Contractor, and Discrepancy (if applicable) as read-only informational fields.
- The Amount field is pre-filled with the invoice amount but is editable.
- The Payment Method dropdown is required and contains options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay.
- The Note field is optional and allows the agency to record internal notes about the payment (maximum 1000 characters).
- The Note field content is visible only to agency owner and team members, not to the contractor.
- The Cancel button closes the modal without any changes.
- The Mark as Paid button is enabled when a payment method is selected and the amount field has a valid value.
- Clicking Mark as Paid records the manual payment, moves the invoice to Paid status, and closes the modal.
4.12 View Invoice Functionality
- Clicking the "View Invoice" button opens a full-screen PDF viewer popup.
- The popup header displays the invoice filename in the format "[Contractor Name] - [Project Name] ([Issue Date]).pdf".
- The popup header includes Print, Download, zoom out (-), zoom percentage dropdown, and zoom in (+) controls.
- A back arrow in the top-left allows the user to close the popup and return to the invoice list.
- The PDF viewer displays the contractor-uploaded invoice document.
4.13 Failed Payment & Retry Logic
- When an ACH payout fails, the system stores the failure reason received from Stripe.
- The Failed tab displays the failure date and failure reason below each failed invoice (e.g., "Card Declined", "Invalid Card Details", "Insufficient Funds", "Payment Blocked").
- The Retry Payment action is available only to Agency Owners.
- Clicking the Retry Payment icon initiates a new Stripe ACH payout attempt for the same invoice.
- Upon retry, the invoice status changes from Failed to Processing.
- The subsequent Stripe webhook will determine whether the invoice moves to Paid or back to Failed.
4.14 Filters Panel Logic
- The Filters panel is accessed by clicking the filter icon in the header.
- A refresh icon at the top of the panel resets all filters to default values.
- Date Issued Filter: A date picker allowing the user to select a specific date or date range.
- Brand Filter: A single-select dropdown defaulting to "All Brands" that filters invoices by the brand associated with the project.
- Contractor Filter: A multi-select list with search functionality allowing the user to select one or more contractors.
- Project Filter: A multi-select list with search functionality allowing the user to select one or more projects.
- When a Brand is selected, the Project filter list is scoped to show only projects belonging to that brand.
- When a Brand is selected, the Contractor filter list is scoped to show only contractors assigned to events within that brand.
- Filters apply across all four status tabs (Unpaid, Processing, Paid, Failed).
- Filter selections persist when switching between status tabs until manually cleared.
- Applying filters immediately refreshes the invoice list without requiring a separate "Apply" action.
4.15 Search Functionality
- The search bar in the header allows quick lookup of invoices.
- Search matches against Contractor Name, Project Name, and Amount.
- Search results are displayed in real-time as the user types.
- Search works in conjunction with applied filters.
- Clearing the search field restores the full filtered list.
4.16 Sorting Logic
- All column headers with a down arrow (↓) are sortable.
- Clicking a sortable column header sorts the list by that column in ascending order.
- Clicking the same column header again toggles to descending order.
- Sortable columns include: Contractor, Issued, Paid (where applicable), Payment Method (where applicable), Status, Project, Amount.
- Default sort order is by Issued date in descending order (most recent first).
- Sorting preferences persist while navigating between tabs within the same session.
4.17 Pagination Logic
- The invoice list supports pagination with a "Rows per page" dropdown (default: 10).
- Available options for rows per page are: 10, 25, 50.
- The pagination footer displays the current range (e.g., "1-4 of 4") and navigation arrows.
- Pagination state resets when switching tabs or applying new filters.
4.18 Project & Event Linkage
- Every Contractor Invoice is mandatorily linked to a specific Event.
- Every Event is mandatorily linked to a Project.
- Every Project is mandatorily linked to a Brand.
- The Project column displays the project name with the event name and event color dot displayed below.
- Clicking on the Project name navigates the user to the Project details page.
- Multiple invoices can exist for the same contractor and event combination.
4.19 3-Dot Overflow Menu Actions
- View Invoice: Opens the PDF viewer popup to display the uploaded invoice document.
- Sync with QuickBooks: Displayed only if the invoice is not synced or sync has failed; triggers a manual sync to QuickBooks.
- Download Invoice: Downloads the invoice PDF to the user's device.
4.20 QuickBooks Integration
- Contractor payments (both online ACH and manual) sync to QuickBooks as expenses.
- When an invoice status becomes Paid, the system creates or updates the corresponding expense entry in QuickBooks.
- The QuickBooks sync icon displays one of three states: Synced successfully, Sync failed, Sync pending.
- Hovering over the sync icon displays a tooltip with status details (e.g., "Synced: Aug 20, 2025 at 7:00pm" or "Not synced yet. Press QuickBooks icon to sync this transaction.").
- If sync fails, the user can click the icon to manually retry the sync.
- Data mapping: Contractor maps to Vendor in QuickBooks, Project maps to Class/Job, and payment amount maps to expense amount.
- If the agency has not connected their QuickBooks account, the sync icon is not displayed.
4.21 Stripe Connect Integration
- Pixally maintains a master Stripe account with both agencies and contractors as connected accounts.
- When an agency invites a contractor to Pixally for the first time, the system creates a Stripe Connect account for the contractor under Pixally's master account.
- Contractors complete the Stripe onboarding process only once, even if invited by multiple agencies.
- Each agency that wants to pay a contractor must set up a customer profile and payment method within the contractor's Stripe account.
- If a contractor is already associated with another agency on Pixally, they do not need to complete onboarding again.
- For ACH payouts to succeed, both the agency's funding bank account and the contractor's payout bank account must be configured in Stripe.
4.22 Notifications & Emails
- Payment Success (to Contractor): When a contractor payment is successfully processed (either via ACH or marked as paid manually), the system sends an email notification and an in-app notification to the contractor confirming the payment.
- Payment Failed (to Agency Owner): When an ACH payout fails, the system sends an email notification to the agency owner with the failure reason.
- New Invoice Submitted (to Agency): When a contractor submits a new invoice, the system sends an in-app notification to agency users.
- Invoice Overage Warning: The warning is displayed only in the UI (Pay Contractor modal and Mark as Paid modal) when the agency attempts to pay an invoice that exceeds the expected contractor fee; no email notification is sent for overage.
4.23 Audit Trail
- The system maintains an audit trail for all payment-related actions.
- Logged actions include: Invoice submitted, Payment initiated, Payment completed, Payment failed, Payment retried, Invoice marked as paid, QuickBooks sync attempted, QuickBooks sync completed, QuickBooks sync failed.
- Each audit entry captures the action timestamp, user who performed the action, and relevant details.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Contractor Name
Text (Display)
Read-only; pulled from contractor profile
Contractor Avatar
Image (Display)
Read-only; pulled from contractor profile
Issued Date
Date (Display)
Read-only; set when contractor submits invoice; Format: MMM D, YYYY
Paid Date
Date (Display)
Read-only; set when payment completes; Format: MMM D, YYYY
Failed Date
Date (Display)
Read-only; set when payment fails; Format: Month D, YYYY
Status
Badge (Display)
Read-only; system-managed based on payment lifecycle
Project Name
Text (Link)
Read-only; clickable to navigate to project details
Event Name
Text (Display)
Read-only; displayed with event color dot below project name
Invoice Amount
Currency (Display)
Read-only; set by contractor; Format: $X,XXX.XX
Expected Contractor Payment
Currency (Display)
Read-only; pulled from contractor assignment on event
Amount Invoiced by Contractor
Currency (Display)
Read-only; cumulative sum of all invoices for contractor-event
Discrepancy
Currency (Display)
Read-only; calculated as (Amount Invoiced - Expected Payment) when positive
Payment Amount
Currency (Input)
Required; Numeric only; Must be greater than $0.00; Pre-filled with invoice amount; Format: $X,XXX.XX
Payment Method (Manual)
Dropdown (Select)
Required for Mark as Paid; Options: Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay
Note
Text Area (Input)
Optional; Maximum 1000 characters; Internal use only
Failure Reason
Text (Display)
Read-only; populated from Stripe webhook response
QuickBooks Sync Status
Icon (Display)
Read-only; States: Synced, Failed, Pending
Search Query
Text (Input)
Optional; Matches against Contractor Name, Project Name, Amount
Date Issued Filter
Date Picker
Optional; Accepts single date or date range
Brand Filter
Dropdown (Single-select)
Optional; Default: All Brands
Contractor Filter
Multi-select List
Optional; Searchable; Multiple selections allowed
Project Filter
Multi-select List
Optional; Searchable; Scoped to selected brand
6. Success Message Handling
Operation
Success Message
Trigger Condition
Post-Success Action
Pay Contractor (ACH)
"Payment initiated successfully. The contractor will receive funds within 3-5 business days."
User clicks "Pay Contractor" and ACH payout is initiated
Modal closes; Invoice moves to Processing tab; List refreshes
Mark as Paid
"Invoice marked as paid successfully."
User clicks "Mark as Paid" with valid payment method selected
Modal closes; Invoice moves to Paid tab; List refreshes
Retry Payment
"Payment retry initiated. Processing will complete within 3-5 business days."
User clicks Retry Payment icon on failed invoice
Invoice moves to Processing tab; List refreshes
QuickBooks Sync
"Successfully synced with QuickBooks."
Manual or automatic sync completes successfully
Sync icon updates to "Synced" state; Tooltip shows sync timestamp
Download Invoice
"Invoice downloaded successfully."
User clicks Download Invoice from 3-dot menu
PDF file downloads to user's device
Filters Applied
(No toast message - list updates silently)
User selects filter values
Invoice list refreshes to show filtered results
Filters Cleared
"Filters cleared."
User clicks "Clear Filters" or refresh icon
All filters reset to defaults; List shows all invoices for current tab
7. Error Message Handling
Error Scenario
Error Message
Trigger Condition
Required Action
Agency Payment Method Not Set Up
"No payment method set up. To pay your contractor, you'll need to add a payment method first."
Agency clicks Pay but has not connected Stripe or added payment method
Click "Add Payment Method" to configure Stripe Financial Connections
Contractor Bank Account Not Set Up
"You can't process the payment as the contractor does not have their bank account set up to receive the payment. Please ask the contractor to add their bank account."
Agency clicks Pay but contractor has not completed Stripe onboarding
Contact contractor to complete bank account setup in Contractor Portal
Payment Amount Invalid
"Please enter a valid payment amount greater than $0.00."
User enters zero, negative, or non-numeric value in Amount field
Enter a valid positive numeric amount
Payment Amount Exceeds Limit
"Payment amount exceeds the maximum allowed limit."
User enters amount exceeding Stripe ACH limit
Enter an amount within the allowed limit
Payment Method Required
"Please select a payment method to continue."
User clicks Mark as Paid without selecting payment method
Select a payment method from the dropdown
ACH Payout Failed - Insufficient Funds
"Payment failed: Insufficient funds in the source account."
Stripe webhook returns insufficient funds error
Verify agency bank account balance and retry payment
ACH Payout Failed - Invalid Account
"Payment failed: Invalid bank account details."
Stripe webhook returns invalid account error
Contractor must update bank account details
ACH Payout Failed - Account Blocked
"Payment failed: The recipient's bank account is blocked."
Stripe webhook returns blocked account error
Contractor must resolve issue with their bank
ACH Payout Failed - Card Declined
"Payment failed: Card declined by the bank."
Stripe webhook returns card declined error
Verify payment details and retry
QuickBooks Sync Failed
"Failed to sync with QuickBooks. Click to retry."
QuickBooks API returns error during sync
Click sync icon to retry; If persistent, verify QuickBooks connection
QuickBooks Not Connected
"Connect your QuickBooks account to sync contractor payments."
User attempts sync but QuickBooks is not connected
Navigate to Settings → Integrations to connect QuickBooks
Search No Results
"No invoices found matching your search."
Search query returns no matching invoices
Modify search term or clear search
Filter No Results
"No invoices match your selected filters."
Applied filters return zero results
Adjust filter criteria or click "Clear Filters"
Note Exceeds Character Limit
"Note cannot exceed 1000 characters."
User enters more than 1000 characters in Note field
Reduce note content to 1000 characters or less
Network Error
"Unable to complete the request. Please check your connection and try again."
Network connectivity issue during any operation
Check internet connection and retry the action
Session Expired
"Your session has expired. Please log in again."
User session times out during operation
Log in again to continue
8. Edge Cases
Edge Case
System Behavior
Contractor submits multiple invoices for the same event
The system accepts all invoices and displays them as separate line items; Amount Invoiced by Contractor shows cumulative total
Total invoiced amount exceeds agreed contractor fee
The system displays a discrepancy warning but does not block payment; Agency can proceed with payment
Agency attempts to pay more than invoice amount
The system allows overpayment as the Amount field is editable; This is useful for tips or bonus payments
Agency pays partial amount
The system processes the partial payment; Invoice status changes based on payment flow; Original invoice amount remains unchanged for reference
Stripe webhook delayed beyond 5 business days
Invoice remains in Processing status until webhook is received; No timeout mechanism auto-fails the payment
Stripe webhook received out of order
The system processes webhooks based on event timestamp, not receipt order
User switches tabs while payment is processing
The invoice correctly appears in Processing tab; Original tab updates upon return
User applies filters then switches tabs
Filter selections persist across tab switches within the same session
Brand with no projects is selected in filter
Project filter shows empty list; Contractor filter shows empty list
Contractor is removed from event after submitting invoice
Existing invoices remain visible and can still be paid; New invoices cannot be submitted
Project is deactivated after invoice submission
Existing invoices remain visible and can still be processed; Project name displays with deactivated indicator
Multiple users attempt to pay same invoice simultaneously
First successful payment request is processed; Subsequent attempts fail with "Invoice already processing" error
QuickBooks sync fails due to disconnection
Sync icon shows failed state; User can reconnect QuickBooks and retry sync
Agency disconnects Stripe account with invoices in Processing
Processing invoices continue through Stripe; New payments cannot be initiated until reconnection
Contractor has multiple bank accounts
The system uses the default payout bank account set in contractor's Stripe Connect account
PDF invoice file is corrupted or cannot be rendered
System displays error "Unable to load invoice. Please contact support." with option to download file directly
User opens Pay modal for invoice that was just paid by another user
Modal displays current status and refreshes; Shows message "This invoice has already been paid."
Internet disconnects during payment confirmation
System displays network error; User should check Processing tab to verify if payment was initiated
Note field contains special characters
System accepts all UTF-8 characters including emojis; Properly escapes for storage
Amount field receives paste with currency symbol
System strips non-numeric characters except decimal point; Validates resulting number
9. Acceptance Criteria
9.1 Navigation & Access
- Users can access Contractor Invoices from Finances menu in left sidebar.
- Unpaid tab is displayed by default when module loads.
- All four status tabs (Unpaid, Processing, Paid, Failed) are visible and clickable.
- Brand dropdown filter defaults to "All Brands" and shows all brands the user has access to.
9.2 Empty States
- System displays hierarchical empty states in correct order.
- Each empty state shows appropriate message.
- Tab-level empty states display when no invoices exist for specific status.
- Filter-induced empty state displays with Clear Filters option when filters return no results.
9.3 Invoice List Display
- Invoice rows display correct columns for each tab type.
- Expandable rows show Expected Contractor Payment, Amount Invoiced, and Discrepancy.
- Project column shows project name with event name and color dot below.
- Status badges display correct color and text for each status.
- Pagination controls work correctly with configurable rows per page.
9.4 Pay Contractor Flow
- Pay button is visible only to Agency Owners.
- Pay Contractor modal displays all required information fields.
- Modal shows appropriate message when agency payment method is not configured.
- Modal shows appropriate message when contractor bank account is not configured.
- Amount field is pre-filled and editable.
- Pay Contractor button initiates Stripe ACH payout.
- Invoice moves to Processing status after successful payment initiation.
9.5 Mark as Paid Flow
- Mark as Paid button is visible to both Agency Owners and Agency Admins.
- Modal displays confirmation message and all required fields.
- Payment Method dropdown shows all seven options (Cash, Check, Zelle, PayPal, Venmo, Google Pay, Apple Pay).
- Note field accepts up to 1000 characters.
- Invoice moves directly to Paid status after confirmation.
9.6 Failed Payment & Retry
- Failed invoices display failure date and reason.
- Retry Payment icon is visible only to Agency Owners.
- Retry initiates new ACH payout attempt.
- Invoice moves to Processing status after retry initiation.
9.7 Filters & Search
- All filter types function correctly (Date, Brand, Contractor, Project).
- Project filter scopes to selected Brand.
- Contractor filter scopes to selected Brand.
- Filters persist across tab switches.
- Search matches against Contractor Name, Project Name, and Amount.
- Clear Filters resets all filters to defaults.
9.8 Sorting
- All designated columns are sortable.
- Sort order toggles between ascending and descending.
- Sort preferences persist within session.
9.9 QuickBooks Integration
- Sync icon displays correct state (Synced, Failed, Pending).
- Tooltip shows sync status details on hover.
- Manual sync triggers successfully when clicked.
- Paid invoices sync to QuickBooks as expenses.
9.10 Notifications
- Contractor receives email and in-app notification on successful payment.
- Agency owner receives email notification on failed payment.
- Agency receives in-app notification when new invoice is submitted.
9.11 View & Download Invoice
- View Invoice opens PDF viewer popup.
- PDF viewer has Print, Download, and zoom controls.
- Download Invoice downloads PDF file to user's device.
10. Manual Test Cases
Test cases are documented in a separate Excel file for import into test management tools.
Refer: Click Here
11. Dependencies
Dependency Type
Dependency Name
Description
Impact if Unavailable
Internal Module
Brands
Brand creation and management
Cannot create invoices; Empty state Priority 1 displayed
Internal Module
Projects
Project creation and linking
Cannot create invoices; Empty state Priority 2 displayed
Internal Module
Events
Event creation within projects
Cannot create invoices; Empty state Priority 3 displayed
Internal Module
Contractor Management
Contractor profiles and event assignment
Cannot submit invoices; Empty state Priority 4 displayed
Internal Module
Contractor Portal
Interface for contractors to submit invoices
Invoices cannot be created by contractors
External Service
Stripe Connect
Payment processing for ACH payouts
Online payments cannot be processed; Mark as Paid still available
External Service
Stripe Financial Connections
Bank account linking for agencies
Agencies cannot add payment methods for ACH
External Service
Stripe Webhooks
Payment status updates
Payment status stuck in Processing; Manual verification required
External Service
QuickBooks API
Expense synchronization
Expense entries not created; Manual accounting required
Configuration
Agency Stripe Account
Agency's connected Stripe account
Cannot initiate ACH payments
Configuration
Contractor Stripe Account
Contractor's Stripe Connect account
Cannot receive ACH payments
Configuration
Agency Payment Method
Linked bank account for fund source
Cannot initiate ACH payments
Configuration
Contractor Bank Account
Linked bank account for payout
Cannot receive ACH payments
12. References
Please refer- Click Here
☑️ Expenses
1. Module Overview
Module Name: Expenses Management Module (Sub-module within Finance Management)
Purpose: Record, manage, and track all outgoing monetary expenses of the company with comprehensive categorization, brand association, and automated QuickBooks integration
Business Goal: Provide centralized expense management with detailed categorization (COGS/OPEX), contractor payment tracking, and brand-specific filtering.
2. User Roles & Permissions
Role
Description
Key Permissions
Agency Owner
Business owner with full financial oversight
Full access: add, edit, delete, view all expenses, manage QuickBooks sync, access all brands and projects
Admin
System administrator with operational control
Full access: add, edit, delete, view all expenses, manage QuickBooks sync, access all brands and projects
Project Manager (PM)
Project-specific management role
Limited access: add expenses only for assigned projects, view own project expenses, cannot delete or edit others' expenses, restricted brand access
3. User Flow
Primary Flow - Expense Management:
- Module Access: User navigates to Finance Management → Expenses
- Expense Listing: System displays expense table with Date, Amount, Category, Notes, QuickBooks Sync Status, Actions
- Filter Application: User applies filters (contractor toggle, brand filter, date range, price range, category search), user can also use the toggle of “Only show amount paid to contractor" to filter out only the amount paid to contractors from all other expenses
- Expense Actions: The User can add new expenses, edit existing ones, or delete expenses based on permissions
- QuickBooks Integration: The System automatically attempts sync with QuickBooks, and provides a manual retry for failed syncs
- Data Management: User manages expense records with proper categorization and project assignment
Secondary Flow - Add New Expense:
- Add Expense: User clicks "Add Expense" button
- Type Selection: User selects COGS or OPEX expense type
- Category Selection: User selects from a predefined category list based on expense type
- Form Completion: User fills required fields (brand, project, date, amount) and optional notes
- Contractor Selection: If the category is "Contractors," the user selects a specific contractor
- Submission: System validates data and creates an expense record
- Auto-Sync: System attempts automatic QuickBooks synchronization
Tertiary Flow - QuickBooks Sync Management:
- Auto-Sync Attempt: The System automatically tries to sync new/modified expenses
- Sync Status Update: System updates the QuickBooks sync icon based on success/failure
- Manual Retry: User clicks the QuickBooks icon for failed syncs to retry manually
- Status Tracking: System maintains sync status for all expense records
4. Field Details & Validations
4.1 Expense Form Fields
Field Name
Required
Validation Rules
Date
Yes
The date of payment
Amount
Yes
The total amount paid for the expenses
Must be numeric and > 0, formatted to 2 decimal places
Category
Yes
The category in which the payment was made
Notes
Yes
Maximum 250 characters
QuickBooks icon
Yes
Will be active if the sync happens, else the user can manually sync by clicking on the icon
Actions
Yes
Delete and edit
4.2 COGS (Cost of Goods Sold) Categories
Category Group
Specific Categories
Select Category
Drop-down values will auto-populate with COGS Values
Select Brand
Drop-down values, Brand values will auto-populate
Select Project (Optional )
Dropdown values and Project values will be autopopulated
Date
Date picker
Amount
Text field to add amount (Only numeric value)
Notes(Optional)
Text Fileds
4.3 OPEX (Operating Expenses) Categories
Category Group
Specific Categories
Select Brand
Drop-down values, Brand values will auto-populate
Select Category
Drop-down values will auto-populate with OPEX values
Select Contrcator
Drop-down values with the respective contractors from the brand
Date
Date picker
Amount
Text field to add amount (Only numeric value)
Notes
Text Fileds
4.4 Filter Panel Fields
Field Name
Type
Validation Rules
Contractor Toggle
Toggle Switch
Filter to show only contractor payment expenses
On/Off state
Brand Filter
Dropdown
Filter expenses by brand association
Must select from available brands, "All Brands" default
Date Filter
Date Range
Filter expenses by date range
Start date ≤ end date, valid date format
Price Range
Number Range
Filter expenses by amount range (Min $0 - Max $200+)
Category Search
Text Input
Search within expense categories of both category
Real-time search functionality
5. Success Message Handling
Validation Scenario
Success Message
Expense created successfully
"Expense has been added successfully."
Expense updated successfully
"Expense details have been updated successfully."
Expense deleted successfully
"Expense has been deleted successfully."
6. Error Message Handling
Field
Validation Scenario
Error Message
Expense Type
Not selected
"Please select expense type (COGS or OPEX)"
Category
Not selected
"Please select a category."
Brand
Not selected
"Please select a brand."
Project
Not selected (when required for PM)
"Please select a project from your assigned projects."
Contractor
Not selected when required
"Please select a contractor for this expense."
Date
Invalid or empty date
"Please select a valid date."
Amount
Invalid or ≤ 0
"Please enter a valid expense amount greater than $0."
Amount
Non-numeric input
"Please enter a valid numeric amount."
Notes
Exceeds 250 characters
"Notes cannot exceed 250 characters."
7. Functional Logic
Expense Type and Category Logic
- COGS Selection: When the user selects the COGS expense type, the system displays only the COGS-related categories
- OPEX Selection: When the user selects the OPEX expense type, the system displays only OPEX-related categories
- Contractor Category Logic: When the "Contractors" category is selected, the contractor dropdown becomes required
- Category Validation: System ensures selected category matches chosen expense type (COGS/OPEX)
Project Assignment Logic
- PM User Restrictions: Project Manager users can only select from assigned projects in the dropdown
- Optional Project Assignment: Agency Owner and Admin can leave the project field empty for company-wide expenses
- Project-Specific Validation: System validates that PM users cannot assign expenses to unassigned projects
Brand Association Logic
- Company-Wide Brand Selection: All expenses can be associated with any brand or "All Brands"
- No Brand Restrictions: No validation rules restrict which expense types can be assigned to specific brands
- Default Brand Setting: System defaults to "All Brands" unless user selects specific brand
QuickBooks Integration Logic
- Automatic Sync Attempt: Every new or modified expense automatically attempts QuickBooks synchronization
- Background Retry Logic: Failed syncs retry automatically in the background at configured intervals
- Manual Sync Capability: Users can manually trigger sync for failed expenses via the QuickBooks icon
- Sync Data Transfer: All expense fields (amount, category, date, notes, project) sync to QuickBooks
- Sync Status Tracking: The System maintains a persistent sync status for each expense record
Price Range Filter Logic
- System-Derived Min/Max: The system automatically calculates the minimum value from the lowest expense amount in the dataset and the maximum value from the highest expense amount. These bounds update dynamically whenever the expense dataset changes.
- User Interaction: The user can drag the range slider between the system-defined Min and Max bounds to filter the expense list. The slider reflects only the range within the actual data.
- Display: The Min ()andMax() and Max ( )andMax() labels are shown above the slider as informational read-only values reflecting the current dataset range.
- Removal of Event Types Filter: The Event Types dropdown has been removed from the filter panel. It is no longer part of the Expenses filter options.
8. Edge Cases
Scenario
Expected Behavior
QuickBooks service unavailable
Expense saved locally, background retry continues, manual sync available when service restored
Contractor toggle applied with no contractor expenses
Show "No contractor expenses found" message with option to clear filter
Category selection with no matching contractor
If contractor required but none available, show "No contractors available" message
Expense deletion with QuickBooks sync
Attempt to delete from QuickBooks, maintain local deletion regardless of sync success
9. Test Cases
10. Acceptance Criteria
- Role-Based Access Control: PM users are restricted to assigned project expenses, Owner/Admins have full access to all expenses
- Expense Type Classification: COGS and OPEX categories display correctly based on expense type selection
- Category Management: All predefined categories from the COGS and OPEX lists are available and properly organized
- Contractor Integration: Contractor dropdown appears only for the Contractors category, required when selected
- Project Assignment: PM users can only assign expenses to assigned projects; others can leave the project optional
- Brand Association: All expenses can be associated with any brand or "All Brands" without restrictions
- QuickBooks Integration: Automatic sync attempts for all new/modified expenses, manual retry available for failures
- Filter Functionality: Contractor toggle, brand filter, date range, price range, and category search work correctly
- Form Validation: All required field validations work properly with appropriate error messaging
- CRUD Operations: Create, read, update, and delete operations work according to user role permissions
- Data Persistence: All expense data is stored correctly with proper formatting and validation
- Sync Status Tracking: QuickBooks sync status displayed accurately with visual indicators
- Performance: Pagination and filtering work efficiently for large expense datasets
- Filter Functionality: Contractor toggle, brand filter, date range, price range slider (with system-generated min/max), and category search work correctly.
11. Dependencies
Module/System
Impact if Unavailable
Brands Management
Cannot associate expenses with brands; brand filtering is unavailable
Contractor Management
Cannot select contractors for contractor category expenses
Project Management
Cannot assign expenses to projects, PM role restrictions fail
QuickBooks Integration
Sync functionality unavailable, manual accounting reconciliation required
Authentication System
Role-based access control fails; permission restrictions cannot be enforced
Client/Project Data
Project assignment and validation cannot function properly
12. QuickBooks Integration Specifications
12.1 Sync Status Indicators
Status
Visual Indicator
Description
Synced
Green checkmark icon on the QuickBooks logo
Successfully synchronized with QuickBooks
Failed
Red cross icon with disabled QuickBooks logo
Sync failed, manual retry available by clicking on it to sync
13. References
No tickets linked — generate test cases directly from this FRD instead.