33. Subscription_Management_Final
Pixally CRMSubscription
Subscription
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated Date: 10 November 2025
Status:
Version 1.0
1. Subscription Plans with Access Control
Subscription Plans with access control
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 23 April 2026
Status:
Version 2.0
FRD 1 — Subscription Plans with Access Control
Module: Subscription Plans with Access Control Version: 2.0 Date: April 23, 2026
1. Module Overview
Module Name: Subscription Plans with Access Control
Purpose: This module defines the four-tier subscription plan structure (Free, Basic, Essentials, Studio) available to Pixally CRM agencies. It governs the feature entitlements, resource limits (projects, brands, team members, contractors), promotional pricing, Stripe transaction fees, and access control rules associated with each plan. The module also manages the Plan Usage Matrix UI that displays real-time consumption of plan resources and triggers upgrade prompts when limits are reached.
Business Goals: The Subscription Plans module drives revenue conversion by clearly communicating plan value, encouraging upgrades through transparent limit visibility, and ensuring agencies operate within their subscribed tier's capacity. It provides the foundation for all plan-based feature gating across the Pixally CRM platform, ensuring consistent access enforcement and upgrade nudges across every module that consumes subscription state.
2. User Roles & Permissions
Role
View Plan Details
View Plan Usage Matrix
View Payment Method
Upgrade Plan
Add Extra Seat
Access Restricted Features
Agency Owner
Yes
Yes
Yes
Yes
Yes
As per plan limits
Agency Admin
Yes (read-only)
Yes (read-only)
No (hidden)
No
No
As per plan limits
Project Manager
No
No
No
No
No
As per plan limits
Supervising Editor
No
No
No
No
No
As per plan limits
Editor
No
No
No
No
No
As per plan limits
Contractor
No
No
No
No
No
Contractor portal only
Client
No
No
No
No
No
Client portal only
3. User Flow
3.1 The agency owner logs into the Pixally CRM portal and navigates to the Subscription page from the left sidebar menu.
3.2 The system loads the Subscription page and displays the current plan name, plan description, payment method summary, seat count, billing cycle, and the Plan Usage Matrix section.
3.3 The system fetches real-time usage counts for Projects, Brands, Seats, and Contractors and renders them as four tiles within the Plan Usage Matrix.
3.4 The system evaluates whether any usage tile has reached or exceeded one hundred percent of the plan's allocated limit.
3.5 If at least one tile has reached its limit, the system displays the "Plan limits reached" warning banner above the tiles with the descriptive message and the two call-to-action buttons labelled "Add seat" and "Upgrade Plan". Add seat button only comes when seat tile reached the limit
3.6 If no tile has reached its limit, the system hides the warning banner and displays only the four usage tiles.
3.7 The agency owner reviews each tile to understand the current consumption against plan limits.
3.8 The agency owner clicks the "Upgrade Plan" button from the warning banner or from any other upgrade entry point within the portal.
3.9 The system opens the Manage Subscription page showing all available plans (Free, Basic, Essentials, Studio) with their pricing, features, Stripe transaction fees per plan, the "Most Popular" badge on the recommended plan, and the currently active plan marked with an "Active Monthly" or "Active Yearly" label.
3.10 The agency owner selects a target plan and proceeds with the upgrade, which is handled in FRD 3 (Upgrade & Downgrade).
3.11 The agency owner clicks the "Add seat" button from the warning banner to invite a new team member, which opens the Invite Team Member modal handled in FRD 5 (Add-ons).
3.12 A non-owner user such as an Admin, Project Manager, Supervising Editor, or Editor who attempts to perform an action that exceeds the plan limit sees a restriction message and cannot initiate an upgrade.
3.13 The agency admin who accesses the Subscription page views all plan details and usage information in read-only mode without any action buttons to upgrade, cancel, or manage payment methods, and the Payment Method section is hidden entirely.
3.14 The agency owner attempts to access a feature that is not included in the current plan and sees a popup prompting an upgrade with a direct link to the Manage Subscription page.
3.15 A contractor or a team member who belongs to an agency that has been downgraded or suspended attempts to log in and sees an access-restriction message describing that access is currently unavailable.
3.16 The agency owner on the Studio plan does not see an Upgrade button anywhere because Studio is the highest tier.
3.17 The agency owner on a plan with a scheduled downgrade sees an informational message under the plan details stating "Your plan will be downgraded on [Date]" along with a "Cancel Downgrade" option.
4. Functional Logic
4.1 Plan Tier Structure
- The system supports exactly four subscription plan tiers, namely Free, Basic, Essentials, and Studio, which are offered in either a Monthly or an Annual billing cycle.
- The Free plan is the permanent fallback plan that any agency defaults to if they do not have an active paid subscription or if their trial has expired without conversion.
- The Basic plan is the entry-level paid plan intended for small teams that need to streamline core project operations.
- The Essentials plan is the mid-tier paid plan designed for growing businesses that need structure, collaboration, and additional management modules, and is marked as "Most Popular" on the plan selection screen.
- The Studio plan is the highest tier paid plan intended for high-performing teams that require unlimited resources, priority support, and advanced reporting.
- The plan pricing for both Monthly and Annual cycles is hardcoded from client-provided values and is not calculated dynamically by the system.
- The Annual cycle offers the equivalent of two months free relative to twelve months of monthly billing, and the exact Annual price is provided directly by the client.
- Prices displayed on the plan selection screen do not include applicable sales tax, and a static note stating "Displayed prices do not include any applicable sales tax" is shown below the pricing cards; sales tax is calculated and added at checkout by Stripe Tax based on the agency's billing address.
4.2 Plan Resource Limits
- The Free plan allows up to 5 active projects, 1 team member, 1 brand, and 0 contractors , with the option to add extra team members at nine dollars per month per seat.
- The Basic plan allows unlimited active projects, 2 team members included, 1 brand, and 0 contractors, with the option to add extra team members at nine dollars per month per seat.
- The Essentials plan allows unlimited active projects, 3 team members included, 2 brands, and up to 20 contractors, with the option to add extra team members at nine dollars per month per seat.
- The Studio plan allows unlimited active projects, unlimited team members, unlimited brands, and unlimited contractors, with no extra-seat charges applicable.
- Contractors are considered a separate entity from team members and do not count toward the team member seat limit on any plan.
- An active project is any project that has reached the Booked stage or is in any post-event pipeline stage; projects in pre-Booked stages such as Inquiry or Quote, and projects that are Archived or Cancelled, are not counted toward the active project limit.
- Projects that belong to a locked brand still count toward the Projects tile usage, ensuring that plan limits are enforced consistently regardless of brand-lock state.
- Contractors are counted per agency, so a contractor who works with multiple agencies is counted only once per agency for that agency's contractor usage.
4.3 Plan Feature Entitlement Matrix
- The system enforces feature-level access control based on the currently active plan, and every feature-gated module consumes the subscription state to determine whether a feature is available, visible in read-only, or locked with an upgrade prompt.
- Free plan users have access to 5 active projects, 1 team member, 1 brand, Email Center, Invoices and Payments, Proposals and Contracts, Calendar, Templates, Basic Reports, Workflow Automation, and Client Portal.
- Basic plan users have access to everything in the Free plan plus unlimited projects, 2 team members included, Google Calendar and Calendly integration, with the option to add extra team members at nine dollars per month per seat.
- Essentials plan users have access to everything in the Basic plan plus 3 team members included, 2 Brands, Contractor Management up to 20 contractors, Post Production Management, QuickBooks Online Integration, Expense Management, and Advanced Reports including Profit and Loss.
- Studio plan users have access to everything in the Essentials plan plus unlimited team members, unlimited brands, unlimited contractors, Priority Support, and SMS Text Message Reminders.
4.4 Promotional Pricing — 50% Off First Year
- All three paid plans (Basic, Essentials, and Studio) are eligible for a first-year promotional discount of fifty percent off.
- The fifty percent promotional discount is valid for 365 days from the user's first successful subscription date.
- he 50% promo discount applies for 365 calendar days starting from the date of the agency's first paid payment per PATCH-003 §6.
- - The 365-day window is calendar-anchored and continues counting through any periods of suspension, cancellation, or other non-paying states; the window does not pause and does not extend.
- - After the 365-day window expires, all subsequent invoices charge at full price.
- - The first-paid-payment date is recorded once and never changes; promo eligibility is anchored per email and is preserved across hard-deletion and re-signup per FRD 1 promo tracking
- The promotional discount is available to new users only and is tracked by the email address used during signup.
- A user who has previously used the promotional offer cannot use it again even after cancelling and re-subscribing with the same email, and even after account deletion and fresh signup with the same email.
- The promotional discount applies only to the base plan price and does not apply to extra seat charges, which are always billed at nine dollars per month per seat regardless of promo status.
- After the 365-day promotional window ends, the user is charged the full plan price starting from the next billing cycle.
- The promotional discount can be stacked with one agency-applied discount coupon code, with the coupon applied after the promotional discount on the already-discounted amount. The exact stacking mechanics are detailed in FRD 3 (Upgrade & Downgrade) and FRD 9 (Subscription Impact on Other Modules).
4.5 Referral Discount
- Users who sign up through a referral link are eligible for a referral discount that is separate from both the fifty percent promotional offer and agency-applied coupon codes.
- The order of discount application on any invoice is: fifty percent first-year promotional discount first, then referral discount, and finally any agency-applied coupon code.
- Discount codes do not apply to extra seat charges; extra seats are always billed at the full nine dollars per month per seat rate.
4.6 Stripe Transaction Fees Per Plan
- Stripe transaction fees vary by plan tier and are displayed on each plan card in the plan selection screen so that agency owners are aware of the total cost of processing client payments through Pixally CRM.
- The Free plan has Credit Card fees of 3.3 percent plus 30 cents per transaction and ACH fees of 1 percent per transaction.
- The Basic plan has Credit Card fees of 2.9 percent plus 30 cents per transaction and ACH fees of 1 percent per transaction.
- The Essentials plan has Credit Card fees of 2.9 percent plus 30 cents per transaction and ACH fees of 0.8 percent with a 12 dollar cap per transaction.
- The Studio plan has Credit Card fees of 2.9 percent plus 30 cents per transaction and ACH fees of 0.8 percent with an 8 dollar cap per transaction.
- These fees are applied to client payments processed through the Pixally CRM invoicing and payment modules, and are separate from the Pixally subscription fees charged to the agency.
4.7 Plan Usage Matrix Display Logic
- The Plan Usage Matrix appears on the main Subscription page between the top plan summary card and the Subscription Receipts section.
- The matrix contains four tiles that display the current consumption of Projects, Brands, Seats, and Contractors against the active plan's limits.
- Each tile displays the current used count, the total allocated count in the format "X of Y used", and a capacity progress bar showing the percentage consumed.
- When a plan has unlimited capacity for a given resource, the corresponding tile displays "No limit" below the used count instead of a progress bar, and the "Unlimited on [Plan Name]" label is shown inline.
- The Contractors tile is not displayed for Free or Basic plan users because these plans do not include contractor access.
- The system polls the usage counts on page load, whenever the browser tab regains focus, and after any action that could change usage such as creating a project, inviting a team member, adding a brand, or inviting a contractor.
- When the consumed count for any tile reaches or exceeds one hundred percent of the allocated limit, the system displays the "Plan limits reached" warning banner immediately above the four tiles.
- The warning banner message dynamically lists which specific limits have been reached, for example "You've reached the limit on Brands and Seats".
- The warning banner contains two call-to-action buttons named "Add seat" and "Upgrade Plan".
- The "Add seat" CTA opens the Invite Team Member modal and is available only on plans that support extra seats (Basic and Essentials). This only comes when seat limit has approached.
- The "Upgrade Plan" CTA opens the Manage Subscription page where the agency owner can select a higher-tier plan.
- The warning banner cannot be dismissed by the user and stays visible until the limit is resolved by either upgrading the plan or by removing excess resources to bring usage below the limit.
- If the Plan Usage Matrix API partially fails and returns data for some tiles but not others, the system renders the successful tiles with their current counts and displays a retry prompt only on the failed tiles.
4.8 Feature Gating Behaviour
- Restricted features that are not included in the user's current plan are never hidden from the user interface and instead remain visible but non-functional.
- When a user clicks a restricted feature or attempts to perform an action beyond their plan limits, the system displays an upgrade prompt popup with a call-to-action routing to the Manage Subscription page.
- If the user attempting to perform the restricted action is not the agency owner, the system instead displays the message "You've reached your plan's limit. Please contact your agency owner to upgrade the plan or add extra capacity." without showing the upgrade call-to-action.
- Feature-gating prompts are consistent across all modules that consume the subscription state and use the same upgrade prompt styling for brand consistency.
- Detailed module-specific feature gating behavior is captured in FRD 9 (Subscription Impact on Other Modules).
4.9 Role-Based Subscription Access
- Only the agency owner has full read and write access to the Subscription page, including plan changes, payment method management, seat purchases, and cancellation.
- The agency admin can view the Subscription page in read-only mode that displays plan details, plan usage matrix, and receipts, but does not display any action buttons for upgrading, cancelling, switching billing cycle, or managing payment methods.
- The Payment Method section is hidden entirely from the agency admin view, and only the agency owner can see the saved payment method details and manage them.
- Project managers, supervising editors, editors, contractors, and clients do not have access to the Subscription page at all and receive a permission-denied response when attempting direct URL access.
- The agency admin, despite not being able to change plans, is permitted to invite new team members within the plan's allowed seat limit as long as extra seat charges are not triggered, since extra-seat charges require the owner's payment authorization.
4.10 Subscription Page Display Elements
- The Subscription page top summary card displays the current plan name, a short plan description, the "Change Plan" button, and the "Cancel Subscription" button for the agency owner.
- The Payment Method section displays the payment method type and the last four digits of the card along with the "Manage Payment Method" button, and is visible only to the agency owner.
- The Seats section displays the total number of seats including the base plan seats and any additional paid seats, along with the "Add Team Member" button.
- The Subscription cycle section displays the current billing cycle (Annual or Monthly), the billing amount, and the next billing date, along with the "Switch to Monthly" or "Switch to Yearly" button as applicable.
- The current plan on the Manage Subscription selection screen is labelled "Active Monthly" or "Active Yearly" based on the billing cycle, and the "Most Popular" badge is shown on the Essentials plan card unless the Essentials plan is also the currently active plan in which case the "Active Monthly" or "Active Yearly" label takes priority.
- On the Studio plan, no Upgrade button is shown anywhere because Studio is the highest available tier; the agency owner can only downgrade, change billing cycle, manage seats, or cancel.
- If the agency owner is currently on an active Free Trial, the top summary card shows the trial plan name with a "Free trial" badge, the number of days remaining in the trial, a "Subscribe to [Plan]" button, and a "View all plans" button instead of the regular plan controls.
- If the agency owner has a scheduled downgrade, an informational message is shown under the plan details stating "Your plan will be downgraded on [Date]" along with a "Cancel Downgrade" option.
- If the agency owner has a scheduled billing cycle switch from Annual to Monthly, an informational message is shown under the billing cycle section stating "Your billing cycle will switch to Monthly on [Date]" along with a "Cancel Switch" option.
- If the agency is in a suspended state due to failed payment, the Subscription page routes the owner to the billing update screen as defined in FRD 7 (Failed Payment Management) and the standard Subscription page is not rendered.
4.11 Trial Plan Access Control
- During an active 14-day free trial, the user has access to all features included in the trial plan, and team member invites are permitted up to the trial plan's included seat count.
- A trial user cannot purchase extra paid seats during the trial period; if the trial user attempts to add a team member beyond the included seat count, the system prompts the user to first subscribe to a paid plan, after which the extra seat purchase can be completed as part of the same flow.
- Once the trial expires without conversion, the account is automatically downgraded to the Free plan and all feature access is restricted to Free plan limits.
4.12 Impact of Plan Changes on Access Control
- When an agency upgrades to a higher plan, the new plan's entitlements take effect immediately after successful payment, and previously restricted features become accessible in real time.
- When an agency schedules a downgrade, the current plan's entitlements remain in effect until the end of the current billing cycle, and the downgrade takes effect at the cycle end.
- At the moment of downgrade execution, the system applies the new plan's limits and locks resources that exceed the new limits according to the rules defined in FRD 3 (Upgrade & Downgrade) and FRD 9 (Subscription Impact on Other Modules).
- Locked resources such as excess projects, deselected brands, deselected team members, and excess contractors retain their data but are marked with a lock icon and are not accessible until the agency upgrades back to a supporting plan.
4.13 Gawd Portal-Applied Discounts
- The Pixally Super Admin (Gawd Portal) can apply discount codes to an agency's subscription, and the discounted pricing is reflected on the agency's Subscription page at the next page load.
- The Gawd Portal cannot directly change an agency's plan tier; plan changes must be initiated by the agency owner through the standard upgrade or downgrade flow.
- Discount codes applied by the Gawd Portal follow the same stacking rules as described in Section 4.4 and 4.5.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Plan Name
Read-only text
Displays the active plan name (Free, Basic, Essentials, or Studio).
Plan Description
Read-only text
Static description text per plan; sourced from the plan catalog.
Plan Badge
Read-only badge
Values: "Free trial", "Active Monthly", "Active Yearly", "Most Popular". Mutually exclusive; active state takes priority over "Most Popular".
Billing Cycle
Read-only text
Values: "Monthly" or "Annual".
Next Billing Date
Read-only date
Format: DD Mon YYYY. Must be a future date for active subscriptions.
Subscription Amount
Read-only currency
Displayed in USD with two decimal places. Sourced from the client-provided pricing table.
Promotional Price Display
Read-only currency
When 50% promo is active, shows discounted price with the original price struck through and a "50% off" badge next to it.
Sales Tax Disclaimer
Read-only text
Static: "Displayed prices do not include any applicable sales tax."
Stripe Fee — CC
Read-only text
Format: "X.X% + 30 cents". Per plan: 3.3%, 2.9%, 2.9%, 2.9% for Free, Basic, Essentials, Studio respectively.
Stripe Fee — ACH
Read-only text
Format: "X% [with $X cap]". Per plan: 1%, 1%, 0.8% with $12 cap, 0.8% with $8 cap.
Projects Used
Read-only integer
Counts projects in Booked stage or any post-event pipeline stage. Must be zero or greater.
Projects Limit
Read-only integer or "Unlimited"
5 for Free; Unlimited for Basic / Essentials / Studio.
Brands Used
Read-only integer
Counts active brands in the agency, including locked brands. Must be zero or greater.
Brands Limit
Read-only integer or "Unlimited"
1 / 1 / 2 / Unlimited for Free / Basic / Essentials / Studio.
Seats Used
Read-only integer
Counts all active team members including owner, included seats, and extra paid seats.
Seats Limit
Read-only integer or "Unlimited"
1 / 2 (+extras) / 3 (+extras) / Unlimited for Free / Basic / Essentials / Studio.
Contractors Used
Read-only integer
Counts active contractors assigned to this agency only (hidden for Free and Basic).
Contractors Limit
Read-only integer or "Unlimited"
0 / 0 / 20 / Unlimited for Free / Basic / Essentials / Studio.
Plan Usage Banner
Read-only text
Dynamically composed based on which limits have been reached.
Trial Days Remaining
Read-only integer
Displayed only when user is on an active trial. Range: 0 to 14.
Scheduled Downgrade Message
Read-only text
Format: "Your plan will be downgraded on [DD Mon YYYY]". Displayed only when a downgrade is scheduled.
Scheduled Cycle Switch Message
Read-only text
Format: "Your billing cycle will switch to Monthly on [DD Mon YYYY]". Displayed only when an Annual-to-Monthly switch is scheduled.
Add Seat CTA
Button
Visible only on Basic and Essentials plans. Disabled for non-owner users.
Upgrade Plan CTA
Button
Visible on Free, Basic, and Essentials plans. Hidden entirely on Studio. Disabled for non-owner users.
Change Plan Button
Button
Visible only to Owner. Routes to Manage Subscription page.
Cancel Subscription Button
Button
Visible only to Owner on paid plans. Hidden on Free plan.
Cancel Downgrade Button
Button
Visible only when a downgrade is scheduled, and only to Owner.
Cancel Switch Button
Button
Visible only when an Annual-to-Monthly cycle switch is scheduled, and only to Owner.
Manage Payment Method Button
Button
Visible only to Owner. Hidden entirely from Admin and other roles.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Plan Usage Matrix loaded
No explicit toast; tiles render silently.
Subscription page loads successfully.
Tiles render with current counts; banner evaluated.
SM-2
Upgrade Plan CTA clicked
"Redirecting to plan selection…" (inline indicator)
User clicks Upgrade Plan.
Route to Manage Subscription page.
SM-3
Add Seat CTA clicked
No toast; modal opens directly.
User clicks Add Seat.
Invite Team Member modal opens.
SM-4
Plan limit resolved (resource removed)
"Plan limit updated. You're now within your plan's limit."
Usage count drops below 100% after removal of a resource.
Warning banner hides.
SM-5
Plan limit resolved (plan upgraded)
"Your plan has been upgraded. You now have additional capacity."
Plan upgrade completes successfully.
Usage tiles refresh; banner hides.
SM-6
Scheduled downgrade cancelled
"Your scheduled downgrade has been cancelled. Your current plan will continue."
User clicks Cancel Downgrade.
Scheduled downgrade message hides.
SM-7
Scheduled cycle switch cancelled
"Your scheduled billing cycle change has been cancelled. Your current billing cycle will continue."
User clicks Cancel Switch.
Scheduled cycle switch message hides.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Non-owner user attempts to upgrade plan
"You've reached your plan's limit. Please contact your agency owner to upgrade the plan or add extra capacity."
Admin, Project Manager, Supervising Editor, or Editor clicks a restricted action.
User must contact the agency owner.
EM-2
Non-owner user attempts to add a seat
"Only the agency owner can purchase additional seats. Please contact your agency owner."
Non-owner clicks Add Seat.
User must contact the agency owner.
EM-3
User attempts a feature not included in current plan
"This feature is not included in your current plan. Upgrade to [Target Plan] to unlock it." with Upgrade CTA.
User clicks a feature-gated element.
Owner can click Upgrade; non-owner sees contact-owner message.
EM-4
User attempts to create a brand beyond plan limit
"You've reached your brand limit. Upgrade your plan or delete an existing brand to add a new one."
User clicks "Create Brand" when at limit.
Owner: upgrade or delete. Non-owner: contact owner message.
EM-5
User attempts to add a project beyond Free plan limit
"You've reached the 5-project limit on the Free plan. Upgrade to any paid plan for unlimited projects."
Free user clicks "Create Project" at limit.
Owner: upgrade. Non-owner: contact owner message.
EM-6
User attempts to invite a contractor on Free or Basic
"Contractor Management is available on Essentials and Studio plans only. Upgrade to unlock this feature."
User clicks any contractor action.
Owner: upgrade. Non-owner: contact owner message.
EM-7
Trial user attempts to purchase an extra seat
"Extra seats are available only on paid plans. Subscribe to continue, and you can add extra seats as part of your subscription." with Subscribe CTA.
Trial user tries to invite beyond included trial seats.
User subscribes first, then adds seats.
EM-8
System fails to load Plan Usage Matrix (all tiles)
"We couldn't load your plan usage. Please refresh the page or try again later."
Usage API returns an error for all tiles.
User refreshes the page.
EM-9
System partially fails to load Plan Usage Matrix
"Unable to load [Tile Name]. Retry" with retry link on affected tiles only.
Usage API returns an error for specific tiles only.
User clicks retry on the failed tile.
EM-10
Unauthorized role attempts to access Subscription page
"You do not have permission to view this page."
Project Manager / Editor / Contractor hits Subscription URL.
User returns to their dashboard.
EM-11
User on suspended account attempts to access Subscription page
Routes to the billing update screen per FRD 7.
Account is in suspended state.
User updates payment on billing page.
EM-12
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
User retries or contacts support.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
An agency is on Basic with 2 included seats and both are filled; the owner adds a third member.
System prompts the owner to purchase an extra paid seat at nine dollars per month; member is added only after payment confirmation.
EC-2
An agency is on the Free plan and the owner tries to create a sixth project.
System blocks creation and shows the 5-project limit message with the Upgrade CTA; the project is not created.
EC-3
An agency downgrades from Essentials to Basic; at the cycle end, 2 brands are active.
System enforces the 1-brand limit at cycle end; the owner has already selected which brand to keep during the downgrade wizard, and the other brand is locked.
EC-4
An agency is on Essentials with 25 contractors and the user upgrades to Studio.
All 25 contractors remain active because Studio supports unlimited contractors.
EC-5
An agency is on Studio and the owner downgrades to Essentials.
At cycle end, the first 20 most recently created contractors are retained and any additional contractors are locked per FRD 3 rules.
EC-6
An agency admin opens the Subscription page.
All fields are rendered read-only; no action buttons are visible; the Payment Method section is hidden entirely; the Plan Usage Matrix is displayed as informational content.
EC-7
A non-owner user such as a Project Manager clicks a direct Subscription URL.
System returns a permission-denied page and redirects the user back to their accessible dashboard.
EC-8
The Plan Usage Matrix count changes between page loads because a team member was added in another session.
On tab focus, the usage tiles are polled and refreshed to reflect the latest counts.
EC-9
The Contractors tile is hidden on Basic; the owner upgrades to Essentials.
Immediately after the upgrade succeeds, the Contractors tile appears with the current count against 20 as the limit.
EC-10
A trial user views the Subscription page.
Top card shows the trial plan with days remaining, trial badge, and "Subscribe to [Plan]" / "View all plans" buttons instead of the standard controls.
EC-11
A Free user has an existing brand locked from a past downgrade and tries to create a new brand.
System blocks creation because the Free plan allows only 1 brand and a locked brand still counts toward the total; prompt asks to upgrade.
EC-12
A user creates projects until the Free limit is reached, then some projects move to the Archived or Cancelled status, and the user tries to create a new project.
System recounts using only projects in Booked or post-event pipeline stages; creation is allowed because Archived and Cancelled projects do not count.
EC-13
Projects exist under a locked brand and the user is on the Free plan.
The Projects tile still counts those projects toward the 5-project limit; the user must delete projects or upgrade to create new ones.
EC-14
The Plan Usage Matrix API times out for all tiles.
All tiles show a skeleton loader; if the retry fails, the error message "We couldn't load your plan usage. Please refresh the page or try again later." is displayed.
EC-15
The Plan Usage Matrix API fails for one tile only.
The successful tiles render their counts; the failed tile shows an inline "Unable to load. Retry" message with a retry link.
EC-16
User reaches multiple limits at the same time, for example both brands and seats.
The warning banner message dynamically lists all breached limits, for example "You've reached the limit on Brands and Seats".
EC-17
Agency is on Essentials, owner adds a paid seat, then later downgrades to Basic; at cycle end the extra paid seat should carry forward.
Per FRD 5 rules, paid extra seats carry forward to the downgraded plan at nine dollars per month until the owner deletes them.
EC-18
A user signed up with a referral link and also has a 50% first-year promo eligibility.
Promo applies first on the base plan price, then referral discount applies on the already-discounted amount, and finally any agency-applied coupon applies on top of that.
EC-19
A contractor is assigned to two agencies, one is on Essentials and one is on Basic.
The Essentials agency's Contractors tile counts the contractor toward its 20-contractor limit; the Basic agency does not show the Contractors tile since Basic does not support contractors.
EC-20
An agency is on Studio and the user views the Subscription page.
No Upgrade Plan button is shown anywhere; only Downgrade, Cancel, billing cycle switch, and seat management options are available.
EC-21
An agency is suspended due to failed payment and the owner opens the Subscription page.
The standard Subscription page is not rendered; the owner is routed to the billing update screen per FRD 7.
EC-22
An agency has both a scheduled downgrade and a scheduled Annual-to-Monthly cycle switch.
Both informational messages are displayed on the Subscription page with their respective "Cancel" actions.
9. Acceptance Criteria
- The Subscription page renders the correct plan details, payment method, seat count, billing cycle, promotional pricing (if applicable), Stripe fee information, and Plan Usage Matrix for the agency owner.
- The Plan Usage Matrix displays four tiles (Projects, Brands, Seats, Contractors) with correct counts that reflect real-time usage based on the defined counting rules.
- The Contractors tile is hidden on Free and Basic plans and is visible on Essentials and Studio.
- The warning banner appears when any tile reaches one hundred percent of its limit and hides when all tiles drop below one hundred percent.
- The banner's CTA buttons route correctly, with "Add seat" opening the Invite Team Member modal and "Upgrade Plan" opening the Manage Subscription page.
- The agency admin can view the Subscription page in read-only mode without any action buttons for plan changes or payment management, and the Payment Method section is hidden entirely from the admin view.
- Non-owner users such as Project Manager, Supervising Editor, and Editor cannot access the Subscription page at all.
- Restricted features display upgrade prompts instead of being hidden from the interface.
- Feature-gating prompts display the correct message for owners and for non-owners.
- The Plan Usage Matrix refreshes on page load, on tab focus, and after any usage-affecting action.
- The Contractors tile appears immediately after an upgrade from Basic to Essentials without requiring a page reload.
- All plan limits are enforced consistently across every resource creation flow for projects, brands, seats, and contractors.
- A trial user sees trial-specific controls on the Subscription page in place of the standard plan controls.
- A trial user cannot purchase extra seats, and any attempt prompts the user to subscribe first.
- The fifty percent promotional pricing is displayed correctly on the plan selection screen with the original price struck through and the discount badge.
- Stripe transaction fees per plan are displayed on each plan card.
- The sales tax disclaimer note is displayed on the plan selection screen.
- The Studio plan does not display any Upgrade Plan button since it is the highest tier.
- Scheduled downgrades and scheduled cycle switches display informational messages with appropriate "Cancel" actions under the plan details.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Required to identify the agency owner and enforce role-based access to the Subscription page.
Subscription page cannot load; user cannot be authorized.
Role & Permission Module
Hard
Provides the fixed role list (Owner, Admin, Project Manager, Supervising Editor, Editor) and their permission mappings.
Role-based visibility rules cannot be enforced.
Project Management Module
Hard
Provides real-time counts of active projects (Booked + post-event pipeline stages) for the Projects tile.
Projects tile cannot be rendered; count defaults to unknown state.
Brand Management Module
Hard
Provides real-time counts of active brands for the Brands tile.
Brands tile cannot be rendered.
Team Management Module
Hard
Provides real-time counts of active team members for the Seats tile.
Seats tile cannot be rendered.
Contractor Management Module
Hard (Essentials+)
Provides real-time counts of active contractors for the Contractors tile.
Contractors tile cannot be rendered on Essentials or Studio.
Stripe Billing Integration
Hard
Provides plan subscription state, billing cycle, payment status, and Stripe Tax calculation.
Plan details cannot be confirmed; page may render with stale data.
Stripe Tax
Hard
Calculates applicable sales tax at checkout based on the billing address.
Tax cannot be calculated; checkout is blocked.
Referral Module
Soft
Provides referral discount eligibility and amount.
Referral discount is not applied; promo and coupon still function.
Gawd Portal (Super Admin)
Soft
Configures trial durations, creates discount codes, and applies discounts directly to agencies.
Agency side continues to function with current subscription state.
Manage Subscription Page (FRD 3)
Navigation
Destination for the Upgrade Plan, Change Plan, and plan-change-related CTAs.
CTA destination becomes unreachable.
Invite Team Member Modal (FRD 5)
Navigation
Destination for the Add Seat CTA.
CTA destination becomes unreachable.
Failed Payment Management (FRD 7)
Navigation
Routes suspended agencies to the billing update screen.
Suspended agencies cannot update payment.
Notification Module
Soft
Delivers in-app notifications about plan-related events.
Users miss in-app notifications; email path continues to work.
12. References
2. Free Trial
Free Trial
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 23 April 2026
Status:
Version 2.0
FRD 2 — Free Trial
Module: Free Trial Version: 2.0 Date: April 23, 2026
1. Module Overview
Module Name: Free Trial
Purpose: This module defines the 14-day free trial lifecycle for new Pixally CRM agencies. It governs trial eligibility, trial plan selection at signup, email verification gating during the trial, trial reminder communications, feature access during the trial, trial expiry behavior, explicit trial cancellation by the agency owner, and the automatic trial reset for returning users managed via the Gawd Portal. The module ensures that prospective agencies can evaluate Pixally CRM features for fourteen days without requiring a credit card, while providing a clear conversion path to paid subscriptions.
Business Goals: The Free Trial module drives new-user acquisition and conversion by offering risk-free access to premium plan features. It balances low friction at signup (no credit card required) with robust email verification enforcement to protect platform integrity. The trial experience is designed to educate the user on the value of paid plans, encourage timely conversion through scheduled reminder emails, and provide a graceful fallback to the Free plan for users who do not convert. Returning expired-trial users are automatically offered a fresh trial every three months on their return to recapture lost engagement.
2. User Roles & Permissions
Role
Start Trial
View Trial Banner
Convert to Paid
Explicitly Cancel Trial
Extend Trial
Access Trial Features
Agency Owner (new signup)
Yes
Yes (with CTA)
Yes
Yes
No
Per trial plan
Agency Admin
No
Yes (informational)
No
No
No
Per trial plan
Project Manager
No
Yes (informational)
No
No
No
Per trial plan
Supervising Editor
No
Yes (informational)
No
No
No
Per trial plan
Editor
No
Yes (informational)
No
No
No
Per trial plan
Contractor
N/A
N/A
N/A
N/A
N/A
Contractor portal only
Client
N/A
N/A
N/A
N/A
N/A
Client portal only
Pixally Super Admin (Gawd Portal)
N/A
N/A
N/A
Yes
Yes
N/A
3. User Flow
3.1 The prospective agency user visits the Pixally marketing website and clicks the "Start 14-Day Free Trial" call-to-action on one of the three paid plan cards (Basic, Essentials, or Studio), or proceeds directly to the signup page without selecting any plan.
3.2 The marketing website carries the selected plan identifier into the signup URL as a query parameter so that the signup form knows which plan the user intended to trial.
3.3 The user completes the signup form by entering their email address, password, and agency details, and submits the form.
3.4 The system validates the email for uniqueness across all Pixally agencies and against the promo usage history log, and creates the agency account.
3.5 The system assigns the selected plan as the trial plan; if no plan was selected, the system defaults the trial plan to Studio to give the user exposure to the highest-tier features.
3.6 The system starts the 14-day trial clock from the signup timestamp and redirects the user to the Pixally CRM dashboard.
3.7 The system displays the trial countdown banner at the top of every dashboard page showing the number of days remaining in the trial along with a call-to-action to purchase a subscription, with banner color logic defined in the Dashboard FRD.
3.8 The system sends a verification email to the user's signup email address with a verification link that is valid for 7 days from the time of sending.
3.9 The user explores the Pixally CRM dashboard and all features included in the trial plan without having to verify their email for the first seven days.
3.10 The system evaluates the user's verification status daily, and if the user has not verified their email within seven days of signup, the system restricts all portal access on day eight.
3.11 The user who has not verified their email by day eight is routed to a dedicated email verification screen that displays a "Resend verification email" call-to-action and cannot access any other part of the portal until verification is completed.
3.12 The user clicks the verification link in the email, completes verification, and the system restores full trial access immediately regardless of which day of the trial they are on.
3.13 The system sends scheduled pre-expiry reminder emails on Days 10, 12, and 14 encouraging the user to subscribe before trial expiry.
3.14 The user clicks the "Subscribe to [Plan]" or "View all plans" call-to-action from the trial banner or the Subscription page to initiate a paid subscription.
3.15 If the user has not verified their email at the time of subscription attempt, the system redirects them to the email verification screen and, after successful verification, automatically returns them to the checkout flow.
3.16 The user completes payment via the Stripe checkout flow and the system converts the trial account to a paid subscription with the selected plan, billing cycle, and payment method.
3.17 On successful conversion, the system cancels all pending trial reminder emails including the post-expiry reminders.
3.18 If the user does not convert and does not explicitly cancel by the end of Day 14, the system automatically downgrades the account to the Free plan at the start of Day 15 and enforces Free-plan limits on projects, brands, team members, and contractors.
3.19 The system displays the "Trial Ended" banner on the dashboard with the "Continue with Free plan" acknowledgement flow as defined in the existing Dashboard FRD for the Trial Ended Banner.
3.20 The system sends post-expiry reminder emails on Days 15, 20, and 25 (counted from the trial end date) prompting the user to subscribe to a paid plan.
3.21 The expired-trial user who logs into the portal after at least three months have passed since their last trial ended automatically receives a fresh 14-day trial starting from the login date.
3.22 The Pixally Super Admin (Gawd Portal) can manually extend an active trial or reset an expired trial, which triggers the system to recalculate the new trial end date and reschedule all pending reminder emails accordingly.
4. Functional Logic
4.1 Trial Eligibility and Plan Assignment
- The Free Trial is available to agencies signing up to Pixally CRM with an email address that is either new to the platform or belongs to a previously hard-deleted account whose data has been permanently removed.
- The three paid plans (Basic, Essentials, and Studio) are eligible for the 14-day free trial; the Free plan is not eligible for any trial because it is itself a permanent free plan.
- If the user selects a specific plan on the marketing website before signup, that plan becomes the trial plan assigned to the agency account via a query parameter carried into the signup form.
- If the user signs up without selecting any plan, the system automatically assigns the Studio plan as the default trial plan to give the user exposure to the highest-tier features.
- The trial plan is locked at signup and cannot be changed to trial a different tier during the trial period; however, the user may subscribe to any paid plan at any time by navigating to the View All Plans screen.
- A user who has previously used the 50% first-year promotional offer is permanently ineligible to use the promo again on any fresh signup with the same email address, even after hard deletion of the original account; this email-level ineligibility persists forever and is tracked in the promo usage history log.
4.2 Trial Clock and Duration
- The trial duration is exactly 14 calendar days starting from the signup timestamp.
- The trial end date is calculated as the signup timestamp plus 14 days, and this date remains fixed regardless of when the user verifies their email.
- Verifying email on Day 7 does not reduce the trial duration; the trial still ends on the original Day 14 calculated from signup.
- The trial clock continues to run even when the user's dashboard access is restricted due to unverified email after Day 7.
4.3 No Credit Card Requirement
- The system does not require a credit card or any payment method to start the 14-day trial.
- A payment method is required only when the user initiates a paid subscription, either during the trial or after trial expiry.
4.4 Email Verification Gate
- The system sends a verification email to the user's signup email address immediately after account creation, containing a verification link that expires 7 days from the time of sending.
- The user can access the full Pixally CRM dashboard and all features included in the trial plan for the first seven days of the trial without verifying their email.
- If the user does not verify their email by the end of Day 7, the system restricts all portal access starting from Day 8 and displays only the email verification screen.
- The restriction from Day 8 onward blocks access to every module of the CRM including the dashboard, projects, clients, invoices, proposals, calendar, and all other functionality.
- The email verification screen contains a "Resend verification email" call-to-action that triggers the system to send a new verification email to the registered address.
- The "Resend verification email" action is rate-limited to one send per minute and a maximum of five sends per day per agency to prevent abuse.
- Once the user completes email verification, the system immediately restores full trial-plan access regardless of which day of the trial it is.
- If the user attempts to subscribe to a paid plan at any time during the trial while their email is not yet verified, the system redirects them to the email verification screen, and after successful verification, the system automatically returns them to the checkout flow without requiring any additional action.
- If the verification email bounces or is undeliverable, the system flags the email as undeliverable, displays a banner to the user on next login stating "We couldn't deliver your verification email. Please contact support.", and continues to serve the verification screen until the user updates their email or resolves delivery.
4.5 Trial Feature Access
- During an active trial, the user has access to all features included in the assigned trial plan as defined in FRD 1 Section 4.3.
- Team member invites during the trial are permitted up to the trial plan's included seat count; for example, a Studio trial allows unlimited team member invites, an Essentials trial allows up to three team members, and a Basic trial allows up to two team members.
- The trial user cannot purchase extra paid seats during the trial period; if the trial user attempts to invite a team member beyond the included seat count, the system prompts the user to first subscribe to a paid plan, after which the extra seat purchase can be completed as part of the same flow.
- All plan-specific features such as Client Portal, Proposals and Contracts, Invoices and Payments, Contractor Management, QuickBooks Integration, Post Production Management, Expense Management, Advanced Reports, Priority Support, and SMS Reminders are accessible according to the trial plan's entitlements.
- Proposals and contracts sent during the trial are legally valid and persist after trial expiry; invoices created and payments collected during the trial are retained in the agency's records.
- If the agency converts to a paid plan after the trial, all trial-created data (projects, clients, invoices, proposals, contracts) carries over seamlessly.
- If the agency falls back to the Free plan after trial expiry, all trial-created data is retained but access to data is restricted by the Free plan's limits (for example, projects beyond the 5-project limit are locked, brands beyond 1 are locked, and so on per FRD 1 rules).
4.6 Trial Countdown Banner
- The trial countdown banner appears at the top of every dashboard page for all users of the agency during an active trial.
- The banner displays the number of days remaining in the trial and a "Choose Plan" call-to-action that routes to the Manage Subscription pricing page.
- The banner color logic (including thresholds, color codes, and visual states) is defined in the Dashboard FRD under the Trial Banner specification; this module does not duplicate that specification.
- Non-owner users doesn’t see the banner
- The banner is always visible and cannot be dismissed by the user during the trial period.
4.7 Subscription Page Behavior During Trial
- The Subscription page top summary card during an active trial displays the trial plan name, a "Free trial" badge, the number of days remaining, a plan description, a "Subscribe to [Plan]" call-to-action, a "View all plans" call-to-action, and a "Cancel Trial" option for the agency owner.
- The Subscription Receipts section displays an empty state with the message "No receipts yet — Your payment history will appear here once your trial ends and billing begins."
- The Plan Usage Matrix is displayed during the trial showing current usage against the trial plan's limits.
- The Payment Method section displays an "Add Payment Method" call-to-action since no payment method has been collected yet.
- The Annual Subscription section displays a "Choose Annual" call-to-action highlighting the annual billing cycle benefit.
- If the user clicks "Subscribe to [Plan]", the system routes to the checkout flow for the trial plan pre-selected.
- If the user clicks "View all plans", the system routes to the Manage Subscription pricing page where the user can select any plan and billing cycle.
4.8 Trial Reminder Email Schedule
- The system sends three pre-expiry reminder emails on Days 10, 12, and 14 of the trial (counted from the signup date) to prompt the user to subscribe before the trial ends.
- The system sends three post-expiry reminder emails on Days 15, 20, and 25 of the trial (counted from the signup date, equivalent to 1, 6, and 11 days after trial end) to users whose trial has expired without conversion and who have not yet subscribed to a paid plan.
- All reminder email day numbers are counted from the signup date and are automatically recalculated if the Pixally Super Admin extends the trial end date.
- The reminder schedule (the number of reminders and the specific days on which they are sent) is dynamically configurable from the backend via the Gawd Portal and is not hardcoded in the system.
- The email templates for each reminder contain the trial plan name, the days remaining or days since expiry, a call-to-action to subscribe, and a link to the Subscription page.
- Reminder emails are delivered by the Notification Module using the email channel, and corresponding in-app notifications are also shown in the Pixally notification center.
- When the user successfully converts to a paid subscription, the system cancels all scheduled future reminders for that agency.
- When the Pixally Super Admin extends the trial period via the Gawd Portal, the system recalculates the new trial end date and reschedules all pending reminder emails based on the new end date.
- If an email delivery bounces, the system logs the bounce and does not retry the bounced email; the next scheduled reminder in the sequence is attempted normally.
4.9 Trial Expiry and Fallback to Free Plan
- If the user does not convert to a paid subscription and does not explicitly cancel the trial by the end of Day 14, the system automatically downgrades the account to the Free plan at the start of Day 15.
- At the moment of downgrade, the system enforces Free plan limits of 5 active projects, 1 team member, 1 brand, and zero contractors, and locks all features not included in the Free plan.
- If the agency has more than the Free plan allows in terms of projects, team members, brands, or contractors at the time of expiry, the system does not delete any resources; instead, it locks the excess resources and displays them with a lock icon until the user subscribes to a supporting plan.
- The "Trial Ended" banner and the "Continue with Free plan" acknowledgement modal flow on the dashboard are defined in the existing Dashboard FRD; this module references that specification without duplication.
- The user continues to receive the three post-expiry reminder emails on Days 15, 20, and 25 until they either convert to a paid plan, or until the reminder schedule completes.
4.10 Trial Extension by Pixally Super Admin
- The Pixally Super Admin can manually extend an active trial via the Gawd Portal by adding additional days to the existing trial end date.
- When a trial is extended, the system updates the trial end date, recalculates the remaining days for the banner, and reschedules all pending pre-expiry and post-expiry reminder emails based on the new end date.
- Only Pixally Super Admins (Gawd Portal users) have the authority to extend a trial; agency owners and other roles cannot extend their own trials.
- The Pixally Super Admin can also extend a trial that has already expired, which restores the account from Free plan back to the original trial plan with the new trial end date.
4.11 Automatic Trial Reset for Returning Expired-Trial Users
- When a user whose trial has previously expired without conversion logs into the Pixally CRM portal after at least three months (90 days) have passed since their last trial ended, the system automatically starts a new 14-day trial from the login date.
- The three-month cooldown is measured from the most recent trial end date, regardless of whether the user has logged in during that period.
- The automatic reset is triggered on a qualifying login event and does not require any Pixally Super Admin action.
- All standard trial behaviors (banner, reminder schedule, feature access, email verification state) apply to the new trial as if it were a fresh trial.
- The automatic reset is recurring: every three months after each expired trial, a qualifying login triggers another fresh 14-day trial.
- The 50% promotional offer is for the client who has never taken any subscription and purchasing for the first time irrespective of how many trials they took.
4.12 Trial State Tracking in Gawd Portal
- The Pixally Super Admin has visibility into all trial users via the Gawd Portal, including users currently on an active trial, users whose trial has expired without conversion, users who have converted to paid subscription, and users who are on the Free plan after trial expiry.
- The Gawd Portal allows the Super Admin to extend active trials, reset expired trials manually, cancel trials, and delete fake or spam accounts.
- The detailed Gawd Portal behavior is defined in the separate Gawd Portal FRD series; this module only describes the agency-side impact.
4.13 Trial Purchase Edge Behavior
- If the user initiates a subscription purchase at any time before the trial end, the subscription takes effect after the trial ends.
- If the user purchases on Day 14 at any time before midnight (in the agency's local timezone), the subscription is processed successfully,subscription starts after trial ends, and the Day 15 post-expiry email is cancelled.
- The billing cycle of the new subscription begins from the purchase date, not from the trial start date, so the user effectively receives the full 14-day trial plus a full billing period.
4.14 Marketing Website Plan Selection Handoff
- When the user clicks "Start 14-Day Free Trial" on a specific plan card on the Pixally marketing website, the website redirects to the signup form with a plan query parameter (for example, ?plan=essentials&cycle=monthly).
- The signup form reads the query parameter and pre-associates the trial account with the selected plan on successful signup.
- If the query parameter is missing, malformed, or references an invalid plan, the system falls back to assigning Studio as the default trial plan.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Trial Plan Name
Read-only text
Displays the assigned trial plan (Basic, Essentials, or Studio).
Trial Badge
Read-only badge
Displays "Free trial" on the Subscription page during an active trial.
Trial Days Remaining
Read-only integer
Range: 0 to 14. Calculated as (trial_end_date − today).
Signup Email
Email text
Required. Must be a valid email format. Uniqueness enforced across all active Pixally agencies.
Email Verification Status
Boolean
Values: Verified / Not Verified / Bounced.
Email Verification Deadline
System-derived date
signup_date + 7 days. Used to enforce Day 8 restriction.
Verification Link Expiry
System-derived datetime
Link-send-timestamp + 7 days. After this, link is invalid.
Trial Start Date
System-derived datetime
Set at signup timestamp. Not editable.
Trial End Date
System-derived or admin-extended datetime
trial_start_date + 14 days at signup. Can be extended by Pixally Super Admin.
Trial Expired Flag
Boolean
Set to true at Day 15 or on explicit cancellation. Consumed by Dashboard FRD for Trial Ended Banner.
Trial Acknowledged Flag
Boolean
Set to true when user acknowledges "Continue with Free plan" in the Trial Ended Banner modal; see Dashboard FRD.
Auto-Reset Eligibility
System-derived Boolean
True if current date ≥ last_trial_end_date + 90 days and user has no active paid subscription.
Last Trial End Date
System-derived datetime
The trial_end_date of the most recent trial; used for auto-reset cooldown calculation.
Subscribe to [Plan] CTA
Button
Visible only to Owner. Opens checkout for the trial plan.
View All Plans CTA
Button
Visible only to Owner. Opens the Manage Subscription pricing page.
Resend Verification Email CTA
Button
Visible on the email verification screen. Rate-limited to one send per minute and ten sends per day per agency.
Reminder Email Schedule
Backend configuration
Dynamic values editable only via Gawd Portal. Default: Day 10, 12, 14 (pre), Day 15, 20, 25 (post), all counted from signup date.
Plan Query Parameter
URL parameter
Format: ?plan=<plan_name>&cycle=<monthly|annual>. Optional. Invalid values fall back to Studio default.
Promo Usage History
System-level log
Tracks email addresses that have ever used the 50% first-year promo. Used to block re-use forever.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Trial started
"Your 14-day free trial of [Plan] has started. Explore all the features your trial includes."
Agency account created via signup.
Dashboard loaded with trial banner; verification email sent.
SM-2
Email verified
"Your email has been verified. Welcome to Pixally!"
User clicks verification link successfully.
Full trial-plan access restored.
SM-3
Trial converted to paid
"Welcome to Pixally [Plan]! Your subscription is now active."
Subscription payment successful.
Trial banner hidden; receipt generated; reminders cancelled.
SM-4
Trial extended by Super Admin
"Your trial has been extended. You now have [X] days remaining."
Gawd Portal admin extends trial.
Banner updated; reminders rescheduled.
SM-5
Automatic trial reset on return
"Welcome back! We've given you a fresh 14-day trial of [Plan] to continue exploring Pixally."
Previously-expired user logs in after 90+ days since last trial end.
Trial banner re-displayed with 14 days.
SM-6
Verification email resent
"A new verification email has been sent to [email]. Please check your inbox."
User clicks Resend Verification Email.
Verification email re-sent.
SM-7
Explicit trial cancellation
"Your trial has been cancelled. You are now on the Free plan."
Owner confirms Cancel Trial popup.
Account moved to Free plan; pre-expiry reminders cancelled.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
User attempts to add a team member beyond trial plan's included seats
"Extra seats are available only on paid plans. Subscribe to continue, and you can add extra seats as part of your subscription." with Subscribe CTA.
Trial user tries to invite beyond included seats.
User subscribes first, then adds seats.
EM-2
User attempts access on Day 8+ without email verification
Full-screen verification prompt: "Please verify your email to continue using Pixally." with Resend and Log Out CTAs.
Day 8 reached without verification.
User verifies email to regain access.
EM-3
User clicks Resend Verification repeatedly within the rate-limit window
"Please wait before requesting another verification email. You can resend in [X] seconds."
Resend clicked within one-minute window.
User waits and retries.
EM-4
User exceeds daily verification resend limit
"You've reached the daily resend limit. Please check your inbox or contact support."
More than ten resends in one day.
User contacts support.
EM-5
Signup email is already in use
"This email is already associated with a Pixally account. Please sign in or use a different email."
Signup attempt with existing active email.
User signs in or uses new email.
EM-6
Verification link expired or invalid
"This verification link has expired or is invalid. Please request a new one." with Resend CTA.
User clicks expired link (older than 7 days) or invalid link.
User requests new verification email.
EM-7
Verification email bounced or undeliverable
"We couldn't deliver your verification email to [email]. Please contact support."
Email service returns bounce notification.
User contacts support or updates email via support.
EM-8
System fails to create the trial account
"We couldn't start your trial right now. Please try again or contact support."
Account creation API fails.
User retries signup.
EM-9
User tries to change trial plan during trial
"Your trial plan is fixed for the trial period. You can subscribe to a different plan at any time from View All Plans."
User attempts to switch trial tier.
User subscribes to a different plan if desired.
EM-10
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
User retries or contacts support.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
User signs up from the marketing website without selecting a plan.
System assigns the Studio plan as the default trial plan and starts the 14-day clock.
EC-2
User clicks marketing CTA with a malformed or invalid plan query parameter (e.g., ?plan=xyz).
System ignores the invalid parameter and falls back to Studio as the default trial plan.
EC-3
User verifies email exactly on Day 7 at 23:59.
Trial access continues uninterrupted; the Day 8 restriction does not trigger; 7 trial days remain.
EC-4
User verifies email on Day 10 (after Day 8 restriction already applied).
Access is fully restored immediately upon verification; the trial clock has continued to run and only 4 days remain.
EC-5
User does not verify email for the entire 14-day trial.
Trial expires as usual on Day 15; account moves to Free plan; the email is still flagged as unverified and verification is required before subscribing to any paid plan.
EC-6
User subscribes at 11:58 PM on Day 14 (agency local timezone).
Subscription processed successfully; trial is terminated; Day 15 post-expiry email is cancelled; billing cycle begins from the subscription date.
EC-7
User on Studio trial wants to purchase Basic.
User navigates to the Subscription page, clicks "View all plans", selects Basic, and completes checkout; the trial is terminated at payment.
EC-8
User on Basic trial wants to purchase Studio.
Same flow as EC-7; user selects Studio from View All Plans and checks out.
EC-9
Pixally Super Admin extends an active trial by 10 additional days on Day 12.
Trial end date is updated from Day 14 to Day 24; banner updates to show 12 days remaining; pre-expiry reminders are rescheduled to Days 20, 22, 24 and post-expiry to Days 25, 30, 35.
EC-10
Pixally Super Admin extends an expired trial (user is already on Free plan).
Account is restored to the original trial plan with the new trial end date; reminder emails are scheduled based on the new end date.
EC-11
Trial user tries to invite a fourth team member on Basic trial.
System blocks the invite and shows the "Extra seats are available only on paid plans" message with Subscribe CTA.
EC-12
Expired-trial user logs in after 90+ days since their last trial ended.
System automatically starts a new 14-day trial from the login date with the same trial plan; all trial behaviors apply as if it were a fresh trial.
EC-13
Expired-trial user logs in 60 days after their last trial ended (before the 90-day cooldown).
No auto-reset triggers; user remains on the Free plan until the cooldown is met on a future login.
EC-14
Expired-trial user receives multiple auto-resets across time (e.g., every 3 months).
System allows recurring auto-resets as long as the 90-day cooldown is met; 50% promo remains permanently blocked.
EC-15
Admin or team member of an active-trial agency logs in.
They see the trial banner as informational content; they cannot initiate subscription purchases, extend the trial, or cancel the trial.
EC-16
User signs up, closes the browser without verifying, and returns on Day 10.
The trial countdown banner shows 4 days remaining; if Day 8 has passed, the user sees the verification screen only and must verify before accessing the dashboard.
EC-17
Pixally Super Admin deletes a fake trial account via Gawd Portal.
Account is removed; the associated email becomes available for re-signup; the email's promo usage history (if any) is retained and continues to block promo re-use.
EC-18
User signs up with an email that was previously hard-deleted.
Signup is allowed because the email has been released from the active-account uniqueness check; however, if the email is in the promo usage history log, the 50% promo remains permanently unavailable.
EC-19
Trial user attempts to upgrade to a different paid plan before the trial ends.
The upgrade flow routes the user to the checkout for the new plan; the trial is terminated at successful payment and the new plan subscription begins.
EC-20
Trial ends while the user is actively logged in on a session.
The session remains active but feature access is restricted to Free-plan limits on the next page load or API call; the Trial Ended banner is displayed per Dashboard FRD.
EC-21
User opens two browser tabs: one at Day 7 (full access) and one at Day 8 (restriction applies).
The Day 8 restriction is enforced on the next API call made from either tab; the Day 7 tab loses functionality on its next server request.
EC-22
Verification email bounces on first send.
System flags the email as bounced; the user sees a banner on next login; the user must contact support or update their email to proceed.
EC-23
User signs up, never logs in, and the signup timestamp is 5 days old.
Trial clock is still counting from signup; by Day 8 from signup, if the user logs in unverified, they are restricted to the verification screen.
EC-24
Trial user is invited to a second agency during their active trial.
The user's participation in the second agency is governed by that agency's subscription state; the user's own trial is unaffected.
9. Acceptance Criteria
- A new agency account starts a 14-day trial immediately on signup without requiring a credit card.
- If no plan is selected at signup, the Studio plan is assigned by default as the trial plan.
- The marketing website passes the selected plan to the signup form via a URL query parameter; invalid values fall back to Studio.
- The trial countdown banner displays the correct number of days remaining and follows the color logic defined in the Dashboard FRD.
- The user has full access to the trial plan's features for the first seven days without email verification.
- After seven days without verification, the user is restricted to the email verification screen only.
- Email verification immediately restores full trial-plan access regardless of which day it is completed.
- Verification link expires seven days from the time of sending; expired links trigger the Resend flow.
- The trial plan cannot be changed to trial a different tier during the trial period, but the user can subscribe to any plan at any time.
- Pre-expiry reminder emails are sent on Days 10, 12, and 14; post-expiry reminder emails are sent on Days 15, 20, and 25 counted from signup.
- The reminder schedule is dynamically configurable from the Gawd Portal backend and is not hardcoded.
- A trial that is extended by the Pixally Super Admin reschedules all pending reminders based on the new end date.
- On successful subscription conversion, all pending reminder emails are cancelled.
- The agency owner can explicitly cancel the trial before Day 14 via the Cancel Trial option with a confirmation popup.
- At Day 15 without conversion or explicit cancellation, the account is automatically downgraded to the Free plan and the Trial Ended banner is displayed per Dashboard FRD.
- Expired-trial users who log in after 90+ days since their last trial end receive an automatic fresh 14-day trial; auto-reset is recurring every 3 months.
- The 50% first-year promotional offer remains permanently blocked for any email that has used it before, across all future signups and auto-resets.
- Trial users cannot purchase extra paid seats and are prompted to subscribe first if they attempt to do so.
- Attempting to subscribe without a verified email redirects to the verification screen and returns to checkout after verification.
- Trial-created data (projects, clients, invoices, proposals, contracts) persists across trial expiry and conversion; locked-resource behavior follows FRD 1 rules on Free plan fallback.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Pixally Marketing Website
Navigation
Source of initial plan selection via URL query parameter.
Users must sign up without plan pre-selection; Studio default applies.
Authentication Module
Hard
Required for agency signup, login, email verification, and session management.
Trial cannot be initiated; users cannot sign up.
Role & Permission Module
Hard
Enforces role-based access to trial controls (only Owner can subscribe or cancel).
Non-owner restrictions cannot be enforced.
Notification Module
Hard
Delivers trial reminder emails and in-app notifications on the defined schedule.
Reminder emails cannot be sent; users miss key conversion prompts.
Email Service Provider
Hard
External email delivery for verification and reminder emails; reports bounces.
Emails are not delivered; verification flow breaks; bounce flag cannot be set.
Dashboard Module
Hard
Hosts the trial countdown banner and the Trial Ended banner including color logic and Continue with Free plan acknowledgement modal.
Banners cannot be displayed; users lose visibility of trial status.
Stripe Billing Integration
Hard
Handles payment collection when the user converts to a paid subscription.
Trial conversion to paid cannot be completed.
Stripe Checkout
Hard
Hosted checkout flow for trial-to-paid conversion and payment method collection.
Conversion payment flow is broken.
Subscription Plans Module (FRD 1)
Hard
Provides plan entitlements (features, limits) enforced during the trial.
Trial plan access rules cannot be enforced.
Manage Subscription Page (FRD 3)
Navigation
Destination for "Subscribe to [Plan]" and "View all plans" CTAs.
CTA destinations become unreachable.
Gawd Portal (Super Admin)
Hard
Configures reminder schedule, extends trials, resets expired trials, tracks trial users, and manages promo usage history.
Super Admin controls over trial lifecycle are unavailable; default schedule applies.
Background Job / Cron Service
Hard
Triggers daily evaluation of verification deadlines, trial expiry, auto-reset cooldown checks, and schedules reminder emails.
Trial expiry, verification gate, and auto-reset logic cannot execute on time.
Project, Brand, Team Member, Contractor Modules
Hard
Enforce trial plan limits at the moment of resource creation.
Trial plan limits cannot be enforced.
Referral Module
Soft
Tracks referral-based signups; may affect pricing at conversion.
Referral discount cannot be applied; trial itself is unaffected.
3. Upgrade & Downgrade
Upgrade & Downgrade
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 23 April 2026
Status:
Version 2.0
FRD 3 — Upgrade & Downgrade
Module: Upgrade & Downgrade Version: 2.0 Date: April 23, 2026
1. Module Overview
Module Name: Upgrade & Downgrade
Purpose: This module defines the end-to-end behavior for plan tier changes (upgrades and downgrades) in the Pixally CRM. It governs the Manage Subscription pricing page, plan comparison view, upgrade checkout flow, the multi-step downgrade wizard with team member and brand selection, proration calculations including the Year 1 blended formula for 50%-off promotional users, scheduled downgrade management, simultaneous plan-plus-cycle changes, and all associated confirmation popups, preview summaries, and success messages.
Business Goals: The Upgrade and Downgrade module is the primary revenue-conversion engine of Pixally CRM. It enables agency owners to seamlessly scale up to higher-tier plans when their business grows, and to scale down with clear visibility into what they will lose when budget or needs change. The module aims to make upgrades frictionless and immediate while treating downgrades with deliberate transparency — showing feature loss, billing impact, and resource locking so that the owner makes an informed decision. The module also preserves revenue continuity by scheduling downgrades at cycle end, carrying existing paid extra seats forward, and automatically reversing scheduled downgrades when the owner chooses to upgrade instead.
2. User Roles & Permissions
Role
View Manage Subscription
Upgrade Plan
Downgrade Plan
Cancel Scheduled Downgrade
Apply Coupon at Checkout
Agency Owner
Yes
Yes
Yes
Yes
Yes
Agency Admin
Yes (read-only)
No
No
No
No
Project Manager
No
No
No
No
No
Supervising Editor
No
No
No
No
No
Editor
No
No
No
No
No
Contractor
No
No
No
No
No
Client
No
No
No
No
No
Pixally Super Admin (Gawd Portal)
N/A
No (cannot change plan)
No (cannot change plan)
No
Yes (admin-applied discount only)
3. User Flow
3.1 Upgrade User Flow
3.1.1 The agency owner navigates to the Subscription page and clicks the "Change Plan" button from the top summary card, or clicks the "Upgrade Plan" call-to-action from the Plan Usage Matrix banner, or clicks an upgrade prompt from any feature-gated area of the portal.
3.1.2 The system displays a brief upgrade routing popup informing the owner that they will be taken to the plan comparison page, and on confirmation routes to the Manage Subscription pricing page.
3.1.3 The system loads the Manage Subscription page showing all four plans (Free, Basic, Essentials, Studio) with their features, Year 1 promotional prices, and Stripe transaction fees, along with the currently active plan labelled "Active Monthly" or "Active Yearly" and the "Most Popular" badge on Essentials where applicable.
3.1.4 The agency owner toggles between Monthly and Yearly billing cycles using the cycle toggle at the top of the pricing page to see prices for each cycle.
3.1.5 The agency owner clicks the "Upgrade to [Plan]" or "Switch to [Plan]" call-to-action on the target plan card.
3.1.6 The system performs a check for any existing scheduled downgrade on the account, and if one exists, displays a confirmation popup stating that the scheduled downgrade will be cancelled and asks the owner to confirm before proceeding.
3.1.7 The system opens the Price Summary preview popup showing the current plan's unused credit, the new plan's blended charge (Year 1) or simple charge (Year 2+), any Year 1 promotional discount breakdown, any applied coupon breakdown, the extra-seat credits if applicable, the final Due Today amount, and the Next Cycle Total.
3.1.8 The agency owner reviews the Price Summary, optionally enters a discount coupon code, and clicks the "Confirm and Pay [Amount]" call-to-action.
3.1.9 The system disables the Confirm button immediately on click to prevent duplicate submissions.
3.1.10 If the agency has a payment method on file, the system initiates the Stripe charge directly for the Due Today amount.
3.1.11 If the agency does not have a payment method on file, the system routes the owner to the Payment page to collect payment method details before processing the charge.
3.1.12 On successful payment, the system updates the subscription state to the new plan, sets the new billing anchor date (preserving the original anchor if the cycle is unchanged, or starting a new anchor from today if the cycle changed), unlocks all features of the new plan immediately, and cancels any previously scheduled downgrade.
3.1.13 The system displays the upgrade success popup with the message "You've unlocked more power" along with "Your plan has been upgraded to [Plan]. Access to premium features is now active." and a "Got It" call-to-action.
3.1.14 The system sends a confirmation email with the invoice attached and an in-app notification confirming the upgrade.
3.2 Downgrade User Flow — No Selection Required (Simple Path)
3.2.1 The agency owner navigates to the Manage Subscription page and selects a lower-tier plan or the Free plan.
3.2.2 The system evaluates the agency's current usage against the target plan's limits and determines that no manual selection is required because all currently plan-included team members fit within the target plan's included-seat count and all active brands fit within the target plan's brand limit.
3.2.3 The system displays the Confirm Plan Downgrade screen showing the list of features that will be lost at the end of the current billing cycle and the next-cycle pricing at the new plan.
3.2.4 The agency owner reviews the lost-features list and clicks "Confirm Downgrade".
3.2.5 The system schedules the downgrade to take effect at the end of the current billing cycle, displays a success confirmation, and returns the owner to the Subscription page where a scheduled-downgrade message and a "Cancel Downgrade" option appear under the plan details.
3.3 Downgrade User Flow — With Selection Required (Wizard Path)
3.3.1 The agency owner navigates to the Manage Subscription page and selects a lower-tier plan or the Free plan.
3.3.2 The system evaluates the agency's current usage against the target plan's limits and determines that manual selection is required because currently plan-included team members exceed the target plan's included-seat count, brands exceed the target plan's brand limit, or both.
3.3.3 The system opens the downgrade wizard with the applicable steps visible in the left sidebar: Step 1 (Team members) if team-member selection is needed, Step 2 (Brands) if brand selection is needed, and Step 3 (Summary) which is always present.
3.3.4 In Step 1, the system displays a dynamic metric row at the top with four values: Available (target plan's included-seat count), Used (count of members currently selected from the plan-included pool), Extra Seats (count of new paid extras the owner has opted into from the plan-included overflow), and Price (Extra Seats × $9.00).
3.3.5 In Step 1, the system displays the "Select who you want to keep" group containing members who were plan-included on the current plan, with Select or Selected toggles on each member row; the agency owner is pre-selected and cannot be deselected.
3.3.6 Below the "Select who you want to keep" group, the system displays the "Paid Extra Seats — Auto-Retained" section listing members who were already being paid as $9/mo extras on the current plan; each such member has a "Retained" status badge and no interactive control because these seats carry forward automatically and cannot be deselected from the wizard.
3.3.7 As the owner selects members beyond the target plan's included-seat count, those extra selections appear in the Extra Seats count of the metric row and the Price dynamically updates by $9.00 per additional selection.
3.3.8 The "Paid Extra Seats — Auto-Retained" section and its members do not count toward the metric row's Used or Extra Seats or Price totals because they are already being paid for on the current plan and are carried forward as an existing cost rather than a new downgrade-triggered charge.
3.3.9 The owner clicks "Next" to proceed to Step 2.
3.3.10 If the current plan is Studio and the target plan is Essentials, and the agency has more than 20 contractors, the system displays a popup on Next click informing the owner that the first 20 contractors by creation date will be retained and older contractors beyond 20 will be locked at cycle end; the owner acknowledges the popup to proceed.
3.3.11 In Step 2, the system displays a metric row with Available Brands (target plan's brand limit) and Used Brands (currently selected count), and a list of active brands with Select or Selected toggles; when the selected count equals the target limit, the remaining brand rows are disabled.
3.3.12 The owner clicks "Next" to proceed to Step 3.
3.3.13 In Step 3, the system displays a consolidated Summary with line items for the target plan base price, the new extra-seat count and monthly charge from Step 1 opt-ins, the auto-retained paid extras carried forward, any promotional discount breakdown, any prorated credit from the current cycle, the Total Due Today amount, and the Next Cycle Total.
3.3.14 The agency owner reviews the Summary and clicks the "Confirm and Pay [Amount]" call-to-action.
3.3.15 The system charges any immediate extra-seat proration (for new extras opted into from Step 1 overflow) to the existing payment method, schedules the plan downgrade to take effect at the end of the current billing cycle, and displays a success confirmation.
3.3.16 The system returns the owner to the Subscription page where the scheduled-downgrade message and a "Cancel Downgrade" option appear under the plan details.
3.4 Cancel Scheduled Downgrade Flow
3.4.1 The agency owner navigates to the Subscription page or the Manage Subscription page and sees a scheduled-downgrade message with a "Cancel Downgrade" option.
3.4.2 The agency owner clicks "Cancel Downgrade" and the system displays a confirmation popup.
3.4.3 The agency owner confirms and the system cancels the scheduled downgrade, removes all pending member and brand selections, discards any pending new-extra-seat opt-ins, and restores the current plan's full entitlements without any changes at cycle end.
3.4.4 The system displays a success message and notifies the owner via email and in-app notification.
3.5 Re-scheduling a Different Downgrade Flow
3.5.1 The agency owner, while already having a scheduled downgrade, navigates back to the Manage Subscription page and selects a different target plan.
3.5.2 The system detects the existing scheduled downgrade and displays a popup stating that the existing scheduled downgrade to [Previous Target] will be replaced with a downgrade to [New Target].
3.5.3 On confirmation, the system discards the previous scheduled downgrade, initiates the new downgrade flow starting with either the Confirm screen or the wizard based on target-plan-limit evaluation, and completes the new scheduled downgrade.
3.6 Upgrade When Scheduled Downgrade Exists Flow
3.6.1 The agency owner, while already having a scheduled downgrade, initiates an upgrade to a higher-tier plan.
3.6.2 The system displays a popup stating: "You currently have a scheduled downgrade. Upgrading will cancel the scheduled downgrade. Are you sure you want to continue?"
3.6.3 On confirmation, the system proceeds with the standard upgrade flow, and on successful payment cancels the scheduled downgrade and notifies the owner via email and in-app notification.
3.6.4 If the upgrade payment fails, the system leaves the scheduled downgrade intact and displays the payment failure message.
4. Functional Logic
4.1 Plan Change Timing Matrix
- A Monthly-to-Monthly upgrade (tier up) takes effect immediately with a prorated charge.
- A Monthly-to-Monthly downgrade (tier down) takes effect at the end of the current monthly cycle and is stored as a scheduled change until then.
- A Yearly-to-Yearly upgrade takes effect immediately with a prorated charge.
- A Yearly-to-Yearly downgrade takes effect at the end of the current annual cycle.
- A Monthly-to-Yearly change (regardless of tier change) takes effect immediately with the billing cycle anchor reset to today and a preview popup confirmation required before completion.
- A Yearly-to-Monthly change always takes effect at the end of the current annual cycle; the annual cycle must complete before the monthly cycle begins.
- Any downgrade-type change combined with a Yearly-to-Monthly switch executes at the end of the annual cycle as a combined scheduled change.
- Any upgrade-type change combined with a Yearly-to-Monthly switch executes the upgrade immediately while deferring the monthly cycle switch to the annual cycle end.
- A downgrade to the Free plan does not involve a billing cycle decision because the Free plan has no cycle; the downgrade is scheduled at the current cycle's end regardless of whether the current cycle is monthly or annual.
4.2 Upgrade Flow Entry Points
- The owner can initiate an upgrade from the "Change Plan" button on the Subscription page summary card.
- The owner can initiate an upgrade from the "Upgrade Plan" call-to-action in the Plan Usage Matrix warning banner.
- The owner can initiate an upgrade from any feature-gated prompt across the portal (for example, clicking Contractor Management on a Basic plan shows an upgrade prompt).
- All entry points route to the Manage Subscription pricing page with a brief routing popup before the transition.
- The Upgrade button is not shown anywhere on the portal when the active plan is Studio because Studio is the highest available tier; only downgrade and cycle-switch options remain available.
4.3 Proration Logic — Core Pricing Definitions
- Plan prices are configured with fixed values provided by the client for both Year 1 promotional rates and Year 2-and-beyond full rates.
- Annual price equals the monthly price multiplied by ten, so the user effectively pays for ten months and receives twelve months of coverage.
- The 50% off first-year promotional discount applies to Basic, Essentials, and Studio plans and is valid for 12 months from the subscription_start_date which is defined as the date of the first paid charge after trial conversion.
- The 50%-off promotional window is tracked per email address and cannot be reused even after account deletion and re-signup.
- After the 12-month promotional window ends, the user is charged the full Year 2 pricing starting from the next billing cycle.
4.4 Year Determination Logic
- On every plan change event, the system computes the current_year based on whether the current date is before or at-or-after the discount_phase_end_date.
- The discount_phase_end_date equals subscription_start_date plus 12 months.
- If the current date is earlier than the discount_phase_end_date, the user is considered to be in Year 1 and the blended formula applies to upgrade and cycle-change proration calculations.
- If the current date is equal to or later than the discount_phase_end_date, the user is considered to be in Year 2 or later and simple Year 2+ pricing applies without any blending.
- The months_used_on_monthly counter is measured as the decimal number of 30-day periods since subscription_start_date on the monthly billing cycle, and it supports fractional values (for example, 5.5 months) calculated as completed_months plus (days_into_current_month ÷ 30).
4.5 Upgrade Proration — Year 2+ (Simple)
- For an upgrade from one plan to another within the same billing cycle (Monthly to Monthly or Annual to Annual) after the 12-month promotional window, the system calculates unused_credit as the current plan's Year 2 price multiplied by the ratio of days_remaining to total_cycle_days.
- The system calculates the new plan debit as the target plan's Year 2 price multiplied by the ratio of days_remaining to total_cycle_days.
- The Due Today amount is calculated as the new plan debit minus unused_credit.
- The original billing anchor date is preserved for the upgraded subscription; the next full cycle continues on the original anniversary date.
- If the Due Today amount is zero or negative, no charge is taken today, a credit balance equal to the absolute value is created, and the credit is applied to the next renewal invoice automatically with access granted immediately.
- If the Due Today amount is greater than zero but less than $0.50, the entire amount is deferred to the next invoice rather than being charged today as a minimum.
4.6 Upgrade Proration — Year 1 with 50% Promo
- For an upgrade during the 12-month promotional window, the system uses the blended formula to compute the new plan charge to correctly reflect the user's mix of discounted and full-price time.
- The discounted_months value equals 12 minus months_used_on_monthly, and the full_price_months value equals months_used_on_monthly, both expressed as decimal values.
- The discounted_portion of the blended annual equals the new plan's Year 1 monthly rate multiplied by (discounted_months ÷ 12) multiplied by 10.
- The full_price_portion of the blended annual equals the new plan's Year 2 monthly rate multiplied by (full_price_months ÷ 12) multiplied by 10.
- The blended_annual equals discounted_portion plus full_price_portion.
- The unused_credit equals the current plan's Year 1 monthly rate multiplied by (days_remaining ÷ 30).
- The Due Today amount equals blended_annual minus unused_credit.
- The same negative-net and minimum-charge rules from Section 4.5 apply: negative nets create credit balances; nets between zero and $0.50 defer to the next invoice.
- After the upgrade completes, the annual cycle starts today, the discount_phase_end_date remains fixed from the original subscription_start_date, and the annual renewal date is set to today plus 12 months at the target plan's Year 2 annual price.
4.7 Upgrade Proration — Monthly to Monthly (Same Cycle)
- For a Monthly-to-Monthly upgrade, the system calculates proration at the daily rate of the current and target plans for the days remaining in the current monthly cycle.
- The original monthly billing anchor is preserved; the next full-month charge occurs on the original anniversary date at the target plan's appropriate rate (Year 1 or Year 2 based on the year determination logic).
- The negative-net and minimum-charge rules apply as defined in Section 4.5.
4.8 Upgrade Plus Monthly-to-Annual Simultaneously
- When the owner upgrades to a higher tier and simultaneously switches from monthly to annual billing, the system treats this as a single combined transaction with a new billing anchor.
- The blended-or-simple Year 1 or Year 2 logic from Sections 4.5 and 4.6 applies, and the unused_credit from the monthly cycle is subtracted from the blended annual charge.
- The new annual cycle starts today; the annual renewal date is set to today plus 12 months; the discount_phase_end_date remains unchanged from the original subscription_start_date.
- Access to the new plan's features is granted immediately on successful payment.
4.9 Upgrade Plus Annual-to-Monthly Simultaneously
- When the owner upgrades to a higher tier and simultaneously requests a switch from annual to monthly billing, the system immediately executes the upgrade at prorated annual rates (Year 1 blended or Year 2 simple, as applicable) and schedules the monthly cycle switch to take effect only at the end of the current annual cycle.
- The first monthly charge after the annual cycle ends uses Year 1 monthly pricing if the monthly cycle start date falls within the discount window, or Year 2 monthly pricing if the monthly cycle starts on or after the discount_phase_end_date.
- Access to the upgraded plan's features is granted immediately on successful payment.
4.10 Upgrade from Free to Paid Plan
- When a Free plan user upgrades to any paid plan, the system routes through the same upgrade flow with the Price Summary preview but does not apply any prorated-credit calculation since the Free plan has no per-day cost.
- The first charge equals the full target plan rate for the selected cycle (Year 1 promotional price if the user is eligible for the 50% promo, or Year 2 price otherwise).
- The subscription_start_date is set to the date of the first paid charge and defines the 12-month discount window.
- Access is granted immediately on successful payment.
4.11 Downgrade Timing and Scheduling
- All downgrade changes (paid-to-paid tier down, paid-to-Free, and Annual-to-Monthly switch) take effect at the end of the current billing cycle and are stored as scheduled downgrades until then.
- During the period between downgrade scheduling and execution, the current plan's entitlements remain in effect and the owner retains full access to all current plan features, resources, and integrations.
- Scheduled downgrades do not trigger any immediate charge refund; the owner's currently-paid cycle continues until its end.
- The only immediate charge that may occur at downgrade scheduling is the prorated charge for new extra seats that the owner has explicitly opted into in Step 1 of the wizard by selecting members beyond the target plan's included-seat count; existing paid extras already on the current plan are not re-charged at scheduling.
- The system does not enforce any rate limit on the frequency of plan changes or re-scheduling; an owner may upgrade, downgrade, cancel a scheduled downgrade, or re-schedule a different downgrade as many times as needed without artificial throttling.
4.12 Downgrade Evaluation — Simple vs Wizard Path
- On target plan selection, the system evaluates the agency's current plan-included team member count against the target plan's included-seat count, and the active brand count against the target plan's brand limit.
- If the current plan-included team member count is less than or equal to the target plan's included-seat count, the Team Members wizard step is skipped.
- If the current brand count is less than or equal to the target plan's brand limit, the Brands wizard step is skipped.
- If both Team Members and Brands steps are skipped, the system routes the owner directly to the simple Confirm Plan Downgrade screen with the features-lost list.
- If at least one of Team Members or Brands exceeds the target limit, the system opens the wizard with the applicable steps plus the Summary step.
- A downgrade to the Free plan does not include a Team Members step because the Free plan allows only one team member (the owner), who is always retained automatically; the Brands step is still required when the agency has more than one brand.
- The wizard skip/show evaluation considers only plan-included members in the comparison; existing paid extras (Pool A) are not counted in this evaluation because they are always auto-retained regardless of selection.
4.13 Downgrade Wizard — Step 1 Team Members (Two-Pool Model)
- Step 1 operates on two distinct member pools shown as separate sections within the same step.
- Pool A — Paid Extra Seats (Auto-Retained): Pool A contains all members who are already being paid as $9/mo extras on the current plan at the moment the downgrade is initiated; these members are displayed in a "Paid Extra Seats — Auto-Retained" section with a "Retained" status badge and no interactive Select, Deselect, or Remove control.
- Pool A Strict Rule: Pool A members cannot be deselected, removed, or otherwise modified from within the wizard; if the owner wants to remove any paid extra seat, they must do so separately via the Team Management module either before starting the downgrade flow or after the downgrade is scheduled and executes.
- Pool B — Plan-Included Members: Pool B contains all members who are currently occupying plan-included seats on the current plan; these members are displayed in the "Select who you want to keep" group with Select or Selected toggles on each row.
- Pool B Selection Logic: The owner must select which Pool B members remain in the target plan's included-seat slots; the agency owner is pre-selected in Pool B and cannot be deselected.
- Pool B Overflow Opt-In: If the owner selects more Pool B members than the target plan's included-seat count, each additional selection beyond the Available count is treated as a new paid extra seat at $9/mo and is added to the Extra Seats count in the metric row.
- Pool B Deselection: Pool B members that the owner does not select (and does not opt-in to pay for as new extras) are treated as deselected team members and are disabled (not deleted) at cycle end per Section 4.18.
- Metric Row Composition: The metric row at the top of Step 1 shows Available (target plan's included count), Used (count of Pool B members currently selected up to Available), Extra Seats (count of Pool B members selected beyond Available, i.e., new paid extras opted into during downgrade), and Price (Extra Seats × $9.00).
- Pool A Exclusion from Metric Row: The metric row Used, Extra Seats, and Price values do not include Pool A members because Pool A is an existing cost being carried forward and not a new downgrade-triggered charge; Pool A charges appear in Step 3 Summary .
- Dynamic Price Update: The Price value in the metric row updates in real time as the owner toggles Pool B selections above or below the Available count.
- Next Button Enabling: The "Next" button is enabled at any time after Step 1 is first rendered because the owner is always pre-selected and thus at least one member is always selected; there is no minimum-selection validation beyond the owner.
4.14 Downgrade Wizard — Contractor Handling on Studio to Essentials
- The contractor transition is automatic and not part of the wizard's manual selection flow.
- When the downgrade is Studio to Essentials and the agency has more than 20 contractors, the system retains the first 20 contractors by creation date (oldest first) and locks all additional contractors at cycle end.
- When the owner clicks "Next" on Step 1, the system displays a popup with the message: "You currently have [X] contractors. When your downgrade to Essentials takes effect, the first 20 contractors will be retained and [X − 20] older contractors will be locked. You can upgrade back to Studio at any time to restore all contractors."
- The owner must acknowledge the popup to proceed to Step 2.
- Contractor handling does not apply to downgrades where the current or target plan does not include contractor management (for example, Essentials to Basic locks the entire Contractor Management module without individual contractor selection).
4.15 Downgrade Wizard — Step 2 Brands
- The wizard Step 2 displays a metric row with Available Brands (target plan's brand limit) and Used Brands (currently selected count).
- A primary list titled "Select which brands you want to keep" displays all active brands with Select or Selected toggles.
- When the selected count reaches the target plan's brand limit, the unselected brand rows become disabled and cannot be selected.
- The "Next" button is enabled only when the selected count matches or is below the Available count.
4.16 Downgrade Wizard — Step 3 Summary
- The wizard Step 3 displays a consolidated Summary of the downgrade with line items for the target plan base price, any new extra-seat count and monthly charge opted into from Pool B overflow in Step 1, any auto-retained Pool A paid extras carried forward as a separate line, any promotional discount breakdown, any prorated credit from the current cycle, the Total Due Today, and the Next Cycle Total.
- The Summary also displays the Next Cycle section showing what the owner will be charged on the next billing date including target plan base, Pool A carried-forward extras, Pool B opted-in new extras, and any applicable promotional line.
- The "Confirm and Pay [Amount]" call-to-action completes the downgrade; clicking it charges any immediate proration for Pool B opted-in new extras to the payment method on file, schedules the plan downgrade, and records the pending selections.
- Once the downgrade is confirmed, the system stores the pending Pool B member selections, brand selections, Pool B new-extra opt-ins, and the Pool A carry-forward list in the scheduled downgrade record without applying any changes to the current plan until cycle end.
4.17 Downgrade to Free Plan
- A downgrade to the Free plan follows the same evaluation logic as any other downgrade and may or may not trigger the wizard depending on the current brand count.
- The Team Members wizard step is shown for downgrade to Free when the agency has more plan-included members than the Free plan's 1 included seat; Owner is pre-selected as the sole plan-included member, and Pool B overflow (all other plan-included members) is offered for opt-in as paid extra seats at $9/mo, identical to downgrades to Basic or Essentials.
- The Brands wizard step is triggered only if the agency currently has more than one brand.
- Pool A on Downgrade to Free: Existing Pool A members (paid extras at $9/mo on the current plan) automatically carry forward to Free and continue billing at $9/mo per seat after downgrade execution, identical to paid-to-paid downgrade behavior; Pool A members are not deselectable from the wizard.
- Pool B on Downgrade to Free: All Pool B members other than the owner are disabled at cycle end because the Free plan includes only the owner.
- Brands on Downgrade to Free: At downgrade execution, brands beyond the selected one are locked per Section 4.19.
- Projects on Downgrade to Free: Active projects beyond 5 are locked (not archived); they retain their data but become inaccessible until the agency upgrades back to a plan with higher limits.
- Contractors on Downgrade to Free: Contractors cannot be migrated because Free does not support contractors; all contractors are locked at cycle end.
4.18 Deselected Team Members on Downgrade Execution
- At downgrade execution, Pool B members who were not selected and not opted-in as new paid extras are disabled (not deleted).
- Disabled team members retain their user record, assigned projects, tasks, and history, but cannot log in until reactivated.
- Disabled team members are preserved per the universal downgrade rule in FRD 9A Section 4.4 and are not auto-restored on plan re-upgrade because team members consume seats and seat counts have direct billing implications. The Owner manually re-activates disabled members from the Subscription page using the "Add Seat" or "Add Team Member" entry points per FRD 5 Section 4.20; the re-activation flow restores the member's role, brand assignment, and project assignments without migration. The Team Management page does not initiate re-activation; it lists disabled members in inactive state but does not expose a re-activate action on the row.
4.19 Deselected Brands on Downgrade Execution
- At downgrade execution, brands that were not selected in Step 2 are locked (not deleted or archived).
- Locked brands retain all associated data including projects, clients, invoices, and proposals, but the owner and team members cannot access the locked brand's data or create anything within it.
- An access attempt on a locked brand opens a popup with the message: "This brand is locked on your current plan. Upgrade to restore full access." and two call-to-action buttons "Upgrade" and "Not Now".
- If the agency later upgrades to a plan with a higher brand limit, all previously locked brands are automatically unlocked without user action.
4.20 Module Lock List by Downgrade Path
4.20.1 Studio → Essentials
The following will be locked at the end of the current billing cycle when an agency schedules a downgrade from Studio to Essentials:
- Priority Support access will be locked.
- SMS Text Message Reminders module will be locked.
- Team member included-seat count will reduce from unlimited to 3; plan-included members beyond 3 will either be retained as paid $9/mo extras (if the owner opts in during the wizard) or be disabled if not selected.
- Paid extra seats at $9/mo will continue on Essentials.
- Brand count will reduce from unlimited to 2; brands beyond the selected 2 will be locked with data retained.
- Contractor count will reduce from unlimited to 20; the first 20 contractors by creation date (oldest first) will be retained and contractors beyond that will be locked.
4.20.2 Studio → Basic
The following will be locked at the end of the current billing cycle when an agency schedules a downgrade from Studio to Basic:
- Priority Support access will be locked.
- SMS Text Message Reminders module will be locked.
- Contractor Management module will be locked.
- QuickBooks Online Integration will be disconnected; previously synced data will be preserved.
- Expense Management module will be locked.
- Post Production Management module will be locked.
- Advanced Reports including Profit and Loss will be locked.
- Team member included-seat count will reduce from unlimited to 2; plan-included members beyond 2 will either be retained as paid $9/mo extras (if the owner opts in during the wizard) or be disabled if not selected.
- Paid extra seats at $9/mo will continue on Basic.
- Brand count will reduce from unlimited to 1; brands beyond the selected 1 will be locked with data retained.
- Contractor count will reduce from unlimited to 0; all existing contractors will be locked.
- Google Calendar and Calendly integration will remain available on Basic.
4.20.3 Studio → Free
The following will be locked at the end of the current billing cycle when an agency schedules a downgrade from Studio to Free:
- Priority Support access will be locked.
- SMS Text Message Reminders module will be locked.
- Contractor Management module will be locked.
- QuickBooks Online Integration will be disconnected; previously synced data will be preserved.
- Expense Management module will be locked.
- Post Production Management module will be locked.
- Advanced Reports including Profit and Loss will be locked.
- Google Calendar and Calendly integration will be locked.
- Active projects count will reduce from unlimited to 5; active projects beyond 5 will be locked (not archived) with data retained.
- Team member included-seat count will reduce from unlimited to 1 (owner only); all other plan-included members will be disabled.
- Team member included-seat count will reduce from unlimited to 1; plan-included members beyond 1 will either be retained as paid $9/mo extras (if the owner opts in during the wizard) or be disabled if not selected.
- Brand count will reduce from unlimited to 1; brands beyond the selected 1 will be locked with data retained.
- Contractor count will reduce from unlimited to 0; all existing contractors will be locked.
4.20.4 Essentials → Basic
The following will be locked at the end of the current billing cycle when an agency schedules a downgrade from Essentials to Basic:
- Contractor Management module will be locked.
- QuickBooks Online Integration will be disconnected; previously synced data will be preserved.
- Expense Management module will be locked.
- Post Production Management module will be locked.
- Advanced Reports including Profit and Loss will be locked.
- Team member included-seat count will reduce from 3 to 2; plan-included members beyond 2 will either be retained as paid $9/mo extras (if the owner opts in during the wizard) or be disabled if not selected.
- Paid extra seats at $9/mo will continue on Basic.
- Brand count will reduce from 2 to 1; brands beyond the selected 1 will be locked with data retained.
- Contractor count will reduce from 20 to 0; all existing contractors will be locked.
- Google Calendar and Calendly integration will remain available on Basic.
4.20.5 Essentials → Free
The following will be locked at the end of the current billing cycle when an agency schedules a downgrade from Essentials to Free:
- Contractor Management module will be locked.
- QuickBooks Online Integration will be disconnected; previously synced data will be preserved.
- Expense Management module will be locked.
- Post Production Management module will be locked.
- Advanced Reports including Profit and Loss will be locked.
- Google Calendar and Calendly integration will be locked.
- Active projects count will reduce from unlimited to 5; active projects beyond 5 will be locked (not archived) with data retained.
- Team member included-seat count will reduce from 3 to 1 (owner only); plan-included members beyond 1 will either be retained as paid $9/mo extras (if the owner opts in during the wizard) or be disabled if not selected.
- Paid extra seats at $9/mo will continue on free plan
- Brand count will reduce from 2 to 1; brands beyond the selected 1 will be locked with data retained.
- Contractor count will reduce from 20 to 0; all existing contractors will be locked.
4.20.6 Basic → Free
The following will be locked at the end of the current billing cycle when an agency schedules a downgrade from Basic to Free:
- Google Calendar and Calendly integration will be locked.
- Active projects count will reduce from unlimited to 5; active projects beyond 5 will be locked (not archived) with data retained.
- Team member included-seat count will reduce from 2 to 1 (owner only); plan-included members beyond 1 will either be retained as paid $9/mo extras (if the owner opts in during the wizard) or be disabled if not selected.
- Paid extra seats at $9/mo will continue on free plan
4.20.7 Lock Behavior Reference
- The specific visual behavior of each locked module (feature lock, data lock, or integration disconnect) is defined in FRD 9 (Subscription Impact on Other Modules).
- Lock behaviors fall into three categories: feature lock (the module will remain visible but become non-functional with an upgrade CTA on click), data lock (data will be retained but become inaccessible until re-upgrade), and integration disconnect (existing external connection will be dropped while previously synced data will be preserved for re-sync on re-upgrade).
4.21 Paid Extra Seats Carry-Forward on Downgrade (Pool A Behavior)
- Existing paid extra seats that the agency is paying $9 per month for on the current plan (Pool A) automatically carry forward to the new plan after downgrade execution, except when the target plan is Free.
- The owner is not presented with a Pool A selection or deletion option during the wizard; Pool A is strictly non-interactive per Section 4.13.
- If the owner wishes to remove any Pool A paid seat, they must do so via the Team Management module, either by deleting the associated member before starting the downgrade or by deleting the member after the downgrade executes.
- Pool A members carry forward to all paid tier downgrades AND to Free plan downgrades at $9/mo per seat per the unified paid-extras rule that applies regardless of the target plan.
- New paid extras that the owner opts into during Step 1 by selecting Pool B overflow are separate from Pool A and are prorated and charged at the moment of downgrade confirmation per Section 4.11.
4.22 Auto-Cancellation of Scheduled Downgrade on Upgrade
- When the owner initiates an upgrade and a scheduled downgrade exists, the system displays a popup with the message: "You currently have a scheduled downgrade. Upgrading will cancel the scheduled downgrade. Are you sure you want to continue?" with "Cancel" and "Continue" buttons.
- On owner confirmation and successful upgrade payment, the system cancels the scheduled downgrade, discards the pending Pool B member selections, brand selections, and new-extra opt-ins, and notifies the owner via email and in-app notification that the scheduled downgrade has been cancelled.
- If the upgrade payment fails, the scheduled downgrade remains intact and the upgrade is aborted with an error message.
4.23 Re-scheduling a Different Downgrade
- When the owner already has a scheduled downgrade and initiates a new downgrade to a different target plan, the system displays a popup with the message: "You have a scheduled downgrade to [Previous Target]. Continuing will replace it with a downgrade to [New Target]. Are you sure?"
- On confirmation, the system discards the previous scheduled downgrade's pending selections and opts-ins and opens the new downgrade's evaluation and wizard/confirm flow.
- The new downgrade's selections replace the previous ones entirely (last action wins); there is no merging or preservation of prior selections or opt-ins.
4.24 Cancel Scheduled Downgrade by Owner
- The owner can cancel a scheduled downgrade at any time before the execution date from either the Subscription page (under plan details) or the Manage Subscription page.
- On clicking "Cancel Downgrade", the system displays a confirmation popup with the message: "Cancel your scheduled downgrade? Your current plan will continue without changes."
- On confirmation, the system removes the scheduled downgrade record, discards all pending Pool B selections and new-extra opt-ins, and restores the agency's Manage Subscription state to showing the current plan as active without any pending change.
- The owner receives a confirmation email and in-app notification.
4.25 Price Summary Preview Popup (Upgrade Path)
- The Price Summary preview popup is shown for every plan change with billing impact, including upgrades, downgrades, cycle switches, and Free-to-Paid conversions.
- For upgrade flows, the popup displays: the current plan's used portion (informational, no credit or refund), the new plan's base charge for the relevant period, the Year 1 promotional discount breakdown if applicable, any prorated credit from the current cycle, any applied coupon code with its discount, the Total Due Today amount, and the Next Cycle Total.
- For downgrade flows, the equivalent Summary is shown within Step 3 of the wizard (see Section 4.16) or on the simple Confirm Plan Downgrade screen.
- For changes that span across the promotional window (for example, upgrading during Year 1 where the new cycle crosses into Year 2), the popup shows up to three pricing periods: Today's price (promo and coupon applied), the mid-period price after coupon expires but promo still active, and the final price after both promo and coupon expire.
- The coupon entry field allows the owner to apply a valid discount code before confirming payment.
- The popup contains a "Cancel" button and a "Confirm and Pay [Amount]" button; the Confirm button is disabled immediately on click to prevent duplicate submissions.
4.26 Coupon Application at Upgrade
- A coupon can be applied in the Price Summary preview popup during any upgrade flow.
- The coupon code is validated against the Gawd Portal Discounts module for validity, expiry, and prior use by the same email.
- Only one coupon code can be active per transaction; a user who has previously applied a coupon cannot apply a second one.
- The coupon discount stacks on top of the 50% first-year promotional discount per the rules in FRD 1 Section 4.4.
- The coupon applies to the base plan amount only; it does not apply to extra seat charges per FRD 5.
4.27 Post-Upgrade Confirmation
- On successful upgrade payment, the system displays the success popup with the title "You've unlocked more power" and the body "Your plan has been upgraded to [Plan]. Access to premium features is now active." along with a single "Got It" call-to-action that dismisses the popup.
- The system immediately unlocks all features of the new plan, refreshes the Plan Usage Matrix, and updates the Subscription page top card to reflect the new plan.
- An email confirmation is sent containing the receipt/invoice, and an in-app notification is posted in the Pixally notification center.
4.28 Post-Downgrade Confirmation
- On successful scheduled-downgrade creation, the system displays a confirmation popup with the message: "Your downgrade to [Plan] has been scheduled for [End-of-Cycle Date]. You will retain full [Current Plan] access until then."
- The system returns the owner to the Subscription page where the scheduled-downgrade message and "Cancel Downgrade" option appear under plan details.
- An email confirmation is sent and an in-app notification is posted.
4.29 Plan Comparison Page (Manage Subscription)
- The Manage Subscription page displays four plan cards: Free, Basic, Essentials, Studio.
- A Monthly/Yearly cycle toggle at the top of the page allows the owner to view prices for each cycle; the Yearly toggle shows a "2 months free" tag.
- Each paid plan card displays the Year 1 promotional price (with the original Year 2 price struck through and a "50% off first year" note), the 2-month-free badge for yearly cycles, the plan description, and a feature list.
- Each plan card also displays Stripe Credit Card fees and ACH fees specific to that plan.
- The currently active plan card is labelled "Active Monthly" or "Active Yearly" depending on the current cycle; the Current Plan card's primary CTA is disabled or shows "Current Plan" text.
- The Essentials plan card shows a "Most Popular" badge unless Essentials is also the currently active plan, in which case the Active label takes priority over Most Popular.
- Other plan cards display action CTAs: "Downgrade to Free" for Free from any paid plan, "Upgrade to [Plan]" for higher-tier plans, and "Switch to Yearly" or "Switch to Monthly" for cycle changes on the same plan.
- The page includes an informational line at the bottom: "Displayed prices do not include any applicable sales tax."
4.30 Studio Plan — No Upgrade Option
- When the currently active plan is Studio, the Manage Subscription page shows Studio as "Current Plan" and all other plan cards display either "Downgrade to [Plan]" (for lower tiers) or billing cycle switch CTAs (for Studio on the opposite cycle).
- The Upgrade-related CTAs (upgrade banners, Upgrade Plan buttons) are hidden from the portal because no higher tier exists beyond Studio.
- The owner can still downgrade, switch billing cycle, manage seats, and cancel subscription on the Studio plan.
4.31 Payment Method Routing
- If the owner has a payment method on file at the time of upgrade or downgrade-with-new-extras confirmation, the system uses the default payment method to charge any Due Today amount directly.
- If the owner does not have a payment method on file, the system routes to the Payment page (defined in FRD 6) to collect payment method details before processing the charge.
- After successful payment collection, the system processes the charge and continues to the success popup.
- Payment method management during checkout (such as adding a new card or switching to a different saved card) is handled per the Stripe embedded component as defined in FRD 6.
4.32 Year 1 Discount Window Handling Across Changes
- The discount_phase_end_date (subscription_start_date + 12 months) is preserved across all plan changes; neither upgrades nor cycle switches extend or reset the 12-month promotional window.
- On any plan change during Year 1, the blended formula automatically applies the remaining discounted months to the new plan's Year 1 price and the consumed months to the new plan's Year 2 price.
- On the annual renewal that falls after the discount_phase_end_date, the system charges the full Year 2 annual price without any blending.
- If the annual renewal date falls before the discount_phase_end_date, the system applies blending using the updated months_used_on_monthly at that point.
4.33 Notifications Generated by Upgrade/Downgrade Events
- Every successful upgrade triggers a confirmation email with the invoice attached and an in-app notification in the Pixally notification center.
- Every scheduled downgrade triggers a confirmation email with the execution date and an in-app notification.
- Cancelling a scheduled downgrade triggers a confirmation email and an in-app notification.
- Auto-cancellation of a scheduled downgrade (due to an upgrade) triggers a dedicated notification: "Your scheduled downgrade has been cancelled because you upgraded your plan."
- At the time of scheduled downgrade execution (cycle end), the system sends a notification confirming the plan change has taken effect, along with individual notifications to disabled members and contractors as defined in FRD 9.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Target Plan
Dropdown/Card selection
Must be one of Free, Basic, Essentials, Studio. Cannot be the same as current plan unless changing cycle.
Target Billing Cycle
Toggle
Values: Monthly or Annual.
Subscription Start Date
System-derived date
Set on first paid charge. Not user-editable.
Discount Phase End Date
System-derived date
subscription_start_date + 12 months. Not user-editable.
Months Used on Monthly
System-derived decimal
Range: 0.0 to 12.0. Supports fractional values (e.g., 5.5).
Days Remaining in Current Cycle
System-derived integer
Range: 0 to 365 for annual, 0 to 31 for monthly.
Unused Credit
System-derived currency
Calculated per Section 4.5 or 4.6. Always non-negative.
New Plan Charge
System-derived currency
Calculated per applicable proration formula.
Due Today
System-derived currency
new_plan_charge − unused_credit. If ≤ $0: no charge, credit balance. If < $0.50: defer to next invoice.
Next Cycle Total
System-derived currency
Target plan base price plus Pool A carry-forward extras plus Pool B opt-in extras; displayed in Price Summary.
Credit Balance
System-derived currency
Accumulated credits applied to next invoice.
Coupon Code
Text input
Alphanumeric uppercase; validated against Gawd Portal Discounts. One per transaction.
Applied Coupon Discount
System-derived currency
Calculated from the coupon's percentage or fixed amount.
Promo Discount Applied
Boolean
True if user is within the 12-month window and the plan is eligible for the 50% promo.
Scheduled Downgrade Target Plan
System-stored
Populated when a downgrade is scheduled. Cleared on cancel or execution.
Scheduled Downgrade Execution Date
System-stored date
The end of the current billing cycle at the time of scheduling.
Scheduled Downgrade Pool B Selections
System-stored list
Plan-included members retained at execution.
Scheduled Downgrade Pool A List
System-stored list
Existing paid extras that will carry forward at $9/mo.
Scheduled Downgrade New Extras Count
System-stored integer
Number of new $9/mo extras the owner opted into from Pool B overflow at scheduling.
Scheduled Downgrade Brand Selections
System-stored list
Brands retained after execution.
Wizard Step 1 Available
System-derived integer
Target plan's included team member count.
Wizard Step 1 Used
System-derived integer
Pool B selections up to Available count.
Wizard Step 1 Extra Seats
System-derived integer
Pool B selections beyond Available (new paid extras opted into).
Wizard Step 1 Price
System-derived currency
Wizard Step 1 Extra Seats × $9.00. Updates dynamically.
Wizard Step 2 Available Brands
System-derived integer
Target plan's brand limit.
Wizard Step 2 Used Brands
System-derived integer
Currently selected brand count.
Pool A Member List
System-derived list
Members currently paid as $9/mo extras on current plan. Read-only in wizard.
Pool B Member List
System-derived list
Members currently occupying plan-included seats on current plan. Editable in wizard Step 1.
Confirm and Pay Button
Button
Disabled on click until response returns to prevent duplicate submissions.
Cancel Downgrade CTA
Button
Visible only when a scheduled downgrade exists. Shown on Subscription page and Manage Subscription page.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Upgrade completed
"You've unlocked more power. Your plan has been upgraded to [Plan]. Access to premium features is now active."
Upgrade payment successful.
Success popup shown with "Got It"; plan features unlocked immediately; email + in-app notification sent.
SM-2
Downgrade scheduled
"Your downgrade to [Plan] has been scheduled for [End-of-Cycle Date]. You will retain full [Current Plan] access until then."
Downgrade confirmation successful.
Return to Subscription page; scheduled-downgrade message shown under plan details.
SM-3
Scheduled downgrade cancelled by owner
"Your scheduled downgrade has been cancelled. Your current plan will continue."
Owner confirms Cancel Downgrade.
Scheduled-downgrade message removed from Subscription page.
SM-4
Scheduled downgrade cancelled by upgrade
"Your scheduled downgrade has been cancelled because you upgraded your plan."
Successful upgrade when a downgrade was scheduled.
Email + in-app notification sent.
SM-5
Cycle switch scheduled (Annual to Monthly)
"Your switch to Monthly billing has been scheduled for [Annual End Date]."
Annual-to-Monthly switch confirmed.
Return to Subscription page; scheduled-switch message shown.
SM-6
Cycle switch completed (Monthly to Annual)
"You are now on Annual billing. Your next renewal is [Date]."
Monthly-to-Annual switch payment successful.
Subscription page updated to reflect annual cycle.
SM-7
Coupon applied successfully
"Coupon [CODE] applied — [X]% or [$X] discount on your upgrade."
Coupon validated in Price Summary.
Coupon line item shown in Price Summary.
SM-8
Credit balance created (negative net)
"No charge today. A credit of $[X] has been applied to your account and will be used on your next invoice."
Due Today ≤ $0.
Credit balance stored; next invoice reflects credit.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Upgrade payment fails
"Your payment could not be processed. Please check your payment method and try again."
Stripe returns payment failure.
Owner updates payment method; retries upgrade. Scheduled downgrade (if any) remains intact.
EM-2
Coupon invalid or expired
"This coupon code is not valid or has expired."
Gawd Portal Discounts rejects code.
Owner removes coupon or enters a valid one.
EM-3
Coupon already used by user
"You have already used a coupon on a previous subscription. Only one coupon per user is allowed."
Email present in coupon usage history.
Owner proceeds without coupon.
EM-4
Upgrade when user is suspended
"Your account is currently suspended. Please update your payment method to continue."
Agency has an unresolved suspension.
Routes to billing page per FRD 7.
EM-5
Non-owner attempts upgrade or downgrade
"Only the agency owner can change the subscription plan. Please contact your agency owner."
Admin or other role reaches Manage Subscription.
User contacts owner.
EM-6
Target plan is same as current plan (no change detected)
"This is already your current plan."
Owner selects the current plan on Manage Subscription.
Owner selects a different plan.
EM-7
Payment method on file declined
"Your card on file was declined. Please update your payment method to continue."
Stripe decline on charge.
Owner updates payment method via FRD 6 flow.
EM-8
Coupon not applicable to this transaction
"This coupon cannot be applied to this plan change."
Coupon rules exclude the action.
Owner removes coupon or selects a different plan.
EM-9
Confirm and Pay double-clicked
No error shown; button is disabled on first click.
User double-clicks.
N/A (prevented by UI).
EM-10
Downgrade wizard Step 2: user selects zero brands
"Please select at least one brand to keep active."
Step 2 Next clicked with no brands selected.
Owner selects at least one brand.
EM-11
Owner attempts to deselect Pool A member from wizard
No error shown; Pool A rows have no interactive control.
User tries to modify Pool A.
N/A (prevented by UI). Direct owner to Team Management for deletion.
EM-12
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
Retry or contact support.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Owner on Basic Monthly upgrades to Essentials Monthly on Day 15 of a 30-day cycle, Year 1.
System computes prorated Essentials charge for remaining 15 days minus unused Basic credit for 15 days; billing anchor preserved; immediate access to Essentials.
EC-2
Owner on Basic Monthly upgrades to Essentials Annual on Day 15, Year 1, 5.5 months used on monthly (decimal).
System applies blended formula: discounted portion = $34.50 × (6.5/12) × 10 = $186.88, full-price portion = $69.00 × (5.5/12) × 10 = $316.25, blended = $503.13; minus unused Basic credit of $19.50 × (15/30) = $9.75; Due Today = $493.38; new annual anchor starts today.
EC-3
Owner on Essentials Annual upgrades to Studio Annual on Day 180 of annual cycle, Year 1.
System computes Studio annual prorated for 185 days remaining at Y1 blended minus Essentials annual unused credit for 185 days; original annual anchor preserved.
EC-4
Owner upgrades resulting in Due Today = -$6.00 (negative net).
No charge today; $6.00 credit balance created; credit applied to next renewal invoice automatically; access granted immediately.
EC-5
Owner upgrades resulting in Due Today = $0.35 (below $0.50 threshold).
No charge today; $0.35 deferred to next invoice; access granted immediately.
EC-6
Owner on Studio downgrades to Essentials on Day 10 of 30-day monthly cycle, with 25 contractors, 5 plan-included members, 0 paid extras, 3 brands.
Wizard opens: Step 1 shown (5 > 3 limit) with no Pool A, Pool B of 5 members; owner selects 3 or opts to pay $9/mo each for overflow; Step 2 shown (3 > 2 limit); popup on Step 1 Next for contractor 20-retain notice; downgrade scheduled for Day 30.
EC-7
Owner on Essentials downgrades to Basic with 3 plan-included members, 2 paid extras (Pool A), 2 brands.
Wizard Step 1 shown (3 plan-included > 2 Basic limit). Pool A section shows the 2 existing paid extras with Retained badge (no interactive controls). Pool B shows 3 members; owner must select 2 (including owner) and may opt to pay $9/mo for the 3rd as a new extra. Step 2 shown (2 brands > 1 Basic limit). Summary shows Basic base + Pool A carry-forward ($18/mo) + any new extra; downgrade scheduled for cycle end.
EC-8
Owner on Essentials downgrades to Basic with 2 plan-included members, 1 brand, 0 paid extras (within limits).
No wizard. Simple Confirm Plan Downgrade screen with features-lost list. Scheduled for cycle end.
EC-9
Owner on Basic (2 plan-included members, 0 paid extras) downgrades to Free. | Step 1 shown (2 plan-included > 1 Free limit)
Owner pre-selected. The other plan-included member is offered as Pool B overflow: owner either opts in to pay $9/mo to keep them as a paid extra on Free, or leaves them unselected to be disabled at cycle end. Step 2 skipped if 1 brand.
EC-10
Owner has scheduled downgrade from Studio to Essentials, then initiates upgrade to Studio Annual from Studio Monthly.
System detects scheduled downgrade; shows popup "Upgrading will cancel the scheduled downgrade. Are you sure?" On confirm: upgrade processed, scheduled downgrade cancelled, notification sent.
EC-11
Owner has scheduled downgrade from Studio to Essentials, then decides to downgrade to Basic instead.
System detects existing scheduled downgrade; shows popup "You have a scheduled downgrade to Essentials. Continuing will replace it with a downgrade to Basic. Are you sure?" On confirm: previous downgrade discarded; new downgrade wizard evaluates Basic limits.
EC-12
Owner cancels scheduled downgrade before execution.
Scheduled downgrade removed; pending Pool B selections, brand selections, and new-extra opt-ins discarded; current plan continues without change at cycle end; confirmation email and in-app notification sent.
EC-13
Owner on Essentials with 4 paid extras (Pool A) upgrades to Studio.
All 4 Pool A extras become redundant on Studio because Studio has unlimited seats; extra-seat credit = 4 × $9 × (days_remaining ÷ total_cycle_days) applied to next invoice; Studio charge prorated normally. If net ≤ $0: $0 today + credit balance; if 0 < net < $0.50: deferred.
EC-14
Owner on Basic (2 included + 2 paid extras) upgrades to Essentials (3 included).
1 paid extra auto-promotes to Essentials included slot (oldest first by creation date); $9/mo charge stops from next cycle for that seat; prorated credit for the promoted extra applied. 1 paid extra remains as Pool A on Essentials.
EC-15
Owner double-clicks the Confirm and Pay button.
Button disabled immediately on first click; only one charge is processed; idempotency key on server prevents duplicate Stripe charges.
EC-16
Owner initiates upgrade but has no payment method on file.
System routes to Payment page (FRD 6) for payment method collection; on success, charge is processed and upgrade completes.
EC-17
Owner on 50% Y1 promo upgrades to a higher plan; new plan's upgrade crosses Year 1 end.
Price Summary shows Today's price (blended Y1/Y2), an intermediate note for the remaining Y1 window, and the final Y2 price that will apply from the discount_phase_end_date onward.
EC-18
Owner applies an expired coupon in Price Summary.
System rejects coupon with "This coupon code is not valid or has expired" error; owner can remove or enter different coupon.
EC-19
Owner on Essentials with 3 brands downgrades to Basic (1 brand limit).
Wizard Step 2 shown; owner selects 1 brand; 2 unselected brands are locked at cycle end with data retained.
EC-20
Owner on Studio downgrades to Free with 8 projects, 5 plan-included members, 2 paid extras (Pool A), 3 brands, 30 contractors.
Step 1 shown (5 plan-included > 1 Free limit). Owner pre-selected as Free's 1 included seat. Pool B (4 non-owner plan-included members) offered for opt-in as paid extras. Pool A (2 existing paid extras) shown in auto-retained section at $9/mo each. Step 2 shown (3 brands > 1). No contractor popup (Studio→Free locks all contractors unconditionally). At cycle end: Pool A (2 extras) carries forward, any Pool B opt-ins charged at $9/mo each, unselected Pool B members disabled, 2 brands locked, 3 excess projects locked, all 30 contractors locked.
EC-21
Owner on Annual Essentials switches to Monthly Essentials mid-annual cycle.
Switch scheduled at annual renewal date; no charge today; at annual end, monthly cycle begins with Y1 monthly or Y2 monthly pricing depending on whether the monthly start date is within the discount window.
EC-22
Owner on Monthly Basic switches to Annual Basic on Day 15, Year 1, 3.5 months used on monthly (decimal).
blended formula for Basic annual: discounted = $19.50 × (8.5/12) × 10 = $138.13; full-price = $39.00 × (3.5/12) × 10 = $113.75; blended = $251.88; unused credit = $19.50 × (15/30) = $9.75; Due Today = $242.13; new annual anchor starts today.
EC-23
Owner's payment method is declined during upgrade.
Error message EM-7 shown; upgrade not processed; scheduled downgrade (if any) remains intact; plan remains unchanged until payment succeeds.
EC-24
Owner tries to apply a coupon that they previously used.
System rejects with "You have already used a coupon on a previous subscription."
EC-25
Owner on Studio plan opens Manage Subscription page.
Studio card shows "Current Plan"; Upgrade CTAs hidden across the portal; only Downgrade, Cycle Switch, and Cancel available.
EC-26
Owner on Essentials (3 plan-included, 2 paid extras Pool A) downgrades to Basic; owner selects 2 Pool B members for Basic included slots and opts to pay for the 3rd as a new extra.
At cycle end, Basic plan includes 2 Pool B members, carries forward 2 Pool A extras at $9/mo each, adds 1 new opted-in extra at $9/mo. Next monthly invoice: $19.50 Basic (Y1) + 3 × $9 = $46.50. Proration for the new extra charged at scheduling; Pool A existing extras not re-charged.
EC-27
Year 2 owner upgrades Essentials Monthly to Studio Monthly on Day 15.
Simple Year 2 formula: Studio charge = $119 × (15/30) = $59.50; unused Essentials credit = $69 × (15/30) = $34.50; Due Today = $25.00; billing anchor preserved.
EC-28
Owner schedules downgrade, then on the execution date cycle-end processing begins.
At cycle end, system applies pending selections: disables unselected Pool B members, locks unselected brands, applies Pool A carry-forward (or disables Pool A if target is Free), locks excess contractors (if Studio→Essentials), sets new plan entitlements, resets Plan Usage Matrix, sends notifications to all affected parties.
EC-29
Owner on Essentials with existing Pool A paid extras tries to deselect a Pool A member from the wizard Step 1.
Pool A rows have no interactive control; the deselect attempt has no effect. Owner must go to Team Management module to delete the paid extra seat (either before starting the downgrade or after it executes).
EC-30
Owner on Basic with 2 plan-included (0 paid extras) downgrades to Free; the owner wants to keep the non-owner plan-included member as a paid extra. seat during the wizard.
Step 1 shown (2 plan-included > 1 Free limit). Owner pre-selected. Non-owner member appears in Pool B. Owner selects non-owner member as a new paid extra opt-in; Extra Seats = 1; Price = $9.00/mo. On Confirm, $9 × (days_remaining/30) prorated charge today; from next cycle, owner's monthly bill is $0 Free + $9 extra = $9/mo. |
EC-31
Owner on Essentials with 3 plan-included (within Basic included count of 2 is false — 3 > 2) and 0 brands above Basic limit (1 brand = Basic limit) downgrades to Basic.
Step 1 shown (3 > 2); Step 2 skipped (1 = 1); Summary shown. Owner selects 2 from Pool B or opts to pay for 3rd.
9. Acceptance Criteria
- The Manage Subscription page correctly displays all four plans with Year 1 promotional prices, Stripe fees, active plan label, Most Popular badge, and the Monthly/Yearly cycle toggle.
- The Upgrade CTA is hidden entirely from the portal when the active plan is Studio.
- An upgrade executes immediately with correct proration: Year 1 blended formula for users within the 12-month promotional window; simple Year 2+ formula otherwise.
- An upgrade combined with Monthly-to-Annual switch resets the annual billing anchor to today and charges the blended or simple annual amount.
- An upgrade combined with Annual-to-Monthly switch processes the upgrade immediately at annual rates and schedules the monthly cycle switch to the annual renewal date.
- A Free-to-Paid upgrade charges the full first-period amount without proration.
- A downgrade is always scheduled at the end of the current billing cycle and does not refund or credit unused days.
- The downgrade wizard appears only when selection is needed: Step 1 (Team Members) if current plan-included members exceed target; Step 2 (Brands) if current brands exceed target; Step 3 (Summary) always when any step was shown.
- A downgrade with no limit breach routes directly to the simple Confirm Plan Downgrade screen.
- Downgrade to Free shows Step 1 when plan-included members exceed Free's 1 included seat (owner pre-selected, Pool B overflow offered as paid extras) and Step 2 only if current brands > 1.
- The wizard Step 1 shows two pools: Pool A (existing paid extras, non-interactive, auto-retained) and Pool B (current plan-included members, user-selectable with opt-in for overflow).
- The Step 1 metric row dynamically updates Used, Extra Seats, and Price as the owner toggles Pool B selections; Pool A members do not contribute to these metrics.
- The agency owner is pre-selected in Pool B and cannot be deselected.
- Pool A members cannot be deselected, removed, or modified from within the wizard under any circumstance.
- Contractor handling on Studio-to-Essentials downgrade auto-retains the first 20 contractors by creation date and displays a popup notice on Step 1 Next.
- Deselected Pool B members are disabled (not deleted) at cycle end and retain their data for future reactivation.
- Deselected brands are locked (not deleted) at cycle end and retain all associated data.
- Pool A paid extras automatically carry forward to the new plan after downgrade (except when downgrading to Free).
- Pool A members carry forward to all downgrades including Free plan at $9/mo per seat per the unified carry-forward rule.
- The Price Summary preview popup is shown for every plan change with billing impact and accurately reflects the used portion, prorated credits, promo breakdown, coupon breakdown, Due Today, and Next Cycle Total.
- A coupon applied at Price Summary stacks on top of the 50% promotional discount and validates against the Gawd Portal Discounts module.
- The Confirm and Pay button is disabled on first click to prevent duplicate submissions.
- If Due Today is ≤ $0, no charge is taken today and a credit balance is created for the next invoice.
- If Due Today is between $0 and $0.50, the amount is deferred to the next invoice rather than charged today.
- Initiating an upgrade when a scheduled downgrade exists triggers a confirmation popup and, on confirmation, auto-cancels the downgrade after successful payment.
- If upgrade payment fails, the scheduled downgrade remains intact.
- Initiating a new downgrade when a scheduled downgrade exists triggers a replacement confirmation popup and, on confirmation, discards the previous selections and opens the new downgrade flow.
- The owner can cancel a scheduled downgrade at any time before execution from the Subscription page or the Manage Subscription page.
- All successful upgrade/downgrade events generate email confirmations and in-app notifications.
- At scheduled-downgrade execution (cycle end), the system applies pending selections, locks/disables applicable resources, sets new plan entitlements, and sends notifications.
- Upgrade success displays the "You've unlocked more power" popup with the specified copy and "Got It" CTA.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Identifies the agency owner and enforces role-based access to Manage Subscription.
Owner cannot be authenticated; plan changes cannot be initiated.
Role & Permission Module
Hard
Enforces owner-only access to upgrade, downgrade, and cancel downgrade actions.
Non-owner restrictions cannot be enforced.
Subscription Plans Module (FRD 1)
Hard
Provides plan definitions, features, resource limits, pricing, and Plan Usage Matrix.
Plan details and entitlements cannot be resolved.
Free Trial Module (FRD 2)
Hard
Handles trial-to-paid conversion which sets the subscription_start_date for Year 1 window tracking.
Discount phase end date cannot be determined correctly.
Billing Cycle Management Module (FRD 4)
Hard
Governs cycle switch timing (Monthly↔Annual).
Combined plan-plus-cycle changes cannot be completed.
Add-ons Module (FRD 5)
Hard
Governs extra seat purchase, seat proration, seat credits, and auto-promotion of extras on upgrade.
Seat-related calculations cannot be executed.
Team Management Module
Hard
Used for Pool A member deletion (paid extras) outside the downgrade wizard, per strict Pool A non-interactive rule.
Owner cannot remove paid extras if desired.
Billing Dashboard + Payment Methods Module (FRD 6)
Hard
Hosts payment method management; routes for missing payment method during upgrade.
Payment method collection is blocked.
Failed Payment Management Module (FRD 7)
Hard
Handles suspended-account state that blocks upgrade attempts.
Suspended-state routing cannot be enforced.
Cancel Subscription Module (FRD 8)
Soft
Shares cancellation flow for owners who choose to cancel instead of downgrade.
No direct impact.
Subscription Impact Module (FRD 9)
Hard
Defines lock/disable/disconnect behavior for modules, team members, brands, contractors.
Downgrade execution cannot apply resource-level restrictions correctly.
Notification Module
Hard
Delivers email and in-app notifications for upgrade/downgrade events.
Owners miss key confirmations.
Stripe Billing Integration
Hard
Processes charges, holds credit balances, applies proration, generates invoices and receipts.
Upgrades cannot be paid; credits cannot be applied.
Gawd Portal Discounts Module
Hard
Validates coupon codes and tracks coupon usage per email.
Coupons cannot be applied.
Background Job / Cron Service
Hard
Executes scheduled downgrades at cycle end.
Scheduled downgrades do not execute on time.
4. Billing Cycle Management
Billing Cycle Management logic
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 23 April 2026
Status:
Version 2.0
FRD 4 — Billing Cycle Management
Module: Billing Cycle Management Version: 1.0 Date: April 23, 2026
1. Module Overview
Module Name: Billing Cycle Management
Purpose: This module defines the behavior for switching the billing cycle of an active paid subscription between Monthly and Annual on the same plan tier. It governs the Monthly-to-Annual immediate switch with prorated credit, the Annual-to-Monthly deferred switch that executes at the end of the current annual cycle, the warning confirmation popup when switching from Annual to Monthly, the cancel-scheduled-switch behavior, the Year 1 blended proration for users within the 12-month promotional window, and the treatment of paid extra seats during cycle switches.
Business Goals: The Billing Cycle Management module supports revenue stability by encouraging users to move to annual billing (through the Monthly-to-Annual immediate switch that rewards the user with two free months) while also respecting user autonomy when they want to switch back to monthly billing. The deferred execution of Annual-to-Monthly switches protects the full annual commitment the user has already paid for. The warning popup on Annual-to-Monthly switches ensures that users understand they will pay more per month if they switch away from annual billing, reducing surprise and preserving trust.
2. User Roles & Permissions
Role
View Billing Cycle Options
Switch M→A
Switch A→M
Cancel Scheduled Switch
Agency Owner
Yes
Yes
Yes
Yes
Agency Admin
Yes (read-only)
No
No
No
Project Manager
No
No
No
No
Supervising Editor
No
No
No
No
Editor
No
No
No
No
Contractor
No
No
No
No
Client
No
No
No
No
Pixally Super Admin (Gawd Portal)
N/A
No
No
No
3. User Flow
3.1 Monthly to Annual Switch Flow
3.1.1 The agency owner navigates to the Subscription page and clicks the "Switch to Yearly" button from the Subscription cycle section, or from the Manage Subscription page by toggling the billing cycle to Yearly and clicking the call-to-action on the current plan card.
3.1.2 The system opens the Price Summary preview popup showing the breakdown: the unused credit from the current monthly cycle, the blended or simple annual charge for the same plan (Year 1 blended or Year 2+ simple), any applied coupon, the Total Due Today, and the Next Cycle Total.
3.1.3 The agency owner optionally enters a discount coupon code and reviews the breakdown.
3.1.4 The agency owner clicks the "Confirm and Pay [Amount]" call-to-action.
3.1.5 The system disables the Confirm button immediately on click to prevent duplicate submissions.
3.1.6 If the agency has a payment method on file, the system initiates the Stripe charge directly for the Due Today amount; if not, the system routes to the Payment page to collect payment method details first.
3.1.7 On successful payment, the system updates the subscription state to Annual billing, sets a new annual billing anchor starting today with the annual renewal date set to today plus 365 days, and keeps the original discount_phase_end_date unchanged.
3.1.8 The system displays a success confirmation and returns the owner to the Subscription page where the billing cycle section now shows "Yearly" along with the next renewal date and the annual billing amount.
3.1.9 The system sends a confirmation email with the invoice attached and an in-app notification confirming the cycle switch.
3.2 Annual to Monthly Switch Flow
3.2.1 The agency owner navigates to the Subscription page and clicks the "Switch to Monthly" button from the Subscription cycle section, or from the Manage Subscription page by toggling the billing cycle to Monthly and clicking the call-to-action on the current plan card.
3.2.2 The system opens the Switch to Monthly warning popup displaying the scheduled switch date, the monthly amount the owner will be charged after the switch, the current per-month equivalent of the annual plan for comparison, and a note that switching to Monthly means paying more per month over the year.
3.2.3 The agency owner reviews the warning and clicks "Schedule Switch" to confirm, or "Cancel" to abort.
3.2.4 On confirmation, the system schedules the cycle switch to take effect at the end of the current annual cycle, displays a success confirmation, and returns the owner to the Subscription page.
3.2.5 The Subscription page now shows a scheduled-switch message under the billing cycle section stating "Your billing cycle will switch to Monthly on [Annual End Date]" along with a "Cancel Switch" option.
3.2.6 The system sends a confirmation email and an in-app notification that the switch has been scheduled.
3.2.7 On the annual end date, the background job executes the switch: the annual subscription ends, a new monthly cycle begins the same day, and the first monthly charge is processed using Year 1 monthly pricing if the switch date is before the discount_phase_end_date, or Year 2 monthly pricing if the switch date is at or after the discount_phase_end_date.
3.2.8 The system sends a post-execution confirmation email with the first monthly receipt and an in-app notification.
3.3 Cancel Scheduled Cycle Switch Flow
3.3.1 The agency owner navigates to the Subscription page and sees the scheduled-switch message under the billing cycle section with a "Cancel Switch" option.
3.3.2 The agency owner clicks "Cancel Switch" and the system displays a confirmation popup with the message: "Cancel your scheduled switch to Monthly? Your Annual billing will continue and renew on [Annual Renewal Date]."
3.3.3 The agency owner confirms and the system removes the scheduled switch record, restores the Subscription page to show only the current Annual cycle without any pending change, and keeps the original annual renewal date intact.
3.3.4 The system sends a confirmation email and an in-app notification that the scheduled switch has been cancelled.
3.4 Coexistence with Scheduled Downgrade Flow
3.4.1 The agency owner has an active scheduled tier downgrade (handled in FRD 3) and initiates an Annual-to-Monthly switch; the system permits both scheduled actions to coexist because both execute at the end of the annual cycle.
3.4.2 The Subscription page displays both scheduled actions separately under plan details: a scheduled-downgrade message with its own "Cancel Downgrade" option, and a scheduled-switch message with its own "Cancel Switch" option.
3.4.3 On the annual end date, the background job executes both scheduled actions simultaneously: the plan tier changes to the downgraded plan and the billing cycle switches to Monthly, with the first monthly charge using the target plan's Year 1 or Year 2 monthly rate depending on whether the execution date is before or at-or-after the discount_phase_end_date.
4. Functional Logic
4.1 Billing Cycle Options
- The system supports two billing cycles for paid plans: Monthly and Annual.
- The Free plan has no billing cycle because it carries no recurring charge; the cycle options described in this module apply only to Basic, Essentials, and Studio plans.
- Plan pricing is hardcoded from client-provided values and is not computed dynamically by the system; the Annual price is the Monthly price multiplied by ten, effectively giving the user two months free over a twelve-month period.
- The Annual toggle on the Manage Subscription page displays a "2 months free" badge to highlight the savings versus Monthly billing.
4.2 Plan Change Timing Reference
- The full plan change timing matrix is defined in FRD 3 Section 4.1; this module references that matrix for cycle-only changes and reproduces the subset relevant to cycle switches: Monthly-to-Annual is immediate with a prorated charge, and Annual-to-Monthly is scheduled to execute at the end of the current annual cycle.
- A cycle switch on the same plan tier does not involve any plan-change wizard because no team member, brand, or contractor selection is required.
4.3 Monthly to Annual Switch — Timing and Billing Anchor
- A Monthly-to-Annual switch executes immediately on successful payment.
- The new annual billing anchor is set to today; the annual renewal date is calculated as today plus 365 days.
- The discount_phase_end_date (subscription_start_date plus 12 months) is preserved and is not reset or extended by the cycle switch.
- If today is before the discount_phase_end_date, the user remains in the Year 1 promotional window and the blended formula from Section 4.4 applies.
- If today is at or after the discount_phase_end_date, Year 2 simple pricing applies per Section 4.5.
4.4 Monthly to Annual Switch — Year 1 Proration (Blended)
- For a Monthly-to-Annual switch during the 12-month promotional window, the system uses the blended formula to compute the annual charge so that the user pays the discounted rate only for the months remaining inside their Year 1 window and the full rate for any months extending beyond that window.
- The discounted_months value equals 12 minus months_used_on_monthly, expressed as a decimal value (for example, 5.5 months).
- The full_price_months value equals months_used_on_monthly, also expressed as a decimal value.
- The discounted_portion of the blended annual equals the current plan's Year 1 monthly rate multiplied by (discounted_months ÷ 12) multiplied by 10.
- The full_price_portion of the blended annual equals the current plan's Year 2 monthly rate multiplied by (full_price_months ÷ 12) multiplied by 10.
- The blended_annual equals discounted_portion plus full_price_portion.
- The unused_credit equals the current plan's Year 1 monthly rate multiplied by (days_remaining_in_monthly_cycle ÷ 30).
- The Due Today amount equals blended_annual minus unused_credit.
- If Due Today is zero or negative, no charge is taken today, a credit balance equal to the absolute value is created, and the credit is applied to the next renewal invoice automatically with access to annual billing granted immediately.
- If Due Today is greater than zero but less than $0.50, the entire amount is deferred to the next invoice rather than being charged today.
4.5 Monthly to Annual Switch — Year 2+ Proration (Simple)
- For a Monthly-to-Annual switch after the 12-month promotional window, the system uses the simple proration formula without any blending.
- The annual_charge equals the current plan's Year 2 annual price.
- The unused_credit equals the current plan's Year 2 monthly rate multiplied by (days_remaining_in_monthly_cycle ÷ 30).
- The Due Today amount equals annual_charge minus unused_credit.
- The same negative-net and sub-$0.50-defer rules from Section 4.4 apply.
4.6 Annual to Monthly Switch — Timing
- An Annual-to-Monthly switch is always deferred and never executes immediately.
- At the moment of scheduling, no charge and no refund occur; the owner's paid annual cycle continues uninterrupted until its end.
- The switch_effective_date equals today plus days_remaining_in_annual_cycle, which is the current annual renewal date.
- On the switch_effective_date, the background job executes the switch: the annual subscription ends, a new monthly cycle begins the same day, and the first monthly charge is processed using the rate defined in Section 4.7.
4.7 Annual to Monthly Switch — First Monthly Charge Rate
- If switch_effective_date is strictly less than discount_phase_end_date, the first monthly charge uses the Year 1 monthly rate because the user is still within the 12-month promotional window on the switch date.
- If switch_effective_date is equal to or greater than discount_phase_end_date, the first monthly charge uses the Year 2 monthly rate because the promotional window has ended by the switch date.
- Subsequent monthly renewals use Year 1 or Year 2 pricing based on whether each renewal date falls inside or outside the discount_phase_end_date window.
4.8 Switch to Monthly Warning Popup
- When the owner initiates an Annual-to-Monthly switch, the system displays a warning popup before proceeding, because switching to Monthly means the owner will pay more per month than the Annual plan's per-month equivalent.
- The popup title is "Switch to Monthly Billing?" and the body reads: "Your billing cycle will switch to Monthly on [Annual End Date]. From that date, you will be charged $[Monthly Price]/month instead of $[Annual Per Month]/month on your current Annual plan. Switching to Monthly means you'll pay more per month over the year compared to Annual billing."
- The popup contains two buttons: "Cancel" and "Schedule Switch".
- The Monthly Price shown in the popup is the current plan's Year 1 monthly rate if the switch will execute before discount_phase_end_date, or the Year 2 monthly rate if the switch will execute at or after discount_phase_end_date.
- The Annual Per Month value equals the current plan's annual price divided by twelve for comparison purposes.
4.9 Monthly to Annual Direct Flow
- A Monthly-to-Annual switch does not show the warning popup because the user is saving money by moving to Annual.
- The flow routes directly from the "Switch to Yearly" call-to-action to the Price Summary preview popup where the owner can review the Year 1 blended or Year 2 simple proration breakdown, optionally enter a coupon code, and confirm payment.
4.10 Price Summary Preview Popup (Cycle Switch)
- The Price Summary preview popup shown for Monthly-to-Annual switches follows the same structure as defined in FRD 3 Section 4.25 and includes the following line items: the unused monthly credit, the blended annual charge (Year 1) or simple annual charge (Year 2+), any promotional discount breakdown if the plan is within the 12-month window, any applied coupon discount, the Total Due Today amount, and the Next Cycle Total (next annual renewal amount).
- The coupon entry field allows the owner to apply a valid discount code; validation follows the same rules as FRD 3 Section 4.26.
- The Confirm and Pay button is disabled immediately on click to prevent duplicate submissions.
- If the switch spans across the discount_phase_end_date (for example, a Monthly-to-Annual switch with some months falling before and some after the Year 1 window), the popup shows up to three pricing periods: Today's price (with promo and coupon applied where eligible), the mid-period price after the coupon expires but the promo still active, and the final price after both expire.
4.11 Paid Extra Seats on Cycle Switch
- Paid extra seats are always billed on a monthly cadence at $9 per seat per month, regardless of whether the main subscription is on Monthly or Annual billing.
- When the main subscription cycle switches from Monthly to Annual, paid extra seats continue to bill monthly at $9 per seat without any change in cadence; there is no upfront annual charge for the extras and no transition from monthly to annual billing for the extras.
- When the main subscription cycle switches from Annual to Monthly, paid extra seats also continue to bill monthly at $9 per seat without any change; the extras were already on monthly billing before the switch.
- Paid extra seats align to their own monthly billing anchor, which is the calendar day on which the first extra seat was purchased, and all subsequent extra seats adopt that same monthly anchor.
- The main subscription (plan base price) and the paid extra seats are billed on the same Stripe subscription object using primary and secondary prices, but they follow different billing cadences when the main subscription is on Annual billing: the main plan charges annually while the extras charge monthly.
- The 50% first-year promotional discount and annual "2 months free" discount do not apply to extra seats at any time; extras always bill at $9 per seat per month at full rate.
4.12 Subscription Page Display During Scheduled Cycle Switch
- When an Annual-to-Monthly switch is scheduled, the Subscription page displays an informational message under the billing cycle section stating: "Your billing cycle will switch to Monthly on [Annual End Date]" along with a "Cancel Switch" option.
- The message and Cancel Switch option are visible to the Owner; the Agency Admin sees the informational message in read-only mode without the Cancel Switch option.
- The message disappears once the scheduled switch is cancelled, replaced, or executed.
4.13 Cancel Scheduled Cycle Switch
- The owner can cancel a scheduled Annual-to-Monthly switch at any time before the execution date from the Subscription page via the "Cancel Switch" option.
- Clicking "Cancel Switch" displays a confirmation popup: "Cancel your scheduled switch to Monthly? Your Annual billing will continue and renew on [Annual Renewal Date]."
- On confirmation, the system removes the scheduled switch record and restores the agency's subscription to show only the Annual cycle with no pending change; the owner receives a confirmation email and in-app notification.
- The owner cannot modify a scheduled switch to a different target (for example, cannot change it to a different plan tier or to a different future date); they must cancel the existing scheduled switch first and then initiate any new action.
4.14 Coexistence of Scheduled Cycle Switch and Scheduled Tier Downgrade
- A scheduled Annual-to-Monthly switch and a scheduled tier downgrade can coexist on the same account because both are scheduled to execute at the end of the current annual cycle.
- The Subscription page displays both scheduled actions separately with their respective Cancel call-to-actions: "Cancel Switch" for the cycle switch and "Cancel Downgrade" for the tier downgrade.
- On the annual end date, the background job executes both scheduled actions together: the plan tier is downgraded per the pending selections in FRD 3, and the billing cycle switches to Monthly; the first monthly charge uses the target downgraded plan's Year 1 or Year 2 monthly rate depending on whether the execution date falls before or at-or-after the discount_phase_end_date.
- If the owner cancels the scheduled downgrade only, the cycle switch remains scheduled and will execute as a cycle-only switch on the same plan tier at the annual end date.
- If the owner cancels the scheduled cycle switch only, the tier downgrade remains scheduled and will execute as a downgrade within the same annual-billed plan tier, keeping the annual billing cycle intact.
4.15 Annual Renewal Pricing Rule
- If the user remains on Annual billing without switching to Monthly, the annual renewal charge on each renewal date follows the rule defined in the billing logic document: renewals that fall before discount_phase_end_date use the blended formula with the updated months_used_on_monthly at that time; renewals at or after discount_phase_end_date use the full Year 2 annual price.
- In practice, for most users whose annual cycle aligns with their subscription_start_date, the first annual renewal falls exactly on discount_phase_end_date and uses the Year 2 annual price.
4.16 Year Determination at Switch Time
- At every cycle switch event, the system computes current_year based on whether today is before or at-or-after discount_phase_end_date.
- If today is earlier than discount_phase_end_date, current_year is 1 and Year 1 rules apply ( blended for Monthly-to-Annual).
- If today is equal to or later than discount_phase_end_date, current_year is 2 or later and simple Year 2 pricing applies.
- The months_used_on_monthly value is measured as a decimal number of 30-day periods since subscription_start_date spent on monthly billing, supporting fractional values.
4.17 Payment Method Routing
- If the owner has a payment method on file at the time of Monthly-to-Annual switch confirmation, the system uses the default payment method to charge the Due Today amount.
- If the owner does not have a payment method on file, the system routes to the Payment page (defined in FRD 6) to collect payment method details before processing the charge.
- The first monthly charge on the Annual-to-Monthly switch execution date uses the payment method on file; if no payment method is available on that date or the charge fails, the standard failed-payment handling from FRD 7 applies.
4.18 Notifications Generated by Cycle Switch Events
- Every successful Monthly-to-Annual switch triggers a confirmation email with the invoice attached and an in-app notification in the Pixally notification center.
- Every scheduled Annual-to-Monthly switch triggers a confirmation email stating the switch execution date and an in-app notification.
- Cancelling a scheduled switch triggers a confirmation email and an in-app notification.
- On the annual end date when a scheduled Annual-to-Monthly switch executes, the system sends a post-execution confirmation email with the first monthly receipt and an in-app notification.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Current Billing Cycle
Read-only text
Values: "Monthly" or "Annual".
Billing Cycle Toggle
Toggle
Values: Monthly, Annual. Shown on Manage Subscription page.
Next Renewal Date
Read-only date
Displayed in the Subscription cycle section; format DD Mon YYYY.
Subscription Amount
Read-only currency
The monthly or annual amount based on current cycle.
Switch to Yearly CTA
Button
Visible only when current cycle is Monthly and user is Owner.
Switch to Monthly CTA
Button
Visible only when current cycle is Annual and user is Owner.
Scheduled Switch Date
System-stored date
Populated when an Annual-to-Monthly switch is scheduled. Cleared on cancel or execution.
Scheduled Switch Message
Read-only text
Format: "Your billing cycle will switch to Monthly on [DD Mon YYYY]". Displayed only when a switch is scheduled.
Cancel Switch CTA
Button
Visible only when a scheduled switch exists.
Unused Monthly Credit
System-derived currency
Calculated per Section 4.4 or 4.5 for M→A switches.
Blended Annual Charge
System-derived currency
Calculated per Section 4.4 Y1 blended formula.
Simple Annual Charge
System-derived currency
Equals Y2 annual price for Year 2+ users.
Due Today
System-derived currency
Annual charge minus unused credit. If ≤ $0: no charge + credit balance. If < $0.50: defer to next invoice.
Next Cycle Total
System-derived currency
Next annual or monthly renewal amount.
Switch Effective Date
System-derived date
For A→M: today + days_remaining_in_annual_cycle.
First Monthly Charge Rate
System-derived
Y1 monthly if switch_effective_date < discount_phase_end_date, else Y2 monthly.
Annual Per Month Value
System-derived currency
Annual price ÷ 12, shown in A→M warning popup for comparison.
Coupon Code (Cycle Switch)
Text input
Same validation as FRD 3 Section 4.26.
Confirm and Pay Button
Button
Disabled on click until response returns.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Monthly-to-Annual switch completed
"You are now on Annual billing. Your next renewal is [Date]."
M→A payment successful.
Subscription page updated to Annual cycle; email + in-app notification.
SM-2
Annual-to-Monthly switch scheduled
"Your switch to Monthly billing has been scheduled for [Annual End Date]."
A→M confirmation successful.
Return to Subscription page; scheduled-switch message shown under cycle section.
SM-3
Scheduled cycle switch cancelled
"Your scheduled switch to Monthly has been cancelled. Your Annual billing will continue."
Owner confirms Cancel Switch.
Scheduled-switch message removed from Subscription page.
SM-4
Scheduled switch executed on annual end
"You are now on Monthly billing. Your next charge will be [Amount] on [Date]."
Background job executes A→M on switch date.
First monthly invoice generated; email + in-app notification.
SM-5
Coupon applied successfully
"Coupon [CODE] applied — [X]% or $[X] discount on your cycle switch."
Coupon validated in Price Summary.
Coupon line item shown in Price Summary.
SM-6
Credit balance created (negative net)
"No charge today. A credit of $[X] has been applied to your account and will be used on your next invoice."
Due Today ≤ $0.
Credit balance stored; next invoice reflects credit.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
M→A payment fails
"Your payment could not be processed. Please check your payment method and try again."
Stripe returns payment failure on M→A switch.
Owner updates payment method; retries switch.
EM-2
Coupon invalid or expired
"This coupon code is not valid or has expired."
Gawd Portal Discounts rejects the code.
Owner removes coupon or enters a valid one.
EM-3
Coupon already used by user
"You have already used a coupon on a previous subscription. Only one coupon per user is allowed."
Email present in coupon usage history.
Owner proceeds without coupon.
EM-4
Switch attempted when user is suspended
"Your account is currently suspended. Please update your payment method to continue."
Agency has an unresolved suspension.
Routes to billing page per FRD 7.
EM-5
Non-owner attempts cycle switch
"Only the agency owner can change the billing cycle. Please contact your agency owner."
Admin or other role reaches the cycle toggle.
User contacts owner.
EM-6
Same-cycle selection (no change)
"You are already on [Cycle] billing."
Owner selects the currently active cycle.
Owner selects a different cycle.
EM-7
Payment method on file declined
"Your card on file was declined. Please update your payment method to continue."
Stripe decline on M→A charge.
Owner updates payment method via FRD 6.
EM-8
A→M first monthly charge fails on execution date
No user-facing error at moment of background execution; FRD 7 failed-payment flow initiates.
Background job charge fails.
Standard failed-payment handling.
EM-9
Owner attempts to modify scheduled A→M switch (not cancel)
"Scheduled switches cannot be modified. Please cancel the existing scheduled switch and try again."
Owner tries to change the switch target or date.
Owner cancels first, then initiates new action.
EM-10
Confirm and Pay double-clicked
No error shown; button is disabled on first click.
User double-clicks.
N/A (prevented by UI).
EM-11
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
Retry or contact support.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Owner on Essentials Monthly Year 1, 5.5 months used on monthly, 15 days remaining in cycle, switches to Essentials Annual.
blended: discounted_portion = $34.50 × (6.5/12) × 10 = $186.88; full_price_portion = $69.00 × (5.5/12) × 10 = $316.25; blended = $503.13. Unused credit = $34.50 × (15/30) = $17.25. Due Today = $485.88. New annual anchor starts today; renewal in 12 months at $690 (Y2 Essentials annual).
EC-2
Owner on Essentials Monthly Year 2, 15 days remaining in cycle, switches to Essentials Annual.
Simple Year 2: Annual charge = $690. Unused credit = $69 × (15/30) = $34.50. Due Today = $655.50. New annual anchor starts today; next renewal in 12 months at $690.
EC-3
Owner on Basic Monthly Year 1, 3.5 months used, switches to Basic Annual.
blended: discounted_portion = $19.50 × (8.5/12) × 10 = $138.13; full_price_portion = $39.00 × (3.5/12) × 10 = $113.75; blended = $251.88. Unused credit = $19.50 × (15/30) = $9.75 (assuming 15 days remaining). Due Today = $242.13.
EC-4
Owner on Studio Annual Year 1, 180 days remaining, switches to Studio Monthly.
Scheduled at annual end (today + 180 days). $0 charged today. On switch date, switch_effective_date = today + 180 days; if < discount_phase_end_date (approx. 185 days out for users aligned with sub start), first monthly = $59.50 (Y1).
EC-5
Owner on Essentials Annual, switch_effective_date equals discount_phase_end_date exactly.
First monthly charge uses Year 2 rate ($69) because the rule in Section 4.7 applies Y2 when switch_effective_date ≥ discount_phase_end_date.
EC-6
Owner on Basic Annual, switch_effective_date is 10 days before discount_phase_end_date.
First monthly charge uses Year 1 rate ($19.50). However, the next monthly renewal 30 days later will fall after discount_phase_end_date and use Year 2 rate ($39).
EC-7
Owner on Basic Monthly with 2 paid extras, switches to Basic Annual on Day 15 of cycle Y1, 5 months used.
blended for Basic annual applies to the base plan only. Extras continue billing monthly at $9/seat without cadence change; no extra-seat proration is added to the M→A Due Today amount; extras continue their own monthly cycle alongside the new annual main plan."
EC-8
Owner on Essentials Annual with 2 paid extras billed monthly schedules A→M switch.
Scheduled at annual end. Extras are unaffected by the switch because they are already billed monthly; they continue at $9/seat per month with no change in cadence before, during, or after the A→M switch.
EC-9
Owner cancels the scheduled A→M switch before execution date.
Scheduled switch removed; annual cycle continues as-is; confirmation email and in-app notification sent.
EC-10
Owner on Studio Monthly Year 1 switches to Studio Annual, Due Today = negative $3 (large unused credit).
No charge today; $3 credit balance created; applied to next renewal invoice; annual access granted immediately.
EC-11
Owner on Essentials Monthly Year 2 switches to Essentials Annual, Due Today = $0.35 (below minimum).
No charge today; $0.35 deferred to next invoice; annual access granted immediately.
EC-12
Owner has scheduled tier downgrade from Essentials Annual to Basic, then schedules A→M switch.
Both scheduled actions coexist. On annual end: plan switches to Basic Monthly; first monthly charge uses Basic Y1 ($19.50) if before discount_phase_end_date, else Basic Y2 ($39).
EC-13
Owner has both scheduled A→M switch and scheduled tier downgrade; owner cancels only the downgrade.
Cycle switch remains scheduled; tier stays on current plan (Essentials). On annual end, only the cycle switches to Monthly on the same plan.
EC-14
Owner has both scheduled actions; owner cancels only the cycle switch.
Tier downgrade remains scheduled; annual cycle preserved. On annual end, plan tier changes to downgraded plan and stays on Annual billing.
EC-15
Owner on Essentials Annual initiates A→M switch; warning popup shown; owner clicks Cancel.
No switch scheduled; Subscription page unchanged; owner remains on Annual cycle.
EC-16
Owner on Monthly cycle applies a coupon at M→A Price Summary; coupon crosses the Year 1 window.
Price Summary shows three pricing periods: Today's price with promo + coupon applied; mid-period after coupon expires but promo still active; final price after both expire.
EC-17
Non-owner (Admin) sees the Subscription page during a scheduled A→M switch.
Scheduled-switch message is visible in read-only mode; Cancel Switch option is not shown.
EC-18
Owner's payment method is declined during M→A switch.
Error EM-7 shown; switch not processed; annual cycle not started; owner updates payment method and retries.
EC-19
Owner tries to switch to the currently active cycle (e.g., Monthly when already on Monthly).
EM-6 shown: "You are already on Monthly billing." Owner selects a different cycle.
EC-20
Owner on Monthly Year 1, 12 months used on monthly exactly at M→A switch time.
blended: discounted_months = 0, full_price_months = 12; blended annual = Y2 annual price. Equivalent to simple Year 2 formula.
EC-21
Owner on Annual Year 2 schedules A→M switch, 30 days remaining in annual cycle.
Switch scheduled at annual end (today + 30 days). switch_effective_date ≥ discount_phase_end_date (which is in the past for Year 2 user), so first monthly charge = Y2 monthly rate.
EC-22
Owner on Annual Year 1, switch_effective_date = 5 days after discount_phase_end_date.
First monthly charge uses Y2 monthly rate because switch is after discount window ends.
EC-23
Owner on Monthly cycle, 0 days remaining (exactly at end-of-cycle), initiates M→A switch.
Unused credit = $0 (no days remaining); Due Today = full annual charge (blended or simple). Switch executes immediately.
EC-24
Annual renewal date arrives for a user who has NOT scheduled any switch or downgrade.
Normal annual renewal per Section 4.15 applies: renewal charge = Y2 annual if renewal date ≥ discount_phase_end_date; blended if before.
EC-25
Owner's account is suspended due to failed payment; owner tries to initiate a cycle switch.
EM-4 shown: "Your account is currently suspended..."; routes to FRD 7 billing update flow.
9. Acceptance Criteria
- The Monthly-to-Annual switch executes immediately on successful payment with Year 1 blended proration for users within the 12-month window, or Year 2 simple proration after the window.
- The Annual-to-Monthly switch is always scheduled to execute at the end of the current annual cycle and does not trigger any immediate charge or refund.
- The Switch to Monthly warning popup is shown before scheduling Annual-to-Monthly and displays the monthly price, the annual-per-month comparison, and a "you will pay more" note.
- The Monthly-to-Annual flow skips the warning popup and goes directly to the Price Summary preview.
- The Price Summary preview popup supports coupon entry and shows the correct proration breakdown including up to three pricing periods when the switch spans the Year 1 window.
- The first monthly charge on the Annual-to-Monthly execution date uses Year 1 monthly pricing if switch_effective_date is strictly before discount_phase_end_date, and Year 2 monthly pricing otherwise.
- The discount_phase_end_date is preserved and is not reset by a cycle switch.
- On Monthly-to-Annual switch, the new annual billing anchor starts today and the annual renewal date is set to today plus 365 days.
- Paid extra seats transition from monthly to annual billing on M→A switch at $108 per seat per year with no promotional discount; on A→M switch they transition back to $9 per month per seat with no refund for unused annual days.
- The Subscription page displays a scheduled-switch message with a Cancel Switch option during any pending Annual-to-Monthly switch.
- The owner can cancel a scheduled switch at any time before execution, with confirmation popup and notifications.
- A scheduled cycle switch and a scheduled tier downgrade can coexist; both execute on the annual end date.
- Cancelling either scheduled action independently leaves the other action intact.
- The Confirm and Pay button is disabled on first click to prevent duplicate submissions.
- Negative-net calculations yield zero charge today with a credit balance created for the next invoice.
- Due Today amounts between $0 and $0.50 are deferred to the next invoice.
- All cycle switch events generate email confirmations and in-app notifications.
- Non-owner users cannot initiate or cancel cycle switches; Admin view is read-only.
- The Agency Admin sees scheduled-switch messages in read-only mode but does not see the Cancel Switch CTA.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Identifies the agency owner and enforces role-based access to cycle switches.
Switch cannot be initiated; owner cannot be authenticated.
Role & Permission Module
Hard
Enforces owner-only access to cycle switch actions.
Non-owner restrictions cannot be enforced.
Subscription Plans Module (FRD 1)
Hard
Provides plan definitions, pricing, and the discount window logic.
Cycle switch pricing cannot be resolved.
Free Trial Module (FRD 2)
Hard
Handles trial-to-paid conversion which sets the subscription_start_date used for Y1 window calculation.
discount_phase_end_date cannot be determined correctly.
Upgrade & Downgrade Module (FRD 3)
Hard
Defines the plan change timing matrix and coexistence rules with scheduled downgrades.
Combined scheduled actions cannot be resolved.
Add-ons Module (FRD 5)
Hard
Governs paid extra seats, which transition billing mode on cycle switches.
Extra seats cannot be correctly billed after switch.
Billing Dashboard + Payment Methods Module (FRD 6)
Hard
Hosts payment method management; routes for missing method during M→A switch.
Payment method collection is blocked.
Failed Payment Management Module (FRD 7)
Hard
Handles failed first-monthly charges on A→M execution and suspended-account blocking.
Failed-payment handling cannot execute.
Notification Module
Hard
Delivers email and in-app notifications for cycle switch events.
Owners miss key confirmations.
Stripe Billing Integration
Hard
Processes charges, applies proration, holds credit balances, generates invoices.
Switches cannot be paid; credits cannot be applied.
Gawd Portal Discounts Module
Hard
Validates coupon codes and tracks coupon usage per email.
Coupons cannot be applied at M→A checkout.
Background Job / Cron Service
Hard
Executes scheduled Annual-to-Monthly switches on the annual end date.
Scheduled switches do not execute on time.
5. Add-ons (Team members)
Add-ons (Team members)
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 23 April 2026
Status:
Version 2.0
FRD 5 — Add-ons (Team Members)
Module: Add-ons — Team Members (Paid Extra Seats) Version: 1.0 Date: April 23, 2026
1. Module Overview
Module Name: Add-ons — Team Members (Paid Extra Seats)
Purpose: This module defines the behavior for purchasing, managing, and billing paid extra team member seats ("extras") beyond a plan's included-seat count. It governs the Invite Team Member flow when plan-included slots are full, the $9 per seat per month pricing, the always-monthly billing cadence for extras regardless of the main plan's cycle, proration on mid-cycle seat purchases and deletions, the automatic promotion of paid extras to plan-included slots when a main-plan slot opens up or on plan upgrade, the visual differentiation of active paid seats versus inactive locked members on the Subscription page, the resend/edit invite capability in Team Management for seats purchased but not yet accepted, and the role assignment requirement at invite time.
Business Goals: The Add-ons module enables agencies to scale their team flexibly without upgrading to a higher plan tier when only a small number of additional seats are needed. It provides predictable flat pricing ($9 per seat per month) with a single monthly billing anchor, protects the owner from accidental charges via mandatory role-assignment on invite, and ensures seamless upgrade economics through automatic seat absorption when plan tiers change.
2. User Roles & Permissions
Role
View Team Management
Invite Team Member (within plan limit)
Purchase Extra Seat
Delete Team Member
Resend/Edit Invite
Assign Role on Invite
Agency Owner
Yes
Yes
Yes
Yes
Yes
Yes
Agency Admin
Yes
Yes
No
Yes (within plan limit)
Yes
Yes
Project Manager
No
No
No
No
No
No
Supervising Editor
No
No
No
No
No
No
Editor
No
No
No
No
No
No
Contractor
No
No
No
No
No
No
Client
No
No
No
No
No
No
Pixally Super Admin (Gawd Portal)
N/A
No
No
No
No
No
3. User Flow
3.1 Invite Team Member — Plan-Included Slots Available
3.1.1 The agency owner or admin navigates to the Team Management module and clicks the "Invite Team Member" button.
3.1.2 The system opens the Invite Team Member modal with fields for email address and role selection.
3.1.3 The user enters the invitee's email address and selects a role from the dropdown (Admin, Project Manager, Supervising Editor, or Editor).
3.1.4 The user clicks "Send Invite" and the system checks plan-included seat availability.
3.1.5 The system confirms that a plan-included slot is available, creates the invite record, and sends an invitation email to the specified address with a join link that is valid for 7 days.
3.1.6 The system displays a success confirmation and the newly invited member appears in the Team Management list with a "Pending Invite" status until the invitee accepts.
3.1.7 The invitee receives the email, clicks the join link, creates an account or signs in with an existing Pixally account, and is added to the agency with the assigned role.
3.1.8 The system notifies the owner via email and in-app notification when the invite is accepted.
3.2 Invite Team Member — Plan-Included Slots Full (Owner)
3.2.1 The agency owner clicks "Invite Team Member" when all plan-included slots are already filled.
3.2.2 The system displays a modal with the message "You've reached your plan's seat limit. [Upgrade Plan] [Add Extra Seat — $9/mo] [Dismiss]"
3.2.3 If the owner clicks "Upgrade Plan", the system routes to the Manage Subscription page per FRD 3.
3.2.4 If the owner clicks "Add Extra Seat — $9/mo", the system opens the Invite Team Member modal with a notice at the top confirming that this invite will add a paid extra seat charged at $9 per month, prorated for the remainder of the current monthly extras cycle.
3.2.5 The owner enters the invitee's email, selects a role, and clicks "Send Invite & Add Seat".
3.2.6 The system displays the prorated charge amount and asks for payment confirmation.
3.2.7 If a payment method is on file, the system charges the prorated amount immediately; if no payment method is on file, the system routes to the Payment page (FRD 6) to collect payment method details.
3.2.8 On successful payment, the system creates the paid extra seat on the subscription, sends the invitation email to the invitee, and displays a success confirmation.
3.2.9 The owner receives a confirmation email with the receipt and an in-app notification.
3.3 Invite Team Member — Plan-Included Slots Full (Admin)
3.3.1 The agency admin clicks "Invite Team Member" when all plan-included slots are already filled.
3.3.2 The system displays the message: "You've reached your plan's limit. Please contact your agency owner to upgrade the plan or add extra capacity."
3.3.3 The admin cannot proceed further; no invite is created.
3.4 Delete Team Member (and Auto-Promote if Applicable)
3.4.1 The owner or admin navigates to the Team Management module and clicks the delete action on a team member row.
3.4.2 The system displays a confirmation popup with the message: "Remove [Member Name] from your agency? This action cannot be undone."
3.4.3 On confirmation, the system revokes the member's access immediately, removes them from project assignments, and marks their seat as vacant.
3.4.4 If the deleted member was occupying a paid extra seat, the system creates a pro-rata credit based on the remaining days in the current monthly extras cycle and applies it to the credit balance on the account, available against the next invoice; the paid seat is removed from the subscription.
3.4.5 If the deleted member was occupying a plan-included slot and the agency has at least one active paid extra seat, the system automatically promotes the oldest paid extra seat (by purchase date — FIFO) to fill the vacated plan-included slot, stops the $9 per month charge for that extra from the next monthly extras cycle, applies the prorated credit for the unused days of that extras cycle to the credit balance, and shows an auto-promote notification to the owner.
3.4.6 If the deleted member was occupying a plan-included slot and the agency has no paid extras, no promotion occurs; the slot simply becomes vacant.
3.5 Resend Invite or Edit Invite Email (Paid Extra Seat Not Yet Accepted)
3.5.1 The owner or admin navigates to the Team Management module and locates a team member row with a "Pending Invite" status.
3.5.2 The user clicks the resend action on the row and the system re-sends the invitation email with a fresh 7-day join link; the paid extra seat remains active and continues to be billed.
3.5.3 The user can alternatively click the edit action on the row to change the invited email address; the system invalidates the original join link, updates the invite record with the new email, and sends a fresh invitation email with a new 7-day link; the paid extra seat remains active and continues to be billed during the re-invite process.
3.5.4 If the invitee accepts the invite at any time while the paid seat is active, the member joins the agency and occupies the paid extra seat.
3.6 Auto-Promote on Plan Upgrade
3.6.1 The owner upgrades the plan tier (handled in FRD 3 upgrade flow) and the new plan's included-seat count is higher than the current plan's.
3.6.2 The system calculates the number of paid extras to absorb: absorbed = minimum(current_extras_count, new_included_count − current_included_count).
3.6.3 The system promotes the absorbed extras in FIFO order (oldest by purchase date first) to plan-included slots, stops the $9 per month charge for each absorbed seat from the next monthly extras cycle, applies a prorated credit for the unused days of each absorbed seat's current extras cycle to the credit balance, and shows an auto-promote notification for each absorbed seat.
3.6.4 Remaining paid extras (if the new plan's included count does not absorb all existing extras) continue at $9 per month per seat without change.
4. Functional Logic
4.1 Extra Seat Availability by Plan
- Paid extra seats at $9 per seat per month are available only on Basic and Essentials plans.
- Studio plan includes unlimited team members at no extra cost, so the paid extra seat concept does not apply to Studio.
- Free plan supports unlimited paid extra seats at $9/mo per seat, identical to Basic and Essentials; the Free plan base is $0 but paid extras are billed monthly, and an account with one or more paid extras on Free is classified as a paid account for the purposes of failed-payment handling per FRD 7. .
- Trial users cannot purchase paid extras; any invite attempt beyond the trial plan's included seats shows the subscribe-first prompt per FRD 2 Section 4.5.
4.2 Extra Seat Pricing
- The extra seat price is fixed at $9 per seat per month (USD) at all times.
- The 50% first-year promotional discount does not apply to extra seats, per FRD 1 Section 4.4.
- The annual "2 months free" savings associated with Annual billing does not apply to extra seats, per FRD 4 Section 4.11.
- Extra seat pricing is hardcoded from client-provided values and is not computed dynamically.
4.3 Always-Monthly Billing Cadence
- Paid extra seats are always billed on a monthly cadence at $9 per seat per month, regardless of whether the main subscription is on Monthly or Annual billing.
- When the agency's main subscription is on Annual billing, the main plan is charged annually while the extras continue to charge monthly on their own cadence.
- When the agency's main subscription is on Monthly billing, the main plan and the extras are both charged monthly but on potentially different anchor dates (the main plan on the plan's monthly anchor, the extras on the extras' monthly anchor as defined in Section 4.5).
- The two cadences coexist on the same Stripe subscription object using primary and secondary prices.
4.4 Extra Seat Proration on Purchase
- When the owner purchases a new paid extra seat mid-cycle, the system calculates a prorated charge for the remaining days of the current monthly extras cycle.
- The prorated charge equals $9 multiplied by (days_remaining_in_extras_cycle ÷ 30).
- The prorated charge is invoiced immediately as a separate line item on the credit card.
- If the prorated amount is less than $0.50, the entire amount is deferred to the next extras invoice rather than charged today.
- From the next monthly extras cycle onward, the full $9 per seat per month rate applies on the extras anchor date.
4.5 Extras Billing Anchor
- The extras billing anchor is the calendar day on which the first-ever paid extra seat was purchased on the agency account.
- All subsequent paid extra seats align to the same anchor date; the system does not create separate anchors for each individual extra seat.
- Once the anchor is established, the monthly extras cycle runs from anchor-day to anchor-day each month (for example, if the anchor is the 15th of the month, the extras invoice generates on the 15th of every month).
- If all paid extras are deleted and later a new paid extra is purchased, the anchor is re-established based on the new purchase date.
4.6 Extra Seat Proration on Deletion
- When the owner or admin deletes a member occupying a paid extra seat mid-cycle, the system creates a prorated credit for the unused days remaining in the current monthly extras cycle.
- The prorated credit equals $9 multiplied by (days_remaining_in_extras_cycle ÷ 30).
- The credit is added to the account's credit balance and applied automatically against the next invoice (either the next extras invoice, the next main-plan invoice, or the next plan-change invoice — whichever is generated first).
- Seat access is revoked immediately on delete; the paid seat is removed from the subscription quantity on the same event.
- If the unused days count is zero (deletion exactly at cycle end), no credit is created.
4.7 Invite Flow When Plan-Included Slots Full (Owner)
- When the owner attempts to invite a team member and all plan-included slots are occupied, the system presents a modal with three actions: Upgrade Plan, Add Extra Seat at $9 per month, and Dismiss.
- The Upgrade Plan action routes the owner to the Manage Subscription page defined in FRD 3.
- The Add Extra Seat action opens the Invite Team Member modal with a notice at the top clarifying that the invite will create a paid extra seat charged at $9 per month, prorated for the remaining days of the current extras cycle.
- The owner must enter the invitee's email and select a role before proceeding.
- On "Send Invite & Add Seat" submission, the system calculates the prorated charge, displays it for confirmation, and processes the charge on the owner's payment method on file (or routes to Payment page per FRD 6 if no method on file).
- On successful payment, the system creates the paid extra seat on the subscription, sends the invite email to the invitee, and notifies the owner via email and in-app notification.
4.8 Invite Flow When Plan-Included Slots Full (Admin)
- When the admin attempts to invite a team member and all plan-included slots are occupied, the system displays the message: "You've reached your plan's limit. Please contact your agency owner to upgrade the plan or add extra capacity."
- The admin cannot proceed further; no invite is created and no paid seat is purchased.
- This restriction enforces the rule that only the agency owner can authorize paid seat purchases because the owner is the billing-responsible party.
4.9 Role Assignment on Invite
- Role selection is mandatory at the time of invite; the Invite Team Member modal has a role dropdown that must be chosen before "Send Invite" is enabled.
- Role options are sourced from the Role and Permission module: Admin, Project Manager, Supervising Editor, Editor.
- The Owner role cannot be selected on invite because there can be only one owner per agency; ownership transfer is out of scope for Phase 1.
- The invitee takes on the assigned role immediately upon accepting the invite.
4.10 Invite Email and Join Link Expiry
- The invitation email is sent via the Notification module using the email channel to the invitee's specified email address.
- The join link embedded in the invitation email is valid for 7 days from the time of sending.
- If the invitee clicks the link after 7 days, the system displays an expired-link message and instructs the invitee to contact the agency owner for a resend.
- The paid extra seat (if purchased) remains active and billed regardless of whether the invitee has accepted the invite.
4.11 Resend Invite and Edit Invite Email
- The owner or admin can resend an invitation email for any Pending Invite member row in the Team Management module; the resend action generates a new 7-day join link without creating a new paid seat or incurring additional charges.
- The owner or admin can edit the invited email address for any Pending Invite member row; editing invalidates the previous join link and sends a fresh invitation email with a new 7-day link to the updated email address.
- During both resend and edit, the paid extra seat (if applicable) remains active and continues to be billed at $9 per month.
- The owner can alternatively delete the pending invite from the Team Management module, which also deletes the associated paid extra seat and creates a prorated credit per Section 4.6.
4.12 Auto-Promote Trigger 1 — Main-Plan Seat Vacated
- When a team member occupying a plan-included slot is deleted, the system checks whether the agency has any active paid extra seats.
- If at least one paid extra exists, the system automatically promotes the oldest paid extra (by purchase date — FIFO ordering) to fill the vacated plan-included slot.
- The promoted seat's $9 per month charge stops from the next monthly extras cycle.
- The system applies a prorated credit for the unused days of the promoted seat's current extras cycle to the credit balance, available against the next invoice.
- The owner receives an auto-promote notification with the message: "Your plan now includes this seat — no additional charges will apply." delivered as an in-app toast notification, an email confirmation, and a visible line item in the next invoice.
- If no paid extras exist when a plan-included slot is vacated, the slot simply becomes empty and no promotion occurs.
4.13 Auto-Promote Trigger 2 — Plan Upgrade With Existing Extras
- When the owner upgrades to a higher plan tier and existing paid extras are present, the system calculates the number of extras to absorb into the new plan's included-seat cap.
- The absorbed count equals minimum(current_extras_count, new_included_count − current_included_count); extras are absorbed in FIFO order (oldest by purchase date first).
- For each absorbed seat, the system stops the $9 per month charge from the next monthly extras cycle, applies a prorated credit for the unused days of that seat's current extras cycle to the credit balance, and sends the auto-promote notification described in Section 4.12.
- When upgrading to Studio (unlimited included seats), all paid extras are absorbed because Studio includes every seat at no extra cost; the absorbed count equals the current_extras_count.
- Remaining paid extras (if the new plan's included count does not absorb all existing extras) continue at $9 per month per seat without change.
4.14 Auto-Promote Notification
- The auto-promote notification is delivered through three channels simultaneously: an in-app toast notification shown on the Subscription page or Team Management module immediately, an email confirmation sent to the owner within a few minutes, and a visible line item on the next invoice showing the stopped charge and the applied credit.
- The message copy is: "Your plan now includes this seat — no additional charges will apply."
- The notification is sent per promoted seat; if multiple seats are promoted in a single event (plan upgrade), the owner receives one consolidated notification listing all promoted seats rather than multiple individual notifications.
4.15 Delete Team Member Equals Cancel Seat
- There is no separate "Cancel Seat" button in the Pixally CRM; seat cancellation is performed by deleting the associated team member.
- The Subscription page displays an informational note next to the "Additional Seats" section: "To cancel an additional seat, remove the associated team member from the Team Management page."
- The note is visible only to the owner to avoid confusing non-owner users who cannot perform billing actions.
4.16 Subscription Page Display of Seats
- The Subscription page "Seats" section displays the total number of seats (plan-included + paid extras), along with the breakdown "[Included] included + [Extra Count] additional" and the "Add Team Member" call-to-action.
- The Team Management module displays individual team members in a single list with two visual states per member: an active paid seat member is shown with a paid-seat icon next to the name, and an inactive or disabled member (locked after downgrade) is shown with a lock icon next to the name.
- Paid-seat icon indicates the member is currently billed as a paid extra at $9 per month.
- Lock icon indicates the member's access has been suspended because they were not selected in a downgrade wizard or their paid seat was removed in a downgrade to Free.
- Active plan-included members display without any special icon (normal row state).
4.17 Admin Role Capabilities
- The agency admin can invite team members into plan-included slots within the plan's limit, and can delete team members.
- The agency admin cannot purchase paid extra seats because extra-seat purchases require billing authorization reserved for the owner.
- When the admin attempts an action that requires a paid extra seat (invite beyond plan-included count), the system displays the "Contact your agency owner" message per Section 4.8.
- The agency admin can resend invites and edit pending invite emails for team members within the plan-included count.
4.18 Payment Method Routing for Seat Purchase
- The payment method routing for extra seat purchase follows the same rules as FRD 3 Section 4.31: if a payment method is on file, the system uses the default method to charge the prorated amount directly; if no payment method is on file, the system routes to the Payment page (FRD 6) to collect payment method details before processing the charge.
- After successful payment collection, the system processes the extra seat purchase and continues to the success confirmation.
4.19 Paid Seats Behavior on Plan Downgrade
- The behavior of existing paid extras during a plan downgrade is governed by FRD 3 Sections 4.13 (Pool A auto-retained) and 4.21 (Paid Extra Seats Carry-Forward on Downgrade).
- On any downgrade (paid-to-paid OR paid-to-Free), existing paid extras (Pool A) automatically carry forward to the new plan at $9 per month per seat without owner action.
- Pool A members cannot be deselected or modified from within the downgrade wizard per FRD 3 Section 4.13; the owner must delete them separately via Team Management if they want to stop those charges before the downgrade executes.
4.20 Notifications Generated by Seat Events
- Every successful paid extra seat purchase triggers a confirmation email with the prorated invoice attached and an in-app notification in the Pixally notification center.
- Every team member deletion triggers a confirmation email to the owner (and to the affected member) and an in-app notification.
- Every auto-promote event triggers the three-channel notification defined in Section 4.14.
- Invite acceptances, resends, and edits generate in-app notifications for the owner; invitees receive their own email notifications for the invite actions.
4.21 Re-Activation of Disabled Team Members from Subscription Page
- The Subscription page exposes two entry points for adding team members: the "Add Seat" button rendered inside the yellow "Plan limits reached" banner per FRD 6, and the "Add Team Member" button rendered next to the seats row in the plan summary card per FRD 6\.
- * Clicking either entry point triggers an eligibility query for re-activation-eligible disabled team members; eligibility requires the disabled member to be in soft-disabled state (downgrade-disabled or owner-disabled, not hard-deleted) and to have a previous brand assignment that is currently accessible on the agency's plan.
- * If at least one eligible member is returned by the query, the system opens a choice popup with the heading "Add team member" and body text "You have disabled members. Re-activate one or invite someone new." The popup contains two horizontally-arranged buttons right-aligned: an outline secondary button labeled "Add existing member" and a yellow primary button labeled "Invite new member". If zero eligible members are returned, the system skips the choice popup and opens the standard Invite Team Member form directly per Section 4.7.
- * Clicking "Invite new member" closes the choice popup and opens the standard Invite Team Member form per Section 4.7; this form itself uses the seat-limit-aware payment behavior per Section 4.7 if the agency is at or above its seat limit.
- * Clicking "Add existing member" closes the choice popup and opens the Add Existing Member modal with a multi-select list of eligible disabled members.
- * The Add Existing Member modal displays a header with title "Add existing member" and subtitle "Your subscription includes {N} seats, with {M} in use. Select the members you want to re-activate. Members beyond your plan limit will be billed as ${X}/month extra seats."
- * Each row in the list displays Name (avatar plus full name plus role pill), Contact (email plus phone), Brand (brand avatar plus brand name), Disabled date, and a Select toggle button.
- * Clicking the Select button toggles the row's selection: outline "Select" button becomes filled yellow "Selected" button and the row background changes to a light yellow tint.
- * Multiple rows may be selected simultaneously; selections are local to the modal and are not persisted on Cancel.
- * The modal evaluates the seat-limit state continuously as the user changes selections and switches between two display modes:
- * Mode A — Within seat limit (count of currently-active members + count of selected disabled members ≤ plan seat limit + currently-purchased paid extras): no banner, no payment breakdown; footer shows "{N} selected" counter, Cancel button, and "Add" yellow button (yellow when ≥1 selected, disabled state when 0 selected).
- * Mode B — Over seat limit (count of currently-active members + count of selected disabled members > plan seat limit + currently-purchased paid extras): amber banner "All seats are currently in use." with body text explaining the extra-seat charge; "DUE TODAY (PRORATED)" section showing each new extra seat as a prorated line item ($9 × days remaining in current cycle / 30 days); "FROM {NEXT MONTH NAME}" section showing next-cycle pricing; footer shows "{N} selected · {N} extra seat{s}" counter, Cancel button, and "Add and Pay ${prorated_total}" yellow button.
- * Pro-ration uses $9/month per extra seat × days remaining in current billing cycle / 30 days; extra seats always bill in 30-day months regardless of the agency's plan billing cycle (monthly or annual) per FRD 5 Section 4.7.
- * Clicking Add (Mode A) re-activates all selected members atomically with no payment; if any individual re-activation fails, the entire batch rolls back and the modal shows an error.
- * Clicking Add and Pay (Mode B) initiates a Stripe charge for the prorated total; on success, paid extras are provisioned per FRD 5 Section 4.7, selected members are re-activated, the modal closes, and email notifications are sent.
- * For each re-activated member: the system auto-restores the member's previous role, brand assignment, and project assignments per FRD 9A Section 4.4; the member receives an email notification "You've been re-added to {Agency Name}" per the Notification Module FRD.
- * The list excludes members whose previous brand is currently locked due to brand cascade per FRD 9A Section 4.3.
- * The Owner can change a re-activated member's role afterward from the Team Management page.
- * The Team Management page's "+ Invite Team Member" call-to-action is unchanged and continues to open the standard Invite Team Member form directly per Section 4.7 with no choice popup; re-activation is exclusively initiated from the Subscription page entry points.
- * Non-owner roles see the same choice popup but the yellow "Invite new member" button is hidden per FRD 9A Section 4.6; the Add Existing Member modal is also accessible to non-owners but the "Add" and "Add and Pay" footer buttons are hidden because non-owners cannot complete payment or trigger re-activation; non-owners see "Please reach out to your agency owner to enable it." messaging.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Invitee Email
Email text
Required. Must be a valid email format. Must not already be a member of the agency.
Role
Dropdown
Required. Values: Admin, Project Manager, Supervising Editor, Editor. Owner role is not selectable.
Invite Status
System-derived
Values: Pending Invite, Active, Expired.
Join Link
System-generated URL
Valid for 7 days from generation. One-time use; invalidated on acceptance or edit.
Seat Type
System-derived
Values: Plan-Included, Paid Extra.
Extras Anchor Date
System-stored date
The calendar day on which the first-ever paid extra was purchased. Persists across add/delete cycles unless all extras are removed.
Days Remaining in Extras Cycle
System-derived integer
Range: 0 to 30. Computed as days from today to the next extras anchor date.
Prorated Seat Charge
System-derived currency
$9.00 × (days_remaining_in_extras_cycle ÷ 30).
Prorated Seat Credit (on delete)
System-derived currency
$9.00 × (days_remaining_in_extras_cycle ÷ 30).
Paid Extras Count
System-derived integer
Count of active paid extra seats at any given time. Used in billing calculations and auto-promote logic.
Add Extra Seat CTA
Button
Visible only to Owner when plan-included slots are full.
Send Invite Button
Button
Enabled only when Email and Role are populated and valid.
Resend Invite Action
Button
Visible on Pending Invite rows. Re-sends a fresh 7-day link without re-charging.
Edit Invite Action
Button
Visible on Pending Invite rows. Opens an email-edit modal; on save, invalidates previous link and sends fresh invite.
Delete Team Member Action
Button
Visible on all member rows to Owner and Admin. Opens confirmation popup.
Paid Seat Icon
Visual indicator
Displayed next to team member name if seat_type = Paid Extra.
Lock Icon
Visual indicator
Displayed next to team member name if member is disabled (post-downgrade).
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Team member invited (plan-included)
"Invitation sent to [email]."
Invite API success.
Member row appears with Pending Invite status; invitee receives email.
SM-2
Extra seat purchased + invite sent
"Extra seat added and invitation sent to [email]. You've been charged $[Prorated] today."
Payment success + invite creation.
Receipt generated; confirmation email + in-app notification.
SM-3
Invite resent
"Invitation resent to [email]."
Resend API success.
New 7-day link active.
SM-4
Invite email edited
"Invitation updated and resent to [new email]."
Edit API success.
Old link invalidated; new link active for 7 days.
SM-5
Team member deleted (paid extra)
"Team member removed. A credit of $[Amount] has been applied to your next invoice."
Delete API success + credit creation.
Seat access revoked; credit balance updated.
SM-6
Team member deleted (plan-included, with extras) auto-promote
"[Member] removed. Your plan now includes this seat — no additional charges will apply."
Delete API + auto-promote success.
$9 charge stops next cycle; prorated credit applied.
SM-7
Team member deleted (plan-included, no extras)
"[Member] removed from your agency."
Delete API success.
Slot vacated; no billing change.
SM-8
Invite accepted by invitee
"[Member] has joined your agency."
Invitee accepts invite.
Member becomes Active.
SM-9
Auto-promote on plan upgrade
"Your plan now includes this seat — no additional charges will apply." (per promoted seat)
Upgrade completion with existing extras.
$9 charges stop next cycle; credits applied.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Admin attempts to purchase paid extra
"You've reached your plan's limit. Please contact your agency owner to upgrade the plan or add extra capacity."
Admin tries to invite beyond plan-included count.
Admin contacts owner.
EM-2
Owner attempts invite on Free plan beyond limit
"Extra seats are not available on the Free plan. Upgrade to Basic or higher to add team members." with Upgrade CTA.
Free user tries to invite a 2nd member.
Owner upgrades or dismisses.
EM-3
Trial user attempts to purchase extra seat
"Extra seats are available only on paid plans. Subscribe to continue, and you can add extra seats as part of your subscription." with Subscribe CTA.
Trial user tries to invite beyond included count.
User subscribes first, then adds seats.
EM-4
Payment method declined on seat purchase
"Your card on file was declined. Please update your payment method to continue."
Stripe decline on prorated charge.
Owner updates payment method via FRD 6.
EM-5
Duplicate invitee email (already a member)
"This person is already a team member of your agency."
Invite email matches existing member.
User enters a different email.
EM-6
Invalid email format on invite
"Please enter a valid email address."
Email field fails format validation.
User corrects email.
EM-7
Role not selected on invite
"Please select a role before sending the invite."
Submit attempted without role.
User selects role.
EM-8
Expired join link clicked by invitee
"This invitation link has expired. Please contact the agency owner for a new invite."
Invitee clicks link after 7 days.
Owner resends invite.
EM-9
Owner attempts to delete themselves
"The agency owner cannot be removed. Ownership transfer is required first."
Owner tries to delete own record.
User does not attempt (Phase 2 flow).
EM-10
Seat purchase when account is suspended
"Your account is currently suspended. Please update your payment method to continue."
Agency has unresolved suspension.
Routes to FRD 7 billing update flow.
EM-11
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
Retry or contact support.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Owner on Basic (2 included, 0 extras) invites 3rd member.
Modal shows [Upgrade Plan] [Add Extra Seat — $9/mo] [Dismiss]. Owner selects "Add Extra Seat", enters email and role, confirms prorated charge (e.g., $4.50 if 15 days remain). Seat purchased, invite sent.
EC-2
Admin on Basic (2 included, 0 extras) invites 3rd member.
System shows: "You've reached your plan's limit. Please contact your agency owner..." Admin cannot proceed.
EC-3
Owner deletes a member occupying a paid extra seat on Day 15 of 30-day extras cycle.
Access revoked immediately. Prorated credit = $9 × (15/30) = $4.50 added to credit balance. Extras count decreases by 1.
EC-4
Owner on Essentials (3 included, 1 extra) deletes a plan-included member.
Main-plan slot vacated. System auto-promotes the oldest paid extra (FIFO) to plan-included slot. $9 charge stops next extras cycle. Prorated credit applied. Auto-promote toast + email sent.
EC-5
Owner on Basic (2 included, 3 extras) upgrades to Essentials (3 included).
Absorbed count = min(3, 3−2) = 1. Oldest extra absorbed as plan-included. 2 extras remain at $9/mo. One auto-promote notification sent.
EC-6
Owner on Basic (2 included, 5 extras) upgrades to Studio (unlimited included).
Absorbed count = min(5, unlimited) = 5. All 5 extras absorbed. Consolidated auto-promote notification lists all 5 seats. No paid extras remain.
EC-7
Invitee does not accept within 7 days; owner resends invite.
System generates new 7-day link and re-sends email. Paid extra seat remains active and billed at $9/mo throughout.
EC-8
Owner realizes they mistyped the email; uses "Edit Invite" to correct.
Original link invalidated. New 7-day link sent to corrected email. Paid extra seat remains active and billed.
EC-9
Owner deletes a Pending Invite row.
Invite invalidated. Associated paid extra seat (if any) removed. Prorated credit for unused days added to credit balance.
EC-10
Owner on Essentials Annual (main plan billed annually) with 2 paid extras.
Main plan charges annually ($345 upfront Y1). Extras charge monthly at $9/seat on extras anchor date. Two separate billing cadences coexist.
EC-11
Owner purchases first-ever extra on Day 15; next extras invoice.
Prorated charge $4.50 today. Extras anchor = Day 15. Next invoice on same calendar day next month for $9/seat.
EC-12
Owner purchases 2nd extra on Day 25 (anchor is Day 15).
Prorated charge for Day 25 to next anchor (Day 15) = $9 × (20/30) = $6.00. Both extras align to same anchor.
EC-13
Owner deletes all extras; later purchases a new extra on a different day.
Old anchor dissolves with last extra deletion. New anchor = new purchase date. Future extras align to new anchor.
EC-14
Owner on Essentials downgrades to Basic; has 3 plan-included + 2 paid extras; selects all 3 in Pool B (opts to pay for 1 as new extra).
Per FRD 3: At cycle end, Basic = 2 included + 1 new extra + 2 carry-forward Pool A extras = 3 extras total. Monthly bill from next cycle: $19.50 Basic Y1 + 3 × $9 = $46.50.
EC-15
Owner downgrades to Free with 2 paid extras.
At cycle end, Pool A (2 paid extras) carries forward to Free at $9/mo each; billing continues uninterrupted. Owner's monthly bill from next cycle: $0 Free + 2 × $9 = $18/mo for extras.
EC-16
Prorated seat charge = $0.35 (below threshold).
Charge deferred to next invoice rather than charged today. Seat is created and invite sent.
EC-17
Prorated seat credit = $0.15 (very small).
Credit balance increased by $0.15. Applied against next invoice.
EC-18
Owner attempts to invite without selecting a role.
"Send Invite" button remains disabled; Role dropdown highlighted as required.
EC-19
Invitee email matches an existing team member.
System rejects with: "This person is already a team member of your agency."
EC-20
Owner's payment method is declined during extra seat purchase.
Error EM-4 shown; seat not purchased; invite not sent.
EC-21
Owner on suspended account attempts to purchase extra seat.
EM-10 shown; routes to billing page per FRD 7.
EC-22
Invite link expires (Day 8+); invitee clicks stale link.
EM-8 shown: "This invitation link has expired. Please contact the agency owner for a new invite."
EC-23
Plan-included member deleted on Free plan (no extras exist).
Slot vacated. No auto-promote (no extras). Slot remains empty.
EC-24
Consolidated auto-promote message on upgrade (e.g., 3 seats absorbed at once).
Single notification listing all 3 promoted seats: "Your plan now includes these seats — no additional charges will apply." Instead of 3 separate toasts.
EC-25
Owner on Essentials Monthly with 2 extras switches to Essentials Annual.
Per FRD 4 §4.11: Main plan prorated + charged annually. Extras unchanged (continue monthly). No annual charge for extras.
EC-26
Owner on Essentials Annual with 2 extras schedules A→M switch.
Per FRD 4 §4.11: Main plan scheduled to switch at annual end. Extras unaffected (already monthly).
EC-27
Owner tries to delete the owner record.
EM-9 shown: "The agency owner cannot be removed. Ownership transfer is required first." (Phase 2 flow.)
EC-28
Owner has 3 disabled members, all from a now-locked brand.
Eligibility query returns zero; clicking Add Seat or Add Team Member opens the invite-new form directly, with no choice popup.
EC-29
Owner has 3 disabled members: 2 from a locked brand and 1 from an accessible brand.
A choice popup appears; the "Add existing member" list shows only the member from the accessible brand.
EC-30
Owner re-activates a member tied to an accessible brand.
The member transitions to active; previous role and brand are auto-restored; project assignments are restored; an email notification is sent.
EC-31
Owner attempts re-activation while at seat limit.
The standard FRD 5 seat-limit flow is triggered; the Owner adds paid seats or upgrades; re-activation completes once a seat is available.
EC- 32
Owner upgrades the plan; a previously locked brand becomes accessible; a previously ineligible member becomes eligible.
On the next click of Add Seat or Add Team Member, the choice popup appears with the now-eligible member in the list.
9. Acceptance Criteria
- Paid extra seats are billed at $9 per seat per month, always on a monthly cadence regardless of the main plan's cycle.
- Extra seats are available only on Basic and Essentials plans; not available on Free or Studio (Studio is unlimited).
- Trial users cannot purchase extra seats; any attempt shows the subscribe-first prompt.
- When an owner invites a team member and plan-included slots are full, a modal offers Upgrade Plan and Add Extra Seat options.
- When an admin invites beyond the plan-included count, the system shows the "contact agency owner" message; admins cannot purchase paid extras.
- Role selection (Admin, Project Manager, Supervising Editor, Editor) is mandatory at invite time.
- The invite email contains a join link valid for 7 days; expired links prompt the invitee to request a new invite.
- Paid extra seats are purchased upfront; if the invitee does not accept, the seat remains active and billed until the owner deletes it.
- The owner or admin can resend an invite or edit the invitee's email from Team Management without re-charging.
- When a plan-included member is deleted and paid extras exist, the oldest paid extra (FIFO) is automatically promoted to fill the vacated slot with the $9 charge stopping from the next extras cycle and a prorated credit applied.
- When the plan is upgraded and existing paid extras are absorbable into the new plan's included count, the oldest extras (FIFO) are absorbed with $9 charges stopped and prorated credits applied.
- The auto-promote notification is delivered via in-app toast, email, and invoice line item simultaneously.
- Paid extras align to a single extras anchor date (the first-ever extra's purchase date); all extras bill on that same anchor.
- Prorated charges or credits below $0.50 are deferred to the next invoice rather than charged/refunded today.
- Delete-team-member equals cancel-seat; a note near the Additional Seats section on the Subscription page clarifies this.
- Active paid seat members display with a paid-seat icon; inactive/disabled members display with a lock icon.
- The agency owner cannot be deleted from Team Management; ownership transfer is Phase 2.
- Payment method routing follows FRD 3 Section 4.31 rules: charge on file directly, or route to Payment page if no method.
- Pool A (existing paid extras) behavior during downgrade follows FRD 3 Sections 4.13 and 4.21.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Identifies the agency owner and invitees for invite flow and access control.
Invite flow cannot execute.
Role & Permission Module
Hard
Provides the role list (Admin, PM, Supervising Editor, Editor) and enforces role-based capabilities.
Role selection dropdown cannot populate.
Team Management Module
Hard
Hosts the Invite Team Member UI, Team list with paid/lock icons, resend/edit/delete actions.
Seat management UI unavailable.
Subscription Plans Module (FRD 1)
Hard
Provides plan-included seat limits and feature entitlements.
Plan-included vs paid-extra determination cannot be made.
Free Trial Module (FRD 2)
Hard
Blocks trial users from purchasing extras.
Trial-user guard cannot be enforced.
Upgrade & Downgrade Module (FRD 3)
Hard
Handles Pool A carry-forward during downgrade and plan-upgrade auto-promote trigger.
Downgrade/upgrade seat transitions cannot be handled.
Billing Cycle Management Module (FRD 4)
Hard
Defines that extras always bill monthly regardless of main cycle; coordinates on M→A and A→M switches.
Cycle-aware extras billing cannot be coordinated.
Billing Dashboard + Payment Methods Module (FRD 6)
Hard
Routes for missing payment method during extra seat purchase.
Seat purchase blocked without payment method collection.
Failed Payment Management Module (FRD 7)
Hard
Handles suspended accounts that cannot purchase seats.
Suspended-state routing cannot be enforced.
Notification Module
Hard
Delivers invite emails, auto-promote notifications, and billing event emails.
Email and in-app notifications fail to deliver.
Stripe Billing Integration
Hard
Processes prorated charges, stores credit balances, bills monthly extras alongside main plan.
Extras cannot be billed or credited.
Background Job / Cron Service
Hard
Runs monthly extras billing on the anchor date.
Extras invoicing fails to execute.
6. Billing Dashboard
Billing Dashboard
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 23 April 2026
Status:
Version 2.0
FRD 6 — Billing Dashboard + Payment Methods
Module: Billing Dashboard + Payment Methods Version: 1.0 Date: April 23, 2026
1. Module Overview
Module Name: Billing Dashboard + Payment Methods
Purpose: This module defines the unified Subscription page that acts as the agency's billing dashboard, hosting the current plan summary, active subscription details, payment method management via Stripe Elements, the Subscription Receipts (invoice history) section with downloadable PDFs, the billing information and tax details capture used by Stripe Tax, and the credit balance display. It governs the primary payment method concept where every agency with an active paid subscription must have exactly one primary card on file at all times, the add-new / set-as-primary / delete actions available on each saved card, the block on deleting the primary method while the account has active recurring charges, and the distinction between subscription-payment methods (credit card only) and the agency's transactional payment methods used when the agency receives money from clients or pays contractors through Pixally.
Business Goals: The Billing Dashboard + Payment Methods module ensures that every agency has a reliable, up-to-date primary payment method at all times to avoid subscription lapse, provides full transparency into past charges through an always-visible Receipts section, and gives the owner a single consolidated page to manage everything subscription-related without navigating across multiple screens. By using Stripe Elements and Stripe Tax for payment-method collection and tax calculation respectively, the module delegates all sensitive card-handling and tax-compliance complexity to PCI-compliant Stripe infrastructure while keeping the Pixally UI lightweight and focused on user actions.
2. User Roles & Permissions
Role
View Subscription Page
View Payment Methods
Add/Delete Payment Method
Set Primary Method
View Receipts / Invoices
Download Invoice PDF
Edit Billing Info
Agency Owner
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Agency Admin
Yes (limited — no billing sections)
No (hidden)
No
No
No (hidden)
No
No
Project Manager
No
No
No
No
No
No
No
Supervising Editor
No
No
No
No
No
No
No
Editor
No
No
No
No
No
No
No
Contractor
No
No
No
No
No
No
No
Client
No
No
No
No
No
No
No
Pixally Super Admin (Gawd Portal)
Yes (read-only)
No
No
No
Yes (read-only)
Yes
No
3. User Flow
3.1 First-time Visit — Free Trial State (No Payment Method Yet)
3.1.1 The agency owner navigates to the Subscription page via the left navigation "Subscription" menu item.
3.1.2 The system displays the plan card showing the current trial status (trial countdown banner, trial plan name, and trial description) alongside the primary call-to-action "Subscribe to [Plan]" and a secondary "View All Plans" call-to-action.
3.1.3 The system displays the Payment Method section in its empty state with an "Add Payment Method" call-to-action; no cards are listed yet because the agency has not entered a paid subscription.
3.1.4 The system displays the Team Members section showing current member count and an "Invite Team" call-to-action.
3.1.5 The system displays the Annual Subscription upsell card promoting the 2-months-free savings for annual billing.
3.1.6 The system displays the Subscription Receipts section in its empty state with the message "No receipts yet. Your payment history will appear here once your trial ends and billing begins."
3.1.7 The owner can choose to subscribe immediately (opens upgrade flow per FRD 3), or add a payment method preemptively (opens the Stripe Elements add-card dialog).
3.2 First-time Visit — Paid Subscription Active
3.2.1 The agency owner navigates to the Subscription page.
3.2.2 The system displays the plan card showing the active plan name, billing cycle, next renewal date, next renewal amount, any scheduled downgrade or cycle switch messages, and any credit balance inline in the plan summary.
3.2.3 The plan card displays the "Change Plan" call-to-action routing to the Manage Subscription page per FRD 3, and the "Cancel Subscription" call-to-action routing to the cancel flow per FRD 8.
3.2.4 The system displays the Payment Method section listing all saved credit cards; the primary card is labelled with a "Primary" badge.
3.2.5 The system displays the Team Members section showing member count and "Invite Team" call-to-action.
3.2.6 The system displays the Subscription Receipts section listing all past charges sorted by most recent first with columns Date, Invoice Number, Description, Amount, Status, and a Download action per row.
3.3 Add Payment Method Flow
3.3.1 The agency owner clicks "Add Payment Method" in the Payment Method section.
3.3.2 The system opens the Stripe Elements payment method dialog with the credit card entry form; the ACH/US bank account option is not available because Pixally accepts only credit cards for subscription payments.
3.3.3 The owner enters card number, expiry date, CVV, billing postal code, and any required billing address fields for Stripe Tax calculation.
3.3.4 The owner clicks "Save Card"; Stripe validates the card via a zero-dollar authorization, tokenizes it, and stores the payment method on the Stripe customer object.
3.3.5 If this is the agency's first saved payment method, the system automatically sets it as the primary payment method.
3.3.6 If the agency already has at least one saved method, the new card is added without changing the existing primary designation; the owner can choose to change the primary later.
3.3.7 The system displays a success confirmation and the new card appears in the Payment Method section with the card brand, last four digits, expiry, and either a "Primary" badge or a secondary state.
3.4 Set as Primary Payment Method Flow
3.4.1 The agency owner opens the three-dot menu on a non-primary saved card in the Payment Method section.
3.4.2 The menu displays two actions: "Set as Primary" and "Delete".
3.4.3 The owner clicks "Set as Primary".
3.4.4 The system confirms the action in a confirmation popup: "Make this your primary payment method? Future charges will go to this card."
3.4.5 On confirmation, the system updates the Stripe customer default payment method to the selected card and moves the "Primary" badge to the selected card on the Payment Method list.
3.4.6 The system sends an in-app notification and a confirmation email that the primary payment method has been updated.
3.5 Delete Payment Method Flow
3.5.1 The agency owner opens the three-dot menu on a saved card and clicks "Delete".
3.5.2 If the selected card is the current primary payment method AND the agency has an active paid subscription (main plan or paid extras), the system blocks the delete action with the message: "You cannot delete your primary payment method while you have an active subscription. Please add another card and set it as primary first, then delete this one."
3.5.3 If the selected card is a non-primary method, or if the card is primary but the account has no active paid subscription, the system displays the confirmation popup: "Remove this payment method? This action cannot be undone."
3.5.4 On confirmation, the system removes the card from Stripe and from the Payment Method section list.
3.5.5 The system sends an in-app notification and a confirmation email that the payment method has been removed.
3.6 Edit Billing Information Flow
3.6.1 The agency owner clicks "Edit Billing Info" from the Subscription page.
3.6.2 The system opens the Billing Information form with fields for Company Name, Billing Address (Street, City, State, ZIP, Country), optional Tax ID, and an optional Invoice CC Email.
3.6.3 The owner updates any of the fields and clicks "Save".
3.6.4 The system validates the fields; Billing Address is required for Stripe Tax calculation.
3.6.5 On successful validation, the system updates the Stripe customer billing details and displays a success confirmation.
3.6.6 Future charges will use the updated billing address for Stripe Tax calculation.
3.7 Download Invoice / Receipt Flow
3.7.1 The agency owner navigates to the Subscription Receipts section on the Subscription page.
3.7.2 The owner clicks the Download action on a receipt row.
3.7.3 The system fetches the invoice PDF from Stripe and initiates a browser download.
3.7.4 The invoice PDF contains line items, tax breakdown, billing address, payment method summary, and the Stripe-generated invoice number.
3.8 Failed Invoice Retry Flow
3.8.1 A past invoice is displayed with "Failed" status due to a declined charge during automated retry.
3.8.2 The owner clicks the "Retry Payment" call-to-action on the failed invoice row.
3.8.3 The system routes to the Failed Payment Management flow per FRD 7 where the owner can update the card and retry the failed charge.
3.9 Gawd Portal — Pixally Super Admin Read-Only View
3.9.1 The Pixally Super Admin navigates through Gawd Portal to view a specific agency's account.
3.9.2 The system displays the agency's Subscription page in read-only mode showing the plan card, Receipts list, and billing information, but does not show Payment Method details (card numbers or saved methods).
3.9.3 The Super Admin can download any invoice PDF for support purposes but cannot modify any billing data.
3.9.4 All read actions are logged in the Gawd Portal audit log.
4. Functional Logic
4.1 Page Scope — Unified Subscription Page
- The Pixally Subscription page is the single unified page for all subscription and billing-related display and actions; there is no separate "Billing Dashboard" page.
- The page is organized into logical sections: Plan Card (top left), Payment Method (top right), Team Members (mid right), Annual Subscription upsell (shown only when applicable), and Subscription Receipts (bottom full width).
- All sections render on a single scrollable page; switching sections is through scrolling, not tabbed navigation.
- Access to the page is governed by the role-based permissions in Section 2; non-owner agency members either see a restricted view (Admin) or cannot access the page (other roles).
4.2 Plan Card — Free Trial State
- When the agency is on an active free trial, the plan card displays the trial countdown in days remaining (with prominent numeric display), a short description confirming trial status ("Your free trial is active. Explore all [Plan] features before subscribing."), and two call-to-action buttons: primary "Subscribe to [Plan]" and secondary "View All Plans".
- The "Subscribe to [Plan]" call-to-action routes the owner directly to the Price Summary preview popup for the trial plan (Studio by default per FRD 2) as a single-step subscribe flow, bypassing the Manage Subscription page; the owner can confirm and pay immediately from there.
- The "View All Plans" call-to-action routes the owner to the Manage Subscription page per FRD 3 for plan comparison and selection.
- The plan card does not display a Cancel Subscription call-to-action during trial because trial cannot be cancelled by the user per FRD 2; the trial either converts to a paid plan when the owner subscribes, or auto-downgrades to Free on Day 15.
- The plan card displays the trial plan name (Studio by default per FRD 2) and shows the features being trialled.
4.3 Plan Card — Active Paid Subscription
- When the agency is on an active paid subscription, the plan card displays the plan name, billing cycle (Monthly or Annual), next renewal date, next renewal amount, and the primary call-to-action "Change Plan" plus a secondary "Cancel Subscription" text link.
- If a scheduled downgrade exists, an informational message is shown under the plan card along with the "Cancel Downgrade" call-to-action per FRD 3.
- If a scheduled cycle switch exists, an informational message is shown along with the "Cancel Switch" call-to-action per FRD 4.
- If both a scheduled downgrade AND a scheduled cycle switch exist simultaneously, the two messages are stacked vertically under the plan card in order — scheduled downgrade message first, scheduled cycle switch message second — with their own independent "Cancel Downgrade" and "Cancel Switch" call-to-actions; cancelling one does not affect the other per FRD 4 Section 4.14.
- If a credit balance is greater than zero, an inline line is added to the plan card summary stating "Credit Balance: $[X] (will be applied to your next invoice)."
- The Change Plan call-to-action routes to the Manage Subscription page per FRD 3; the Cancel Subscription call-to-action routes to the cancel flow per FRD 8.
4.4 Plan Card — Free Plan (No Trial, No Paid Extras)
- When the agency is on the Free plan with no paid extras, the plan card displays "Free Plan" as the name, the feature list, and a primary call-to-action "Upgrade Plan" routing to the Manage Subscription page per FRD 3.
- No renewal date or amount is shown because Free has no recurring charge.
- No Cancel Subscription call-to-action is shown because there is no paid subscription to cancel.
4.5 Plan Card — Free Plan with Paid Extras
- When the agency is on the Free plan with one or more paid extra seats, the plan card displays "Free Plan" as the name, plus a line "Paid Extras: $[X]/mo for [N] additional seats" showing the recurring monthly charge for extras.
- The card shows the next extras billing date as the renewal date (since extras always bill monthly on the extras anchor date per FRD 5 Section 4.5).
- Both "Upgrade Plan" and "Cancel Subscription" call-to-actions are shown because the account is classified as a paid account per NQ-6 once any paid extras exist, and FRD 7 failed-payment handling applies.
4.6 Payment Method Section — Structure
- The Payment Method section displays all saved credit cards on file as individual rows.
- Each card row shows the card brand logo, brand name, masked card number (last four digits), expiry date in MM/YY format, and a "Primary" badge on the primary card.
- If the primary card is expired, the row displays both the "Primary" badge and a red "Expired" warning badge alongside the card details, plus an inline prompt "Please update your payment method to avoid subscription interruption" directing the owner to add a new card; the Primary designation is not automatically removed on expiry.
- A three-dot menu on each row provides two actions: "Set as Primary" (hidden if the card is already primary) and "Delete".
- An "Add Payment Method" call-to-action is always visible at the bottom of the section regardless of how many cards are saved.
- If no cards are saved, the section shows an empty state with only the "Add Payment Method" call-to-action visible.
4.7 Payment Method — Credit Card Only for Subscription
- Pixally accepts credit cards only for subscription payments; ACH and other payment methods are not supported for agency subscription payment.
- The Stripe Elements payment method dialog is configured to show the Card entry form only; the US Bank Account (ACH) and other Stripe payment options are disabled for subscription payments.
- The ACH fees and Credit Card fees displayed on the Manage Subscription pricing page per FRD 3 Section 4.29 refer to Pixally's transaction fees when the agency processes payments from clients or pays contractors through Pixally's money-movement features, and are not related to how the agency pays for its own Pixally subscription.
4.8 Primary Payment Method Rule
- At all times when the agency has an active paid subscription, exactly one saved credit card must be designated as the primary payment method.
- On the first card add, the system auto-sets that card as the primary without any user action.
- When multiple cards are saved, the owner can change the primary designation via the "Set as Primary" menu action on any non-primary card.
- The primary payment method is used automatically for all recurring charges: main-plan renewals, paid-extra seat invoices, upgrade prorations, cycle-switch prorations, and retries after failed charges.
- The Stripe customer object's default_payment_method field stays in sync with Pixally's designated primary method.
4.9 Delete Primary Method Block
- The system blocks deletion of the current primary payment method if the agency has an active paid subscription (main plan paid subscription OR at least one active paid extra seat).
- Attempt to delete the primary under these conditions shows the blocking message: "You cannot delete your primary payment method while you have an active subscription. Please add another card and set it as primary first, then delete this one."
- The owner can delete the primary method freely if the account is fully unsubscribed (no main-plan subscription AND no active paid extras), for example after cancelling the subscription and completing the retention period.
- Non-primary cards can be deleted at any time without restriction.
4.10 Add Payment Method via Stripe Elements
- The Add Payment Method dialog uses Stripe Elements (Payment Element or Card Element) as the embedded collection UI.
- The dialog collects card number, expiry, CVV, and billing postal code at minimum; the full billing address is collected during the initial subscribe flow or can be updated via Edit Billing Info later.
- Stripe performs a zero-dollar or minimal-amount authorization on the card to verify it is valid before saving.
- Stripe tokenizes the card and returns a payment method ID which is stored on the agency's Stripe customer object; Pixally never stores raw card data.
- On save, the dialog closes and the new card appears in the Payment Method section list.
4.11 Stripe Elements — No In-Place Edit
- The Payment Method section does not provide an in-place edit action on saved cards; there is no "Edit" option in the three-dot menu.
- To change any card detail (new expiry, updated billing address, replacement card), the owner adds a new card and deletes the old one.
- This approach avoids the PCI complexity of in-place card edits and aligns with Stripe's recommended practice of card replacement over update.
4.12 Billing Information — Fields and Capture
- The billing address (Street, City, State, ZIP, Country, and optional phone number) is captured by Stripe Elements as part of the Add Payment Method dialog at the time of card entry; Stripe handles the address collection and stores the data on the Stripe customer object.
- The Company Name, Tax ID (optional), and Invoice CC Email (optional) are additional Pixally-owned billing information fields captured via the "Edit Billing Info" form on the Subscription page; these are independent of Stripe's card-collection flow.
- The Billing Address is required by Stripe Tax to compute applicable sales tax; without a valid address captured through Stripe Elements, tax calculation cannot be performed.
- After the initial capture, the billing information can be edited anytime via the "Edit Billing Info" action on the Subscription page; billing address updates route through Stripe's update-billing-details flow, while Pixally-owned fields are saved directly.
- Country selection is handled by Stripe Elements; Pixally does not maintain its own country dropdown.
4.12.1 Trial with Saved Payment Method
- If the owner saves a payment method during the active trial period as a preparatory step, the saved card is stored on the agency's Stripe customer but no charge occurs automatically when the trial ends.
- On Day 15 of the trial, if the owner has not explicitly subscribed to a paid plan, the system auto-downgrades the agency to the Free plan per FRD 2 regardless of whether a card is saved on file.
- Saving a card during trial is an opt-in preparatory action and does not constitute consent to automatic conversion; the owner must explicitly click "Subscribe to [Plan]" and confirm the Price Summary to trigger the first paid charge.
4.13 Tax Calculation via Stripe Tax
- Sales tax is calculated automatically by Stripe Tax using the agency's billing address at the time of each billable event (upgrade, cycle switch, seat purchase, renewal).
- Tax is shown as a separate line item in the Price Summary preview popup per FRD 3 Section 4.25, labelled "Sales Tax" with the applicable rate and amount, and added to the Due Today total.
- For recurring renewals, tax is automatically applied to each invoice based on the current billing address and the current tax rules in effect on the renewal date.
- The Manage Subscription page includes the informational line "Displayed prices do not include any applicable sales tax" per FRD 3 Section 4.29 to set expectation that Stripe Tax will add tax at checkout.
4.14 Subscription Receipts Section
- The Subscription Receipts section displays the complete invoice history for the agency sorted by most recent first; the sort order is fixed and not user-configurable.
- Each row shows Date (invoice creation date from Stripe), Invoice Number (Stripe-generated alphanumeric), Description (Stripe-generated line item summary), Amount (total including tax), Status (Paid, Failed, Open, or Refunded), and a Download action.
- The Download action fetches the invoice PDF from Stripe and triggers a browser download using Stripe's default filename.
- The Receipts list is paginated at 10 rows per page by default with page navigation controls at the bottom; the owner can change the page size to 5, 25, 50, or 100 rows per page via a page-size selector.
- Date range and Status filters are provided above the list for narrowing results; an Invoice Number search field is also provided.
- On an empty state (no receipts), the message "No receipts yet. Your payment history will appear here once your trial ends and billing begins." is shown.
- The Receipts PDF and all email communications are in English only in Phase 1.
4.14.1 Invoice Structure for Mixed-Cycle Billing (Annual Main + Monthly Extras)
- For agencies on Annual main plan billing with paid monthly extras, the invoice structure on the first billing event combines both the annual main plan charge and the first month's extras proration into a single invoice for convenience (for example, Essentials Annual $345 + 2 extras prorated = $363 on the first invoice).
- From the second month onward, the Receipts list shows monthly extras-only invoices (for example, 2 extras × $9 = $18 per month) until the next annual renewal.
- At annual renewal, a new annual main-plan invoice is generated separately from the ongoing monthly extras invoice; the two do not combine at renewal time.
- For agencies on Monthly main plan billing with paid monthly extras, the main plan and extras invoices may combine on shared anchor dates or appear as separate invoices depending on Stripe's invoice-grouping behavior; the Receipts list reflects the actual generated invoices without modification.
4.15 Failed Invoice Retry Action
- A receipt row with Status "Failed" displays a "Retry Payment" call-to-action alongside the Download action.
- Clicking "Retry Payment" routes the owner to the Failed Payment Management flow per FRD 7 where the owner can update the card and retry the charge.
- The retry routing is the only manual intervention available from the Receipts section; there is no manual "Pay Now" button for Open (unpaid but not failed) invoices because Stripe's automated collection handles Open invoices via scheduled retries.
4.16 Credit Balance Display
- When a credit balance is greater than zero, the plan card on the Subscription page displays an inline line: "Credit Balance: $[X] (will be applied to your next invoice)."
- The credit balance is also reflected on the next invoice as a deduction line item when the invoice is generated.
- The credit balance is automatically consumed against the next invoice in FIFO order (oldest credit applied first); no user action is required to apply credits.
4.17 Admin Role — No Billing Visibility
- Agency Admins do not see the Payment Method section, the Subscription Receipts section, the Billing Information section, or the Credit Balance inline line on the plan card.
- The Subscription page rendered for Admins shows only the plan card (name, cycle, renewal date) and the Team Members section for context.
- This restriction ensures that billing-sensitive information is accessible only to the agency Owner who is the billing-responsible party.
4.18 Gawd Portal — Read-Only Billing View
- The Pixally Super Admin accessing an agency's account through Gawd Portal sees a read-only version of the Subscription page with the plan card, Receipts list, and Billing Information visible.
- Payment Method details (saved cards and their last-four digits) are not shown in Gawd Portal to protect user privacy; the Super Admin can see that a primary card exists but cannot see card identifying information.
- Invoice PDFs can be downloaded by the Super Admin for support purposes.
- All actions taken in Gawd Portal are recorded in the Gawd Portal audit log.
- The Super Admin cannot modify any billing data, change plans, update payment methods, or cancel subscriptions through Gawd Portal; plan changes must be initiated by the agency owner only per FRD 1 permissions.
4.18.1 Refund Flow — Pixally Super Admin Only
- Refunds are handled exclusively by the Pixally Super Admin through the Gawd Portal as a support-only action; the agency owner cannot self-serve a refund from the Subscription page in Phase 1.
- The Super Admin initiates a refund on a specific past invoice by accessing the agency's Receipts list in Gawd Portal, selecting the invoice, and triggering the refund action via Stripe's refund API.
- A refund can be full (entire invoice amount) or partial (specific line items or a custom amount); the refund reason is recorded in the Gawd Portal audit log.
- On successful refund, the invoice status on the agency's Subscription page flips to "Refunded" (blue badge) and an email confirmation is sent to the owner.
- The refunded amount returns to the original payment method on file.
- There is no refund initiation UI visible to the agency owner; all refund requests must be made through Pixally support channels.
4.19 Payment Method Routing from Other Flows
- When the owner initiates an upgrade, cycle switch, or extra seat purchase and no payment method is on file, the respective flow routes to the Add Payment Method dialog defined in this module before processing the charge.
- This routing is referenced from FRD 3 Section 4.31, FRD 4 Section 4.17, and FRD 5 Section 4.18; in all cases the Add Payment Method dialog behaves identically as described in Section 4.10.
- After successful card add, the originating flow resumes with the charge processed on the newly added (now primary) card.
4.19.1 Stripe Webhook Handling for Async Events
- Asynchronous billing events from Stripe (payment succeeded, payment failed, invoice finalized, subscription updated, refund processed) are delivered to the Pixally backend via Stripe webhooks.
- On receiving a webhook, the backend updates the relevant subscription state, invoice status, and credit balance records in Pixally's database.
- The Subscription page UI fetches the latest state from the Pixally backend on page load, section refresh, or user navigation; there is no WebSocket or real-time push to the UI in Phase 1.
- If the owner is actively viewing the Subscription page when an async event occurs, the updated state will appear on the next page reload or section refresh; the UI does not automatically poll for changes in Phase 1.
- Any critical user-impacting events (failed payment, subscription suspension, refund processed) also trigger immediate in-app notifications and emails so the owner is alerted even without viewing the Subscription page.
4.20 Transactional Email — No Opt-Out
- Billing-related emails are transactional and cannot be opted out of; these include successful payment receipts, failed payment alerts, upcoming renewal reminders, subscription confirmation emails, and credit balance notifications.
- Emails are sent to the Agency Owner's primary email address and, if specified, to the Invoice CC Email on the Billing Information.
- Marketing and promotional emails (feature announcements, upsell offers) are governed by separate email preferences and can be opted out of; those are handled outside this FRD.
4.21 Currency Scope
- All billing in Phase 1 is in US Dollars (USD) only.
- Multi-currency support is out of scope for Phase 1 and is expected in a future release.
- The Subscription page and all receipts display amounts in USD with the "$" prefix.
4.22 Notifications Generated by Billing Events
- Every successful recurring charge (main plan renewal, extras monthly charge) triggers a receipt email with the invoice PDF attached.
- Every successful one-time charge (upgrade proration, cycle switch proration, seat purchase proration) triggers a receipt email.
- Every failed charge triggers the failed-payment notification per FRD 7.
- Every payment method add, set-as-primary, or delete triggers an in-app notification and a confirmation email.
- Every billing information update triggers an in-app notification and a confirmation email.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Current Plan Name
Read-only text
Values: Free, Basic, Essentials, Studio, or [Plan] — Free Trial.
Billing Cycle
Read-only text
Values: Monthly, Annual, or Trial.
Next Renewal Date
Read-only date
Format: DD Mon YYYY. Shown only when subscription is active.
Next Renewal Amount
Read-only currency
Shown only when subscription is active. Includes tax at renewal.
Credit Balance
Read-only currency
Inline on plan card when > $0.
Change Plan CTA
Button
Visible to Owner only. Routes to Manage Subscription (FRD 3).
Cancel Subscription CTA
Text link
Visible to Owner only when account has active paid subscription. Routes to Cancel flow (FRD 8).
Subscribe to [Plan] CTA
Button
Visible only during free trial state. Routes to checkout flow.
View All Plans CTA
Button
Visible during trial and on Free plan. Routes to Manage Subscription.
Card Brand Logo
Visual
Auto-detected from card number (Visa, Mastercard, Amex, Discover, etc.).
Card Last 4 Digits
Display text
Masked; shown as "•••• 4242".
Card Expiry
Display text
Format: MM/YY.
Primary Badge
Badge
Displayed only on the current primary method.
Set as Primary Action
Menu item
Hidden on current primary method.
Delete Payment Method Action
Menu item
Always visible; blocked per Section 4.9 for primary with active sub.
Add Payment Method CTA
Button
Always visible in Payment Method section.
Company Name
Text input (Pixally)
Required for Billing Info. Max 255 chars.
Billing Address (full)
Stripe Elements collection
Collected by Stripe Elements during card entry; includes Street, City, State, ZIP, Country, and optional phone number. Stripe handles field rendering and validation.
Tax ID
Stripe Elements collection
Optional. Stripe handles capture and format validation per country.
Invoice CC Email
Email input (Pixally)
Optional. Must be valid email format if provided.
Receipts Table — Date
Display date
Format: DD Mon YYYY.
Receipts Table — Invoice #
Display text
Stripe-generated, alphanumeric.
Receipts Table — Description
Display text
Stripe-generated line item summary.
Receipts Table — Amount
Display currency
Total including tax.
Receipts Table — Status
Badge
Values: Paid (green), Failed (red), Open (grey), Refunded (blue).
Download Invoice Action
Button
Triggers PDF download from Stripe.
Retry Payment Action
Button
Visible only on Failed status rows. Routes to FRD 7.
Date Range Filter
Date picker range
Optional. Narrows Receipts list.
Status Filter
Dropdown
Optional. Filters Receipts list by status.
Invoice Number Search
Text input
Optional. Matches against Invoice # column.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Payment method added
"Your card ending in [last4] has been added."
Stripe card save successful.
Card appears in list; if first card, set as primary automatically.
SM-2
Payment method set as primary
"Your primary payment method has been updated."
Set as Primary action successful.
Primary badge moves to selected card; email + in-app notification.
SM-3
Payment method deleted
"Payment method ending in [last4] has been removed."
Delete action successful.
Card removed from list; email + in-app notification.
SM-4
Billing info updated
"Your billing information has been updated."
Edit Billing Info save successful.
Stripe customer updated; future invoices use new info.
SM-5
Invoice PDF downloaded
No inline success message; browser download begins.
Download action clicked.
PDF downloaded to user's device.
SM-6
First-time card add (auto-primary)
"Your card ending in [last4] has been added and set as your primary payment method."
First card save on account with no existing methods.
Primary badge shown on the new card.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Card declined on save
"Your card was declined. Please check the card details or try a different card."
Stripe zero-dollar authorization fails.
Owner re-enters or uses different card.
EM-2
Card expired
"This card has expired. Please use a valid card."
Stripe rejects expired card.
Owner uses a different card.
EM-3
Delete blocked — primary with active subscription
"You cannot delete your primary payment method while you have an active subscription. Please add another card and set it as primary first, then delete this one."
Owner attempts delete on primary card while account is active.
Owner adds another card first.
EM-4
Billing address rejected by Stripe Tax
"Please enter a valid billing address. Tax cannot be calculated without complete address." (Shown within Stripe Elements UI.)
Stripe Tax rejects address during card entry.
Owner corrects address in Stripe Elements.
EM-5
Invoice CC Email invalid format
"Please enter a valid email address."
Email fails format validation on Pixally form.
Owner corrects email.
EM-6
Non-owner attempts billing action
"Only the agency owner can manage billing. Please contact your agency owner."
Admin or other role tries a billing action.
User contacts owner.
EM-7
Stripe API error (generic)
"We couldn't complete this action due to a temporary issue. Please try again in a moment."
Stripe API returns error.
Retry.
EM-8
Invoice PDF fetch failure
"Unable to download invoice at this time. Please try again or contact support."
Stripe invoice fetch fails.
Retry or contact support.
EM-9
Attempt to delete primary when account has paid extras on Free plan
"You cannot delete your primary payment method while you have active paid extra seats. Please remove the extra seats first or add an alternative payment method."
Delete attempted on primary card while Free+extras account.
Owner removes extras or adds alt card.
EM-10
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
Retry or contact support.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Owner adds first-ever payment method during free trial (pre-subscribe).
Card added to Stripe customer. Card appears in Payment Method section with "Primary" badge. No immediate charge occurs. Card is ready for use when owner subscribes.
EC-2
Owner has 2 saved cards; deletes non-primary card.
Non-primary card removed without restriction. Primary card remains primary.
EC-3
Owner has 2 saved cards; attempts to delete primary card.
System blocks with EM-3. Owner must "Set as Primary" on the other card first, then delete the original primary.
EC-4
Owner has 1 saved card (primary); cancels subscription and enters retention period; attempts to delete the primary card.
If account has no active paid subscription (main plan cancelled AND no paid extras), delete proceeds without block. If subscription is still in its final paid cycle (cancelled but not yet ended), the card stays as primary until the cycle ends and then can be deleted.
EC-5
Owner on Free plan with 2 paid extras; attempts to delete primary card.
System blocks with EM-9 because account is classified as paid (has paid extras). Owner must delete extras first or add alternative card.
EC-6
Owner attempts to add ACH / US Bank Account as a payment method.
Stripe Elements is configured to show Card tab only; ACH tab is not presented. If user arrives at legacy URL with ACH, system shows "Only credit cards are accepted for subscription payments."
EC-7
Owner's card on file expires during active subscription.
FRD 7 failed payment flow initiates when the next charge fails. Owner receives notification to update card. Primary card remains until explicitly deleted or replaced.
EC-8
Owner subscribes and enters billing address; address is invalid per Stripe Tax.
EM-4 shown during initial checkout. Owner corrects address and retries. Subscription does not activate until valid address is captured.
EC-9
Credit balance > $0 is applied against next invoice.
Invoice shows credit deduction line item (e.g., "Credit Applied: −$4.50"). Remaining amount charged to primary card. Plan card inline credit line updates to reflect remaining credit after application.
EC-10
Receipts list has 150 invoices over 2 years.
Paginated at 10 per page. 15 pages total. Owner can use date filter and status filter to narrow.
EC-11
Owner downloads an invoice PDF.
Browser downloads the Stripe-generated PDF containing line items, tax breakdown, billing address, and invoice number.
EC-12
Failed charge retried from Receipts section.
"Retry Payment" button routes owner to FRD 7 flow. Owner updates card and retries; on success, invoice status flips from Failed to Paid.
EC-13
Admin user visits Subscription page.
Subscription page renders with plan card and Team Members section only. Payment Method, Receipts, Billing Info, and Credit Balance inline are hidden entirely.
EC-14
Pixally Super Admin views agency billing via Gawd Portal.
Read-only Subscription page shown with plan card, Receipts list, and Billing Info visible. Payment Method details not shown. Invoice PDFs downloadable. Action logged.
EC-15
Owner updates billing address after first charge.
Billing info saved. Future invoices use new address for Stripe Tax. Past invoices are not re-issued with the new address.
EC-16
Owner has no primary card on file and tries to subscribe from trial.
Subscribe flow prompts owner to add payment method first via the same Add Payment Method dialog. On successful card add, the card is auto-set as primary and the subscribe flow resumes.
EC-17
Invoice with status Open displayed in Receipts.
Invoice row shown with Open status badge (grey). No manual Pay Now button. Stripe's automated collection handles the charge per its retry schedule; if it ultimately fails, status flips to Failed and Retry Payment button appears.
EC-18
Owner updates primary card mid-cycle (deletes old primary after setting new primary).
New primary card is used for the next recurring charge. Old card can be deleted after primary is transferred. Any pending charges between the switch and deletion use the new primary.
EC-19
Owner has $0 credit balance.
Credit Balance inline line is not shown on plan card; no indicator of zero credit.
EC-20
Free plan user with paid extras has a declined extras charge.
Failed invoice appears in Receipts with Retry Payment button. FRD 7 flow begins (28-day grace; full access retained during grace for the main plan, which is Free anyway; extras access continues until grace ends).
EC-21
Trial user saves a card during trial, then trial ends on Day 15 without user explicitly subscribing.
Per FRD 2, agency auto-downgrades to Free on Day 15. No automatic charge occurs on the saved card even though it is on file. Saved card remains on Stripe customer for future use.
EC-22
Owner has BOTH scheduled tier downgrade AND scheduled cycle switch (A→M) at the same time.
Plan card displays both messages stacked vertically: scheduled-downgrade message first with Cancel Downgrade CTA, scheduled-switch message second with Cancel Switch CTA. Cancelling one does not affect the other.
EC-23
Primary card on file is expired (expiry date in past) but still saved.
Payment Method section shows the card row with both "Primary" badge and red "Expired" warning badge, plus inline prompt "Please update your payment method to avoid subscription interruption". Primary designation is not removed automatically. Next recurring charge will likely fail and trigger FRD 7 flow.
EC-24
Owner on Essentials Annual ($345/yr) purchases 2 paid extras mid-annual-cycle; views Receipts.
First invoice shows combined line: Annual main plan charge + first-month prorated extras (e.g., $345 + $4.50 for half-month prorated extras = $349.50). Subsequent monthly invoices show extras-only charges ($18/mo for 2 extras) until annual renewal. At renewal, a new annual main-plan invoice is generated separately from the ongoing monthly extras invoices.
EC-25
Pixally Super Admin processes a full refund on a past invoice through Gawd Portal.
Refund initiated via Stripe API; invoice status flips to "Refunded" (blue badge) on the agency's Receipts list; refunded amount returns to the original payment method; owner receives email confirmation; action logged in Gawd Portal audit log. Owner has no self-serve refund initiation UI.
EC-26
Owner owns 2 separate Pixally agencies using the same email address.
Each agency has its own Stripe customer object, its own primary payment method, and its own Receipts list; payment methods and billing information are not shared across agencies. Owner switches between agencies via the account switcher.
EC-27
Async event (payment succeeded, failed, refund processed) occurs while owner is viewing Subscription page.
Updated state from Stripe webhook is persisted in Pixally backend; the Subscription page UI reflects the new state on next page load, section refresh, or navigation. UI does not auto-poll in Phase 1. Critical events (failed payment, refund) also trigger immediate in-app notifications and emails.
EC-28
Owner clicks "Subscribe to Studio" during active Studio trial.
Routes directly to Price Summary preview popup for Studio plan; bypasses Manage Subscription page for this single-step subscribe flow. On confirm and pay, trial converts to active paid Studio subscription.
9. Acceptance Criteria
- The Subscription page is a single unified page that hosts plan card, payment method section, team members section, subscription receipts, and billing information; no separate Billing Dashboard page exists.
- During free trial, the plan card shows trial countdown, Subscribe call-to-action routing directly to Price Summary preview for the trial plan, View All Plans routing to Manage Subscription, and no Cancel Subscription option.
- Subscribing during trial bypasses the Manage Subscription page and takes the owner directly to the Price Summary preview popup for the trial plan.
- For active paid subscription, the plan card shows plan name, cycle, next renewal date, next renewal amount, Change Plan CTA, and Cancel Subscription text link.
- Scheduled downgrade and scheduled cycle switch messages are displayed independently and can coexist; each has its own Cancel CTA.
- Credit balance > $0 is displayed inline on the plan card.
- Pixally accepts credit cards only for subscription payment; ACH is not supported for subscription.
- Payment methods are collected via Stripe Elements with card tokenization; raw card data never touches Pixally servers.
- Billing address, country, and tax ID are collected by Stripe Elements during card entry; Pixally-owned fields (Company Name, Invoice CC Email) are captured via Edit Billing Info form.
- On first card add, the system auto-sets the card as the primary payment method.
- Each payment method row has a three-dot menu with "Set as Primary" (hidden on current primary) and "Delete" actions only; no "Edit" action.
- An expired primary card displays both "Primary" and red "Expired" warning badges along with a prompt to update.
- The primary payment method cannot be deleted if the account has an active paid subscription (main plan or paid extras); the owner must add an alternative and switch primary first.
- A saved card during trial does not trigger an automatic charge when the trial ends; the owner must explicitly subscribe.
- Stripe Tax (a paid Stripe add-on enabled for Pixally) calculates sales tax automatically using the billing address and adds the tax as a line item in Price Summary and on each invoice.
- Subscription Receipts section displays the complete invoice history sorted by most recent first with Date, Invoice #, Description, Amount, Status, and Download actions.
- Receipts list paginates at 10 per page by default; page size selector offers 5, 25, 50, 100 options.
- Invoice PDFs are downloadable via the Download action using Stripe's default filename; invoices are in English only in Phase 1.
- For Annual main plan plus monthly extras, the first month's invoice combines both; subsequent months show extras-only until annual renewal.
- Failed invoice rows show a Retry Payment button routing to FRD 7.
- Open invoice rows do not show a manual Pay Now button; Stripe's automated collection handles open invoices.
- Refunds are initiated only by Pixally Super Admin via Gawd Portal; owner has no self-serve refund UI in Phase 1.
- Stripe webhook events update Pixally backend state; UI reflects updates on page load or navigation, with immediate push notifications for critical events.
- Payment methods are per-agency; owners with multiple agencies maintain separate payment methods for each.
- Agency Admins cannot view any billing sections; only the plan card and team members section are rendered for Admin.
- Pixally Super Admin (Gawd Portal) has read-only access to plan card, Receipts, and billing info, but not payment method details; actions are logged.
- Transactional billing emails cannot be opted out of and are sent to Owner's email and Invoice CC Email.
- All billing in Phase 1 is USD only.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Identifies the agency owner for access to Subscription page and billing actions.
Owner cannot access subscription management.
Role & Permission Module
Hard
Enforces Owner-only access to billing sections; restricts Admin and other roles.
Billing access cannot be restricted appropriately.
Subscription Plans Module (FRD 1)
Hard
Provides current plan details, Plan Usage Matrix, feature entitlements shown on plan card.
Plan card cannot render plan info.
Free Trial Module (FRD 2)
Hard
Provides trial state, countdown, and subscribe flow for trial users.
Trial state cannot be displayed on plan card.
Upgrade & Downgrade Module (FRD 3)
Hard
Change Plan CTA routes to Manage Subscription; Price Summary uses tax from Stripe Tax.
Plan change flow broken.
Billing Cycle Management Module (FRD 4)
Hard
Scheduled cycle switch messages shown on plan card; Cancel Switch CTA hosted here.
Cycle switch messages cannot render.
Add-ons Module (FRD 5)
Hard
Paid extras count and monthly charge shown on plan card for Free+extras accounts.
Extras info cannot render.
Failed Payment Management Module (FRD 7)
Hard
Retry Payment from failed invoice rows routes here; suspended state handling.
Failed-payment flow cannot be initiated.
Cancel Subscription Module (FRD 8)
Hard
Cancel Subscription CTA routes to this module.
Cancel flow cannot be initiated from plan card.
Gawd Portal Module
Soft
Provides Super Admin read-only billing view.
Super Admin cannot view agency billing.
Notification Module
Hard
Sends transactional billing emails and in-app notifications.
Users miss critical billing notifications.
Stripe Billing Integration
Hard
Stores payment methods via Payment Element/Card Element, generates invoices and PDFs, handles tax calculation via Stripe Tax.
Payment methods cannot be saved; invoices cannot be generated.
Stripe Tax
Hard
Calculates sales tax on all charges based on billing address.
Tax calculation fails; checkout blocked or incorrect.
Background Job / Cron Service
Hard
Triggers recurring charges per Stripe subscription schedule.
Recurring billing fails to execute on time.
12. References
- Figma Design — Subscription Page Main View (Trial State): Pixally Figma 04-20-2026 overview screen
- Figma Design — Stripe Elements Payment Details (Saved / Card / US Bank Account tabs): Batch 1, Image 5, Image 6
- Figma Design — Subscription Receipts Empty State: Pixally Figma overview screen
- Figma Design — Plan Comparison Page with Fee Display: Batch 2, Image 25
- Source of Truth — Subscription Module Logic Meeting: April 20, 2026 (PDF + JSON transcript)
- Source of Truth — Subscription Logic Discussion (Hinglish): April 21, 2026
- Source of Truth — Subscription Billing & Proration Logic Document: Provided April 22, 2026
- Related FRDs:
- FRD 1 — Subscription Plans with Access Control (plan-card info source)
- FRD 2 — Free Trial (trial-state plan card, no cancel option)
- FRD 3 — Upgrade & Downgrade (Section 4.25 Price Summary, Section 4.29 Plan Comparison Page, Section 4.31 Payment Method Routing)
- FRD 4 — Billing Cycle Management (scheduled switch messages on plan card)
- FRD 5 — Add-ons (Team Members) (paid extras display, Section 4.18 Payment Method Routing)
- FRD 7 — Failed Payment Management (Retry Payment, suspension state)
- FRD 8 — Cancel Subscription
- Gawd Portal FRD
- Notification Module FRD
- Stripe Integration Technical Spec
End of FRD 6 — Billing Dashboard + Payment Methods
7. Failed Payment Management
Failed Payment Management
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 24 April 2026
Status:
Version 2.0
FRD 7 — Failed Payment Management
Module: Failed Payment Management Version: 1.0 Date: April 24, 2026
1. Module Overview
Module Name: Failed Payment Management
Purpose: This module defines the complete lifecycle for handling recurring payment failures on the Pixally CRM platform. It governs Stripe Smart Retries for automated payment retry attempts, the 28-day grace period that begins from the first failed charge, the amber grace-period banner that appears on the Dashboard and Subscription pages after Stripe's three retries fail, the five-touchpoint email and in-app notification schedule during grace, the transition to indefinite account suspension on Day 29, the suspension experience for the Agency Owner (Subscription page only with red suspension banner, no left navigation, selective button greyouts), the dedicated "Account is Suspended" full-page screen shown to all non-Owner roles on login during suspension, the manual Pay Invoice action that opens the Retry Payment choice dialog, the reactivation flow that charges the original failed invoice plus the current month's full charge (skipping invoices for suspended months), the assignment of a new billing cycle anchor on reactivation, and the pausing of all background automations during suspension. It also defines the distinct treatment of one-time charge failures (upgrade, cycle switch, seat purchase) which do not trigger the grace period, as well as the special handling of Free plan accounts with paid extras that behave as paid accounts for failed-payment purposes per FRD 5.
Business Goals: The Failed Payment Management module protects Pixally's recurring revenue by automating the collection of failed payments through Stripe Smart Retries before resorting to human-visible intervention, gives agency owners a fair 28-day window to resolve billing issues without losing access to their workspace and data, prevents indefinite free usage by suspending accounts that remain unpaid beyond the grace period, and provides a clean reactivation path that collects the minimum required charges (original failed invoice plus current month) without burdening the user with back-charges for suspended months they could not use. By pausing the Stripe subscription on Day 29 rather than generating accumulating failed invoices during suspension, the module keeps Stripe data and Pixally records clean and predictable. The module is critical to subscription revenue health and sets clear expectations for both owners and their team members when billing issues arise.
2. User Roles & Permissions
Role
Grace Banner (Day 1-28)
Click "Update Payment"
Pay Invoice During Suspension
Cancel Subscription
Access During Suspension
Agency Owner
Yes (banner on Dashboard + Subscription page with "Update Payment" and "Contact Support" CTAs)
Yes — routes to Payment Method section
Yes — opens Retry Payment choice dialog
Yes (during grace or suspension)
Only Subscription page accessible (no left nav); red suspension banner shown
Agency Admin
Yes (banner visible; "Update Payment" CTA shows "Contact owner" message)
No — message: "Contact owner"
No
No
Redirected to "Account is Suspended" full-page screen on login
Project Manager
No (no access to Dashboard or Subscription page)
No
No
No
Redirected to "Account is Suspended" full-page screen on login
Supervising Editor
No
No
No
No
Redirected to "Account is Suspended" full-page screen on login
Editor
No
No
No
No
Redirected to "Account is Suspended" full-page screen on login
Contractor
No
No
No
No
Redirected to "Account is Suspended" full-page screen on login
Client
No
No
No
No
Redirected to "Account is Suspended" full-page screen on login
Pixally Super Admin (Gawd Portal)
Yes (read-only)
No
No
No
Full read-only view via Gawd Portal; can manually reactivate with support note
3. User Flow
3.1 First Failed Payment — Stripe Smart Retries
3.1.1 A scheduled recurring charge (main plan renewal or monthly paid-extras charge) fails on the agency's primary payment method due to card decline, expiry, insufficient funds, 3D Secure authentication failure, or other card-related error.
3.1.2 The system records the failure event via Stripe webhook and marks Day 1 of the 28-day grace period as the current date.
3.1.3 The system sends the Day 1 failed-payment notification email to the Agency Owner and an in-app notification; no banner is shown yet on the Subscription page or Dashboard because Stripe's automated retries are still in progress.
3.1.4 Stripe initiates its Smart Retries sequence (3 automated retry attempts timed by Stripe's machine-learning algorithm, typically spread across several days within the first week).
3.1.5 If any Stripe retry succeeds, the invoice is marked paid, grace period is closed automatically, no banner is shown, and a payment confirmation email is sent to the owner; the subscription continues normally.
3.2 All Stripe Retries Exhausted — Grace Banner Appears
3.2.1 If all three of Stripe's Smart Retries fail, the system receives the final "invoice.payment_failed" webhook event from Stripe.
3.2.2 The system displays the amber grace-period banner on the Dashboard page and the Subscription page with the exact text "Your last payment failed. If payment is not completed, your account will be suspended on [Day 28 date]. Please update your payment method or pay the invoice to avoid losing access to your account."
3.2.3 The banner shows two call-to-actions: "Update Payment" (primary) and "Contact Support" (secondary).
3.2.4 Clicking "Update Payment" scrolls the user to the Payment Method section on the Subscription page where the owner can add a new card or open the Retry Payment choice dialog from the failed invoice row in the Subscription Receipts section.
3.2.5 Clicking "Contact Support" opens the Pixally support URL configured via the Gawd Portal in a new browser tab.
3.2.6 The banner persists on all subsequent visits to the Subscription and Dashboard pages until the grace period ends, the failed invoice is paid, or the owner cancels the subscription.
3.3 Grace Period Email Reminders
3.3.1 The system sends a total of five email and in-app notifications during the 28-day grace period on Day 1 (first failure), Day 7 (after Stripe retries exhausted), Day 14 (midway reminder), Day 21 (final week warning), and Day 28 (final pre-suspension warning).
3.3.2 Each notification includes the owner's name, the failed amount, the card brand and last four digits that were declined, the exact date the account will be suspended, and a direct link to the Subscription page to update the payment method and retry.
3.3.3 Notifications are sent to the Agency Owner's primary email, any configured Invoice CC Email per FRD 6, and as in-app notifications to the Owner.
3.4 Retry Payment Action — User-Initiated During Grace
3.4.1 The Agency Owner navigates to the Subscription page and locates the failed invoice in the Subscription Receipts section.
3.4.2 The owner clicks the "Retry Payment" call-to-action on the failed invoice row.
3.4.3 The system opens a Retry Payment choice dialog with two options: "Retry with current card on file" and "Add a new payment method".
3.4.4 If the owner chooses "Retry with current card on file", the system submits the failed invoice to Stripe for immediate retry on the current primary payment method; the result is returned synchronously via Stripe API.
3.4.5 If the owner chooses "Add a new payment method", the system opens the Add Payment Method dialog per FRD 6 Section 4.10; on successful card add the new card is auto-set as primary, and the system immediately retries the failed invoice on the new primary card.
3.4.6 If the retry charge succeeds, the system marks the invoice paid, closes the grace period, hides the banner, sends a payment confirmation email, and resumes normal subscription state; full access is restored immediately.
3.4.7 If the retry charge fails, the system shows an error message in the dialog with the Stripe decline reason and offers the owner to try again with a different card.
3.5 Payment Method Updated During Grace — Automatic Retry
3.5.1 During the grace period, the Agency Owner navigates to the Payment Method section on the Subscription page and adds a new credit card.
3.5.2 The owner sets the new card as the primary payment method.
3.5.3 The system detects the primary-payment-method change via Stripe webhook and automatically submits all outstanding failed invoices (per FRD 7 Section 4.11 single-grace rule) to Stripe for retry on the new primary card, without requiring the owner to click Retry Payment.
3.5.4 If the automatic retry succeeds, the system marks the invoice paid, closes grace, hides the banner, sends confirmation email, and resumes normal state.
3.5.5 If the automatic retry fails on the new card, grace period continues on the original 28-day clock and the owner is notified via email with the new decline reason.
3.6 Grace Period Ends — Account Suspended
3.6.1 At the end of Day 28 with the failed invoice still unpaid, the system transitions the account to the Suspended state via a scheduled background job.
3.6.2 The system pauses the Stripe subscription (status set to "paused" or equivalent) so that no further recurring charges, invoices, or retries are generated while the account remains suspended.
3.6.3 The system records the suspension date as the account's "last activity date" per FRD 8 and the 365-day data-retention clock begins from this date.
3.6.4 The system sends a suspension-confirmation email to the Agency Owner with instructions to log in and reactivate.
3.7 Suspended Account Login — Owner
3.7.1 The Agency Owner attempts to log in to Pixally while the account is in the Suspended state.
3.7.2 Authentication succeeds and the system loads the Subscription page directly as the only accessible page; the left navigation sidebar is hidden entirely from view.
3.7.3 A red suspension banner is displayed at the top of the Subscription page with the exact text "Your account has been suspended due to failed payment." along with two call-to-actions: "Pay Invoice" (primary) and "Contact Support" (secondary).
3.7.4 The Subscription page renders normally below the banner with the plan card, payment method section, team members section, annual subscription upsell card (if applicable), and Subscription Receipts list all visible.
3.7.5 Selective buttons on the Subscription page are greyed out during suspension: "Add Team Member" and "Switch to Monthly" are disabled and non-clickable; "Change Plan", "Cancel Subscription", and "Manage Payment Method" remain clickable for the owner to take action.
3.7.6 The owner can download past receipts from the Subscription Receipts list because the Receipts section is fully visible on the suspension-state Subscription page.
3.7.7 The owner cannot navigate away from the Subscription page because the left navigation is hidden; direct URL entry to other pages redirects back to the Subscription page.
3.7.8 The owner's options at this point are to click "Pay Invoice" to reactivate per Section 3.8, click "Cancel Subscription" to cancel per Section 3.10, or click "Contact Support" to reach Pixally support.
3.8 Pay Invoice — Reactivation Flow
3.8.1 The Agency Owner clicks "Pay Invoice" on the red suspension banner at the top of the Subscription page.
3.8.2 The system opens the Retry Payment choice dialog with two options: "Retry with current card on file" and "Add a new payment method"; the dialog displays the amount due calculated as the original failed invoice amount plus the current month's full subscription charge (main plan plus any paid extras) since months during which the account was suspended are not back-charged.
3.8.3 If the owner chooses "Retry with current card on file", the system submits the combined charge to Stripe for immediate retry on the existing primary payment method.
3.8.4 If the owner chooses "Add a new payment method", the system opens the Add Payment Method dialog per FRD 6 Section 4.10; on successful card add the new card is auto-set as primary, and the system immediately submits the combined charge on the new primary card.
3.8.5 On successful charge, the system resumes the Stripe subscription (un-pausing it), sets the billing cycle anchor to the reactivation date, restores all paid extra seats at the same count as before suspension, resumes all background automations, re-enables the left navigation, hides the red banner, sends a "Welcome back" confirmation email with the consolidated invoice PDF attached, and restores full application access.
3.8.6 From the reactivation date forward, the billing cycle is anchored to this new date; for example, if reactivation occurs on March 28 and the plan is monthly, subsequent monthly renewals will bill on the 28th of each month.
3.8.7 If the charge fails, the owner remains on the suspended Subscription page with the error message displayed; the owner can retry with a different card from the same dialog or open the Manage Payment Method flow.
3.9 Admin and Team Member Login During Suspension
3.9.1 An Agency Admin, Project Manager, Supervising Editor, Editor, Contractor, or Client attempts to log in while the account is suspended.
3.9.2 Authentication succeeds but the system loads the dedicated "Account is Suspended" full-page screen instead of the full application; no navigation sidebar, no page content, no functional elements are accessible.
3.9.3 The full-page screen displays the Pixally logo at the top-right, a hero image on the left side, and a centered card with the title "Account is Suspended" along with the message "Looks like this account is currently on hold, so access to portals, files, and other resources isn't available right now. Please reach out to the account owner or agency administrator to get things back up and running."
3.9.4 The user has no call-to-actions on this screen; they cannot update payment methods, cancel the subscription, contact support, or take any action to resolve the suspension on behalf of the Owner.
3.9.5 All non-Owner sessions remain locked to this screen until the Owner reactivates the account, at which point the user can log in normally on their next attempt.
3.10 Cancel Subscription During Grace or Suspension
3.10.1 During the grace period or while the account is suspended, the Agency Owner can choose to cancel the subscription entirely rather than paying the outstanding balance.
3.10.2 On the Subscription page during grace, or on the suspended Subscription page during suspension, the owner clicks "Cancel Subscription" and is routed to the cancellation flow per FRD 8.
3.10.3 Cancellation during grace overrides the grace period and immediately ends the subscription; the failed invoice is written off by Pixally and is no longer due from the owner.
3.10.4 Cancellation from suspension also ends the subscription and waives the outstanding failed invoice; the 365-day data-retention clock that started at suspension continues uninterrupted.
3.11 Pixally Super Admin Reactivation via Gawd Portal
3.11.1 The Pixally Super Admin accesses the Gawd Portal and locates the suspended agency.
3.11.2 The Super Admin reviews the account status and, with a recorded support note, manually reactivates the agency bypassing the standard payment flow.
3.11.3 The system lifts suspension, resumes the Stripe subscription with the reactivation date as the new anchor, and sends notification to the Agency Owner.
3.11.4 All Super Admin manual reactivation actions are logged in the Gawd Portal audit log for financial reconciliation and support traceability.
4. Functional Logic
4.1 Scope of Failed Payment Handling
- The failed-payment grace-period and suspension logic applies exclusively to recurring charges: main-plan monthly or annual renewals, monthly paid-extras charges, and any scheduled automated invoice from Stripe.
- One-time charges that fail (plan upgrade proration, cycle switch proration, extra-seat purchase proration) do not trigger the grace period; those flows simply fail immediately with an error message and the owner must retry the action manually per FRD 3, FRD 4, and FRD 5 respectively.
- The module handles any card-related failure reason including card declined, card expired, insufficient funds, 3D Secure authentication failure, fraud detection blocks, issuer decline, and network errors.
- Free plan agencies with zero paid extras cannot experience failed-payment grace because they have no recurring charges; however, Free plan agencies with one or more paid extra seats are classified as paid accounts per FRD 5 Section NQ-6 and enter the grace period if the monthly extras charge fails.
4.2 Day 1 — First Failed Charge
- The 28-day grace period begins on the exact date of the first failed recurring charge; this date is recorded on the agency's subscription state and is the canonical anchor for all grace-period countdowns and banner displays.
- On Day 1, no banner is displayed on the Subscription page or Dashboard because Stripe's Smart Retries are still in progress and the failure may be transient; showing a banner immediately would cause unnecessary alarm for issues that Stripe may resolve automatically.
- Day 1 triggers the first failed-payment notification email and in-app notification to the Agency Owner; the notification informs the owner of the failure, the declined card, the amount, and that automatic retries are being attempted.
4.3 Stripe Smart Retries
- The retry strategy for failed invoice charges is configurable globally via the Gawd Portal "Adjust Failed Payments" popup; the popup exposes Max retry attempts (1-10, default 3) and Days between retries (1-30 or "Smart Retry", default Smart Retry).
- * The default configuration delegates retry timing to Stripe's Smart Retries algorithm with up to 3 attempts; this default uses machine-learning to determine optimal retry times based on card type, issuer, historical success patterns, and time-of-day signals and matches the previously hardcoded behavior.
- * When the Pixally Super Admin configures a fixed "Days between retries" interval (e.g., 7 days), the system overrides Smart Retry with a fixed schedule: retries occur at the configured interval starting from the initial failure date, up to the configured Max retry attempts value.
- * During the retry window, the failed invoice remains in "Open" status in the Subscription Receipts list and is not marked "Failed" until all configured retries have been exhausted.
- * If any retry succeeds, the invoice status updates to "Paid", the grace period is automatically closed, and no user-facing banner is shown; this is the happy-path resolution that handles the majority of transient failures.
- * Configuration changes apply to newly-triggered failed-payment events only; in-flight retries continue with the configuration that was in effect when they began.
4.4 Grace-Period Banner Display — After Stripe Retries Exhausted
- When Stripe's final retry attempt (the third) fails, the system receives the "invoice.payment_failed" webhook with the "next_payment_attempt" field set to null, indicating Stripe has stopped retrying.
- At this point, the failed invoice status transitions from "Open" to "Failed" in the Subscription Receipts list, and the amber grace-period banner is displayed at the top of the Dashboard page and the Subscription page.
- The banner is not displayed on other pages of the Pixally application (Projects, Clients, Team Management, and so on); the visibility is scoped to billing-relevant pages to avoid overwhelming the user with banners throughout the portal.
- The banner displays the exact text "Your last payment failed. If payment is not completed, your account will be suspended on [Day 28 date]. Please update your payment method or pay the invoice to avoid losing access to your account." with the suspension date calculated as twenty-eight days from the first failure date.
- The banner shows two call-to-actions: "Update Payment" (primary, yellow) scrolls the user to the Payment Method section on the Subscription page, and "Contact Support" (secondary) opens the Pixally support URL configured via Gawd Portal in a new browser tab.
- The grace-period banner is not dismissible by the user; it persists on every visit to the Subscription page and Dashboard until the failed invoice is paid (retry succeeds), the subscription is cancelled, or the account transitions to suspension.
4.5 Grace-Period Banner Visibility by Role
- The Agency Owner sees the full amber banner with both "Update Payment" and "Contact Support" call-to-actions; clicking "Update Payment" scrolls to the Payment Method section where the owner can take action.
- The Agency Admin sees the same banner text for awareness, but clicking the "Update Payment" call-to-action displays the message "Only the agency owner can update payment methods. Please contact your agency owner." because only the Owner has billing permissions per FRD 1.
- Project Managers, Supervising Editors, Editors, Contractors, and Clients do not see the failed-payment banner because these roles do not have access to the Subscription page or Dashboard.
4.6 Email and In-App Notification Schedule
- The system sends five notifications across the configured grace period (default 28 days, configurable globally via the Gawd Portal "Suspend account after" setting) at proportional milestones: first-failure alert at Day 1, post-retry-exhausted alert at approximately 25% of grace, midway reminder at 50%, final-week warning at approximately 75%, and final pre-suspension warning at the last day of grace.
- * For the default 28-day grace period, the proportional milestones resolve to Day 1, Day 7, Day 14, Day 21, and Day 28 respectively, matching the original notification schedule.
- * Each notification is delivered via both email (to the Owner's primary email and any configured Invoice CC Email per FRD 6\) and as an in-app notification via the Notification module; SMS reminders are also sent when the Gawd Portal master toggle is enabled.
- * Each notification includes contextual information: the owner's first name, the current day of grace, the number of days remaining before suspension, the failed amount, the declined card brand and last four digits, the exact suspension date, a clear "Update Payment Method" call-to-action, and a direct deep-link to the Subscription page.
- * Notification language is escalating in tone across the five touchpoints — the first email is informational ("your payment was declined"), the second is prompting ("automatic retries were unsuccessful, action needed"), the third is warning, the fourth is urgent, and the final is "your account will be suspended tomorrow".
- * All notification delivery is gated by the Gawd Portal "Send email and text reminders" master toggle; when disabled, all notifications are suppressed regardless of grace progression. The custom reminder text from the Gawd Portal "Reminder" field, when populated, is included in the body of each notification (both email and SMS).
4.7 Retry Payment — User-Initiated
- The "Retry Payment" call-to-action is shown on the failed invoice row in the Subscription Receipts section per FRD 6 Section 4.15; clicking it opens the Retry Payment choice dialog.
- The dialog offers two options: "Retry with current card on file" (which submits the invoice to Stripe for an immediate charge on the existing primary payment method) and "Add a new payment method" (which opens the Add Payment Method dialog per FRD 6 Section 4.10, sets the new card as primary, then retries).
- On successful retry, the failed invoice is marked Paid, the grace period is immediately closed, the banner is hidden, a payment-confirmation receipt email is sent, and normal subscription state is restored.
- On failed retry, the dialog displays the Stripe decline reason in human-readable form and allows the owner to try another method without exiting the retry flow.
4.8 Automatic Retry on Primary Card Change
- When the Agency Owner updates their primary payment method during the grace period (either by adding a new card and setting it as primary, or by switching primary to an existing alternate card), the system detects the change via Stripe webhook and automatically submits the failed invoice for retry on the new primary card.
- This automatic retry does not require the owner to click Retry Payment manually; updating the primary method is treated as an implicit intent to resolve the failed payment.
- If the automatic retry succeeds, grace period is closed and the banner is hidden just as with a manual retry.
- If the automatic retry fails on the new primary method, the grace-period clock continues uninterrupted on the original 28-day timeline (the card change does not reset the grace period) and the owner is notified with the updated decline reason.
4.9 Grace Period Protects Full Access
- Throughout the 28-day grace period, the Agency Owner and all team members retain complete access to the Pixally application with zero feature restrictions; all plan features remain functional exactly as they were before the payment failure.
- Paid extras (additional seats billed at $9 per month per FRD 5) continue to function for all extra-seat users during the grace period, even though the extras charge itself may be one of the failed invoices.
- Contractors continue to have their normal access to the Contractor Portal and their assigned jobs during grace.
- Clients continue to have their normal access to the Client Portal during grace.
- The rationale for full access during grace is to give paying customers every opportunity to resolve billing issues without punishing them prematurely for what are often transient card problems (expired card, temporary hold, traveling abroad, and so on).
4.10 Day 29 — Suspension Begins
- At the end of the configured grace period with the failed invoice still unpaid (Day 28 for the default 28-day configuration), a scheduled background job transitions the account from "grace period" state to "suspended" state on the day immediately following.
- * At the moment of suspension, the system pauses the Stripe subscription (setting its status to "paused" or equivalent on the Stripe side) so that no new recurring charges are generated and no new failed invoices accumulate while the account remains suspended.
- * All background automations belonging to the agency (workflow automations, scheduled client emails, recurring invoice generation, contractor payment processing, and any other time-triggered jobs) are paused at suspension and remain paused until the account is reactivated or cancelled.
- * The system schedules the deletion timer at the moment of suspension transition: scheduled deletion date \= suspension start date \+ configured "Delete account after" duration (default 1 year, configurable globally via the Gawd Portal). Pre-deletion warning emails are scheduled at 1 month, 1 week, and 1 day before the scheduled deletion date per Section 4.10.1 and FRD 8 Section 4.18.
4.10.1 Suspended-to-Deletion Pipeline
- * The system records the suspension date as the "last activity date" for the account, which is the anchor for the data-retention deletion timer.
- * The system sends a suspension confirmation email to the Agency Owner informing them of the suspension and instructing them to log in, visit the Subscription page, and pay the comeback amount to reactivate.
- he suspension state has a finite duration determined by the Gawd Portal "Delete account after" configuration (default 1 year from suspension start, configurable globally).
- * During the suspended-to-deletion window, the agency's behavior is identical to standard suspension per Section 4.12 (Owner sees only Subscription page; non-owners see "Account is Suspended" full-page screen); the framework's per-module locks are bypassed by the suspension override.
- * The agency can reactivate at any time during the suspension-to-deletion window by paying the comeback amount via the Subscription page per Section 4.16; reactivation cancels the scheduled deletion and removes the deletion timer.
- * Pre-deletion warning emails are sent at 1 month, 1 week, and 1 day before the scheduled deletion date; the schedule and content are identical to the cancellation-Free deletion warnings defined in FRD 8 Section 4.18, forming a unified deletion warning system.
- * If the agency does not reactivate by the scheduled deletion date, the system executes hard deletion: all agency data is permanently removed, the primary email is released for fresh re-signup, and promo history is retained per FRD 1\.
- * Hard deletion is irreversible; no recovery mechanism exists after the deletion job completes.
- * Pixally Super Admins can cancel a scheduled deletion for an individual agency from the Gawd Portal in cases requiring manual intervention (e.g., agency reaches out to support requesting an extension).
4.11 Multiple Failed Invoices Share Single Grace Period
- When multiple recurring charges fail in quick succession (for example, the main plan renewal fails on Day 1 and then the monthly extras charge fails on Day 10 of the same grace period), all failed invoices share the same single 28-day grace period anchored to the first failure date.
- The grace-period clock is not reset by subsequent failures; the account moves to suspension at Day 29 from the original first failure regardless of how many additional failed invoices accumulate in between.
- When the owner retries payment or updates their payment method during grace, the system attempts to clear all outstanding failed invoices together; partial success is handled per individual invoice (one can succeed while another fails, and the banner remains as long as any failed invoice is still unpaid).
4.12 Suspended State Behavior — Owner
- When the Agency Owner logs in to a suspended account, authentication succeeds and the system loads the Subscription page as the only accessible page of the Pixally application; the left navigation sidebar is hidden entirely and cannot be expanded or shown.
- The red suspension banner is displayed at the top of the Subscription page with the exact text "Your account has been suspended due to failed payment." and two call-to-actions: "Pay Invoice" (primary, white button) and "Contact Support" (secondary).
- The Subscription page renders its standard layout below the banner: the plan card showing current plan, billing cycle, and renewal info; the Payment Method section; the Team Members section; the Annual Subscription upsell card if applicable; and the full Subscription Receipts list.
- Selective call-to-actions on the page are disabled and greyed during suspension: "Add Team Member" (in Team Members section) and "Switch to Monthly" (annual-to-monthly switch button) are non-clickable; clicking them has no effect.
- The following call-to-actions remain clickable during suspension: "Change Plan" (routes to Manage Subscription per FRD 3), "Cancel Subscription" (routes to cancel flow per FRD 8), and "Manage Payment Method" (opens the Add Payment Method dialog per FRD 6).
- The Subscription Receipts list is fully visible and interactive; the owner can download past invoice PDFs from this list even while the account is suspended.
- The owner cannot navigate to any other page (Projects, Clients, Calendar, Tasks, Reports, Settings, and so on) because the left navigation is hidden; any direct URL entry to other pages redirects the owner back to the suspension-state Subscription page.
- Clicking "Pay Invoice" opens the Retry Payment choice dialog with the combined amount due (original failed invoice plus current month's charge) as described in Section 4.14.
- Clicking "Contact Support" opens the Pixally support URL configured via Gawd Portal in a new browser tab.
4.13 Suspended State Behavior — Non-Owner Roles
- When any non-Owner role (Agency Admin, Project Manager, Supervising Editor, Editor, Contractor, or Client) attempts to log in to a suspended account, authentication succeeds but the system loads the dedicated "Account is Suspended" full-page screen instead of the regular application.
- The screen layout consists of a hero image on the left half of the viewport and a content panel on the right half; the Pixally logo is displayed at the top-right corner.
- The content panel displays a centered warning icon, the heading "Account is Suspended", and the message "Looks like this account is currently on hold, so access to portals, files, and other resources isn't available right now. Please reach out to the account owner or agency administrator to get things back up and running."
- The screen has no call-to-actions or interactive elements; the user has no way to update payment methods, cancel the subscription, contact support, or otherwise act on the suspension from this screen.
- All non-Owner sessions remain locked to this screen; direct URL access to any other page of Pixally is blocked and redirects back to the "Account is Suspended" screen.
- Once the Owner reactivates the account, non-Owner users regain normal access on their next login without any further action required from them.
4.14 Reactivation Logic — Amount Due
- When the Agency Owner clicks "Reactivate Subscription" from the suspension banner, the system opens the comeback flow which prompts the Owner to select a target plan from the available plans (Free, Basic, Essentials, Studio).
- * The failed grace-period invoice that triggered the original payment failure cascade is written off automatically by the reactivation flow; the agency is not charged for the failed invoice and the invoice is marked as "Written Off" in the Subscription Receipts list and audit log.
- * The comeback payment charged to the Owner equals one full month of the agency's selected comeback plan; the amount is the plan's standard monthly price.
- * The current-month charge is the full monthly amount, not prorated; this pays for a full month of access starting from the reactivation date and aligns with the new billing anchor rule in Section 4.15.
- * The comeback charge applies the 50% promo discount if the agency is still within its 365-day promo window per FRD 1; otherwise the comeback charge is at full price.
- * If the Owner selects Free as the comeback plan, no Stripe charge is initiated; the agency transitions from Suspended directly to Free.
- * Invoices for months during which the account was suspended are not charged; the comeback payment covers only the upcoming month from the reactivation date forward.
- * If the agency had a credit balance on file at the time of failed payment, the credit is applied to the comeback charge before the card is charged for the balance.
4.15 Reactivation Logic — New Billing Cycle Anchor and Paid Extras Restoration
- On successful comeback payment, the billing cycle anchor date is set to the reactivation date (the date the comeback charge succeeds), replacing the original anchor.
- * For example, if an agency was originally on a monthly cycle with renewals on the 1st of each month, failed payment on January 1, entered grace, suspended on January 29, and reactivated on March 28, the new billing cycle anchor becomes March 28 and subsequent monthly renewals will occur on the 28th of each month going forward.
- * For annual subscriptions, the reactivation date becomes the new annual anchor, and the next annual renewal occurs one year from the reactivation date.
- * All previously-purchased paid-extras seats are released on comeback; the agency returns with only the comeback plan's default seat count (1 for Free, 2 for Basic, 3 for Essentials, unlimited for Studio).
- * Team members who were occupying paid-extras seats at the time of suspension remain in soft-disabled state on comeback; the Owner can re-activate them via the FRD 5 Section 4.21 multi-select flow, which will trigger Mode B prorated payment for re-acquired paid extras.
- * The Stripe subscription is updated on comeback to remove all paid-extras line items; the next monthly invoice charges only the comeback plan's base price (with 50% promo discount if applicable).
- * The Year 1 promo window (50% discount eligibility per FRD 1\) is calendar-anchored to the original first paid payment date and continues counting through suspension without pausing; if the reactivation date is still within the original 365-day promo window, the 50% discount applies to the comeback charge and any future monthly renewals until the original promo end date.
- * Audit log records both the billing cycle reset and the paid-extras reset for traceability.
4.16 Reactivation Flow — Payment Processing
- Clicking "Reactivate Subscription" on the suspension banner opens the comeback flow which begins with a plan-selection step; the Owner sees the available plans (Free, Basic, Essentials, Studio) with current pricing and feature highlights per FRD 1\.
- * The Owner selects a target plan; the comeback payment amount is calculated as one full month of the selected plan, with 50% discount applied if within the 365-day promo window per FRD 1\.
- * If the Owner selects Free, no Stripe charge is initiated and the agency transitions to Free directly.
- * For paid plans, the Retry Payment choice dialog per FRD 6 Section 4.15 opens with the comeback amount displayed; the dialog offers two options: "Retry with current card on file" (charges the comeback amount to the existing primary payment method) and "Add a new payment method" (opens the Add Payment Method dialog per FRD 6 Section 4.10, sets the new card as primary, then charges).
- * On successful charge, the system writes off the failed grace-period invoice, un-pauses the Stripe subscription on the selected comeback plan, sets the new billing cycle anchor to the reactivation date, releases all previously-purchased paid extras (Owner re-adds via FRD 5 §4.21 if needed), resumes all background automations, re-enables the left navigation, hides the suspension banner, cancels the scheduled deletion timer, generates an invoice PDF for the comeback amount, sends a "Welcome back" email with the invoice attached, and restores full application access on the selected plan.
- * If the comeback selects a plan different from the previously-suspended plan, the framework's downgrade-to-X cascade rules per FRD 3 Section 4.18 (for downgrade) or normal upgrade behavior (for upgrade) apply at activation.
- * All tax calculations on the comeback charge are handled by Stripe Tax per its standard behavior.
- * On failed charge, the owner remains on the suspended Subscription page with the error message displayed in the dialog; the deletion timer continues toward the scheduled deletion date; the owner can retry with a different card as many times as needed.
4.17 Cancellation During Grace or Suspension
- During the 28-day grace period, the Agency Owner retains the right to cancel the subscription by navigating to the standard Cancel Subscription flow per FRD 8 from the Subscription page.
- Cancellation during grace overrides the grace period and immediately ends the subscription; the failed invoice is written off by Pixally and is no longer collectible, the Stripe subscription is cancelled (not paused), and the account enters the post-cancellation state per FRD 8.
- During the suspension state, the Agency Owner can cancel via the "Cancel Subscription" button on the suspended Subscription page; this triggers the same cancellation flow and writes off the failed invoice.
- Cancellation from suspension does not restore any data or access; it simply transitions the account from "suspended" to "cancelled" and continues the 365-day data-retention clock that started at suspension.
4.18 Pixally Super Admin Manual Reactivation
- The Pixally Super Admin has the authority to manually reactivate a suspended agency through the Gawd Portal, bypassing the standard owner-paid reactivation flow.
- Manual reactivation is used for support scenarios such as resolving billing disputes, applying courtesy reactivations for long-standing customers, or recovering accounts that have suspension-related data errors.
- The Super Admin must record a support note explaining the reason for manual reactivation; this note is stored in the Gawd Portal audit log along with the admin identity, timestamp, and affected agency identifier.
- On manual reactivation, the system un-pauses the Stripe subscription, applies the current date as the new billing cycle anchor, and sends notification to the Agency Owner that their account has been reactivated by Pixally support.
- Manual reactivation does not collect payment for the original failed invoice unless the Super Admin explicitly configures a charge as part of the reactivation action.
4.19 One-Time Charge Failures and Other Non-Grace Events — No Grace Period
- One-time charges that fail during plan upgrade, cycle switch, or extra-seat purchase do not trigger the 28-day grace period; these flows simply fail immediately with an inline error message in the Price Summary popup or upgrade wizard.
- The user's account state is not affected by one-time charge failures; their existing subscription continues on its current plan and cycle without disruption.
- The user can retry the upgrade, switch, or seat purchase as a fresh action at any time; no record of the failed attempt is persisted beyond Stripe's standard charge log.
- The zero-dollar authorization that Stripe performs during the Add Payment Method flow is not a recurring charge; a failed zero-dollar authorization simply shows the card-add error in the dialog and does not trigger the grace period.
- Stripe Smart Retries only attempts the primary payment method on file; the system does not automatically fall back to other saved cards on the agency's Stripe customer object when the primary fails. If the owner wants to switch to another saved card, they must use the Retry Payment action or update the primary method manually.
- This distinction keeps the failed-payment flow simple and focused on recurring subscription revenue recovery.
4.19.1 Owner Self-Delete Blocked During Suspension
- While the agency account is in the Suspended state, the Agency Owner cannot delete their own user account or otherwise remove themselves from the agency; any attempt to self-delete is blocked with a message instructing the owner to first either reactivate the subscription or cancel the subscription through the Cancel Subscription flow per FRD 8.
- This block prevents orphaned agency accounts where the only user capable of reactivation has been removed and no path to restoration exists without Super Admin intervention.
- The Pixally Super Admin retains the ability to reactivate via the manual Gawd Portal flow per Section 4.18 if needed.
4.20 Interaction with Scheduled Downgrade
- If the account has a scheduled downgrade (per FRD 3) at the end of the current billing cycle when a payment failure occurs, the grace period and potential suspension take precedence.
- The scheduled downgrade does not execute while the account is in grace or suspended; execution is paused until the account is either reactivated or cancelled.
- If the owner reactivates during or after grace, the scheduled downgrade is evaluated against the new billing cycle anchor; if the original downgrade date has already passed during the suspension period, the downgrade is rescheduled to execute at the end of the next cycle from the reactivation date.
- If the owner cancels during or after grace, the scheduled downgrade is cancelled automatically as the subscription is ending entirely.
4.21 Interaction with Scheduled Cycle Switch
- Similarly to scheduled downgrade, a scheduled cycle switch (per FRD 4) is paused if the account enters grace or suspension.
- On reactivation, the scheduled cycle switch is re-evaluated against the new anchor; if the scheduled switch date has passed during suspension, the switch is rescheduled to the end of the next cycle from the reactivation date.
- On cancellation, the scheduled cycle switch is cancelled automatically.
4.21.1 Interaction with Pending Team Member Invites
- Any pending team member invites that have been sent but not yet accepted at the time the account enters suspension (Day 29) are automatically cancelled by the system.
- The invited users who had not yet joined receive no additional communication; if they click an expired invite link they see the standard "invite expired" message per FRD 5.
- On reactivation, previously-cancelled invites are not restored; the Agency Owner must manually re-invite any team members they still want to add after reactivation per FRD 5 flow.
4.21.2 Active Admin Session During Day 29 Suspension Transition
- If an Agency Admin has an active session when the Day 29 suspension transition occurs, the system forcibly terminates the Admin's session so that the next page action requires re-authentication.
- On re-login, the Admin is routed to the "Account is Suspended" full-page screen per Section 4.13.
- This differs from Owner session handling: Owner sessions are not forcibly terminated; the Owner's next navigation refreshes state and routes the Owner to the suspended Subscription page per Section 4.12.
4.21.3 Currency
- All failed-payment charges, grace-period amounts, and reactivation charges are in United States Dollars (USD) only for Phase 1, consistent with the currency scope defined in FRD 6 Section 4.21.
4.22 Stripe Webhook Events Consumed
- The module consumes the following Stripe webhook events to maintain accurate state: "invoice.payment_failed" (each retry failure), "invoice.paid" (successful retry or manual payment), "invoice.voided" (on cancellation during grace), "customer.subscription.paused" (Day 29 transition), "customer.subscription.resumed" (reactivation), and "customer.subscription.deleted" (cancellation).
- The Pixally backend updates the agency's subscription state in response to these webhooks and surfaces the current state to the UI on page load per FRD 6 Section 4.19.1.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Failed Invoice Amount
Read-only currency
Shown on grace banner, suspension page, and Retry Payment dialog. Includes tax.
Grace Period Start Date
Read-only date
Set to the date of first failed payment. Used as anchor for countdown.
Grace Period End Date
Read-only date
Calculated as Grace Start + 28 days. Shown verbatim in grace banner text.
Days Remaining
Internal calculation
Dynamically calculated as 28 minus days elapsed since Grace Start. Used to derive banner suspension date.
Suspension Date
Read-only date
Set at Day 29 transition; equals last activity date for 365-day retention clock.
Grace-Period Banner
Amber banner component
Appears on Dashboard + Subscription page only after Stripe's 3 retries exhausted. Not dismissible. Text: "Your last payment failed. If payment is not completed, your account will be suspended on [date]. Please update your payment method or pay the invoice to avoid losing access to your account."
Suspension Banner
Red banner component
Appears on Subscription page during Suspended state. Text: "Your account has been suspended due to failed payment."
Update Payment CTA
Button (grace banner)
Owner: scrolls to Payment Method section. Admin: shows "Contact owner" message.
Pay Invoice CTA
Button (suspension banner)
Visible to Owner only. Opens Retry Payment choice dialog.
Contact Support CTA
Button (both banners)
Opens Pixally support URL configured via Gawd Portal in a new browser tab.
Retry Payment Action
Button (in Receipts row)
Visible only on Failed-status invoice rows. Opens Retry Payment choice dialog.
Retry Payment Choice Dialog
Modal
Two options: "Retry with current card" and "Add new payment method".
Reactivation Amount Due
Read-only currency
Calculated as original failed invoice + current month's full charge. Credit balance applied first if available. Tax via Stripe Tax.
Cancel Subscription CTA
Text link / button
Visible to Owner during grace (on Subscription page) and suspension (on suspended Subscription page). Routes to FRD 8 cancel flow.
Add Team Member CTA
Button (greyed during suspension)
Disabled/non-clickable on suspended Subscription page.
Switch to Monthly CTA
Button (greyed during suspension)
Disabled/non-clickable on suspended Subscription page.
Change Plan CTA
Button (clickable during suspension)
Active on suspended Subscription page. Routes to Manage Subscription per FRD 3.
Manage Payment Method CTA
Button (clickable during suspension)
Active on suspended Subscription page. Opens payment method management per FRD 6.
"Account is Suspended" Full-Page Screen
Screen
Shown to non-Owner roles on login. Hero image left + content panel right with heading, message, and Pixally logo. No CTAs.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Stripe retry succeeds
No banner shown; standard payment confirmation email sent.
Any of the 3 Stripe Smart Retries succeeds.
Invoice marked Paid; grace period closed silently; normal state.
SM-2
Manual retry succeeds
"Payment successful. Your account is back in good standing."
Owner clicks Retry Payment and charge succeeds.
Banner hidden; grace period closed; receipt generated; full access confirmed.
SM-3
Primary card update triggers auto-retry success
"Payment successful using your updated card. Your account is back in good standing."
Owner updates primary during grace, auto-retry clears failed invoice.
Same as SM-2.
SM-4
Reactivation successful
"Welcome back! Your account is reactivated and ready to use."
Pay Invoice charge succeeds.
Stripe subscription un-paused; new cycle anchor set to reactivation date; paid extras auto-restored; automations resumed; left nav re-enabled; red banner hidden; full access restored.
SM-5
Super Admin manual reactivation
"This agency has been manually reactivated by Pixally support."
Super Admin reactivates via Gawd Portal with support note.
Suspension lifted; agency owner notified via email; action logged.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Retry Payment on current card fails
"Your card was declined: [Stripe decline reason]. Please try another payment method."
Retry charge returns Stripe decline.
Owner tries different card or waits and retries.
EM-2
Reactivation charge fails
"We couldn't process your reactivation payment: [Stripe decline reason]. Please update your payment method and try again."
Combined reactivation charge declined.
Owner updates card and retries.
EM-3
Admin clicks Update Payment Method on banner
"Only the agency owner can update the payment method. Please contact your agency owner."
Admin attempts billing action from banner.
Admin contacts Owner.
EM-4
Non-Owner tries to access suspended account
Full-page "Account is Suspended" screen displayed. Message: "Looks like this account is currently on hold, so access to portals, files, and other resources isn't available right now. Please reach out to the account owner or agency administrator to get things back up and running."
Any non-Owner role logs in during suspension.
User contacts Owner.
EM-5
Owner tries to navigate to a non-Subscription page during suspension
Left nav is hidden; direct URL access redirects to Subscription page. No error dialog shown.
Owner attempts direct URL or browser back during suspension.
Owner must reactivate or cancel.
EM-6
Owner tries to self-delete account during suspension
"You cannot delete your account while your subscription is suspended. Please reactivate or cancel your subscription first."
Owner attempts account deletion from Profile/Account Settings during suspension.
Owner reactivates or cancels subscription.
EM-7
Stripe webhook delivery delayed
No user-facing error; UI shows last-known state until next page load.
Webhook latency or temporary Stripe outage.
Page refresh fetches latest state.
EM-8
Reactivation attempted when account is not in Suspended state
"This account is not currently suspended."
Race condition or direct API access.
No user action; system returns to current state.
EM-9
Retry Payment attempted on already-paid invoice
"This invoice has already been paid."
Race condition between user action and async retry success.
UI refreshes to show updated status.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Primary card fails on renewal; the same card becomes unusable (e.g., closed account).
Stripe's 3 retries all fail on the bad card; banner appears on Day 7-ish; owner must add a new payment method to resolve.
EC-2
Owner updates card on Day 15; auto-retry succeeds.
Banner hidden, grace period closed on Day 15; invoice marked paid; full access retained (was never lost); no suspension.
EC-3
Owner updates card on Day 15; auto-retry also fails on new card.
Grace period continues on original 28-day timeline; owner is notified with new decline reason; clock is not reset.
EC-4
Owner ignores all emails and banner; grace ends on Day 28.
Account suspended on Day 29; Stripe subscription paused; automations paused; suspension email sent; on next owner login, the Subscription page is shown with the red suspension banner and left nav hidden.
EC-5
Suspended owner logs in on Day 35, clicks Pay Invoice, pays, and resumes.
Pay Invoice charge = original failed invoice + current month's full charge. New billing cycle anchor set to reactivation date. Paid extras auto-restored at same count. Automations resumed. Left nav re-enabled. Red banner hidden. Full access restored.
EC-6
Suspended owner remains suspended for 90 days, reactivates.
Amount due = original failed invoice + current month's full charge. Intermediate suspended months are NOT charged. New cycle anchor = reactivation date.
EC-7
Suspended owner remains suspended for 365 days.
On Day 365 from suspension date, account transitions to "cancelled & data deleted" per FRD 8 data retention policy; reactivation no longer possible.
EC-8
Owner on Essentials Monthly with 2 paid extras has main plan failure on Jan 1.
Grace period triggered for main plan charge; extras billed on shared cycle per FRD 5 join the same grace. All failed invoices share single grace anchored to Jan 1.
EC-9
Owner on Free plan with 1 paid extra has extras charge fail.
Grace period triggered (Free+extras = paid account per FRD 5 NQ-6); amber banner appears on Dashboard + Subscription page after Stripe retries exhausted.
EC-10
Owner cancels subscription during grace on Day 14.
Cancellation overrides grace; failed invoice written off; subscription cancelled; 365-day retention begins from cancellation effective date.
EC-11
Owner cancels from suspended Subscription page on Day 40.
Cancellation allowed via Cancel Subscription button (which remains clickable during suspension); failed invoice written off; Stripe subscription moved from "paused" to "cancelled"; 365-day retention continues from original suspension date.
EC-12
Admin tries to update payment method from grace banner.
Admin clicks "Update Payment" button and sees message "Only the agency owner can update payment methods. Please contact your agency owner."
EC-13
Contractor logs in during grace period.
Contractor sees full normal access to Contractor Portal; no banner or indication of billing issue (contractors are not exposed to agency billing).
EC-14
Contractor logs in during suspension.
Contractor is routed to "Account is Suspended" full-page screen; no access to Contractor Portal until agency reactivated.
EC-15
Multiple failed invoices accumulate during grace (main plan + extras charges).
All failed invoices share single grace period anchored to first failure. Retry Payment or card update attempts to clear all together.
EC-16
Owner clicks Retry Payment but the underlying issue is Stripe outage.
Error dialog shows generic "temporary issue" message per FRD 6 EM-7; owner can retry later.
EC-17
Scheduled downgrade was set for Feb 1; agency suspended on Jan 29 before downgrade executes.
Scheduled downgrade paused. If owner reactivates on March 15, downgrade rescheduled for end of next cycle (April 15) since the original Feb 1 date has passed.
EC-18
Scheduled cycle switch (annual to monthly) for Feb 1; agency suspended on Jan 29.
Cycle switch paused. Rescheduled on reactivation per new cycle anchor.
EC-19
Stripe webhook "invoice.payment_failed" delivered out of order (second failure before first).
System processes webhooks based on event timestamps, not arrival order; grace period anchor remains on true first-failure date.
EC-20
Owner's session is active when Day 29 suspension triggers.
Next page navigation or action triggers a state refresh; owner is redirected to the suspended Subscription page with left nav hidden. The active session is not forcibly terminated.
EC-21
Pixally Super Admin manually reactivates a suspended agency without collecting payment.
Stripe subscription un-paused; new billing cycle anchor = manual reactivation date; paid extras restored; automations resumed; Gawd Portal audit log records action with support note; Agency Owner notified.
EC-22
Owner initiates reactivation but closes the browser during payment processing.
Payment may complete in background via Stripe webhook; on next login, if payment succeeded the suspension is lifted and the account is active; if payment failed the suspended Subscription page is shown again.
EC-23
Agency on Annual plan has its annual renewal fail on Jan 1; suspended on Jan 29.
Same logic as monthly: grace period, suspension, reactivation with annual plan charge. On reactivation at, say, April 15, the new annual anchor is April 15; next annual renewal is April 15 of next year.
EC-24
Owner reactivates from suspension and immediately cancels subscription.
Reactivation charge processes first; then cancellation flow executes; owner retains access until the end of the current billing cycle (new cycle starting at reactivation date).
EC-25
Agency has $20 credit balance when Essentials monthly $34.50 charge fails.
Credit applied first toward failed invoice; Stripe attempts to charge remaining $14.50 on primary card; if that amount fails, grace period triggers on the $14.50 shortfall. On reactivation, credit already consumed; user pays remaining failed amount + current month's full charge.
EC-26
Owner's payment method updated during grace; auto-retry succeeds on Day 15.
All outstanding failed invoices (main plan + any extras) cleared together on the new primary card. Grace closed silently. Banner hidden. Full access retained throughout.
EC-27
Owner is on 50% promo (signed up Jan 1); fails Mar 1; suspended Mar 29; reactivates Jul 15.
Reactivation amount = failed Mar 1 invoice (at 50%-off rate since within promo window) + Jul 15 current-month charge (at 50%-off rate since still within Jan 1 + 365 days promo window). Future renewals continue at 50% until Dec 31.
EC-28
Owner has 3 paid extras when suspended; reactivates 60 days later.
All 3 extra seats auto-restored on reactivation; reactivation amount includes 3 × $9 = $27 for current month's extras in addition to main plan and failed invoice. All 3 extra-seat users regain access automatically.
EC-29
Agency Admin has active session during Day 29 suspension transition.
Admin session is forcibly terminated. Admin must re-login, which routes to the "Account is Suspended" full-page screen.
EC-30
Pending team invite (sent 2 days before suspension) is awaiting user acceptance when account suspends.
Pending invite is cancelled on Day 29 suspension. If the invited user clicks the invite link, they see standard "invite expired" message per FRD 5. On reactivation, owner must re-invite.
EC-31
Owner attempts to delete their own user account while agency is suspended.
Deletion blocked with message "You cannot delete your account while your subscription is suspended. Please reactivate or cancel your subscription first."
EC-32
Zero-dollar authorization fails during Add Payment Method dialog on a suspended account.
Card-add error shown in dialog per FRD 6 EM-1. No grace-period logic triggered since zero-dollar auth is not a recurring charge. Owner tries another card.
EC-33
Owner has 3 saved cards; primary fails on renewal; Stripe retries on primary only.
All 3 Stripe retries attempt the primary card only. If all fail, grace banner appears. System does not automatically try the other 2 saved cards; owner must use Retry Payment with explicit card choice or change primary.
9. Acceptance Criteria
- The 28-day grace period begins on the date of the first failed recurring charge and is the single anchor for all countdowns, banner displays, and state transitions.
- Stripe Smart Retries (3 automated attempts) handle the initial retry sequence before any user-facing banner appears; successful retries close grace silently with only a standard payment confirmation email.
- The amber grace-period banner appears on the Dashboard and Subscription pages only after all 3 Stripe retries have exhausted; the banner is not displayed on any other pages.
- The grace-period banner uses the exact Figma copy: "Your last payment failed. If payment is not completed, your account will be suspended on [date]. Please update your payment method or pay the invoice to avoid losing access to your account." with CTAs "Update Payment" and "Contact Support".
- The grace-period banner is not dismissible by the user.
- Five notifications are sent during grace at Day 1, Day 7, Day 14, Day 21, and Day 28 via both email and in-app.
- Agency Owner has full application access during the entire 28-day grace period with zero feature restrictions.
- Paid extras continue to function during grace even if the extras charge is the failed invoice.
- All team members, contractors, and clients retain normal access during grace.
- On Day 29 with unpaid failed invoice, the account transitions to Suspended state, the Stripe subscription is paused (no new invoices generated), and all background automations are paused.
- Suspension has no automatic expiry; the account remains suspended indefinitely until the Owner reactivates or cancels.
- Suspension date is recorded as the account's last activity date; the 365-day data retention clock begins from this date.
- During suspension, the Agency Owner can access only the Subscription page; the left navigation is hidden entirely and direct URL access to other pages redirects back to the Subscription page.
- The suspended Subscription page shows a red banner at the top with exact copy "Your account has been suspended due to failed payment." and two CTAs: "Pay Invoice" and "Contact Support".
- On the suspended Subscription page, "Change Plan", "Cancel Subscription", and "Manage Payment Method" remain clickable; "Add Team Member" and "Switch to Monthly" are greyed out and non-clickable.
- The Subscription Receipts list remains fully visible during suspension and the owner can download past invoice PDFs.
- During suspension, all non-Owner roles (Admin, Project Manager, Supervising Editor, Editor, Contractor, Client) are redirected on login to the dedicated "Account is Suspended" full-page screen with Figma-accurate copy; they have no CTAs or interactive elements.
- Owner cannot self-delete their user account while the agency is suspended; deletion is blocked with a clear message.
- Agency Admin's active session is forcibly terminated at Day 29 transition; on re-login the Admin sees the "Account is Suspended" full-page screen.
- Pending team member invites (unaccepted) are automatically cancelled at Day 29 suspension; owner must re-invite after reactivation.
- Clicking "Pay Invoice" opens the Retry Payment choice dialog with the combined amount (original failed invoice + current month's full charge) and two options: retry on current card or add new payment method.
- Reactivation charges the original failed invoice plus the current month's full charge (no proration); invoices for intermediate suspended months are not back-charged.
- Credit balance on file is applied first to the reactivation amount (failed invoice → remaining credit applied to current month); card is charged for the remaining balance only.
- On successful reactivation, the new billing cycle anchor is set to the reactivation date, all paid extra seats are auto-restored at the same count, and all extra-seat users regain access automatically without re-invite.
- All background automations are resumed on successful reactivation; the left navigation is re-enabled; the red banner is hidden; full application access is restored.
- The Year 1 promo window is tracked against the original subscription signup date and is not shifted by suspension; reactivation within the promo window preserves the 50% discount.
- Tax on the reactivation charge is handled by Stripe Tax per its standard behavior; Pixally does not override or split tax across line items.
- Stripe Smart Retries only attempts the primary payment method on file; no automatic fallback to other saved cards.
- Manual Retry Payment action (from Receipts row or Pay Invoice CTA) offers a choice between retrying on the current card or adding a new payment method.
- Updating the primary payment method during grace automatically retries all outstanding failed invoices on the new card without requiring the owner to click Retry Payment manually.
- Multiple failed invoices during the same grace period share a single grace clock anchored to the first failure.
- Owner can cancel subscription during grace (from Subscription page) or suspension (from suspended Subscription page); cancellation overrides grace and writes off the failed invoice.
- Pixally Super Admin can manually reactivate a suspended account via Gawd Portal with a recorded support note; manual reactivation also auto-restores paid extras and resumes automations.
- One-time charge failures (upgrade, switch, seat purchase) do not trigger grace; they fail immediately with an error.
- Zero-dollar authorization failures during Add Payment Method dialog do not trigger grace.
- Scheduled downgrades and cycle switches are paused during grace and suspension; rescheduled on reactivation or cancelled on cancellation.
- All failed-payment charges, grace amounts, and reactivation charges are in USD only for Phase 1.
- Stripe webhook events drive all state transitions; the Pixally UI reflects the latest state on page load or navigation per FRD 6 Section 4.19.1.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Determines login routing for suspended vs active states.
Cannot gate suspended users to the Subscription page (owner) or "Account is Suspended" screen (non-owners).
Role & Permission Module
Hard
Distinguishes Owner vs non-Owner behavior during suspension.
Cannot enforce owner-only reactivation.
Subscription Plans Module (FRD 1)
Hard
Provides plan details and entitlements that determine reactivation charge amount.
Cannot compute reactivation amount accurately.
Free Trial Module (FRD 2)
Soft
Trial accounts cannot fail payment (no charges), but Free-plan post-trial with extras can enter grace.
None in practice.
Upgrade & Downgrade Module (FRD 3)
Hard
Scheduled downgrades interact with grace/suspension (paused during, resumed or cancelled after).
Scheduled downgrade state may become inconsistent.
Billing Cycle Management Module (FRD 4)
Hard
Scheduled cycle switches interact with grace/suspension.
Scheduled switch state may become inconsistent.
Add-ons Module (FRD 5)
Hard
Paid extras are included in reactivation charge; Free+extras triggers grace logic.
Cannot correctly compute amounts or trigger grace for extras-only failures.
Billing Dashboard + Payment Methods Module (FRD 6)
Hard
Retry Payment action, Receipts section, and Add Payment Method dialog are hosted here.
Cannot render banner, retry action, or collect payment updates.
Cancel Subscription Module (FRD 8)
Hard
Cancel during grace or suspension routes here.
Owner cannot cancel during failed-payment states.
Gawd Portal Module
Soft
Super Admin manual reactivation entry point.
Support cannot manually reactivate.
Notification Module
Hard
Delivers email and in-app notifications on Day 1, 7, 14, 21, 28.
Owner misses critical billing alerts.
Stripe Billing Integration
Hard
Handles Smart Retries, invoice management, subscription pause/resume, and payment processing.
Entire failed-payment flow is inoperable.
Background Job / Cron Service
Hard
Executes Day 29 suspension transition, notification scheduling, and webhook reconciliation.
Suspension transitions and notifications fail to execute on time.
8. Cancel Subscription
Cancel Subscription
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 24 April 2026
Status:
Version 2.0
FRD 8 — Cancel Subscription
Module: Cancel Subscription Version: 1.0 Date: April 24, 2026
1. Module Overview
Module Name: Cancel Subscription
Purpose: This module defines the user-initiated subscription cancellation flow for paid Pixally CRM agencies. It governs the four-step cancellation modal sequence (reason selection, retention offer, confirm cancellation with dynamic features-lost list, cancellation success), the end-of-cycle cancellation effective date with no refund policy, the automatic transition to the Free plan at cycle end following FRD 3 downgrade-to-Free logic, the auto-cancellation of pending scheduled downgrades and cycle switches on subscription cancellation, the one-click Reactivate Subscription option available between cancellation request and cycle end, the 365-day data retention window anchored to Free-plan inactivity (last-login date), the deletion warning email schedule one month, one week, and one day before hard deletion, the restoration of data when the user re-subscribes within the retention window, the permanent email-based tracking that blocks promo reuse after re-signup, and the generic third-party messaging that revokes contractor access without exposing the agency's plan status. It also covers cancellation during the failed-payment grace period and suspended state per FRD 7, and explicitly excludes free-trial cancellation per FRD 2 (trial users cannot cancel).
Business Goals: The Cancel Subscription module provides a dignified exit path for paying customers who choose to leave Pixally while maximizing retention opportunities through the "Before You Cancel" offer screen, preserving customer data for 365 days to welcome returning customers without friction, and continuing to offer a usable Free-plan experience after cancellation rather than locking the user out entirely. By making cancellation explicit (mandatory reason selection) and delaying execution to the end of the current billing cycle, the module respects the customer's commitment to the paid period they already paid for while gracefully winding down premium feature access. Cancellation reasons are captured for product-improvement insights. Integration with the FRD 3 downgrade-to-Free logic ensures a consistent post-cancellation experience aligned with the existing plan-tier matrix.
2. User Roles & Permissions
Role
View Cancel Subscription CTA
Initiate Cancel Flow
Complete Cancellation
Reactivate Before Cycle End
Export Data
Agency Owner (paid plan)
Yes (Subscription page + suspended Subscription page)
Yes
Yes
Yes
Out of scope for Phase 1
Agency Owner (free plan)
No (nothing to cancel)
No
No
No
Out of scope
Agency Owner (trial)
No (trial cannot be cancelled per FRD 2)
No
No
No
Out of scope
Agency Admin
No
No
No
No
Out of scope
Project Manager
No
No
No
No
Out of scope
Supervising Editor
No
No
No
No
Out of scope
Editor
No
No
No
No
Out of scope
Contractor
No
No
No
No
Out of scope
Client
No
No
No
No
Out of scope
Pixally Super Admin (Gawd Portal)
Cancel on behalf of agency handled separately via Gawd Portal (outside this FRD)
—
—
—
—
3. User Flow
3.1 Cancel Subscription Initiation — Paid Active State
3.1.1 The Agency Owner navigates to the Subscription page and locates the "Cancel Subscription" call-to-action on the plan card.
3.1.2 The owner clicks "Cancel Subscription".
3.1.3 The system opens Step 1 of the cancellation flow, the "We'd hate to see you go..." reason selector modal.
3.2 Step 1 — Cancellation Reason Selector
3.2.1 The reason selector modal displays the heading "We'd hate to see you go..." with the subtitle "Before you cancel, could you share why you're leaving? Your feedback helps us make Pixally better for creators like you."
3.2.2 The modal displays nine radio-button reasons: "I no longer need Pixally for my business", "I'm switching to a different tool", "Too expensive / not worth the cost", "Missing features I need", "Too complicated / hard to use", "I only needed it for a one-time project", "I had technical issues or bugs", "My business has slowed down or closed", and "Other (please specify)".
3.2.3 If the owner selects "Other (please specify)", a free-text field appears below the radio group where the owner must enter at least ten characters explaining their reason.
3.2.4 The "Continue to Cancel" primary call-to-action is disabled until a reason is selected and (if applicable) the "Other" text field meets the minimum-ten-character requirement.
3.2.5 The owner selects a reason and clicks "Continue to Cancel".
3.2.6 The system records the selected reason and proceeds to Step 2.
3.2.7 If the owner clicks "Close" (secondary call-to-action) or the "×" icon at any point, the modal closes without saving any state and the owner is returned to the Subscription page.
3.3 Step 2 — Before You Cancel Retention Offer
3.3.1 The system opens the "Before You Cancel..." retention offer modal with the subtitle "We understand. Here are some alternatives to canceling:".
3.3.2 The modal displays one offer card: "Switch to a lower-cost plan" with the description "Keep essential features for less".
3.3.3 If the owner clicks "Switch to a lower-cost plan", the system closes the cancel flow modal and routes the owner to the Manage Subscription page per FRD 3 with lower-cost plans visible for selection; any partially-captured cancellation state (selected reason) is discarded because the owner is opting for downgrade instead of cancel.
3.3.4 If the owner clicks "Still Want to Cancel", the system proceeds to Step 3.
3.3.5 If the owner clicks "Keep My Subscription", the system closes all cancellation modals, discards the captured reason, and returns the owner to the Subscription page with no subscription changes.
3.4 Step 3 — Confirm Cancellation with Features-Lost List
3.4.1 The system opens the "Confirm Cancellation" modal with the heading "Confirm Cancellation" and the subtitle "You'll lose access to:".
3.4.2 The modal displays a dynamic list of features the owner will lose access to, computed by subtracting the Free plan's feature set from the owner's current plan feature set per FRD 1 and following the same dynamic-list logic used in FRD 3 Section 4.22 for downgrade-to-Free features-lost display.
3.4.3 For an Essentials-plan owner, the features-lost list typically includes items such as contractor management, QuickBooks Online integration, expense management, advanced reports, and any other Essentials-tier feature not included in the Free plan.
3.4.4 For a Studio-plan owner, the features-lost list additionally includes priority support, SMS reminders, unlimited team members beyond one, unlimited brands beyond one, and unlimited contractors.
3.4.5 The modal displays two call-to-actions: "Keep My Subscription" (secondary) and "Cancel Subscription" (primary, red-styled).
3.4.6 If the owner clicks "Keep My Subscription", all modals close, captured state is discarded, and the owner returns to the Subscription page with no changes.
3.4.7 If the owner clicks "Cancel Subscription", the system commits the cancellation to Stripe (marks the subscription for cancellation at period end, not immediate), persists the captured reason, auto-cancels any pending scheduled downgrade or cycle switch, and proceeds to Step 4.
3.5 Step 4 — Cancellation Success Confirmation
3.5.1 The system opens the "Subscription Canceled" success modal with a checkmark icon.
3.5.2 The modal displays the message "Your [Plan Name] subscription is now canceled. You'll continue to have access to all features until [Cycle End Date]. After that, your account will switch to the free plan with limited features. You can upgrade again at any time to regain full access."
3.5.3 The modal displays a single primary call-to-action "Got It".
3.5.4 The owner clicks "Got It" and the system closes the modal, returns the owner to the Subscription page, and the plan card updates to display a scheduled-cancellation indicator with the cycle end date and a "Reactivate Subscription" call-to-action.
3.5.5 The system sends a cancellation confirmation email to the owner's primary email address with the cycle end date, details of the plan being cancelled, and a "Reactivate Subscription" link.
3.6 Reactivate Subscription Before Cycle End
3.6.1 During the window between cancellation confirmation and the cycle end date, the plan card on the Subscription page displays a notice "Your subscription is scheduled to end on [Cycle End Date]" and a "Reactivate Subscription" call-to-action.
3.6.2 The Agency Owner clicks "Reactivate Subscription".
3.6.3 The system displays a confirmation popup "Reactivate your [Plan Name] subscription? Your next renewal will continue as originally scheduled on [Next Renewal Date]. No additional charge is required today."
3.6.4 On confirmation, the system removes the cancel-at-period-end flag on the Stripe subscription, restores normal subscription state, hides the scheduled-cancellation notice, and displays a success toast "Your subscription is active again."
3.6.5 The system sends a reactivation confirmation email with the next renewal date and amount.
3.7 Cycle End — Transition to Free Plan
3.7.1 At the end of the current billing cycle, a scheduled background job executes the cancellation by transitioning the agency's subscription state to "cancelled" on Stripe and downgrading the agency plan to Free in Pixally.
3.7.2 The transition to Free plan follows the same logic defined in FRD 3 Section 4.22 for downgrade-to-Free: the system auto-retains the Agency Owner and auto-disables all other team members per the Free-plan one-seat limit, auto-keeps one brand and archives any brands over the one-brand limit, and auto-archives projects over the five-active-project Free-plan limit (oldest-first).
3.7.3 Any paid extra seats are cancelled at cycle end; $9-per-seat-monthly billing stops from the cycle end date forward; users occupying paid extra seats are auto-disabled along with other non-Owner members.
3.7.4 Any pending team member invites that have not been accepted are automatically cancelled at cycle end.
3.7.5 Any scheduled downgrade or scheduled cycle switch is automatically cancelled because the subscription itself is ending.
3.7.6 The Agency Owner becomes a Free-plan user with Free-plan entitlements; the Subscription page displays the Free plan card with an "Upgrade Plan" call-to-action.
3.7.7 The 365-day data-retention clock begins from the owner's last-login date (following FRD 2 Section for Free-plan inactivity rules); the clock resets on every subsequent login.
3.8 Re-Subscribe Within Retention Window
3.8.1 The owner logs in to their Free-plan account within the 365-day window and wishes to regain access to their previous paid features.
3.8.2 The owner navigates to the Subscription page or clicks any feature-gated upgrade prompt, routing to the Manage Subscription page per FRD 3.
3.8.3 The owner selects a paid plan, completes the checkout flow, and pays.
3.8.4 On successful payment, the system restores the agency to the selected paid plan with all data intact; previously-disabled team members can be re-enabled via Team Management, archived brands become accessible, and archived projects become active again.
3.8.5 If the owner's original promo (50% off first year) was already consumed during the previous subscription, the system does not grant the promo again regardless of how much time has passed since cancellation.
3.9 Deletion Warning and Hard Delete — 365-Day Inactivity
3.9.1 If the owner does not log in for an extended period after their subscription ends, the 365-day inactivity clock approaches hard deletion.
3.9.2 At Day 335 from last-login date (approximately one month before deletion), the system sends the first deletion warning email to the owner's primary email informing them of the upcoming deletion and providing a login link to reset the clock.
3.9.3 At Day 358 from last-login date (approximately one week before deletion), the system sends a second deletion warning email with the same content and a sharper tone.
3.9.4 At Day 364 from last-login date (one day before deletion), the system sends the final deletion warning email.
3.9.5 If the owner logs in at any point before Day 365, the deletion clock resets to the new login date and warning emails are cancelled.
3.9.6 If the owner does not log in by Day 365, the system performs a hard deletion of the account, including all associated data in Pixally (projects, clients, invoices, contracts, brands, team member records, contractor records, files, and any other agency-owned entities) at midnight UTC on Day 365.
3.9.7 After hard deletion, the email address is released for re-signup; however, the email remains flagged in the promo-history log so that previously-used promo codes including the 50%-off-first-year offer are permanently blocked for any new account signing up with this email.
3.10 Cancel During Failed-Payment Grace Period
3.10.1 During the 28-day grace period defined in FRD 7, the Agency Owner can click "Cancel Subscription" on the Subscription page to enter the cancellation flow.
3.10.2 The cancellation flow proceeds through the standard four steps (reason selector, retention offer, confirm cancellation, success) identically to Section 3.1 through Section 3.5, with one variation in Step 4 success-modal copy to reflect immediate transition rather than cycle-end transition.
3.10.3 Cancellation during grace overrides the grace period with immediate effect: the failed invoice is written off by Pixally and is no longer collectible, the Stripe subscription is cancelled outright (not scheduled at period end), and the agency transitions to the Free plan immediately on the same day the cancellation is confirmed.
3.10.4 The 365-day data-retention window begins from the cancellation date, and the account operates under Free-plan entitlements from that moment forward per the downgrade-to-Free logic in FRD 3 Section 4.22.
3.11 Cancel During Suspension
3.11.1 While the account is in the Suspended state defined in FRD 7, the Agency Owner sees only the suspended Subscription page with the red banner and clicks the "Cancel Subscription" call-to-action on the plan card.
3.11.2 The cancellation flow proceeds through the same four steps as the standard flow, with the Step 4 success-modal copy reflecting immediate transition rather than cycle-end transition.
3.11.3 Cancellation from suspension writes off the failed invoice and ends the Stripe subscription immediately; the account transitions to Free plan immediately on the cancellation date, the red suspension banner is hidden, and the left navigation is re-enabled as the account operates under normal Free-plan entitlements from that moment forward.
3.11.4 The 365-day data-retention window is reset and begins fresh from the cancellation date, replacing any earlier anchor that had been established at the original suspension date per FRD 7.
4. Functional Logic
4.1 Scope of Cancellation
- The cancellation flow applies exclusively to Agency Owners on an active paid subscription (Basic, Essentials, or Studio on any billing cycle) or on the suspended state per FRD 7.
- Free-trial accounts cannot be cancelled by the user per FRD 2; the Cancel Subscription call-to-action is not shown to trial users.
- Free-plan accounts with zero paid extras have no subscription to cancel; the Cancel Subscription call-to-action is not shown on the Subscription page.
- Free-plan accounts with one or more paid extras (classified as paid accounts per FRD 5 NQ-6) show the Cancel Subscription call-to-action; cancellation in this case ends the paid extras and the account continues on the Free plan.
- Super Admin cancellation via Gawd Portal is handled separately and is not documented in this module.
4.2 Cancel Subscription Call-to-Action Placement
- The "Cancel Subscription" call-to-action is rendered on the plan card of the Subscription page as a secondary text link or outlined button, visible to the Agency Owner only.
- On the suspended Subscription page per FRD 7, the "Cancel Subscription" button remains clickable even though other buttons are greyed.
- The call-to-action is not shown for Agency Admin or other non-Owner roles per FRD 1 permissions.
4.3 Four-Step Modal Flow
- The cancellation experience is structured as four sequential modals: Step 1 is the reason selector "We'd hate to see you go...", Step 2 is the retention offer "Before You Cancel...", Step 3 is the confirm cancellation with features-lost list, and Step 4 is the success confirmation.
- Each step has its own modal; completing one step opens the next and closes the current.
- Closing any modal via the "×" icon, the "Close" button, or the "Keep My Subscription" button at any point discards all captured state and returns the owner to the Subscription page with no changes.
4.4 Reason Selector — Required Selection
- The nine predefined reasons are displayed as a radio-group; exactly one reason must be selected before the owner can continue.
- The ninth reason "Other (please specify)" includes a free-text input that becomes visible only when this reason is selected; the text must be at least ten characters long for the owner to proceed.
- The selected reason is persisted to the agency's subscription record and is available in Gawd Portal reporting for product-analytics use.
- The "Continue to Cancel" button is disabled until both conditions are met: a reason is selected and (if "Other" is selected) the text field contains at least ten characters.
4.5 Retention Offer — Two Alternatives
- The retention offer modal shows one alternative to cancellation: "Switch to a lower-cost plan".
- * The same alternative is shown to every owner regardless of which cancellation reason was selected; the retention offer is not personalized by reason in Phase 1\.
- * Clicking "Switch to a lower-cost plan" discards the cancellation flow and routes the owner to the Manage Subscription page per FRD 3 where all lower-cost plans (Free, Basic, or Essentials depending on current plan) are visible and selectable.
- * The "Schedule a 1:1 setup call" option is excluded from Phase 1 and is not present in the modal; this option may be reintroduced in a future phase pending a calendar-booking integration with the Pixally success team.
- * Clicking "Still Want to Cancel" proceeds to Step 3 (Confirm Cancellation).
- * Clicking "Keep My Subscription" discards the cancellation flow and returns the owner to the Subscription page.
4.6 Confirm Cancellation — Dynamic Features-Lost List
- The Confirm Cancellation modal displays a dynamic list of features the owner will lose access to upon cancellation, computed by taking the owner's current plan's full feature entitlements per FRD 1 and excluding any feature that is also included in the Free plan.
- The dynamic computation follows the identical logic defined in FRD 3 Section 4.22 for downgrade-to-Free features-lost display; both cancellation and downgrade-to-Free result in the same end-state (Free plan), so both flows show the same features-lost list for the same source plan.
- The list is rendered as a checklist of red-X items; the visual style matches FRD 3 downgrade-to-Free Confirm modal.
- Typical items for an Essentials-plan owner include contractor management, QuickBooks Online integration, expense management, post-production management, advanced reports, and unlimited team members or brands beyond the Free plan limits.
- Typical items for a Studio-plan owner additionally include priority support, SMS reminders, and fully unlimited contractors and brands.
4.7 Cancellation Commit — Stripe Cancel at Period End
- When the owner clicks "Cancel Subscription" in the Confirm modal, the system calls Stripe's subscription update API to set the "cancel_at_period_end" flag to true on the subscription object; this schedules the cancellation to execute at the end of the current billing cycle without an immediate cancellation.
- The subscription remains active in Stripe until the billing cycle end date; no additional charge is generated for the next cycle.
- Pixally's backend marks the agency's subscription state as "cancelled_scheduled" with the cycle end date stored for downstream processing.
- The selected cancellation reason and optional "Other" text are persisted to the agency's subscription record.
- Any pending scheduled downgrade or scheduled cycle switch on the subscription is automatically cancelled because the subscription is ending; no separate user action is required.
4.8 No Refund Policy
- No refund is issued for the unused portion of the current billing cycle when the owner cancels mid-cycle; the owner retains full access to all paid features until the cycle end date.
- For annual subscribers cancelling mid-year, the owner retains access for the remaining months of the annual period with no pro-rata refund.
- This is aligned with Pixally's no-refund policy communicated on the Manage Subscription page and during the cancellation flow success confirmation.
4.9 Subscription Canceled Success Message — Two Variants
- The Step 4 success modal has two copy variants depending on whether cancellation takes effect at cycle end (normal cancellation) or immediately (grace-period cancellation and suspension cancellation).
- Variant 1 — Normal Cancellation (cancel at cycle end): The plan name and cycle end date are injected into the copy: "Your [Plan Name] subscription is now canceled. You'll continue to have access to all features until [Cycle End Date]. After that, your account will switch to the free plan with limited features. You can upgrade again at any time to regain full access." This variant is used when the Owner cancels from an active paid subscription in good standing.
- Variant 2 — Immediate Cancellation (grace period or suspension): The plan name is injected into the copy: "Your [Plan Name] subscription is now canceled. Your account has been switched to the free plan with limited features. You can upgrade again at any time to regain full access." This variant is used when the Owner cancels during the failed-payment grace period per FRD 7 or while the account is in the Suspended state.
- Both variants display a single primary call-to-action "Got It" that closes the success modal and returns the owner to the Subscription page.
4.10 Post-Cancellation Plan Card State
- After cancellation is confirmed, the plan card on the Subscription page displays a scheduled-cancellation indicator banner with the text "Your subscription is scheduled to end on [Cycle End Date]" along with a "Reactivate Subscription" call-to-action.
- The plan details (plan name, cycle, current seats, and other plan info) remain visible so the owner can see what they are scheduled to lose.
- The "Change Plan" and "Cancel Subscription" call-to-actions are replaced by the "Reactivate Subscription" call-to-action during this window; the owner cannot initiate a new plan change or cancel again while a cancellation is already pending.
4.11 Reactivate Subscription Before Cycle End
- Between the cancellation confirmation and the cycle end date, the Agency Owner can reactivate the subscription with a single click of the "Reactivate Subscription" call-to-action on the plan card.
- Clicking the call-to-action opens a confirmation popup asking the owner to confirm reactivation; on confirmation, the system calls Stripe to remove the "cancel_at_period_end" flag, restoring the subscription to normal active state.
- Reactivation restores the agency to its ORIGINAL plan and billing cycle that were in effect at the time of cancellation; the Reactivate flow does not offer a plan-change option. If the owner wishes to reactivate as a different plan (upgrade or downgrade), they must first reactivate the original plan, then initiate a Change Plan action per FRD 3 separately.
- No additional charge is required for reactivation because the owner has already paid for the current cycle; the next scheduled renewal proceeds as originally planned on the next renewal date.
- The scheduled-cancellation banner is hidden, and the plan card returns to its normal display with "Change Plan" and "Cancel Subscription" call-to-actions restored.
- The system sends a reactivation confirmation email to the owner with the next renewal date and amount per the Notification Module.
4.11.1 Team Invites During Cancel-to-Cycle-End Window
- From the moment the Owner confirms cancellation in Step 3 until the cycle end date, the Agency can not accept any new team member invites; pending invites that were sent before cancellation are blocked from acceptance during this window.
- If an invitee clicks their invite link during the cancel-to-cycle-end window, they see an informational message "This agency's subscription is ending soon. New team member additions are paused." and cannot complete the invite acceptance flow.
- Pending invites that have not been accepted by the cycle end date are automatically cancelled per Section 3.7.4.
- If the Owner reactivates the subscription before cycle end per Section 4.11, the invite block is lifted and any still-valid pending invites become acceptable again.
- The Invite Team Member call-to-action on the Team Management page is also disabled during the cancel-to-cycle-end window to prevent new invite creation.
4.12 Cycle End Execution — Cancellation to Free Plan Transition
- At the end of the billing cycle on the scheduled cancellation date, a backend scheduled job executes the cancellation by calling Stripe to finalize the cancellation and by downgrading the agency plan to Free in Pixally's own records.
- The downgrade-to-Free execution follows the same logic as a user-initiated downgrade-to-Free per FRD 3 Section 4.22: the system auto-keeps the Agency Owner as the sole active team member (Free plan allows one seat), auto-disables all other team members (including paid-extras-seat users), auto-keeps one brand and archives any additional brands, and auto-archives projects beyond the Free-plan five-active-project limit, oldest-first.
- Auto-disabled team members are not deleted; their records are preserved with an "Inactive" flag and can be re-enabled if the owner re-subscribes to a plan that supports more seats.
- Auto-archived brands and projects remain in the system; owners can access archived-brand data in a read-only view under the Free-plan constraints until the agency re-subscribes.
4.13 Paid Extras at Cycle End
- Any paid extra seats billed at $9 per month under the current paid plan are cancelled at cycle end; the monthly $9-per-seat billing stops from the cycle end date forward, and no refund is issued for the unused portion of the current month's $9 seat charges.
- Users occupying paid extra seats are treated identically to plan-included team members in the auto-disable logic: at cycle end, all non-Owner members (whether seat-included or paid-extras) are disabled because the Free plan allows only one seat.
- A worked example illustrates this: on an Essentials plan with four team members (three plan-included plus one paid extra at $9 monthly equals $43.50 total monthly), the owner cancels on January 5 and the cycle ends January 31; all four members retain full access until January 31; on February 1, the plan becomes Free with the Owner retained and the other three members (regardless of whether they were plan-included or paid-extras) auto-disabled, and the $9 paid-extras billing stops.
- For subscribers on an Annual main plan with monthly paid extras (per FRD 4 Section SQ-10 which defines extras as always billed monthly regardless of main-plan cycle), the "cycle end" anchor for cancellation is the Annual main-plan renewal date; all features including monthly extras continue until the annual renewal date, with extras continuing to be billed monthly at $9 per seat through each monthly extras-billing date until the annual renewal arrives; on the annual renewal date, both the main plan and all paid extras are cancelled together in a single cycle-end transition to Free.
- A worked example for Annual+extras illustrates: Essentials Annual subscribed on January 1 for $345 plus two monthly paid extras at $9 each ($18 monthly); owner cancels on July 15; the annual renewal date is December 31; from July 15 through December 31 the agency retains full Essentials access; monthly extras continue billing on each monthly extras-anchor date (August, September, October, November, December) at $18 per month; on December 31, the annual main plan and all extras cancel together, the agency transitions to Free, and no further billing occurs.
4.14 Contractor Access After Cancellation
- Because the Free plan does not include the Contractor Management module per FRD 1, all active contractors lose access to the Contractor Portal at cycle end when the agency transitions to Free.
- When a contractor attempts to log in after the agency has cancelled and transitioned to Free, the system displays a generic message "Your access is revoked. Please contact the agency." and does not reveal that the agency cancelled or downgraded; this protects the agency's business privacy.
- Contractor data (assigned jobs, historical payments, profile records) is preserved in the system and becomes accessible again if the agency re-subscribes to a plan that supports Contractor Management.
4.15 Client Access After Cancellation
- Because the Client Portal is included in the Free plan per FRD 1, clients continue to have normal Client Portal access after the agency cancels and transitions to Free.
- Client-facing functionality (viewing project status, communicating with the agency, reviewing invoices, making payments) continues to operate exactly as it did before cancellation within Free-plan feature limits.
- No messaging about the cancellation or plan change is shown to clients.
4.16 Team Member Access After Cancellation
- At cycle end, all team members except the Owner are auto-disabled via the Free-plan downgrade logic; disabled team members cannot log in and see the standard "Your account has been deactivated. Please contact your agency owner." message on login attempts, consistent with FRD 3 downgrade-to-Free behavior.
- Disabled team members' data (assigned projects, task histories, activity logs) is preserved; re-enabling them requires the agency to re-subscribe to a plan that supports additional seats and for the Owner to manually re-enable them via Team Management.
4.17 365-Day Data Retention Window
- The 365-day data-retention window anchors to the Agency Owner's most recent login date once the agency transitions to Free after cancellation, not to the cancellation date itself.
- Every time the owner logs in after transitioning to Free, the 365-day clock resets to the new login date.
- If the owner logs in regularly (for example, every few months), the agency account remains indefinitely; only sustained inactivity triggers the deletion pathway.
- This anchoring to last-login rather than cancellation date ensures that actively engaged Free-plan users (including those who cancelled a paid subscription) are never penalized for their cancellation choice.
4.18 Deletion Warning Email Schedule
- Deletion warnings are part of a unified system that applies to two trigger paths: the cancellation-Free path defined in this FRD (365 days from last-login) and the suspension path defined in FRD 7 Section 4.10.1 (configured period from suspension start; default 1 year).
- * The warning schedule for both paths is identical: 1 month before scheduled deletion (first warning), 1 week before (second warning), and 1 day before (final warning).
- * For the cancellation-Free path, warnings fire at Day 335, Day 358, and Day 364 from last-login date.
- * For the suspension path, warnings fire at suspension start \+ (delete-after − 30 days), suspension start \+ (delete-after − 7 days), and suspension start \+ (delete-after − 1 day).
- * Each email explains that the agency's data will be permanently deleted on the scheduled date, identifies the trigger (cancellation inactivity or suspension), provides a recovery link (login link for cancellation path, payment link for suspension path), and describes the consequences of allowing deletion (no data recovery possible, promo history retained per FRD 1).
- * If the owner takes the recovery action (logs in for cancellation path; pays comeback payment for suspension path) at any time during the warning period, the scheduled warnings and the deletion itself are cancelled; the cancellation-path clock resets to the new login date; the suspension path returns the agency to Active state.
- * Deletion warnings respect the Gawd Portal master notifications toggle; when disabled, no warnings are sent but deletion still occurs on schedule.
4.19 Hard Deletion at Day 365
- If the owner does not log in by Day 365 from last-login date, a scheduled backend job performs a hard deletion of the agency at midnight UTC on Day 365.
- Hard deletion is irreversible; all data associated with the agency is permanently removed from Pixally's primary databases including projects, clients, contracts, invoices, payments, proposals, tasks, calendar events, contractor records, team member records, brand assets, uploaded files, notification history, email logs, and any other agency-owned entity.
- The Stripe customer object is either deleted or archived per Stripe's retention rules; Pixally does not retain any billing or card data beyond hard-deletion point.
- After hard deletion, the email address previously associated with this agency is released and can be used to sign up a new Pixally account.
- The email address is retained in a separate promo-history log indefinitely so that any past promo usage (including the one-time 50% off first year offer) remains tracked against the email and cannot be reused on a new signup.
4.20 Re-Subscribe Within Retention — Data Restoration
- When the Agency Owner re-subscribes to a paid plan within the 365-day retention window (before hard deletion), all agency data is restored to its pre-cancellation state along with the plan's feature entitlements.
- Previously auto-disabled team members remain in the "Inactive" state after re-subscription and require manual re-enablement by the Owner via Team Management; this gives the Owner control over which team members to reinstate since their needs may have changed.
- Previously archived brands become accessible again up to the new plan's brand limit; if the new plan has a lower brand limit than the original plan (for example, re-subscribing to Basic after originally having Essentials with two brands), the one-brand Basic limit applies and the remaining brand stays archived until a further upgrade.
- Previously archived projects above the Free-plan five-project limit become active again up to the new plan's limit; for unlimited-project plans (Basic and above), all projects become active.
- Contractors regain access if the new plan supports Contractor Management (Essentials or Studio); on plans without contractor support (Free, Basic), contractor records remain preserved but contractors cannot log in.
- The original subscription signup date continues to anchor the Year 1 promo window; if the owner re-subscribes within the original 365-day promo window, the 50% discount applies to the new subscription for the remainder of the promo window.
4.21 Re-Signup After Hard Deletion
- If an individual signs up a new agency using an email address that was previously hard-deleted, the system allows the new signup and creates a fresh agency record with no connection to the prior deleted data.
- The email is checked against the promo-history log during signup; any promo codes and the 50% off first-year offer that were previously consumed on this email are blocked for the new signup.
- The new signup receives standard signup benefits (14-day free trial if applicable per FRD 2) except for promo entitlements already consumed.
4.22 Cancellation Email Notifications
- The system sends a cancellation confirmation email to the Agency Owner immediately upon Step 4 confirmation; the email includes dynamic variables (plan name being cancelled, cycle end date or immediate-transition indicator, reactivation link, summary of features that will be lost at cycle end), with exact email copy maintained centrally in the Notification Module and subject to marketing review and finalization.
- At the exact cycle end date when the transition to Free executes for normal cancellations, the system sends a "Your subscription has ended" email summarizing the transition to Free, with exact copy maintained in the Notification Module.
- For grace-period and suspension cancellations (where the transition is immediate rather than at cycle end), the immediate-transition cancellation email replaces both the confirmation and cycle-end emails into a single notification on the cancellation date.
- The deletion warning emails defined in Section 4.18 are sent at Day 335, Day 358, and Day 364 from last-login date; exact copy for each of the three warning touchpoints is maintained in the Notification Module.
- The reactivation confirmation email sent on Reactivate Subscription per Section 4.11 is similarly maintained in the Notification Module.
- All cancellation-related emails are transactional and cannot be opted out of per FRD 6 Section 4.20.
4.22.1 Super Admin-Initiated Cancellation — Owner-Facing Impact
- When the Pixally Super Admin initiates a cancellation on behalf of an agency via the Gawd Portal (the cancellation flow itself being documented in the Gawd Portal FRD and outside the scope of this module), the Agency Owner receives the same cancellation confirmation email as a self-initiated cancellation.
- The plan card on the Subscription page displays the same scheduled-cancellation banner and "Reactivate Subscription" call-to-action (for normal cancellation) or the same immediate-transition behavior (for grace/suspension cancellation) as a self-initiated cancellation; the UI does not specially indicate that the cancellation was admin-initiated.
- The owner can reactivate the subscription via the normal Reactivate flow if the cancellation was a normal cycle-end cancellation; for immediate-transition cancellations initiated by the Super Admin, the owner must re-subscribe via the standard checkout flow.
4.23 Cancellation During Grace Period
- When the Agency Owner initiates cancellation during the 28-day failed-payment grace period defined in FRD 7, the cancellation flow proceeds through the same four steps as the standard flow, with the Step 4 success-modal copy using the "immediate transition" variant described in Section 4.9.
- On Step 3 confirmation, the system immediately writes off the failed invoice (marks it uncollectible on Stripe and in Pixally's records), cancels the Stripe subscription outright (not "cancel at period end" because grace means no future renewal is scheduled and the outstanding invoice defines the state), and transitions the agency to the Free plan immediately on the same day.
- The amber grace-period banner is hidden because the subscription is now cancelled and the agency is on the Free plan.
- The 365-day retention window begins from the cancellation date, and the account operates under Free-plan entitlements from that moment forward.
- All downstream Free-plan transition behaviors defined in Section 4.12 (auto-disable non-Owner members, auto-archive brands and projects over Free-plan limits) execute immediately on cancellation rather than at a future cycle-end date.
- All paid extras are cancelled immediately; $9-per-seat billing stops; paid-seat users are auto-disabled per Section 4.13 on the cancellation date.
4.24 Cancellation During Suspension
- When the Agency Owner initiates cancellation from the suspended Subscription page per FRD 7, the cancellation flow proceeds through the same four steps as the standard flow, with the Step 4 success-modal copy using the "immediate transition" variant described in Section 4.9.
- On Step 3 confirmation, the system writes off the failed invoice, transitions the Stripe subscription from "paused" to "cancelled", and transitions the agency to the Free plan immediately on the cancellation date.
- The 365-day retention window is reset and begins fresh from the cancellation date, replacing any earlier retention anchor that had been established at the original suspension date per FRD 7 Section 4.10.
- The red suspension banner is hidden after cancellation; the Subscription page restores normal navigation (left nav re-enabled) because the account is now in a normal Free-plan state, not suspended.
- All downstream Free-plan transition behaviors defined in Section 4.12 (auto-disable non-Owner members, auto-archive brands and projects over Free-plan limits) execute immediately on cancellation.
- All paid extras are cancelled immediately; paid-seat users are auto-disabled; $9-per-seat billing stops on the cancellation date.
4.25 Scheduled Downgrade and Cycle Switch Auto-Cancellation
- Any pending scheduled downgrade per FRD 3 that exists on the subscription at the time of cancellation is automatically cancelled when the cancellation is committed in Step 3; the scheduled downgrade no longer applies because the subscription itself is ending.
- Any pending scheduled cycle switch per FRD 4 that exists on the subscription at the time of cancellation is similarly cancelled automatically.
- The auto-cancellation is silent (no separate confirmation or notification) because it is a natural consequence of the cancellation; the user is not made to acknowledge something they already superseded by a bigger action.
4.26 Owner Transfer Out of Scope
- Owner transfer functionality (transferring agency ownership to another team member before cancellation) is out of scope for Phase 1; the current Owner must cancel their own agency.
- If an owner wishes to hand off the agency to another individual, they must coordinate outside of Pixally and a new agency must be created by the intended new owner.
4.27 Grace-Period Banner Visibility During Cancel Flow Modals
- During a cancel flow initiated while the account is in the grace period per FRD 7, the amber grace-period banner is temporarily hidden while any of the four cancellation modals (reason selector, retention offer, confirm cancellation, success confirmation) is open in the viewport.
- The banner is hidden by adjusting page z-index behavior so that the cancel flow modal occupies full visual attention without competing visual elements.
- If the owner closes all modals without completing cancellation, the banner becomes visible again on the Subscription and Dashboard pages per its normal visibility rules.
- This rule applies only to the grace-period amber banner; the red suspension banner during Suspended state is replaced entirely by the Subscription page suspended-state rendering and does not need separate hide-during-modal handling.
4.28 Access to Historical Invoices and Receipts Post-Cancellation
- The Subscription Receipts list remains fully visible and accessible to the Agency Owner on the Subscription page during the cancel-to-cycle-end window for normal cancellations, allowing the owner to download past invoice PDFs for tax and accounting purposes.
- After the cycle-end transition to Free (or immediately for grace-period and suspension cancellations), the Subscription Receipts list continues to display all historical paid invoices under the Free-plan Subscription page view, even though the agency is no longer a paying subscriber.
- Historical receipts remain downloadable for the full duration of the 365-day retention window; upon hard deletion per Section 4.19, all invoice records are removed along with other agency data.
- This rule provides continuity of financial records for the Owner regardless of subscription state.
5. Field Details & Validations
Field Name
Field Type
Validation Rules
Cancel Subscription CTA
Text link / Button
Visible to Agency Owner on paid subscription only. Hidden during trial, for Free-plan-no-extras accounts, and for all non-Owner roles.
Cancellation Reason
Radio group (single-select)
Required. Nine predefined options plus "Other".
Other Reason Text
Textarea
Required only if "Other" selected. Minimum 10 characters. Maximum 500 characters.
Continue to Cancel Button
Primary button
Disabled until reason selected and (if "Other") text meets minimum length.
Switch to Lower-Cost Plan Offer Card
Card with click handler
Routes to Manage Subscription (FRD 3); discards cancellation state.
Schedule 1:1 Setup Call Offer Card
Card with click handler
Routing to be discussed with client. Phase 1 implementation pending.
Still Want to Cancel Button
Secondary button
Proceeds to Step 3 Confirm.
Keep My Subscription Button
Primary button (retention), Secondary button (confirm)
Closes all modals; discards state; returns to Subscription page.
Features-Lost List
Dynamic red-X checklist
Computed from current plan minus Free plan features per FRD 1 and FRD 3 Section 4.22.
Cancel Subscription Confirm Button
Primary button (red)
Commits Stripe cancel_at_period_end; proceeds to Step 4.
Success Modal Plan Name
Read-only text injected
Dynamic; current plan name.
Success Modal Cycle End Date
Read-only date injected
Dynamic; format "MMM DD, YYYY".
Got It Button
Primary button
Closes success modal.
Reactivate Subscription CTA
Primary button on plan card
Visible between cancellation confirmation and cycle end date only.
Reactivate Confirmation Popup
Modal
Confirms intent; no payment required.
Scheduled Cancellation Banner
Notice component
Visible on plan card between cancellation and cycle end.
Deletion Warning Emails
Transactional emails
Sent at Day 335, Day 358, Day 364 from last-login date.
Contractor Generic Message
Read-only text
"Your access is revoked. Please contact the agency." Shown on Contractor Portal login attempt after cancellation.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Cancellation committed (Step 3 confirm)
Success modal: "Your [Plan] subscription is now canceled. You'll continue to have access to all features until [Date]. After that, your account will switch to the free plan with limited features. You can upgrade again at any time to regain full access."
Owner clicks "Cancel Subscription" in Step 3.
Stripe cancel_at_period_end set; reason persisted; pending schedules auto-cancelled; confirmation email sent.
SM-2
Reactivation before cycle end
Toast: "Your subscription is active again."
Owner clicks Reactivate + confirms popup.
Stripe cancel flag removed; scheduled-cancellation banner hidden; email sent.
SM-3
Cycle end transition to Free
Email: "Your subscription has ended. You are now on the Free plan."
Scheduled job executes at cycle end.
Plan transitions to Free; non-Owner members disabled; excess brands/projects archived; paid extras cancelled.
SM-4
Retention offer — Switch to lower plan
No success message from cancel flow; Manage Subscription page opens.
Owner clicks "Switch to a lower-cost plan".
Cancel flow state discarded; user proceeds through FRD 3 downgrade.
SM-5
Re-subscribe within retention
Standard checkout success per FRD 3.
Owner re-subscribes while data still exists.
All agency data restored at plan-level limits; team members remain Inactive pending manual re-enable.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Continue to Cancel clicked without reason
"Please select a reason to continue." (Inline message or button remains disabled.)
Owner tries to proceed without selecting reason.
Owner selects a reason.
EM-2
"Other" selected but text under 10 chars
"Please provide a brief explanation (at least 10 characters)."
Owner selects Other, enters short text, tries to continue.
Owner adds more detail.
EM-3
Stripe cancel API failure
"We couldn't cancel your subscription due to a temporary issue. Please try again or contact support."
Stripe API returns error during commit.
Owner retries.
EM-4
Reactivate API failure
"We couldn't reactivate your subscription due to a temporary issue. Please try again or contact support."
Stripe API returns error during reactivate.
Owner retries.
EM-5
Non-Owner attempts Cancel CTA (defensive)
"Only the agency owner can cancel the subscription. Please contact your agency owner."
Non-Owner reaches cancel endpoint via direct URL or race.
Non-Owner contacts Owner.
EM-6
Cancellation attempted on trial
"Your trial does not require cancellation. It will expire automatically on its scheduled date."
Edge case: defensive check if trial user somehow reaches cancel flow.
No action needed; trial continues.
EM-7
Cancel flow initiated during trial (defensive)
Cancel Subscription CTA should not be visible; if reached, show EM-6.
Trial state per FRD 2.
—
EM-8
Contractor log-in after agency cancellation
"Your access is revoked. Please contact the agency."
Contractor attempts Contractor Portal login after agency transitions to Free.
Contractor contacts agency outside Pixally.
EM-9
Deactivated team member log-in after cancellation
"Your account has been deactivated. Please contact your agency owner."
Team member tries to log in after cycle end transition.
Member contacts Owner for re-enable (requires re-subscription).
EM-10
Generic system failure
"Something went wrong. Please try again or contact support."
Any unhandled exception.
Retry.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Owner selects a reason, clicks Continue, then clicks X on retention modal.
All modals close; no state persisted; returned to Subscription page; no subscription changes. Owner can restart cancel flow later.
EC-2
Owner reaches Step 3 Confirm, closes modal, then re-opens Cancel flow.
Starts fresh from Step 1 (reason selector). Prior selection is not preserved across sessions.
EC-3
Owner on Essentials with 4 seats (3 included + 1 paid extra) cancels on Jan 5; cycle ends Jan 31.
All 4 members retain full access until Jan 31. On Feb 1, plan transitions to Free; Owner retained; 3 other members auto-disabled; $9 extras billing stops; no refund.
EC-4
Owner on Studio Annual at $1,190/year (paid Jan 1) cancels on July 1.
Owner retains Studio access until Dec 31 (full annual cycle); no prorated refund for the remaining 6 months; on Jan 1 transition to Free.
EC-5
Owner has scheduled downgrade to Basic at cycle end; cancels before cycle ends.
Scheduled downgrade auto-cancelled. At cycle end, agency transitions to Free (not Basic).
EC-6
Owner has scheduled cycle switch (Annual→Monthly) at annual end; cancels mid-annual.
Scheduled cycle switch auto-cancelled. At annual end, agency transitions to Free.
EC-7
Owner cancels on Day 5 of cycle; clicks Reactivate on Day 20.
Stripe cancel flag removed; subscription continues normally; next renewal on original scheduled date; no additional charge.
EC-8
Owner cancels on Day 5; attempts to Reactivate on Day 35 (after cycle end).
Reactivate CTA is no longer available after cycle end. Owner must re-subscribe via Manage Subscription at normal plan pricing.
EC-9
Owner cancels during 28-day failed-payment grace on Day 14.
Cancellation overrides grace; failed invoice written off; Stripe subscription cancelled outright; agency transitions to Free plan IMMEDIATELY on cancellation date (not at any future cycle end); amber banner hidden; 365-day retention begins from cancellation date; all paid extras cancelled immediately and paid-seat users auto-disabled; Variant 2 success modal copy displayed.
EC-10
Owner cancels from suspended Subscription page on Day 40 after Day 29 suspension.
Stripe subscription moved from paused to cancelled; failed invoice written off; agency transitions to Free IMMEDIATELY on cancellation date; red suspension banner hidden; left nav re-enabled; 365-day retention RESETS and begins fresh from cancellation date (replacing the suspension-date anchor); Variant 2 success modal displayed.
EC-10A
Owner invites a new team member 3 days before cancelling; invitee clicks the invite link 2 days AFTER owner cancelled (still within cancel-to-cycle-end window).
Invitee sees informational message "This agency's subscription is ending soon. New team member additions are paused." Invite acceptance is blocked. If owner reactivates before cycle end, invite becomes acceptable again.
EC-11
Owner selects "Other" with exactly 10 characters.
Valid; Continue enabled.
EC-12
Owner selects "Other" with 9 characters.
Invalid; Continue disabled; EM-2 displayed.
EC-13
Owner clicks "Switch to lower-cost plan" from Step 2.
Cancel flow modals close; routes to Manage Subscription page (FRD 3); no cancellation persisted; owner proceeds through downgrade flow normally.
EC-14
Owner clicks "Schedule a 1:1 setup call" from Step 2.
Opens scheduling flow in new browser tab; specific routing to be discussed with client; Pixally cancel flow closes.
EC-15
Trial user attempts to navigate to Cancel Subscription via direct URL.
Cancel CTA is not rendered for trial accounts; direct URL access defensively shows EM-6 or redirects to Subscription page.
EC-16
Free-plan user with zero paid extras attempts Cancel.
Cancel CTA is not rendered on Free-plan accounts with no paid subscription. Nothing to cancel.
EC-17
Free-plan user with 1 paid extra cancels.
Cancel flow proceeds normally; extras cancelled at cycle end; account remains on Free plan (continues as Free user without paid extras).
EC-18
Owner re-subscribes 100 days after cancellation via Manage Subscription.
All data restored; previously archived brands and projects become accessible up to new plan limits; disabled team members remain Inactive and require manual re-enable. Original 50%-off promo window is still active if within 365 days of original signup; otherwise not.
EC-19
Owner re-subscribes 200 days after cancellation to a LOWER plan than originally cancelled.
Data restored but constrained by new plan limits; excess brands/projects/members remain archived/inactive until owner upgrades further.
EC-20
Owner does not log in for 300 days after cancellation; then logs in.
Deletion clock resets to this new login date; no warnings sent yet because 335-day threshold not reached.
EC-21
Owner receives Day 335 warning email but ignores it; logs in on Day 350.
Warning emails cancelled; deletion cancelled; clock resets to Day 350 login date (new Day 0).
EC-22
Owner does not log in for full 365 days from last login after cancellation.
Warning emails sent at 335, 358, 364. On Day 365, hard deletion executes at midnight UTC. All data permanently removed. Email released for re-signup; promo history retained.
EC-23
Deleted user signs up a new agency with the same email.
New signup allowed; new trial starts; but any promo codes previously used (including 50%-off first year) are blocked for this email.
EC-24
Owner has Essentials plan with 20 contractors; cancels.
All 20 contractors retain access until cycle end. After cycle end, contractors lose access (Free plan does not include Contractor Management); each contractor's login attempt shows "Your access is revoked. Please contact the agency."
EC-25
Owner has active Client Portal with 50 clients; cancels.
Clients continue to have normal Client Portal access before and after cycle end because Client Portal is included in the Free plan. No messaging shown to clients.
EC-26
Owner cancels, then within 1 hour wants to Reactivate.
Reactivate CTA is available immediately after Step 4 success modal; owner clicks Reactivate, confirms popup, subscription continues as if cancel never happened; restored to original plan only (no plan change in this flow).
EC-26A
Owner cancels Essentials, then during cancel-to-cycle-end window wants to reactivate as Studio (upgrade).
Reactivate flow only restores the original Essentials plan. Owner must first click Reactivate to restore Essentials, then initiate Change Plan per FRD 3 to upgrade to Studio as a separate action.
EC-26B
Owner on Annual Essentials ($345/yr) with 2 paid extras cancels July 15; annual ends Dec 31.
Full Essentials access retained through Dec 31. Monthly paid extras continue billing $18/month on each monthly extras anchor date (August, September, October, November, December). On Dec 31, annual main plan and all extras cancel together; agency transitions to Free; Variant 1 success modal copy used at cancel confirmation time.
EC-27
Owner tries to initiate a plan Change while cancellation is pending.
"Change Plan" CTA is hidden/replaced by "Reactivate Subscription" during the cancellation window; owner must reactivate first, then initiate change.
EC-28
Stripe webhook for cycle-end cancellation execution is delayed.
Pixally backend detects delayed webhook on next page load; state synchronization follows FRD 6 Section 4.19.1. In the meantime, the UI continues to show the scheduled-cancellation banner until execution is confirmed.
EC-29
Owner has credit balance when cancelling.
Credit balance is not applied to anything because no future invoices are generated after cancellation; the credit is forfeited when the subscription ends and the account transitions to Free.
EC-30
Owner on 50% first-year promo cancels on Month 4; re-subscribes on Month 9 (still within 365-day promo window from original signup).
Re-subscription continues the 50% discount for the remaining months of the original 365-day promo window; at Month 12 (original signup + 1 year), promo expires and full-price billing begins.
EC-31
Owner on 50% first-year promo cancels on Month 4; re-subscribes on Month 15 (after promo window expired).
Re-subscription at full price; no promo applies because original 365-day promo window has closed.
EC-32
Agency has pending team member invites when owner cancels.
Pending invites are cancelled at cycle end along with other team-member-level changes; if the invitee clicks an expired link, they see the standard "invite expired" message per FRD 5.
9. Acceptance Criteria
- The Cancel Subscription CTA is visible only to the Agency Owner on active paid subscriptions (including suspended state); it is hidden for trial, free-no-extras, and non-Owner roles.
- The cancellation flow is a sequential four-step modal experience: reason selector, retention offer, confirm with features-lost list, and success confirmation.
- The reason selector shows nine predefined reasons plus "Other (please specify)"; one reason must be selected to continue.
- The "Other" option requires at least 10 characters of free-text before the owner can continue.
- The retention offer modal shows two alternatives: "Switch to a lower-cost plan" (routes to FRD 3 Manage Subscription) and "Schedule a 1:1 setup call" (routing to be discussed with client).
- The Confirm Cancellation modal shows a dynamic features-lost list computed from the current plan minus Free-plan entitlements per FRD 1 and FRD 3 Section 4.22.
- Normal cancellation (active paid subscription in good standing) commits to Stripe with cancel_at_period_end flag set; the subscription remains active until cycle end with no refund; Variant 1 success modal copy is displayed.
- Grace-period cancellation and suspension cancellation override normal cancel_at_period_end behavior with immediate transition to Free on the cancellation date; the failed invoice is written off; Variant 2 success modal copy is displayed.
- Between normal cancellation and cycle end, the plan card displays a scheduled-cancellation notice with a Reactivate Subscription CTA.
- Reactivation before cycle end is one-click and restores the ORIGINAL plan only (no plan-change option in the reactivate flow); no additional charge; normal renewal proceeds on original schedule.
- Plan changes after reactivation must be initiated through a separate Change Plan action per FRD 3.
- During the cancel-to-cycle-end window, pending team invites cannot be accepted; new invite creation is disabled on the Team Management page; invitees clicking invite links see an informational message.
- At cycle end (normal cancellation only), a scheduled job transitions the agency to Free plan following FRD 3 downgrade-to-Free logic: Owner retained, non-Owner members auto-disabled, one brand kept, projects over five archived oldest-first.
- For grace-period and suspension cancellations, the transition to Free executes immediately on cancellation rather than at any future cycle-end date.
- Paid extras are cancelled at cycle end for normal cancellation, or immediately for grace/suspension cancellation; $9-per-seat billing stops; no refund for unused portion.
- For Annual main plan with monthly paid extras, cancellation cycle-end anchor is the annual renewal date; monthly extras continue billing through each monthly anchor until the annual renewal date, at which point all cancel together.
- Users occupying paid extra seats are treated identically to plan-included team members in auto-disable logic.
- Any pending scheduled downgrade or cycle switch is auto-cancelled on cancellation.
- After cycle end (or immediate cancellation), contractors lose access and see generic message "Your access is revoked. Please contact the agency." that does not reveal cancellation or downgrade.
- After cycle end, clients continue Client Portal access normally because Client Portal is included in the Free plan.
- The 365-day data-retention window for normal cancellation anchors to the owner's last-login date on the Free plan (not to cancellation date).
- For grace-period cancellation, the 365-day retention window begins from the cancellation date as the initial anchor.
- For suspension cancellation, the 365-day retention window is reset and begins fresh from the cancellation date, replacing any prior suspension-date anchor.
- Deletion warning emails are sent at Day 335, Day 358, and Day 364 from last-login date; exact email copy is maintained in the Notification Module.
- Login at any time during the warning period resets the clock and cancels the pending deletion.
- Hard deletion at Day 365 permanently removes all agency data; email is released for re-signup.
- Promo codes (including 50% first-year) remain blocked for re-signups using the same email regardless of hard deletion.
- Re-subscribing within the retention window restores all agency data at the new plan's limits; disabled team members remain Inactive pending manual re-enable.
- Historical receipts remain accessible via the Subscription Receipts list throughout the cancel-to-cycle-end window and during the Free-plan state for the full retention period.
- The amber grace-period banner is temporarily hidden while any cancel flow modal is open.
- Super Admin-initiated cancellation results in the same owner-facing email notification and plan card treatment as a self-initiated cancellation.
- All cancellation-related email copy is maintained centrally in the Notification Module.
- Trial cancellation is not supported per FRD 2.
- Owner transfer is out of scope for Phase 1.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. The test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after all Subscription FRDs are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Gates Cancel Subscription CTA visibility to Agency Owner role.
Cannot restrict cancellation to Owner.
Role & Permission Module
Hard
Enforces Owner-only cancel access; defines permission boundaries.
Cannot enforce role-based access.
Subscription Plans Module (FRD 1)
Hard
Provides plan feature entitlements for dynamic features-lost list computation.
Cannot compute what user will lose on cancellation.
Free Trial Module (FRD 2)
Hard
Defines the "trial cannot be cancelled" rule.
Cannot enforce trial exclusion.
Upgrade & Downgrade Module (FRD 3)
Hard
Provides downgrade-to-Free logic (Section 4.22) reused at cycle end transition; "Switch to lower-cost plan" retention offer routes here; features-lost list logic shared.
Cancellation cycle-end transition cannot execute; retention offer broken.
Billing Cycle Management Module (FRD 4)
Soft
Scheduled cycle switches are auto-cancelled on subscription cancellation.
Leftover scheduled switches may not be cleaned up.
Add-ons (Team Members) Module (FRD 5)
Hard
Paid extras are cancelled at cycle end; pending invites cancelled; paid-seat users treated as regular members in auto-disable.
Paid extras billing may continue incorrectly.
Billing Dashboard Module (FRD 6)
Hard
Hosts the Cancel Subscription CTA on the Subscription page; handles post-cancellation plan card state with Reactivate CTA; receipts remain accessible.
Cancel CTA cannot be rendered.
Failed Payment Management Module (FRD 7)
Hard
Grace-period and suspension-state cancellation flows integrate here; failed-invoice write-off is handled by this module's logic.
Grace/suspension cancellation paths broken.
Notification Module
Hard
Sends cancellation confirmation email, cycle-end transition email, three deletion warning emails, reactivation email.
Owner may miss critical notifications.
Stripe Billing Integration
Hard
Executes cancel_at_period_end, reactivation via flag removal, write-off for grace cancellation, and final cancel at cycle end.
Cancellation state cannot be synchronized.
Background Job / Cron Service
Hard
Executes cycle-end transition job, deletion warning emails at 335/358/364, hard delete at 365 from last-login.
Critical lifecycle events fail to execute.
Gawd Portal Module
Soft
Cancellation reasons flow to Gawd Portal reporting for product-improvement analytics.
Reason data not surfaced for analytics.
Contractor Portal Module
Hard
Contractor access revocation at cycle end with generic message.
Contractors may retain access incorrectly.
Client Portal Module
Hard
Client access continuity after cancellation (Free plan includes Client Portal).
Clients may lose access incorrectly.
9. Subsciption Impact
Subscription Impact
Functional Requirement Document
BA & Ideation: Deval Chauhan
Reviewed By: KG (Project Manager)
Updated By: Sehal Maheshwari(BA)
Updated Date: 27 April 2026
Status:
Version 2.0
FRD 9A — Subscription Impact Framework
Module: Subscription Impact Framework (Cross-Cutting Consistency Layer) Version: 1.0 Date: April 22, 2026 Status: Draft for review
1. Module Overview
Module Name: Subscription Impact Framework
Purpose: This module establishes the cross-cutting consistency layer for how every other module in Pixally CRM behaves when subscription state changes. It defines the universal vocabulary of plan-gating: the seven visual lock patterns (menu lock, card lock, entity-row lock, tab lock, action button lock, section hide, full-page locked state), the three behavior tiers (Tier 1 full lock, Tier 2 graceful degradation, Tier 3 section hide), the cascading lock rule that propagates from a locked brand through every dependent project, event, invoice, and portal access, the universal downgrade rule that turns previously-accessible higher-plan features into locked-but-visible states, the owner-facing yellow upgrade popup and its non-owner "contact your agency owner" variant, the full-page locked state that takes over when locked menu items are clicked or locked URLs are typed, the deferred plan-change visibility model where upgrades take effect on next page load and downgrades wait for cycle end, the search behavior that surfaces locked entities when their data exists and hides sections entirely when it does not, and the state-override interactions with grace, suspension, and cancellation states. This framework is consumed by every product module described in FRD 9B and prevents inconsistent or duplicated lock behaviors across the application.
Business Goals: The framework gives users one consistent mental model for subscription gating across every page of Pixally CRM, drives upsell conversion by surfacing locked features in-product rather than hiding them, preserves user data through plan changes so downgraded users never lose visibility into what they had, gives non-owner team members the same visual experience as owners while routing them to the owner for upgrade decisions, and reduces engineering complexity by centralizing all gating decisions into reusable patterns rather than per-module custom implementations.
2. User Roles & Permissions
Role
Sees Lock Visuals
Yellow Upgrade Button on Cards/Rows
Click Locked Element Triggers
Can Resolve Lock
Agency Owner
Yes
Yes — visible
Owner upgrade popup (yellow Upgrade CTA)
Yes — clicks Upgrade, routes to Manage Subscription per FRD 3
Agency Admin
Yes (same lock visuals)
No — button hidden
Non-owner popup (Close only, no Upgrade button)
No — must contact Owner
Project Manager
Yes (same lock visuals)
No — button hidden
Non-owner popup
No
Supervising Editor
Yes (same lock visuals)
No — button hidden
Non-owner popup
No
Editor
Yes (same lock visuals)
No — button hidden
Non-owner popup
No
Paid-Extras Seat User
Same as their assigned role above
No — button hidden
Non-owner popup
No
Contractor (Contractor Portal)
No — never sees locks or upgrade popups
n/a
n/a — sees "access revoked" message when their content is plan-locked
n/a
Client (Client Portal)
No — never sees locks or upgrade popups
n/a
n/a — sees "please contact your agency" when their content is plan-locked
n/a
Pixally Super Admin (Gawd Portal)
Sees agency's lock state in read-only views
n/a
n/a — does not act on locks from agency-side
Manages plans from Gawd Portal, not the agency app
3. User Flow
3.1 Owner Clicks a Locked Menu Item
3.1.1 The Agency Owner is on a Free, Basic, or Essentials plan and the left navigation displays a menu item with a lock icon next to its label, for example "Post Production" on a Basic plan.
3.1.2 The owner clicks the locked menu item.
3.1.3 The browser navigates to the destination route (for example, /post-production) and the page loads.
3.1.4 Instead of rendering the feature's normal page content, the page renders the full-page locked state with a centered upgrade card, the Pixally upgrade icon, the heading "Upgrade your plan", the body text "Unlock more features and higher limits by upgrading to a higher plan.", and a single yellow "Upgrade" call-to-action.
3.1.5 The owner clicks "Upgrade" and the system routes to the Manage Subscription page per FRD 3.
3.2 Owner Clicks a Locked Card on a Grid-of-Cards Page
3.2.1 The Agency Owner is on a Basic plan and visits the Reports page; the page renders ten report cards, three unlocked and seven locked.
3.2.2 The owner clicks one of the locked cards (for example, "Financial Forecast"); the entire card is a click target including its yellow "Upgrade" button.
3.2.3 The system opens the upgrade popup as a modal overlay with the same upgrade icon, heading, body text, and yellow "Upgrade" call-to-action plus a "Close" secondary button.
3.2.4 The owner clicks "Upgrade" and is routed to Manage Subscription per FRD 3, or clicks "Close" to dismiss the popup and remain on the Reports page.
3.3 Owner Clicks a Locked Entity Row in a List
3.3.1 The Agency Owner is on a Free plan and the Project Listing page shows accessible projects above a divider labeled "Locked · Upgrade to unlock" followed by inaccessible projects.
3.3.2 The owner clicks anywhere on a locked project row (the row title, the lock icon, or the row's "Upgrade" button).
3.3.3 The system opens the upgrade popup as a modal overlay.
3.3.4 The owner clicks "Upgrade" or "Close" as in the card flow.
3.4 Owner Clicks a Locked Tab Inside a Page
3.4.1 The Agency Owner is on a Basic plan and inside a Project Details page; the tab strip at the top includes a "Post Production" tab with a small lock icon.
3.4.2 The owner clicks the locked tab.
3.4.3 The tab content area updates to render the full-page locked state (the same upgrade card centered in the tab content area, with the yellow "Upgrade" button); the rest of the page (header, sidebar, other tab strip) remains intact.
3.4.4 The owner clicks "Upgrade" and is routed to Manage Subscription per FRD 3.
3.5 Owner Clicks a Locked Action Button
3.5.1 The Agency Owner is on a Free plan and the right sidebar of a Project Details page displays an "Upload Timeline" or "Deliverables" action button with a small lock icon overlay.
3.5.2 The owner clicks the locked action button.
3.5.3 The system opens the upgrade popup as a modal overlay.
3.5.4 The owner clicks "Upgrade" or "Close".
3.6 Owner Hits an Entity Creation Limit
3.6.1 The Agency Owner is on a Free plan with the Free-plan limit of five projects already created.
3.6.2 The owner clicks the "+ New Project" call-to-action on the Project Listing page.
3.6.3 The system detects that the owner has reached the plan's project limit and opens the upgrade popup instead of the New Project form.
3.6.4 The owner clicks "Upgrade" and is routed to Manage Subscription per FRD 3, or clicks "Close" to remain on the Project Listing.
3.7 Owner Types a Direct URL to a Locked Page
3.7.1 The Agency Owner is on a Basic plan and types or pastes a URL for a feature that is not included in their plan, for example /contractors directly into the browser address bar.
3.7.2 The browser navigates to the URL and the page loads.
3.7.3 The system renders the full-page locked state in the page area, identically to the menu-click flow described in Section 3.1.
3.7.4 The owner clicks "Upgrade" to route to Manage Subscription, or navigates away via the left navigation, browser back, or other means.
3.8 Non-Owner Role Clicks Any Locked Element
3.8.1 An Agency Admin, Project Manager, Supervising Editor, Editor, or paid-extras seat user logged in to a Pixally agency account on Free, Basic, or Essentials clicks any locked menu item, card, row, tab, action button, or hits any creation limit.
3.8.2 The system detects the non-Owner role and opens the non-owner upgrade popup instead of the standard owner popup; the visual template is identical (icon, heading, position) but the body text reads "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and the only call-to-action is a single "Close" button (no yellow "Upgrade" button).
3.8.3 The non-owner clicks "Close" or the × icon to dismiss the popup; no other action is offered because non-owners cannot upgrade subscriptions.
3.9 Owner Searches for an Entity Across Plans
3.9.1 The Agency Owner opens the global search modal and types a query.
3.9.2 The system returns results grouped into sections (Projects, Clients and Companies, Contractors, Files, etc.).
3.9.3 For each section, the system includes the section header and result rows only if matching data exists for the agency; sections with zero matching entities are omitted entirely.
3.9.4 Within each section, individual results are displayed with the standard lock icon and the row at reduced opacity if the result is plan-locked (for example, a contractor result on a downgraded Basic-plan account).
3.9.5 The owner clicks an unlocked result and navigates to the entity's detail page; the owner clicks a locked result and the standard upgrade popup opens.
3.10 Plan Change Takes Effect
3.10.1 The Agency Owner upgrades their plan via the Manage Subscription page per FRD 3 and the plan change is committed in Stripe and Pixally backend.
3.10.2 The current page the owner is on does not update locks in real time; the existing rendered DOM continues to show the old lock state until the next navigation or page refresh.
3.10.3 On the next page navigation or browser refresh, the system fetches the current plan state and re-evaluates all lock patterns; locks that are no longer applicable disappear, and any newly-accessible features render normally.
3.10.4 For downgrade actions, no immediate UI change occurs; the downgrade is scheduled for cycle end per FRD 3, and locks for the lower plan only begin appearing after the cycle-end execution job runs and the new plan state is in effect.
3.11 Cascading Lock from a Locked Brand
3.11.1 An agency was on Essentials with two brands and downgraded to Basic which allows only one brand; the system kept Brand A and locked Brand B per FRD 3 downgrade-to-Basic logic.
3.11.2 The owner navigates to the Project Listing page; the system applies the cascade lock rule and locks every project that belongs to Brand B, regardless of project age or activity.
3.11.3 The owner navigates to the Finances page; invoices, expenses, and other financial entities tied to projects in Brand B are also locked.
3.11.4 Clients and contractors associated with projects in Brand B see their respective portal access scoped down per Sections 3.13 and 3.14.
3.12 Cascading Lock from a Locked Project
3.12.1 An agency on Free has more than five projects; the system identifies the five most recently created projects within the agency's accessible brand and marks them accessible, with all remaining projects locked.
3.12.2 The owner navigates to a locked project's URL or entity row and is shown the standard upgrade popup or full-page locked state.
3.12.3 All events, invoices, files, notes, contractor assignments, and other child entities of a locked project are also locked and inherit the same lock behaviors.
3.13 Contractor Portal Access After Cascade
3.13.1 A contractor is associated with an agency that downgraded from Studio to Essentials; the agency had thirty contractors, and Essentials allows only twenty active contractor seats.
3.13.2 The system identifies the twenty contractors with the longest agency relationship (oldest contractor records by invitation date) per FRD 3 logic; these contractors retain their normal Contractor Portal access on next login.
3.13.3 Contractors beyond the top twenty cannot log in to the Contractor Portal; on attempted login, they see the message "Your access is revoked. Please contact the agency." with no other call-to-action, consistent with the FRD 8 cancellation contractor messaging.
3.13.4 For contractors who retained portal access but whose assigned events or projects belong to a locked brand or locked project, the relevant events and projects are individually disabled inside the Contractor Portal; the contractor sees these in their list but cannot access them, with a similar "this event is unavailable; please contact the agency" treatment.
3.14 Client Portal Access After Cascade
3.14.1 A client is associated with an agency that downgraded; the client's project belongs to a brand that is now locked.
3.14.2 The client's account technically exists but the project they were granted access to is locked from the agency's side; on attempted Client Portal login or access to the project, the client sees the message "Please contact your agency."
3.14.3 If the client's brand is still accessible (Brand A retained), the client retains normal Client Portal functionality consistent with the always-included Client Portal in the Free plan per FRD 1.
3.15 Trial Day 15 Auto-Downgrade Triggers Locks
3.15.1 An agency completed its 14-day trial on Studio per FRD 2 and the system auto-downgrades the agency to Free on Day 15.
3.15.2 The downgrade-to-Free logic per FRD 3 Section 4.22 executes: the Owner is retained, all other team members are auto-disabled, the oldest brand is kept and other brands archived, projects beyond the Free-plan five-project limit are auto-archived oldest-first, and all contractor assignments are disabled.
3.15.3 On the owner's next login or page navigation after Day 15, all Free-plan locks (Post Production, Contractor sub-menu, Integrations parent, Reports parent, Profit & Loss, Taxes, Contractor Invoices, Expenses, QuickBooks Finances) become visible and active.
3.15.4 The owner receives an email-only notification on Day 15 informing them of the trial ending and the transition to Free, with no in-app banner per the locked decision in Q26 of the Round 9 consultation.
3.16 Failed Payment Grace and Suspension State Overrides
3.16.1 An agency with a failed payment is in the 28-day grace period per FRD 7; the agency retains full access to the plan they were on (for example, full Essentials access).
3.16.2 The framework's lock patterns evaluate the agency as still on the paid plan and apply locks accordingly; no additional locks are introduced by the grace state itself.
3.16.3 At Day 29 the agency transitions to Suspended state per FRD 7; the entire application is locked except for the Subscription page and a "Account is Suspended" full-page screen per FRD 7 Sections 4.12 and 4.13; the per-module lock framework defined here is not applied because the entire app is gated by the suspension state.
3.16.4 On reactivation, the agency returns to its plan and the framework resumes evaluating locks based on the active plan.
3.17 Cancellation Pending and Post-Cycle-End
3.17.1 An agency cancelled its subscription per FRD 8 with the cancellation scheduled for cycle end; during the cancel-to-cycle-end window, the agency retains full access to its current plan.
3.17.2 The framework treats the agency as still on the paid plan during this window; locks reflect the current plan, not the future Free state.
3.17.3 At cycle end, the agency transitions to Free per FRD 3 downgrade-to-Free logic; the framework re-evaluates and applies Free-plan locks on next page navigation.
3.17.4 If the cancellation occurred during grace or suspension per FRD 8 Sections 4.23 and 4.24, the agency transitions to Free immediately on cancel and locks apply on next page load.
4. Functional Logic
4.1 The Three Behavior Tiers
- The framework defines three tiers for how a plan-gated capability impacts product behavior, applied consistently across every module documented in FRD 9B.
- Tier 1 — Full Lock: the entire feature requires the gated capability and cannot function without it; the feature's menu item, page, or section is shown with a lock icon and the standard upgrade interaction is triggered on click; examples include Post Production, Contractor Management, the QuickBooks integration, the Expenses page, the Taxes page, and any Essentials-or-Studio-only report tile.
- Tier 2 — Graceful Degradation: the feature works on lower plans without the gated capability and a subset of internal options or sub-capabilities are gated; the feature is open and usable, with locked sub-capabilities individually marked with the standard lock visuals; examples include Meetings (where in-person and phone meetings work on all plans while Google Meet and Calendly integrations are gated), Notifications (email and in-app on all plans, SMS on Studio only), and Invoices (manual invoices on all plans, QuickBooks sync on Essentials and Studio only).
- Tier 3 — Section Hide: a section, column, or activity feed entry depends on entities that do not exist on the current plan and is not rendered at all rather than rendered with a lock; examples include the "Payments to contractors" section inside Project Details Finances on Free and Basic, contractor activity entries in the Activity feed on Free and Basic, and the Contractor and Raw Media sub-tabs inside Event Details on Free and Basic.
4.2 The Seven Visual Lock Patterns
- The framework defines seven reusable visual patterns for representing locks; every gated element in Pixally maps to exactly one of these patterns.
- Menu Lock: applied to left-navigation items; renders a small padlock icon (12 to 14 pixels, 50 to 60 percent opacity) right-aligned next to the menu item label; the menu item itself is at reduced opacity to signal the unavailable state.
- Card Lock: applied to grid-of-cards pages such as Reports and Integrations; renders a small lock badge in the top-right corner of the card (approximately 20 by 20 pixels with subtle background) and replaces the card's primary call-to-action button with a yellow "Upgrade" button; the entire card surface is clickable as a single hit target.
- Entity-Row Lock: applied to list and table views such as Project Listing, Invoice list, Contractor list; renders the locked rows below an "Locked · Upgrade to unlock" divider, with each locked row at reduced opacity, a small lock icon adjacent to the entity name, and a yellow "Upgrade" button replacing the row's normal action button.
- Tab Lock: applied to tab and sub-tab strips inside pages such as Project Details and Event Details; renders the locked tab with the same small lock icon next to its label; clicking the locked tab activates it and renders the full-page locked state inside the tab's content area.
- Action Button Lock: applied to call-to-action buttons that gate specific actions such as "Upload Timeline" or "Assign Contractors"; renders the button with a small lock icon overlay and reduces button opacity; clicking opens the upgrade popup.
- Section Hide: applied to entire sections, columns, or activity entries that fall under Tier 3; the element is not rendered in the DOM at all and leaves no visual trace; users on lower plans do not know the section exists.
- Full-Page Locked State: applied to entire route-level pages and to tab content areas after a tab lock click; renders a centered upgrade card with the upgrade icon, the heading "Upgrade your plan", the body text, and a single yellow "Upgrade" call-to-action; the surrounding chrome (left navigation, top header) remains intact for the full-page variant; for the tab variant, only the tab content area renders the locked state.
4.3 The Cascading Lock Rule
- The framework enforces a single cascading rule: if an entity is locked, every dependent entity, feature, action, and portal access that derives from it is also locked.
- The cascade chain begins at the brand level: a locked brand cascades to all projects in that brand, then to all events within those projects, then to all invoices, expenses, contractor assignments, files, notes, deliverables, and historical activity entries tied to those projects, and finally to client portal access for the relevant projects and contractor portal scoping for assignments in those projects.
- The cascade is enforced at every point of access: list pages filter and sort accessible-first then locked entities, detail pages render in locked state, related-entity references in other modules show locks, and search results display locked rows with the standard lock visuals.
- The cascade is one-directional: a locked project does not lock its parent brand; a locked event does not lock its parent project; locks always propagate downward from parent to child.
- The cascade is computed at request time based on current plan state, not pre-computed and stored; this allows the cascade to resolve correctly the moment a plan changes (on next page navigation per Section 4.16).
4.4 The Universal Downgrade Rule
- When a plan downgrade takes effect (immediately for upgrade reversals, at cycle end for scheduled downgrades, or immediately for grace and suspension cancellations per FRD 8), every feature, page, sub-page, action, and entity that was accessible on the higher plan and is not accessible on the new lower plan is locked rather than deleted.
- Locked entities and features remain visible in the user interface in their respective list, page, or section locations with the appropriate visual lock pattern (menu lock, card lock, entity-row lock, tab lock, action button lock, or full-page locked state).
- Click interactions on locked elements open the standard upgrade popup or full-page locked state per Section 4.5.
- Underlying data is preserved indefinitely or until the agency reaches the data-retention boundary defined in FRD 8; downgrades do not delete any data.
- Re-upgrading the agency to the original or higher plan immediately restores access to all locked entities and features without manual restoration steps for most entity types (brands, projects, contractors, files, notes, integrations, etc.); access changes take effect on the user's next page navigation per Section 4.16.
- The exception is team members: because team members consume seats and seat counts have direct billing implications, disabled team members are not auto-restored on plan re-upgrade. The Owner manually re-activates disabled members from the Subscription page entry points ("Add Seat" or "Add Team Member") per FRD 5 Section 4.20. Disabled members tied to a currently-locked brand are not eligible for re-activation until that brand becomes accessible (via further upgrade) because re-activating them without their brand assignment would violate the data-integrity preservation principle of this rule.
4.5 Owner Upgrade Popup and Full-Page Locked State
- The owner upgrade popup is a modal overlay rendered on top of the current page with a dim backdrop blocking clicks outside the popup; it is a generic, non-feature-specific component that is identical for every type of lock interaction.
- The popup contains a centered upgrade icon (a stacked upward chevron), the heading "Upgrade your plan", the body text "Unlock more features and higher limits by upgrading to a higher plan.", a primary yellow "Upgrade" call-to-action that routes to Manage Subscription per FRD 3, a secondary white "Close" button that dismisses the popup, and an "×" close icon in the top-right corner.
- The popup is dismissible via the "Close" button, the "×" icon, clicking on the dim backdrop outside the popup, or pressing the Escape key.
- The full-page locked state is functionally the same content rendered as a centered card on the page, without a modal overlay or backdrop and without the "Close" button (because there is no modal to dismiss); only the yellow "Upgrade" button is present.
- The full-page locked state is triggered by two interactions: clicking a locked menu item, and direct URL access to a locked page; in both cases the browser navigates to the destination route and the route renders the locked state instead of the feature's normal content.
4.6 Non-Owner Upgrade Popup
- Non-owner roles (Agency Admin, Project Manager, Supervising Editor, Editor, Paid-Extras Seat User) see the same lock visuals as the Agency Owner everywhere in the application; the difference is only in the popup that opens on click and in the absence of an "Upgrade" call-to-action button on locked cards and entity rows.
- The non-owner popup uses the same visual template as the owner popup (icon, heading, position, dimensions, dismiss controls) but with two changes: the body text reads "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and the only call-to-action is a single "Close" button (the yellow "Upgrade" button is omitted entirely).
- For locked cards (Reports, Integrations) and locked entity rows (Project Listing, Invoice list, Contractor list, etc.), the yellow "Upgrade" button is hidden entirely from the non-owner view; non-owners see only the lock icon and the underlying entity content. Clicking the locked card or row anywhere on its surface opens the non-owner popup directly.
- The omission of the "Upgrade" button is intentional and consistent across all lock patterns: non-owners cannot perform the upgrade action, and offering them a yellow call-to-action that routes to a "you cannot upgrade" page would be a false-promise interaction; the single "Close" reflects their actual options.
- Non-owners see the same full-page locked state as owners on locked menu and direct URL flows; the locked state's "Upgrade" button is replaced with a non-clickable explanation message for non-owner role context, or rendered with the body text reflecting the contact-owner instruction.
4.7 Visual Specifications for Lock Icons and Colors
- The lock icon used across all patterns is a small filled padlock at 12 to 14 pixels for inline locations (menu items, entity rows, table rows) and 16 to 20 pixels for prominent locations (card badges, tab labels, action buttons).
- Lock icon color matches the surrounding text color at 50 to 60 percent opacity for inline placement, or uses a neutral muted gray when placed inside a colored badge background.
- Locked elements (menu items, rows, tabs, action buttons) render at 50 to 60 percent opacity overall; their child content (icons, text, secondary metadata) inherit this opacity unless explicitly overridden.
- Full-opacity remains for cards in the card-lock pattern: the card stays at full opacity to remain readable and aspirational, with only the lock badge and yellow "Upgrade" button signaling the locked state.
- The yellow "Upgrade" button uses the Pixally brand yellow consistent with primary call-to-actions across FRDs 1 through 8 (Subscribe, Confirm and Pay, Pay Invoice, Reactivate Subscription, etc.); the button has a dark text color for sufficient contrast and uses standard button padding and border-radius from the design system.
4.8 Trigger Behavior Summary by Pattern
- Clicking a Menu Lock triggers the full-page locked state (browser navigates to the page; page renders the centered upgrade card).
- Clicking a Card Lock triggers the modal upgrade popup.
- Clicking an Entity-Row Lock triggers the modal upgrade popup.
- Clicking a Tab Lock triggers the full-page locked state inside the tab content area only (the tab strip and surrounding page chrome remain intact).
- Clicking an Action Button Lock triggers the modal upgrade popup.
- Section Hide elements are not rendered and have no click target.
- Direct URL access to a locked route triggers the full-page locked state.
- An entity creation action that would exceed a plan limit (for example, "+ New Project" at the five-project Free limit) triggers the modal upgrade popup before opening the creation form.
4.9 Search Behavior with Locks
- The global search modal returns results grouped into sections by entity type (Projects, Clients and Companies, Contractors, Files, and any future entity sections).
- A section is rendered if and only if the agency has at least one entity of that type in its data; sections with zero entities are omitted entirely from search results, regardless of the agency's current plan.
- Within a rendered section, individual entity results are evaluated against the cascading lock rule and the universal downgrade rule; locked entities appear with the small lock icon and reduced opacity, while accessible entities appear normally.
- Clicking an accessible entity navigates to its detail page; clicking a locked entity opens the standard upgrade popup.
- Search results do not surface entities that have been hard-deleted per FRD 8 data retention policy.
4.10 Automation with Locked Nodes
- Workflow automations created on a higher plan that contain trigger or action nodes gated by capabilities not available on the current plan are paused entirely on the cycle-end transition that follows a downgrade.
- A pause banner is displayed on the Automations module landing page indicating that one or more automations contain locked steps and require manual review; the banner lists the affected automations.
- Locked nodes within an individual automation are rendered with the standard lock visual; clicking opens the upgrade popup for the owner or the non-owner variant for non-owners.
- The owner can edit the automation to remove or replace locked nodes and unpause the automation manually; the system does not auto-replace locked nodes with fallbacks because doing so could silently change business behavior (for example, sending an email instead of an SMS reminder when the user expected an SMS).
- New automations created on a lower plan show all available nodes in the builder palette with the locked nodes marked using the standard lock visual; selecting a locked node opens the upgrade popup.
4.11 Plan Change Visibility and Timing
- Plan changes do not propagate locks in real time on the user's currently rendered page; the existing DOM continues to display the lock state that was active when the page initially loaded.
- On the next page navigation (clicking a menu item, following a link, or refreshing the browser), the system fetches the current plan state and re-evaluates all lock patterns; locks that no longer apply disappear and newly-accessible features render normally.
- This deferred-update model intentionally avoids in-page lock toggling which could produce confusing intermediate states; the user always sees a consistent snapshot of the plan state for the duration of any single page view.
- For upgrades, this means the owner experiences the new plan's expanded access starting from their next navigation; for downgrades scheduled at cycle end, this means the new lower-plan locks become visible only after the cycle-end backend job runs and the owner navigates to a page after that point.
- The owner is not required to manually refresh; normal navigation in the application picks up the new plan state automatically.
4.12 Multi-Agency Lock Scoping
- Each agency has its own independent plan state and its own independent lock state; an owner who owns multiple agencies sees different locks in each agency based on each agency's individual plan.
- Switching between agencies in the agency-switcher (per FRD 1) reloads the agency context including plan state, and locks update on the next page render in the new agency context.
- A team member who is part of multiple agencies via separate invitations sees locks scoped to the agency they are currently active in.
4.13 Grace Period State Override
- During the failed-payment grace period defined in FRD 7 (default 28 days, configurable globally via the Gawd Portal "Suspend account after" setting), the agency retains full access to its current paid plan; the framework treats the agency as if the plan were active and applies locks accordingly.
- No additional locks are introduced by the grace state itself; the only grace-specific UI is the amber banner on the Dashboard and Subscription pages described in FRD 7 Section 4.4.
- If the agency's failed payment is resolved during grace, the framework continues evaluating locks against the same plan with no transition; if the agency proceeds to suspension at Day 29, the suspension override per Section 4.14 takes effect.
4.14 Suspension State Override
- During the Suspended state defined in FRD 7, the entire Pixally application is gated to the Subscription page only for the Owner and to the "Account is Suspended" full-page screen for non-owners; the per-module lock framework documented here is not applied because the global suspension override blocks all module access.
- * The suspension state has a finite duration determined by the Gawd Portal "Delete account after" configuration (default 1 year); at the end of this duration, the agency is hard-deleted unless the Owner reactivates by paying the comeback payment per FRD 7 Section 4.16.
- * During the entire suspension-to-deletion window, the framework's behavior is unchanged from standard suspension; the agency can reactivate at any point and return to Active state.
- * On reactivation per FRD 7 Section 4.16, the suspension override lifts and the framework resumes evaluating locks based on the active plan; the scheduled deletion is cancelled.
- * After hard deletion, the agency record no longer exists; the framework has no entity to evaluate; the deleted agency's primary email becomes available for fresh re-signup with no carry-over of agency-specific state per FRD 1 and FRD 2\.
4.15 Cancellation State Behavior
- During the cancel-to-cycle-end window for normal cancellation per FRD 8, the agency retains full access to its current plan; the framework treats the agency as still on the paid plan and applies locks consistent with that plan.
- For grace-period and suspension cancellations per FRD 8 Sections 4.23 and 4.24 which transition to Free immediately, the framework re-evaluates locks for the Free plan on the user's next page navigation; the immediate transition activates Free-plan locks at that point.
- After cycle-end execution for normal cancellation, the agency is on the Free plan and Free-plan locks apply on next navigation.
4.16 Trial State and Trial-End Transition
- During the 14-day Studio trial defined in FRD 2, the agency has full Studio-level access and no locks apply; all features that are gated on lower plans are accessible and usable during the trial.
- On Day 15 the auto-downgrade to Free executes per FRD 2 and FRD 3 downgrade-to-Free logic; the framework re-evaluates locks for the Free plan on the owner's next page navigation.
- The owner receives an email-only notification on Day 15 informing them of the trial completion and the transition to Free; no in-app banner is shown to introduce the locks per the Q26 locked decision.
4.17 Cross-FRD Reference Map
- The framework does not duplicate logic that already exists in dependent FRDs; it references them and applies its visual patterns over their behavior.
- Plan entitlements (which features are on which plan) are sourced from FRD 1 and the Plan Usage Matrix per FRD 6.
- Trial Studio access and Day 15 transition are sourced from FRD 2.
- Downgrade-to-Free, downgrade-to-Basic, and downgrade-to-Essentials behaviors are sourced from FRD 3 Section 4.22 and applied uniformly across all modules through this framework's cascading lock rule.
- Cycle-switch interactions are sourced from FRD 4.
- Paid-extras seat handling is sourced from FRD 5.
- Subscription page hosting of the upgrade popup destination ("Upgrade" button routes to Manage Subscription per FRD 3 from the Subscription page in FRD 6) is sourced from FRD 6.
- Grace period banner, suspension full-page screen, and reactivation logic are sourced from FRD 7.
- Cancellation flow, post-cancellation Free-plan transition, retention window, and contractor "access revoked" messaging are sourced from FRD 8.
4.18 Sort and Filter Behavior with Locked Rows
- On any list or table view that contains both accessible and locked entity rows (Project Listing, Invoice list, Contractor list, etc.), the framework preserves the accessible-first then locked-second visual ordering at all times.
- Sort actions chosen by the user (e.g., sort by date, name, status) apply within each group independently: the accessible rows above the divider are sorted by the chosen criterion, and the locked rows below the divider are sorted by the same criterion separately. The two groups never interleave regardless of sort.
- Filter actions chosen by the user apply to both groups independently using the same filter criterion; if a filter results in zero accessible rows, the accessible-group section above the divider is empty and only the divider plus locked rows are shown; if a filter results in zero locked rows, the divider and locked-group section are hidden entirely.
- The framework does not provide a dedicated "show only locked" or "filter by locked status" filter option, because surfacing locked items is already a primary visual treatment in the list.
4.19 Pagination with Mixed Accessible and Locked Rows
- A list view with both accessible and locked rows uses a single combined pagination control, not separate paginations per group.
- Page one is filled with accessible rows first up to the page-size limit; if accessible rows do not fill the page, the divider is shown and locked rows are displayed below to complete the page.
- Subsequent pages continue with locked rows until all rows in both groups are paginated through.
- The pagination indicator (for example "1-10 of 95") reflects the combined count of accessible and locked rows.
4.20 Empty State Behavior
- When a list, page, or section contains zero data and the feature itself is accessible on the current plan, the system displays the standard empty-state component for that module (for example, "No projects yet — create your first project").
- When a list, page, or section contains zero data and the feature is plan-locked, the system displays the full-page locked state per Section 4.5 instead of an empty-state, because the lock takes precedence and there is nothing to show.
- The combination of "no data + plan-locked" is treated identically to a populated locked feature: full-page locked state with the upgrade card.
4.21 Plan Downgrade During Grace Period
- An agency in the 28-day failed-payment grace period defined in FRD 7 may initiate a plan downgrade as an alternative to paying the failed invoice or cancelling the subscription.
- The downgrade is allowed and follows the standard FRD 3 downgrade flow with one important distinction: because the agency is in grace following a failed payment, the downgrade takes effect at the end of the current failed cycle (the cycle whose payment failed), with the failed invoice written off in the same write-off treatment used by FRD 8 grace-period cancellation per Section 4.23 of FRD 8.
- After the downgrade takes effect, the agency is on the new lower plan and the framework's lock patterns evaluate against the lower plan on the user's next page navigation.
- The owner may also choose to pay the failed invoice instead, in which case grace is resolved and no downgrade occurs; or to cancel the subscription per FRD 8.
4.22 Floating Action Buttons and Quick Actions
- Floating action buttons and quick-action shortcuts (FAB and similar UI controls) are themselves rendered normally regardless of plan; they are not hidden or globally locked because their menu may include a mix of accessible and gated actions.
- Inside the FAB or quick-action menu, individual actions that are gated by plan are rendered with the standard lock visuals defined in Section 4.2 (small lock icon, reduced opacity).
- Selecting a locked action from the FAB or quick-action menu opens the standard upgrade popup per Section 4.5 (modal overlay) and does not initiate the gated action.
4.23 Per-User Deferred Update on Plan Change
- The deferred-update model defined in Section 4.11 applies independently to every logged-in user of the affected agency, not only the user who initiated the plan change.
- When the Owner upgrades or downgrades, each Admin, Project Manager, Editor, paid-extras seat user, and other team member who is currently logged in continues to see the previous plan's lock state on their currently-rendered page.
- Each user's UI updates to the new plan state on their own next page navigation or browser refresh; the framework does not push real-time updates across user sessions.
5. Field Details & Validations
Field / Component
Type
Specification
Lock Icon (inline)
SVG icon
Filled padlock, 12 to 14 pixels, current text color at 50-60% opacity, right-aligned in menu items and entity rows.
Lock Badge (card corner)
Component
Square ~20×20 pixels, neutral background, padlock icon centered, top-right corner of card.
Lock Icon (tab)
SVG icon
11 to 12 pixels, inline with tab label text, color matches secondary text.
Lock Icon (action button)
SVG icon overlay
12 pixels, top-right of button, indicates plan-gated action.
Locked Element Opacity
CSS property
50 to 60% on locked menu items, locked entity rows, locked tabs, locked action buttons; cards remain at 100% with only the badge and yellow button as locked indicators.
Upgrade Popup (Owner)
Modal
400 pixels wide, centered, dim backdrop, dismissible via Close, ×, backdrop click, or Escape key. Contains icon, heading, body, "Upgrade" (yellow) and "Close" buttons.
Upgrade Popup (Non-Owner)
Modal
Same template as owner popup with body text "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and only "Close" button (no Upgrade).
Full-Page Locked State
Page section
Centered upgrade card on the page or in tab content area; no modal overlay; no Close button; only yellow "Upgrade" call-to-action.
Upgrade Heading
Static text
"Upgrade your plan" — universal across all locks.
Upgrade Body (Owner)
Static text
"Unlock more features and higher limits by upgrading to a higher plan."
Upgrade Body (Non-Owner)
Static text
"This feature requires a plan upgrade. Please reach out to your agency owner to enable it."
Upgrade CTA (yellow button)
Button
Pixally brand yellow background, dark text, label "Upgrade" — primary call-to-action for owners only.
Close CTA
Button
Outline button on white, label "Close" — present in modal popups, absent in full-page locked state.
"Locked · Upgrade to unlock" Divider
List separator
Section divider in entity-row lock pattern, separating accessible rows above from locked rows below.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Owner clicks Upgrade in popup or full-page state
No standalone success message; routes to Manage Subscription page per FRD 3.
Owner clicks yellow "Upgrade" button.
Browser navigates to Manage Subscription where the upgrade flow continues.
SM-2
Owner upgrades plan, navigates to a previously-locked page
Page renders normally; no special success message.
After plan-change processing, on next page navigation.
Locks are removed and the feature is now usable.
SM-3
Owner cancels Upgrade flow and returns to the locked surface
Standard navigation; no message.
Owner clicks Close, ×, or backdrop.
Returns to the surface where the locked element was clicked.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Non-owner clicks an upgrade-related call-to-action by URL hack or race condition
"This feature requires a plan upgrade. Please reach out to your agency owner to enable it."
Non-owner attempts an Owner-only billing action through any means.
Non-owner contacts Owner; no further action available in-app.
EM-2
Plan state cannot be loaded due to backend error
The framework defaults to the most-restrictive plan (Free) until a successful response is obtained, locking features that may be available on the agency's actual plan.
Backend or webhook lag prevents plan-state retrieval.
User refreshes; if the error persists, contact Pixally support.
EM-3
Cascade computation fails due to missing parent entity reference
The framework defaults to locking the dependent entity for safety until the parent reference is resolved.
Data integrity issue with brand-project or project-event linkage.
Owner contacts Pixally support; affected entities remain locked until resolved.
EM-4
Entity-row lock divider rendered with zero accessible items
The page renders only the "Locked · Upgrade to unlock" divider followed by the locked rows, with no accessible-rows section above.
Agency has all entities of a type locked due to plan downgrade or cascade.
Owner clicks any locked row to see the upgrade popup, or clicks "+ New" call-to-action which itself triggers a creation-limit popup.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Owner is on Basic and clicks the locked Post Production menu item.
Browser navigates to /post-production. Page renders the full-page locked state with centered upgrade card and yellow "Upgrade" button. Click routes to Manage Subscription per FRD 3.
EC-2
Owner is on Free and types /contractors directly into the address bar.
Page navigates and renders the full-page locked state identically to the menu-click flow.
EC-3
Project Manager (non-owner) clicks the same locked menu item as EC-1.
Browser navigates to /post-production. Page renders the full-page locked state with the non-owner body text "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and no Upgrade button (or a non-clickable owner-only message).
EC-4
Owner on Basic clicks a locked Reports card (Financial Forecast).
Card-lock pattern triggers modal upgrade popup. Owner clicks Upgrade, routes to Manage Subscription.
EC-5
Owner on Free clicks the "Post Production" tab inside Project Details.
Tab activates; tab content area renders the full-page locked state inside it. Surrounding tab strip and right sidebar remain intact. Click Upgrade in the locked state routes to Manage Subscription.
EC-6
Owner on Free clicks "+ New Project" with five projects already created.
System detects creation-limit; modal upgrade popup opens before the New Project form. Owner can Upgrade or Close.
EC-7
Owner has Brand A (active) and Brand B (locked after downgrade). Owner navigates to Project Listing.
Projects from Brand A appear at the top (accessible per the cascade rule). Projects from Brand B appear below the "Locked · Upgrade to unlock" divider with row-lock visuals.
EC-8
Same Owner navigates to Finances → Billing on the same downgraded plan.
Invoices for Brand A projects display normally; invoices for Brand B projects display with row-lock visuals below the divider.
EC-9
Same Owner globally searches for a project name that exists in both brands.
Search returns Brand A's matching project unlocked and Brand B's matching project locked, both inside the Projects section.
EC-10
Contractor associated with a project in Brand B (locked) attempts to access that project in their portal.
The project is disabled in the contractor's portal; clicking it shows a "this event is unavailable; please contact the agency" message. The contractor's other accessible projects in Brand A still function normally.
EC-11
Client whose only project is in Brand B (locked) attempts Client Portal access.
Client sees the message "Please contact your agency." and cannot access the project.
EC-12
Owner upgrades from Basic to Studio mid-page-view of the Reports page.
The current page does not update; the Reports page continues to display 3 unlocked + 7 locked cards. On next navigation or refresh, all 10 cards render unlocked.
EC-13
Owner schedules a downgrade from Studio to Essentials at cycle end.
No locks appear during the cancel-to-cycle-end window; user retains full Studio access. After cycle end, on next page navigation, all Essentials-plan locks (contractor-count cap, SMS, etc.) take effect.
EC-14
Trial agency on Day 14 evening clicks Post Production.
Studio-level access is in effect; Post Production opens normally with no locks.
EC-15
Same agency on Day 15 morning after auto-downgrade clicks Post Production.
Free-plan locks now apply; the menu item shows a lock icon and clicking it triggers the full-page locked state.
EC-16
Agency in 28-day grace period clicks any locked feature.
No additional locks are introduced by grace; the framework evaluates locks against the agency's paid plan and the user accesses or sees locks identically to a non-grace state on the same plan.
EC-17
Same agency on Day 29 enters Suspension.
The framework's per-module lock evaluation is bypassed; the agency-wide suspension override per FRD 7 takes precedence and locks the entire app to the Subscription page (Owner) or "Account is Suspended" screen (non-owner).
EC-18
Owner on Basic creates a workflow automation that includes a "Send SMS" action node.
The "Send SMS" node appears in the builder palette with a lock icon. Clicking opens the upgrade popup. The owner cannot save an automation that contains an unconfigured locked node.
EC-19
Owner had an automation on Studio that includes an SMS node; agency downgrades to Essentials.
The automation is paused at the cycle-end transition. A banner appears on the Automations landing page listing the paused automation. Owner edits the automation, removes or replaces the SMS node, and unpauses manually.
EC-20
Owner globally searches "wedding"; agency has no contractor data and matching results in Projects, Clients, and Files only.
The Contractors section is omitted entirely from search results because no contractor data exists; remaining sections render with their respective lock states applied per the cascading rule.
EC-21
Owner downgrades to Free and the agency had ten contractors and five reports; owner navigates to Reports page.
Reports parent lock applies (Free plan has no Reports access); the page renders the full-page locked state. Contractors are scoped down separately per FRD 3 and are not visible in any module-listing because contractors are gated by Tier 1 lock on Free.
EC-22
Multi-agency owner switches from a Studio agency to a Free agency.
New agency context loads with Free-plan state. Locks appear for the Free agency and are independent of the previous Studio agency.
EC-23
Non-owner Project Manager accesses the same multi-agency context as EC-22.
Project Manager sees the same lock visuals as the Owner of that agency, but clicking any lock opens the non-owner popup.
EC-24
Backend webhook delays plan-state update after a successful upgrade.
The framework continues showing the old plan's locks on the next navigation until the updated state is fetched on a subsequent navigation. The user may need to refresh once if the lag exceeds the typical webhook latency.
EC-25
Owner refreshes the page during grace period.
Grace state is preserved; locks evaluate against the active paid plan; the amber banner per FRD 7 continues to display on Dashboard and Subscription.
EC-26
Owner on Free clicks an action button that is locked (e.g., "Upload Timeline" inside Project Details right sidebar).
Action button shows lock icon and reduced opacity. Click opens modal upgrade popup. Owner Upgrades or Closes.
EC-27
Owner has zero data of all entity types and opens global search.
Search modal renders with a "No results yet" empty state and no section headers; the lock framework does not apply because there is nothing to lock or hide.
EC-28
Owner on Free is on Project Listing page with 50 projects total.
Five most recently created projects within the accessible brand are displayed above the divider, sorted by user's chosen sort. The remaining 45 are displayed below the divider with row-lock visuals, sorted by the same criterion within their own group.
EC-29
Owner sorts the Project Listing by name ascending.
Sort applies within each group separately. The five accessible projects above the divider are sorted A-Z; the locked projects below the divider are sorted A-Z within their own group. The two groups never interleave.
EC-30
Owner filters Project Listing by a brand that is locked.
The accessible-group section above the divider is empty (no accessible projects match the locked brand). The divider plus locked-group section displays projects from that brand with row-lock visuals.
EC-31
Owner has 95 locked projects and a page size of 10 on Project Listing.
Page 1 shows 5 accessible projects + divider + 5 locked projects. Pages 2 through 10 show 10 locked projects each. Pagination indicator shows "1-10 of 100".
EC-32
Agency on Studio downgrades to Essentials with 30 contractors.
The 20 contractors with the longest agency relationship (oldest invitation date) are retained per FRD 3 logic. The remaining 10 contractors lose Contractor Portal access on next login and see "Your access is revoked. Please contact the agency."
EC-33
Project Manager (non-owner) navigates to Reports page on a Basic plan agency.
Page renders 3 unlocked cards + 7 locked cards. Locked cards show the lock icon and reduced opacity; the yellow "Upgrade" button is hidden entirely on the locked cards for non-owners. Clicking anywhere on a locked card opens the non-owner popup with "Close" only.
EC-34
Project Manager navigates to Project Listing on a Free plan agency with 50 projects.
Listing displays 5 accessible projects + divider + 45 locked projects. Locked rows show lock icons; yellow "Upgrade" button is hidden on locked rows. Clicking a locked row opens the non-owner popup.
EC-35
Owner is in 28-day failed-payment grace period and decides to downgrade plan instead of paying or cancelling.
Downgrade is allowed and follows the standard FRD 3 flow. The downgrade takes effect at the end of the current failed cycle (immediately, since the cycle's payment already failed) and the failed invoice is written off in the same treatment as FRD 8 grace-period cancellation. Locks for the new lower plan apply on next page navigation.
EC-36
Owner is on Project Listing with 5 accessible projects + 0 locked projects (Free plan with exactly 5 projects).
List shows the 5 accessible projects with no divider; the "Locked · Upgrade to unlock" divider is hidden because there are no locked rows to display.
EC-37
Owner upgrades from Basic to Studio while an Agency Admin is concurrently logged in on a different device.
The Owner's UI updates to the new plan state on their next page navigation. The Admin's UI does not update in real-time and continues to display Basic-plan locks until the Admin's own next page navigation, at which point the Admin's UI reflects the new plan. Each user updates independently on their own next navigation.
EC-38
Owner on Free has zero projects and visits the Reports page (which is fully locked on Free).
The Reports page renders the full-page locked state with the centered upgrade card; no empty-state message is shown because the lock takes precedence over the empty data condition.
EC-39
Owner on Essentials plan has zero projects and visits the Project Listing page (which is accessible).
The Project Listing page renders the standard empty-state component (e.g., "No projects yet — create your first project") because the feature is accessible on the plan and there is no lock to display.
EC-40
Owner on Free plan opens a floating action button menu containing "+ New Project", "+ New Client", "+ Invite Team Member".
The FAB itself is rendered normally. Inside the menu, "+ New Project" shows a lock icon if the agency has reached its 5-project limit, "+ Invite Team Member" shows a lock icon if at the 1-seat limit, and "+ New Client" is rendered normally. Selecting a locked item opens the upgrade popup.
9. Acceptance Criteria
- The framework defines exactly seven visual lock patterns (menu lock, card lock, entity-row lock, tab lock, action button lock, section hide, full-page locked state) and every gated element in Pixally maps to exactly one of these patterns.
- The framework defines exactly three behavior tiers (Tier 1 Full Lock, Tier 2 Graceful Degradation, Tier 3 Section Hide) and every plan-gated capability is classified into one tier.
- Clicking a locked menu item or typing a direct URL to a locked page navigates the browser to that route and renders the full-page locked state with a yellow "Upgrade" call-to-action for owners.
- Clicking a locked card, entity row, action button, or hitting an entity creation limit opens the standard modal upgrade popup with a yellow "Upgrade" call-to-action for owners.
- Clicking a locked tab activates the tab and renders the full-page locked state inside the tab content area only; the surrounding page chrome remains intact.
- Section Hide elements are not rendered in the DOM at all and have no click target.
- The cascading lock rule propagates from a locked brand to all dependent projects, events, invoices, expenses, files, notes, deliverables, and portal access tied to those entities.
- The universal downgrade rule preserves all data and renders previously-accessible higher-plan features as locked rather than deleted; re-upgrading restores access immediately on next page navigation.
- Non-owner roles see the same lock visuals as owners; clicking opens a popup with the body text "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and only a Close button.
- Plan-change visibility is deferred to the next page navigation or refresh; the current rendered page does not update locks in real time.
- Multi-agency owners and team members see independent lock state per agency.
- Grace period preserves the agency's paid-plan locks with no additional gating; suspension overrides the framework entirely; cancellation pending preserves paid-plan locks until cycle end.
- Trial provides full Studio access with no locks; auto-downgrade on Day 15 activates Free-plan locks on next navigation; the trial-end notification is delivered by email only with no in-app banner.
- Search omits sections entirely when no data exists for that entity type; surfaces locked entities with the standard lock visuals when data exists; click on locked result opens the upgrade popup.
- Workflow automations with locked nodes pause at the cycle-end transition with a banner; owner manually edits and unpauses; locked nodes are not auto-replaced with fallbacks.
- Contractors and clients in their respective portals never see lock icons or upgrade popups; they see "access revoked" or "please contact your agency" messages when their content is plan-locked.
- The yellow "Upgrade" button is the single primary call-to-action for plan-change initiation across the entire framework and routes to Manage Subscription per FRD 3.
- The lock icon is consistent in style (filled padlock), size proportional to context (12 to 20 pixels), and color (current text color at 50-60% opacity or neutral muted gray inside badges) across every pattern.
- For Free-plan project access, the five most recently created projects within the accessible brand are accessible; remaining projects are locked.
- For Studio-to-Essentials contractor downsizing, the twenty contractors with the longest agency relationship (oldest invitation date) are retained.
- Sort and filter actions on list views apply within each group (accessible above divider, locked below divider) separately; the two groups never interleave regardless of sort.
- Pagination is single combined across both groups; page one fills with accessible rows first then locked overflow.
- The "Locked · Upgrade to unlock" divider is hidden when there are zero locked rows; the empty-state component for the module is shown when there are zero accessible rows on an unlocked feature; the full-page locked state is shown when there are zero rows on a locked feature.
- Plan downgrade is allowed during the 28-day failed-payment grace period; the downgrade takes effect at the end of the current failed cycle with the failed invoice written off, consistent with FRD 8 grace-period cancellation treatment.
- Floating action buttons and quick-action shortcuts are rendered normally; individual menu items inside them apply standard lock visuals when plan-gated.
- Concurrent users in the same agency each update their own UI on their own next page navigation; the framework does not push real-time plan-change updates across user sessions.
- The yellow "Upgrade" button on locked cards and entity rows is hidden entirely for non-owner roles; non-owners see only the lock icon and entity content, and clicking the locked surface opens the non-owner popup with "Close" only.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. Test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after FRD 9B is finalized to ensure full coverage of the per-module application of this framework.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Authentication Module
Hard
Identifies the user role for owner vs non-owner popup variants.
Cannot differentiate owner from non-owner; defaults to non-owner safety popup.
Role & Permission Module
Hard
Determines which roles see locks and which routes are accessible per role.
Lock visibility may be inconsistent across roles.
Subscription Plans Module (FRD 1)
Hard
Sources the plan entitlement matrix used to determine which features are gated on which plan.
Framework cannot evaluate any lock; defaults to Free-plan locks for safety.
Free Trial Module (FRD 2)
Hard
Sources trial-state behavior, Studio access during trial, and Day 15 transition.
Trial agencies may incorrectly see locks during trial.
Upgrade & Downgrade Module (FRD 3)
Hard
Sources downgrade-to-Free, downgrade-to-Basic, downgrade-to-Essentials, and Brand/Project keep-rules used in the cascading lock rule.
Cascade rule cannot resolve correctly; downgrades may not take effect.
Billing Cycle Management Module (FRD 4)
Soft
Sources scheduled cycle switch state for the deferred plan-change visibility.
Scheduled switches may not take effect at the right time.
Add-ons (Team Members) Module (FRD 5)
Hard
Sources paid-extras seat handling for team-member visibility under the cascade rule.
Paid-extra seat users may see incorrect locks.
Billing Dashboard + Payment Methods Module (FRD 6)
Hard
Hosts the "Manage Subscription" destination of the yellow Upgrade button.
Upgrade button has no destination; user cannot complete the upgrade flow.
Failed Payment Management Module (FRD 7)
Hard
Sources grace-period and suspension state overrides that bypass or augment the framework.
Grace and suspension states may not behave correctly in the framework.
Cancel Subscription Module (FRD 8)
Hard
Sources cancel-to-cycle-end behavior, immediate-cancellation states, and post-cancellation Free plan transition.
Cancellation states may not transition locks correctly.
Notification Module
Hard
Delivers the trial-end email notification on Day 15.
Owners may not receive the trial-end notification.
Stripe Billing Integration
Hard
Provides plan-state webhooks that trigger lock-state re-evaluation on next navigation.
Plan-state lag can cause stale lock display.
All Per-Module FRDs (covered in FRD 9B)
Hard
Apply this framework's patterns and rules to their specific module behavior.
Without FRD 9B's per-module mapping, individual modules may apply locks inconsistently.
Frontend Component Library
Hard
Implements the seven visual lock patterns as reusable components for cross-application consistency.
Patterns may render inconsistently across modules.
9B-1 Subscription Impact: Agency App Core
FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules
Module: Subscription Impact on Core Workflow Modules Version: 1.0 Date: April 22, 2026 Status: Draft for review
1. Module Overview
Module Name: Subscription Impact on Core Workflow Modules (FRD 9B Part 1 of 4)
Purpose: This document is the first of four sub-documents that detail how the Subscription Impact Framework defined in FRD 9A applies to each individual Pixally CRM module. This part covers the eleven core workflow modules of the agency-side application — Dashboard, Brand Setup, Brands Management, Events / Projects Listing, Project Details, Event Details, Contractors Management, Team Management, Calendar & Check Availability, Tasks Management, and Library. For each module, this document specifies the assigned behavior tier (Tier 1 full lock, Tier 2 graceful degradation, or Tier 3 section hide), the plan-by-plan access matrix at module and sub-element granularity, the specific lock pattern applied (menu lock, card lock, entity-row lock, tab lock, action button lock, section hide, or full-page locked state), the cascade dependencies that propagate from upstream entities such as locked brands or locked projects, the behavior on plan downgrade for already-existing entities, and the behavior on plan upgrade for previously-locked entities. The companion documents are FRD 9B-2 (Templates & Communication), FRD 9B-3 (Finance, Reports, Settings & Integrations), and FRD 9B-4 (External Portals).
Business Goals: This part of FRD 9B serves as the implementation specification for the engineering teams building the agency-side product modules and as the QA reference for verifying plan-gating behavior across the most-used surfaces of the application. It enables consistent application of the Subscription Impact Framework patterns by mapping every plan-gated element of every core workflow module to a specific tier and lock pattern, so that no module needs to invent its own gating rules.
2. User Roles & Permissions
Role
Behavior in This Document
Reference
Agency Owner
Sees lock visuals; clicks open Owner upgrade popup with yellow Upgrade CTA.
FRD 9A Section 4.5
Agency Admin
Sees same lock visuals as Owner; yellow Upgrade button hidden on cards/rows; clicks open Non-Owner popup with Close only.
FRD 9A Section 4.6
Project Manager
Same as Agency Admin.
FRD 9A Section 4.6
Supervising Editor
Same as Agency Admin.
FRD 9A Section 4.6
Editor
Same as Agency Admin.
FRD 9A Section 4.6
Paid-Extras Seat User
Same as their assigned role above.
FRD 9A Section 4.6
Contractor (Contractor Portal)
Does not interact with these agency-side modules; sees own portal per FRD 9B-4.
FRD 9B-4
Client (Client Portal)
Does not interact with these agency-side modules; sees own portal per FRD 9B-4.
FRD 9B-4
Pixally Super Admin (Gawd Portal)
Sees agency-side module data in read-only views per FRD 9B-4.
FRD 9B-4
3. User Flow
3.1 Owner Navigates Through a Free Plan with Existing Higher-Plan Data
3.1.1 An Agency Owner whose plan was previously Essentials or Studio and is now on Free plan (after a downgrade or after Trial Day 15) logs into the Pixally agency app.
3.1.2 The owner lands on the Dashboard and sees the standard widget layout; widgets display data scoped to entities the agency still has access to under the Free plan.
3.1.3 The owner navigates to Project Listing through the left navigation; the listing displays the five most recently created projects within the accessible brand at the top, followed by the "Locked · Upgrade to unlock" divider and the remaining projects below as locked rows.
3.1.4 The owner clicks an accessible project and is routed to its Project Details page; the standard six tabs (Activity, Files/Documents, Meetings, Finances, Notes, Post Production) render with Free-plan locks applied per Section 4.5.
3.1.5 The owner clicks a locked project row and the standard upgrade popup opens per FRD 9A Section 4.5.
3.2 Owner Switches Brands When Multiple Brands Exist with Some Locked
3.2.1 An Agency Owner on a Basic plan that previously held two brands on Essentials downgraded; the system kept the brand the Owner selected during the downgrade flow per FRD 3 and locked the other brand.
3.2.2 The Owner clicks the brand switcher in the top navigation; the dropdown displays both brands with the locked brand showing a small lock icon and reduced opacity.
3.2.3 The Owner attempts to select the locked brand; the system opens the standard upgrade popup instead of switching brand context.
3.2.4 The Owner can only continue working within the unlocked brand until they upgrade to a plan that supports both brands.
3.3 Owner on Free Tries to Add a New Project Beyond Limit
3.3.1 An Agency Owner on a Free plan with five projects already created clicks the "+ New Project" call-to-action on the Project Listing page.
3.3.2 The system detects that the agency has reached the Free-plan project limit and opens the upgrade popup instead of the New Project form per FRD 9A Section 4.8.
3.3.3 The Owner clicks Upgrade and is routed to Manage Subscription per FRD 3, or clicks Close to return to Project Listing.
3.4 Owner on Free Opens a Project Details Page
3.4.1 An Agency Owner on Free clicks an accessible project on the Project Listing page.
3.4.2 The Project Details page renders with all six tabs visible; the Post Production tab shows a small lock icon next to its label.
3.4.3 The owner clicks each tab in turn:
- Activity tab opens normally; only client and agency activity entries are shown; contractor activity entries are hidden entirely per Tier 3 hide rule.
- Files/Documents tab opens normally; only client and agency files are shown.
- Meetings tab opens normally; the meeting type options offered to the Owner are in-person and phone only; Google Calendar and Calendly integrations are not offered as the underlying integrations are not available on Free.
- Finances tab opens normally; the "Payments from client" section is rendered; the "Payments to contractors" section is hidden per Tier 3.
- Notes tab opens normally; only client and agency notes are shown.
- Post Production tab is locked; clicking it activates the tab and renders the full-page locked state inside the tab content area per FRD 9A Section 4.4.
3.4.4 The owner observes the right-sidebar action panel; all buttons are visible. The "Deliverables" action button shows a small lock icon and reduced opacity. Clicking it opens the upgrade popup per FRD 9A Section 4.5.
3.5 Owner on Free Opens an Event Details Page
3.5.1 An Agency Owner on Free navigates from a Project Details page into an Event Details page; the event header and the six sub-tabs (Services, Contractors, Raw Media, Files/Documents, Notes, Info) render.
3.5.2 The owner observes the sub-tab strip:
- Services sub-tab is accessible and active by default.
- Contractors sub-tab shows a lock icon next to its label.
- Raw Media sub-tab shows a lock icon next to its label.
- Files/Documents sub-tab is accessible.
- Notes sub-tab is accessible.
- Info sub-tab is accessible.
3.5.3 The owner views the Services sub-tab and sees the "Assign Contractors" call-to-action button is disabled with a lock icon overlay; clicking it opens the upgrade popup.
3.5.4 The owner clicks the locked Contractors sub-tab; the sub-tab activates and the full-page locked state renders inside the sub-tab content area.
3.5.5 The owner clicks the locked Raw Media sub-tab; the same full-page locked state renders inside the sub-tab content area.
3.6 Owner Downgrades from Essentials to Basic with Active Contractors and Brand B
3.6.1 An Agency Owner on Essentials with two brands (Brand A active, Brand B active) and twenty active contractors initiates a downgrade to Basic per FRD 3.
3.6.2 The downgrade wizard runs at cycle end per FRD 3 Section 4.22; the system retains the brand the owner selected and locks the other brand; all contractors are disabled because Basic does not support Contractor Management.
3.6.3 On the owner's next page navigation after cycle end, the framework re-evaluates locks per FRD 9A Section 4.11; left navigation now shows the Contractors sub-menu with a lock icon and the Post Production menu item with a lock icon.
3.6.4 The owner navigates to Project Listing; projects in the kept brand are accessible above the divider; projects in the locked brand are below the divider with row-lock visuals.
3.6.5 The owner navigates to a project that has active contractor assignments and views the Event Details page; the Contractors and Raw Media sub-tabs are now locked; the Services sub-tab Assign Contractor button is locked; existing contractor assignments are visible in view-only mode without the ability to modify them per Section 4.6.
3.7 Owner on Free Reaches the Team Member Limit
3.7.1 An Agency Owner on a Free plan with one team member (the Owner) clicks "+ Invite Team Member" on the Team Management page.
3.7.2 The system detects that the agency has reached the Free-plan one-seat limit (Owner only, paid extras not yet purchased) and opens the upgrade popup instead of the Invite Team Member modal.
3.7.3 The owner clicks Upgrade to route to Manage Subscription, or alternatively initiates the paid-extras flow per FRD 5 to add seats without changing plans.
3.8 Owner on Free Tries to Use Check Availability
3.8.1 An Agency Owner on a Free plan clicks the "Check Availability" sub-menu item under the Clients & Contractors menu.
3.8.2 The browser navigates to the Check Availability route; the page renders the full-page locked state per FRD 9A Section 4.5 because Check Availability is gated to Essentials and Studio plans.
3.8.3 The owner clicks Upgrade to route to Manage Subscription.
4. Functional Logic
4.1 Dashboard
- The Dashboard is accessible to all plans; the menu item "Dashboard" is never locked.
- The Dashboard displays the same widget layout regardless of plan; individual widgets that depend on plan-gated features render with their data appropriately scoped or with internal locks per the cascade rule.
- Widgets that aggregate data across all brands are scoped to accessible brands only; data from locked brands is excluded from totals and counts displayed on the Dashboard.
- Widgets that aggregate data across all projects are scoped to accessible projects (top 5 most recently created projects on Free; all projects on Basic and above) and exclude locked projects.
- Widgets that depend on contractor data (for example, a "Contractor Activity" widget if present) are hidden entirely on Free and Basic per Tier 3 hide rule, and on Essentials and Studio they display data scoped to accessible contractors.
- Widgets that depend on advanced reports (Profit & Loss, Income, Sales, etc.) are hidden on plans that do not include those reports per Tier 3 hide rule and re-appear on plans that include them.
- Quick-action shortcuts inside Dashboard such as "+ New Project", "+ Invite Team Member", "+ Add Brand" follow the standard creation-limit interaction defined in FRD 9A Section 4.8: clicking opens the upgrade popup if the agency has reached the plan's limit for that entity type.
4.2 Brand Setup
- Brand Setup is the one-time wizard that runs when the agency first signs up and chooses to configure a brand identity (logo, colors, contact details); this wizard is accessible to all plans.
- The wizard does not have plan-gated steps; every plan can complete brand setup successfully for at least one brand.
- The wizard enforces the plan-specific brand count limit at completion: Free and Basic accept exactly one brand, Essentials accepts up to two brands, and Studio accepts an unlimited number.
- An agency that re-runs the wizard (for example, to add a second brand on Essentials) sees the Add Brand call-to-action gated by the standard creation-limit interaction; reaching the plan's brand limit opens the upgrade popup before opening the wizard.
4.3 Brands Management
- The Brands Management page is accessible to all plans.
- The page displays all brands belonging to the agency, including brands that are currently accessible and brands that are currently locked due to plan downgrade per FRD 9A Section 4.4 (Universal Downgrade Rule).
- Accessible brands are displayed first in the standard list view; locked brands are displayed below the "Locked · Upgrade to unlock" divider with row-lock visuals per the entity-row lock pattern defined in FRD 9A Section 4.2.
- Clicking an accessible brand opens that brand's settings or detail surface.
- Clicking a locked brand opens the standard upgrade popup per FRD 9A Section 4.5.
- The "+ Add Brand" call-to-action follows the creation-limit interaction; reaching the plan's brand limit (Free or Basic at one brand, Essentials at two brands) opens the upgrade popup instead of the Add Brand wizard.
- The brand switcher in the top navigation displays all brands; locked brands appear with a small lock icon and reduced opacity in the dropdown.
- Selecting a locked brand from the switcher opens the upgrade popup; the application's brand context does not change to the locked brand.
- A locked brand serves as the cascade origin per FRD 9A Section 4.3: every project, event, invoice, expense, file, note, contractor assignment, and portal access tied to that brand inherits the locked state automatically across the entire application.
4.4 Events / Projects Listing
- The Events / Projects Listing page is accessible to all plans.
- The page exposes two top-level tabs: an Events tab and a Projects tab; both tabs are always visible.
- On the Events tab, events are grouped by their parent project's accessibility status: events whose parent project is accessible appear at the top in the standard list ordering, followed by events whose parent project is locked appearing below the "Locked · Upgrade to unlock" divider with row-lock visuals.
- On the Projects tab, the same accessibility-first then locked-below ordering is applied: accessible projects appear above the divider sorted by the user's chosen sort, and locked projects appear below the divider sorted by the same criterion within their own group.
- For Free-plan agencies with more than five projects, the five most recently created projects within the accessible brand are accessible above the divider; the remaining projects (whether they exceed the Free five-project limit or belong to the locked brand) are below the divider.
- For Basic, Essentials, and Studio agencies that have downgraded from a higher plan and have locked brands, the projects in locked brands are below the divider regardless of project age; projects in accessible brands are above.
- The "+ New Project" call-to-action follows the standard creation-limit interaction: clicking on a Free plan with five existing projects opens the upgrade popup; clicking on Basic, Essentials, or Studio with the brand switcher set to a locked brand also opens the upgrade popup; clicking on accessible plan-and-brand state opens the New Project form normally.
- Filters applied on the Projects tab (by brand, by status, by date range, etc.) operate within each group separately per FRD 9A Section 4.18; filtering by a locked brand returns zero accessible rows above the divider and the relevant locked rows below.
- Sort options on the Projects tab apply within each group separately; the two groups never interleave regardless of sort.
- Pagination is single combined across both groups per FRD 9A Section 4.19.
4.5 Project Details
- The Project Details page is the primary detail surface for a single project; it is accessible if and only if the project itself is accessible per the cascade rule (a locked brand's project is locked; a project beyond the Free five-project limit is locked).
- An accessible Project Details page exposes a fixed set of six tabs: Activity, Files/Documents, Meetings, Finances, Notes, and Post Production.
- The Activity tab is accessible to all plans; activity entries are filtered using the Tier 3 hide rule so that contractor-related activity entries (entries originating from contractor portal activity, contractor invoice creation, contractor assignment, etc.) are not rendered for agencies on Free and Basic plans; client-side and agency-side activity entries are always rendered.
- The Files/Documents tab is accessible to all plans; the file list is filtered using the Tier 3 hide rule for cleanly-sourced files: client files and agency files are always rendered; contractor-uploaded files are rendered only for plans that include Contractor Management (Essentials and Studio).
- For agencies that downgraded from Essentials or Studio and previously had contractor files attached to a project, those contractor files remain visible in the Files/Documents list on the lower plan but are individually locked per the universal downgrade rule; clicking a locked file opens the upgrade popup.
- The Meetings tab is accessible to all plans and exhibits Tier 2 graceful degradation behavior: agencies on Free can create in-person meetings and phone meetings normally; the Google Calendar and Calendly integration options are not offered in the meeting creation flow on Free because the underlying integrations are not available; agencies on Basic, Essentials, and Studio see the integration options because Google Calendar and Calendly integrations are available on those plans.
- The Finances tab is accessible to all plans; the tab renders two sections: "Payments from client" and "Payments to contractors". The "Payments from client" section is always rendered. The "Payments to contractors" section is rendered using Tier 3 hide rule on Free and Basic plans (the section is not rendered at all because Contractor Management is not available); on Essentials and Studio plans the section is rendered with its standard content.
- For agencies that downgraded from Essentials or Studio with existing contractor payment data, the "Payments to contractors" section is hidden on the new lower plan; the underlying data is preserved per FRD 9A Section 4.4 and reappears if the agency upgrades.
- The Notes tab is accessible to all plans; notes are filtered using the Tier 3 hide rule so that contractor-side notes are not rendered for agencies on Free and Basic; client-side and agency-side notes are always rendered.
- For agencies that downgraded with existing contractor notes, those notes remain in the data store but are individually locked on the lower plan; users see them in the list with row-lock visuals and clicking opens the upgrade popup.
- The Post Production tab is gated by Tier 1 full lock on Free and Basic plans; the tab is rendered with a small lock icon next to its label and reduced opacity; clicking the locked tab activates it and renders the full-page locked state inside the tab content area per FRD 9A Section 4.4.
- The right-sidebar action panel renders all action buttons regardless of plan; action buttons that are gated by plan apply the action button lock pattern from FRD 9A Section 4.2: "Deliverables" is locked on Free and Basic plans (button shown with lock icon overlay; click opens popup); other actions follow their own gating rules per FRD 9A Sections 4.18 to 4.20 and the creation-limit interaction.
- For agencies that downgraded with previously-created Deliverables, the "Deliverables" action remains disabled with the lock visual; existing deliverables records are preserved and accessible if the agency upgrades.
4.6 Event Details
- The Event Details page is the detail surface for a single event within a project; it inherits its accessibility from its parent project per the cascade rule.
- An accessible Event Details page exposes a fixed set of six sub-tabs: Services, Contractors, Raw Media, Files/Documents, Notes, and Info.
- The Services sub-tab is accessible to all plans; the sub-tab content renders the event's services list normally; the "Assign Contractors" action button on this sub-tab follows the action button lock pattern: button is rendered with a lock icon overlay and reduced opacity on Free and Basic plans, and clicking opens the upgrade popup.
- For agencies that downgraded from Essentials or Studio with existing contractor assignments on services, the assigned contractors remain visible in the services list in view-only mode; the agency cannot add, modify, or remove contractor assignments, and the "Assign Contractors" button remains locked.
- The Contractors sub-tab is gated by Tier 1 full lock on Free and Basic plans; the sub-tab is visible in the strip with a lock icon next to its label and reduced opacity; clicking it activates the sub-tab and renders the full-page locked state inside the sub-tab content area.
- The Raw Media sub-tab is gated by Tier 1 full lock on Free and Basic plans; this sub-tab is functionally tied to contractor-uploaded raw media and shares the contractor-cascade rule; on Essentials and Studio plans the sub-tab renders normally.
- The Files/Documents sub-tab follows the same hide-and-lock rules as the Project Details Files/Documents tab per Section 4.5.
- The Notes sub-tab follows the same hide-and-lock rules as the Project Details Notes tab per Section 4.5.
- The Info sub-tab is accessible to all plans; the event metadata (date, time, location, custom fields, lead source, tags) is plan-agnostic and always rendered.
4.7 Contractors Management & Setup
- Contractors Management is the dedicated module for inviting, organizing, and managing contractors; the module is gated by Tier 1 full lock on Free and Basic plans.
- The "Contractors" sub-menu item under "Clients & Contractors" in the left navigation is rendered with a lock icon on Free and Basic plans; clicking the locked sub-menu item navigates to the route and renders the full-page locked state per FRD 9A Section 4.4.
- On Essentials, the Contractors page is accessible with a hard cap of twenty active contractor records; on Studio, the cap is unlimited.
- For an agency that downgraded from Studio to Essentials with more than twenty contractors, the system retains the twenty contractors with the longest agency relationship (oldest invitation date) per FRD 9A Section 4.4 and FRD 3 cascading downgrade logic; the remaining contractors are locked and lose Contractor Portal access per the cross-portal cascade in FRD 9A Section 3.13.
- The Contractors page on Essentials and Studio displays the standard contractor list view; the "+ Invite Contractor" call-to-action follows the standard creation-limit interaction: on Essentials, clicking when the cap of twenty is reached opens the upgrade popup; on Studio, the call-to-action is always available.
- The locked-contractor portion of the list (when an Essentials agency has previously held more than twenty contractors after downgrade from Studio) is rendered below the "Locked · Upgrade to unlock" divider with row-lock visuals.
- A locked contractor's record cascades to all dependent assignments: events and projects with that contractor assigned will not show contractor information from this individual on the agency side; contractor portal access for this individual is fully revoked per FRD 9A Section 3.13.
- A locked brand cascades to contractors associated with projects in that brand: while the contractor record is technically still active in the Contractors module list, their assigned events and projects in the locked brand are individually disabled in the contractor's portal per FRD 9A Section 3.13.4.
4.8 Team Management
- Team Management is accessible to all plans; the menu item is never locked.
- The Team Management page displays the agency's team members in a single list view with the Owner first, followed by other members in standard ordering.
- Plan-specific seat limits are enforced at the moment of inviting a new team member: Free allows the Owner plus paid extras only (one plan-included seat), Basic allows the Owner plus one additional plan-included seat plus paid extras, Essentials allows the Owner plus two additional plan-included seats plus paid extras, and Studio allows unlimited seats.
- The "+ Invite Team Member" call-to-action on the Team Management page goes directly to the standard Invite Team Member form per FRD 5 Section 4.7 and never shows the choice popup; this differs from the Subscription page entry points ("Add Seat" and "Add Team Member") which render the choice popup for selecting between re-activating a disabled member and inviting a new member per FRD 5 Section 4.20.
- - The "+ Invite Team Member" call-to-action follows the creation-limit interaction defined in FRD 9A Section 4.8: clicking when the plan limit is reached opens the upgrade popup; the owner can also choose to add paid-extras seats per FRD 5 from the Subscription page rather than upgrading plan, and the upgrade popup links the owner to that flow indirectly via the Manage Subscription destination.
- For agencies that downgraded with more team members than the new plan allows, the FRD 3 downgrade wizard requires the Owner to select which members to retain; members not selected are auto-disabled per FRD 3 Section 4.22 and remain in the Inactive state until the agency re-upgrades or the owner manually removes them.
- Disabled team members appear in the Team Management list with an Inactive status indicator; they are not subject to the lock pattern (they were processed by the FRD 3 downgrade flow); the framework's lock patterns do not apply.
- Paid-extras seat users appear in the team list identically to plan-included team members; their seat status is not surfaced specially in the Team Management list.
4.9 Calendar & Check Availability
- The Calendar sub-menu item under "Tools" is accessible to all plans.
- The Calendar page renders the agency's events, tasks, and other scheduled items normally regardless of plan; calendar contents are filtered to accessible projects only (locked brands' events are not rendered, and on Free plan only events from the five most recently created accessible projects are rendered).
- The Calendar page does not introduce its own lock visuals; entities that are locked due to cascade rules are simply excluded from the calendar view.
- Sync-related actions on the Calendar page that depend on integrations apply the standard action button lock pattern: a "Sync to Google Calendar" action is locked on Free (because the integration is gated to Basic and above per FRD 9A); on Basic and above, the action is available.
- The "Check Availability" sub-menu item under "Clients & Contractors" is gated by Tier 1 full lock on Free and Basic plans.
- The Check Availability sub-menu item is rendered with a lock icon on Free and Basic plans; clicking navigates to the route and renders the full-page locked state per FRD 9A Section 4.4.
- On Essentials and Studio plans, the Check Availability page is accessible and operates as a contractor-availability lookup tool that draws from contractor records; this is consistent with the gating logic that Check Availability is functionally tied to Contractor Management which is also Essentials-and-Studio gated.
4.10 Tasks Management
- Tasks Management is accessible to all plans; the menu item is never locked.
- The Tasks page renders the standard task list and board views without plan-specific gating on the page itself.
- Task entities are scoped to accessible projects per the cascade rule: tasks belonging to projects in locked brands are not rendered, and on Free plans, tasks are scoped to projects within the five accessible projects.
- Task assignment dropdowns honor the team-member visibility rules: only active (non-disabled) team members are selectable as assignees; disabled team members from a downgrade are not in the dropdown.
- No specific Task-related call-to-action is plan-gated as of Phase 1; this module is treated as a pure entity-CRUD module with cascade-based filtering only.
4.11 Library
- Library is accessible to all plans; the menu item is never locked.
- The Library module hosts agency-wide reusable assets (templates, image library, copy snippets, etc.) and operates without plan-specific gating on the module itself.
- Library entities are not subject to brand-cascade rules in the standard sense because library assets are not strictly tied to a single brand or project; library content remains visible across all plans.
- Storage limits per plan are not defined in Phase 1; the framework does not introduce lock interactions on Library entity creation.
- No specific Library-related call-to-action is plan-gated as of Phase 1.
5. Field Details & Validations
5.1 Per-Module Plan Access Summary Table
Module
Free
Basic
Essentials
Studio
Tier
Lock Pattern
Dashboard
✓
✓
✓
✓
n/a
n/a (data scoped via cascade)
Brand Setup
✓ (1 brand)
✓ (1 brand)
✓ (2 brands)
✓ (∞)
n/a
Creation-limit popup
Brands Management
✓
✓
✓
✓
n/a
Entity-row lock for excess brands; cascade origin
Events / Projects Listing
✓
✓
✓
✓
n/a
Entity-row lock per cascade
Project Details (page)
Per cascade
Per cascade
Per cascade
Per cascade
n/a
Inherits accessibility from project
→ Activity tab
✓ (filtered)
✓ (filtered)
✓
✓
Tier 3
Section hide for contractor entries
→ Files/Documents tab
✓ (filtered)
✓ (filtered)
✓
✓
Tier 3 + Universal Downgrade
Hide on Free/Basic; lock on downgrade
→ Meetings tab
✓ (no integrations)
✓ (with integrations)
✓
✓
Tier 2
Graceful degradation
→ Finances tab — Payments from client
✓
✓
✓
✓
n/a
Always visible
→ Finances tab — Payments to contractors
Hidden
Hidden
✓
✓
Tier 3
Section hide
→ Notes tab
✓ (filtered)
✓ (filtered)
✓
✓
Tier 3 + Universal Downgrade
Hide / lock
→ Post Production tab
🔒
🔒
✓
✓
Tier 1
Tab lock + full-page locked state
→ Right sidebar — Deliverables button
🔒
🔒
✓
✓
Tier 1
Action button lock
Event Details (page)
Per cascade
Per cascade
Per cascade
Per cascade
n/a
Inherits accessibility from project
→ Services sub-tab
✓
✓
✓
✓
n/a
Always visible
→ Services — Assign Contractors
🔒
🔒
✓
✓
Tier 1
Action button lock
→ Contractors sub-tab
🔒
🔒
✓
✓
Tier 1
Tab lock + full-page locked state
→ Raw Media sub-tab
🔒
🔒
✓
✓
Tier 1
Tab lock + full-page locked state
→ Files/Documents sub-tab
✓ (filtered)
✓ (filtered)
✓
✓
Tier 3 + Universal Downgrade
Hide / lock
→ Notes sub-tab
✓ (filtered)
✓ (filtered)
✓
✓
Tier 3 + Universal Downgrade
Hide / lock
→ Info sub-tab
✓
✓
✓
✓
n/a
Always visible
Contractors Management menu item
🔒
🔒
✓ (20 cap)
✓ (∞)
Tier 1
Menu lock + full-page locked state
Team Management
✓ (1+paid)
✓ (2+paid)
✓ (3+paid)
✓ (∞)
n/a
Creation-limit popup
Calendar
✓
✓
✓
✓
n/a
Cascade-filtered content
Check Availability
🔒
🔒
✓
✓
Tier 1
Menu lock + full-page locked state
Tasks Management
✓
✓
✓
✓
n/a
Cascade-filtered content
Library
✓
✓
✓
✓
n/a
None
5.2 Key Field-Level Validations
Field / CTA
Validation
"+ New Project" call-to-action
On click: if plan project limit reached or active brand is locked, open upgrade popup; otherwise open New Project form.
"+ Add Brand" call-to-action
On click: if plan brand limit reached, open upgrade popup; otherwise open Add Brand wizard.
"+ Invite Team Member" call-to-action
On click: if plan seat limit reached and no paid extras flow initiated, open upgrade popup; otherwise open Invite modal.
"+ Invite Contractor" call-to-action
On click on Essentials with twenty contractors: open upgrade popup; on Studio: always open Invite modal; on Free/Basic: button is not rendered because the entire Contractors module is Tier 1 locked.
Brand switcher dropdown
Renders all brands; locked brands have lock icon and reduced opacity; selecting a locked brand opens upgrade popup; selecting an accessible brand changes brand context.
Project list rows
Accessible rows above divider; locked rows below divider with lock icon and reduced opacity; row-level click opens project details (accessible) or upgrade popup (locked).
Tab labels (Project Details and Event Details)
Locked tabs render with small lock icon next to label and reduced opacity; click activates tab and renders full-page locked state in tab content area.
Right-sidebar action buttons (Project Details)
Locked actions render with lock icon overlay and reduced opacity; click opens upgrade popup.
"Assign Contractors" button (Event Details Services sub-tab)
Locked on Free/Basic with lock icon overlay; click opens upgrade popup.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Owner upgrades plan from upgrade popup triggered in any of the 11 modules
No standalone success message; routes to Manage Subscription per FRD 3.
Owner clicks yellow Upgrade button.
Standard upgrade flow continues per FRD 3.
SM-2
Owner navigates to a previously-locked module after upgrading
No special message; module renders normally with previously-locked content unlocked.
After plan-change processing, on next page navigation.
All locks within the module are removed.
SM-3
Plan-change cycle-end execution completes for downgrades affecting these modules
No in-app message; framework re-evaluates locks on next page navigation.
Cycle-end backend job runs.
Locks for the new lower plan apply on next navigation.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Owner clicks "+ New Project" at Free plan five-project limit
Upgrade popup opens with the standard generic message defined in FRD 9A.
Plan limit reached.
Owner upgrades or closes.
EM-2
Owner clicks "+ Add Brand" at plan brand limit
Upgrade popup opens.
Plan brand limit reached.
Owner upgrades or closes.
EM-3
Owner clicks "+ Invite Team Member" at plan seat limit
Upgrade popup opens.
Plan seat limit reached and paid extras flow not initiated.
Owner upgrades, adds paid extras per FRD 5, or closes.
EM-4
Owner attempts to switch to a locked brand via brand switcher
Upgrade popup opens; brand context does not change.
User selects locked brand from dropdown.
Owner upgrades or remains on current brand.
EM-5
Owner clicks a locked project, brand, contractor, or other locked entity row
Upgrade popup opens.
User clicks a locked row.
Owner upgrades or closes.
EM-6
Owner clicks a locked tab (Post Production, Contractors, Raw Media)
Tab activates and full-page locked state renders in tab content area.
User clicks a locked tab.
Owner upgrades or navigates away.
EM-7
Owner clicks a locked action button (Deliverables, Assign Contractors, etc.)
Upgrade popup opens.
User clicks a locked action button.
Owner upgrades or closes.
EM-8
Non-owner role attempts any of the above on a locked element
Non-owner popup opens with "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and only Close button.
Non-owner clicks any locked element.
Non-owner contacts Owner.
EM-9
Cascade-locked entity referenced in a list (e.g., locked brand's project surfaced in search or in another module's list)
Row is rendered with row-lock visuals; click opens upgrade popup.
Cross-module cascade reference.
Owner upgrades or closes.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Free agency has zero projects and clicks Project Listing menu item.
Page renders with the standard empty-state component for Project Listing ("No projects yet — create your first project"); the lock framework does not apply because the module itself is accessible.
EC-2
Free agency has exactly five projects, all in the accessible brand.
Page renders the five accessible projects; "Locked · Upgrade to unlock" divider is hidden because there are no locked rows. "+ New Project" call-to-action is gated by creation-limit popup.
EC-3
Free agency has exactly one project.
Page renders the single project; no divider; "+ New Project" call-to-action is available because the agency has not reached the five-project limit.
EC-4
Free agency has six projects in the accessible brand, all created within the same hour, identical timestamps.
The five most recently created (using primary sort plus deterministic tiebreaker on internal entity ID) are accessible; the sixth is locked.
EC-5
Basic agency had Brand A and Brand B on Essentials, downgraded; the system retained one brand per FRD 3.
Project Listing shows projects from the retained brand at top, projects from the locked brand below the divider with row-lock visuals.
EC-6
Free Owner clicks Post Production tab inside an accessible Project Details page.
Tab activates; full-page locked state renders in tab content area; rest of the page (header, other tabs, right sidebar) remains intact.
EC-7
Free Owner views Project Details Files/Documents tab on a project that previously had contractor files (agency was on Essentials before).
Client and agency files are visible normally; contractor files are visible in the list with row-lock visuals; clicking a locked file opens the upgrade popup.
EC-8
Free Owner views Project Details Finances tab on a project that previously had contractor payment data.
"Payments from client" section renders with full data; "Payments to contractors" section is not rendered at all per Tier 3; underlying contractor payment data is preserved and reappears on upgrade.
EC-9
Free Owner opens the Meetings tab and clicks "+ New Meeting".
Meeting creation form opens with options for in-person and phone meeting only; Google Calendar and Calendly options are not present in the form because the integrations are not available on Free.
EC-10
Basic Owner opens the Meetings tab and clicks "+ New Meeting".
Meeting creation form opens with all options including Google Calendar and Calendly because both integrations are available on Basic and above.
EC-11
Free Owner opens an Event Details page and clicks the locked Contractors sub-tab.
Sub-tab activates and full-page locked state renders inside the sub-tab content area; the sub-tab strip and other surrounding chrome remain intact.
EC-12
Free Owner opens an Event Details page and clicks the locked Raw Media sub-tab.
Same behavior as the Contractors sub-tab; the sub-tab activates and renders the full-page locked state inside its content area.
EC-13
Essentials agency has twenty active contractors and clicks "+ Invite Contractor".
Standard creation-limit interaction triggers; upgrade popup opens advising the owner to upgrade to Studio for unlimited contractors.
EC-14
Studio agency downgrades to Essentials with twenty-five active contractors.
The twenty contractors with the longest agency relationship are retained; the remaining five are locked and lose Contractor Portal access on next login.
EC-15
Free Owner with 1 plan-included seat (only the Owner) clicks "+ Invite Team Member".
Upgrade popup opens; Owner can also navigate to Subscription page to add paid extras per FRD 5 instead of upgrading plan.
EC-16
Basic agency has 2 plan-included seats plus 3 paid-extra seats and clicks "+ Invite Team Member".
Invite modal opens normally; the agency has unlimited paid-extras seats and is not at any limit.
EC-17
Owner navigates to brand switcher with one accessible brand and one locked brand.
Both brands are visible in the dropdown; locked brand has lock icon; selecting locked brand opens upgrade popup; selecting accessible brand changes context.
EC-18
Owner of a locked brand attempts to access the brand's Brand Settings via the brand switcher.
Selecting the locked brand opens upgrade popup; brand context does not change; Owner cannot reach the Brand Settings of a locked brand without upgrading.
EC-19
Owner navigates to Calendar on Free plan with one project.
Calendar renders with all events from the accessible project; no lock visuals on the Calendar page itself.
EC-20
Owner clicks Check Availability menu item on Free plan.
Browser navigates to /check-availability; full-page locked state renders.
EC-21
Owner upgrades from Free to Essentials and immediately navigates to Project Listing.
Page does not update locks in real time per FRD 9A Section 4.11; on the next navigation or refresh, all projects in the accessible brand become accessible (Free five-project limit removed); locked-from-cascade projects in any locked brand remain locked if applicable.
EC-22
Owner downgrades from Essentials to Basic with active scheduled cycle switch from Annual to Monthly.
Both the downgrade and the cycle switch are scheduled and execute at cycle end per FRD 3 and FRD 4 logic; on next navigation after cycle end, both changes take effect simultaneously and locks reflect the new Basic plan with the new cycle.
EC-23
Free Owner has zero projects and zero brands and lands on Dashboard.
Dashboard renders with empty-state widgets ("No projects yet", "Get started by creating your first brand", etc.); Quick-action buttons such as "+ New Project" and "+ Add Brand" are available because the agency has not yet reached any limit.
EC-24
Free Owner is in 28-day grace period after a failed payment on Essentials.
The framework treats the agency as still on Essentials per FRD 9A Section 4.13; all Essentials-level locks (no Tier 1 locks for Essentials features) apply; the agency retains full Essentials access during grace.
EC-25
Free Owner cancels subscription per FRD 8 immediate-cancellation path during grace.
The framework re-evaluates locks for Free plan on next navigation; all Free-plan locks apply; the agency transitions to Free immediately per FRD 8 Section 4.23.
EC-26
Owner clicks a locked Project Details right-sidebar action ("Deliverables" on Free).
Action button has lock icon overlay and reduced opacity; click opens upgrade popup.
EC-27
Owner clicks "+ New Project" while the brand switcher is set to a locked brand.
System detects locked brand context and opens upgrade popup instead of New Project form.
EC-28
Free Owner has six projects in the accessible brand and the sixth project is referenced in another module (for example, search results for the project name).
The sixth project is rendered with row-lock visuals in any module that lists it; click opens upgrade popup.
EC-29
Free Owner has zero events on the Calendar tab.
Calendar renders empty; standard empty-state for Calendar applies; no lock visuals because Calendar itself is not gated.
EC-30
Free Owner navigates to Tasks Management with five projects and many tasks.
Tasks list renders only tasks belonging to the five accessible projects; tasks belonging to projects beyond the five-project limit are excluded from the view; no lock visuals on Tasks page itself.
9. Acceptance Criteria
- The eleven core workflow modules covered by this document apply the lock patterns and tier rules defined in FRD 9A consistently.
- The Dashboard is accessible to all plans; widgets are scoped to accessible entities only and contractor-related widgets are hidden on Free and Basic per Tier 3.
- Brand Setup is accessible to all plans; the wizard enforces plan brand limits at completion via the creation-limit popup interaction.
- Brands Management lists all brands; accessible brands appear above the "Locked · Upgrade to unlock" divider and locked brands appear below; the brand switcher in the top navigation reflects the same accessibility states.
- Events / Projects Listing exposes Events and Projects tabs; accessible entities are displayed first followed by the divider and then locked entities; sort and filter operate within each group.
- Project Details renders six tabs (Activity, Files/Documents, Meetings, Finances, Notes, Post Production); the Post Production tab is Tier 1 locked on Free and Basic; the Activity, Files/Documents, and Notes tabs apply Tier 3 hide for contractor-related entries on Free and Basic and apply the universal downgrade rule for previously-uploaded contractor entities.
- Project Details Meetings tab applies Tier 2 graceful degradation: in-person and phone options are always available; Google Calendar and Calendly integrations are gated to Basic and above.
- Project Details Finances tab renders "Payments from client" always and "Payments to contractors" only on Essentials and Studio (Tier 3 hide elsewhere).
- Project Details right-sidebar action panel renders all buttons; "Deliverables" is action-button-locked on Free and Basic.
- Event Details renders six sub-tabs; Contractors and Raw Media sub-tabs are Tier 1 locked on Free and Basic and render the full-page locked state inside the sub-tab content area on click; Services sub-tab is always accessible but the "Assign Contractors" action button is action-button-locked on Free and Basic.
- Contractors Management is Tier 1 locked at the menu level on Free and Basic; on Essentials, the page enforces the twenty-contractor cap; on Studio, the cap is unlimited; downgrade from Studio to Essentials retains the twenty oldest contractors.
- Team Management enforces seat limits at invite time via creation-limit popup; downgrades follow FRD 3 wizard logic; disabled team members are surfaced in the list with Inactive status.
- Calendar is accessible to all plans; events are scoped via cascade; integration-dependent actions follow action button lock pattern.
- Check Availability is Tier 1 locked at the menu level on Free and Basic; locked menu click and direct URL access render the full-page locked state.
- Tasks Management is accessible to all plans; tasks are scoped via cascade.
- Library is accessible to all plans without lock interactions in Phase 1.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. Test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after FRD 9B-2, 9B-3, and 9B-4 are finalized to ensure full coverage.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Subscription Impact Framework (FRD 9A)
Hard
Defines the seven lock patterns, three tiers, cascade rule, universal downgrade rule, and popup variants applied throughout this document.
Per-module behavior cannot be implemented consistently.
Subscription Plans Module (FRD 1)
Hard
Source of plan entitlements (which features and limits are on which plan).
Per-module access matrix cannot resolve.
Free Trial Module (FRD 2)
Hard
Source of trial-state behavior and Day 15 transition that triggers Free-plan locks for trial agencies.
Trial transitions may not apply locks correctly.
Upgrade & Downgrade Module (FRD 3)
Hard
Source of downgrade-to-Free, -to-Basic, -to-Essentials logic for keep-rules on brands, projects, team members, and contractors used in the cascade rule.
Cascade and downgrade behaviors cannot resolve correctly.
Add-ons (Team Members) Module (FRD 5)
Hard
Source of paid-extras seat behavior under Team Management and creation-limit interactions.
Paid extras may not interact with seat limits correctly.
Failed Payment Management (FRD 7)
Hard
Source of grace-period and suspension state behaviors that override the framework.
Grace and suspension states may not transition locks correctly.
Cancel Subscription Module (FRD 8)
Hard
Source of cancellation states (cancel-to-cycle-end, immediate cancellation during grace or suspension) that re-evaluate locks at cycle end or immediately.
Cancellation transitions may not apply correctly.
Project Module FRD
Hard
Source of project-specific behavior (creation, listing, detail surface, archival logic) that this document overlays with subscription gating.
Module-specific behavior gaps.
Event Module FRD
Hard
Source of event-specific behavior under Project Details.
Module-specific behavior gaps.
Contractor Management Module FRD
Hard
Source of contractor entity behavior, invitation flow, assignment logic, and contractor portal cross-references.
Contractor-related cascade rules cannot resolve.
Brand Management Module FRD
Hard
Source of brand entity behavior, switcher logic, and brand-cascade origin behavior.
Brand cascade cannot resolve.
Team Management Module FRD
Hard
Source of team member roles, invitation flow, and disabled-state behavior.
Team-related limits cannot enforce.
Calendar Module FRD
Hard
Source of calendar rendering, sync logic, and availability behavior.
Calendar-related cascades cannot apply.
Tasks Module FRD
Hard
Source of task entity logic.
Task cascade cannot apply.
Library Module FRD
Soft
Source of library asset logic; mostly plan-agnostic in Phase 1.
Limited impact.
Frontend Component Library
Hard
Implements the seven visual lock patterns from FRD 9A as reusable components consumed by these modules.
Lock visuals will be inconsistent.
9B-2 — Subscription Impact: Agency App Templates
FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules
Module: Subscription Impact on Templates & Communication Modules Version: 1.0 Date: April 22, 2026 Status: Draft for review
1. Module Overview
Module Name: Subscription Impact on Templates & Communication Modules (FRD 9B Part 2 of 4)
Purpose: This document is the second of four sub-documents detailing how the Subscription Impact Framework defined in FRD 9A applies to each individual Pixally CRM module. This part covers the eleven templates and communication modules of the agency-side application — Email Center, Email Templates, Lead Form, Packages, Proposals, Invoices, Client Contract, Service Agreement, Questionnaires, Notifications, and Automation. For each module, this document specifies the assigned behavior tier (Tier 1 full lock, Tier 2 graceful degradation, or Tier 3 section hide), the plan-by-plan access matrix, the specific lock pattern applied, the cascade dependencies that propagate from upstream entities such as locked brands or locked projects, the behavior on plan downgrade for already-existing entities, and the behavior on plan upgrade for previously-locked entities. The companion documents are FRD 9B-1 (Core Workflow Modules), FRD 9B-3 (Finance, Reports, Settings & Integrations), and FRD 9B-4 (External Portals). The two most plan-gated modules in this part are Notifications (Tier 2 graceful degradation around SMS being Studio-only) and Automation (Tier 2 graceful degradation around locked workflow nodes that pause automations on downgrade).
Business Goals: This part of FRD 9B serves as the implementation specification for the engineering teams building the agency-side templates and communication modules and as the QA reference for verifying plan-gating behavior across these surfaces. Most modules in this group are accessible across all plans because templates and communication are foundational to running an agency at any scale; the gating in this group is concentrated in two areas — SMS notifications which are exclusive to Studio, and Automation workflow nodes that depend on plan-gated capabilities such as SMS sending, contractor assignment triggers, and QuickBooks sync actions.
2. User Roles & Permissions
Role
Behavior in This Document
Reference
Agency Owner
Sees lock visuals; clicks open Owner upgrade popup with yellow Upgrade CTA.
FRD 9A Section 4.5
Agency Admin
Sees same lock visuals as Owner; yellow Upgrade button hidden on cards/rows; clicks open Non-Owner popup with Close only.
FRD 9A Section 4.6
Project Manager
Same as Agency Admin.
FRD 9A Section 4.6
Supervising Editor
Same as Agency Admin.
FRD 9A Section 4.6
Editor
Same as Agency Admin.
FRD 9A Section 4.6
Paid-Extras Seat User
Same as their assigned role above.
FRD 9A Section 4.6
Contractor (Contractor Portal)
Does not interact with these agency-side modules; receives emails and notifications sent from these modules per the Contractor Portal scope in FRD 9B-4.
FRD 9B-4
Client (Client Portal)
Does not interact with these agency-side modules; receives emails and notifications sent from these modules per the Client Portal scope in FRD 9B-4.
FRD 9B-4
Pixally Super Admin (Gawd Portal)
Sees agency-side module data in read-only views per FRD 9B-4.
FRD 9B-4
3. User Flow
3.1 Owner Drafts an Email in Email Center on Free Plan
3.1.1 An Agency Owner on a Free plan clicks "Email Center" in the navigation and lands on the Email Center page.
3.1.2 The page renders normally with the standard email composition interface, the recipients field, the email template selector, and the conversation list of past emails.
3.1.3 The owner selects a recipient that is a client of an accessible project; the email composition flow proceeds normally.
3.1.4 The owner attempts to send an email to a recipient who is a contact of a locked brand or project; the recipient picker filters the list to accessible recipients only per the cascade rule, and locked-brand contacts are not selectable.
3.1.5 The owner sends the email and the email is recorded in the project's activity log per the standard Project Details Activity tab behavior in FRD 9B-1.
3.2 Owner Configures Notifications on Free Plan
3.2.1 An Agency Owner on a Free plan navigates to Settings → Notifications.
3.2.2 The Notifications Settings page renders with two tabs: Personal Notifications and Company Notifications.
3.2.3 The owner clicks the Company Notifications tab and sees the standard list of notification rules with three columns of toggle controls per row: None, In-App, and Email; the Email column is the default for most rules.
3.2.4 The owner scrolls to the Payment Reminders section and Contractor Reminders section; each row shows None, SMS, and Email columns; the SMS column toggle is rendered with a lock icon and reduced opacity on Free, Basic, and Essentials plans.
3.2.5 The owner clicks the locked SMS toggle for any reminder row; the standard upgrade popup opens because SMS notifications are exclusive to Studio plan.
3.2.6 The owner can freely toggle None, In-App, and Email columns on all rows because those channels are accessible on all plans.
3.3 Owner Builds a Workflow Automation on Basic Plan
3.3.1 An Agency Owner on a Basic plan clicks "Automations" in the left navigation and opens the Automation Builder for a new automation.
3.3.2 The builder renders with the standard trigger-action node palette; the palette includes node categories such as Triggers (lead created, project status changed, invoice paid, etc.) and Actions (send email, create task, schedule reminder, send SMS, sync to QuickBooks, assign contractor, etc.).
3.3.3 Nodes that are gated by plan are rendered with a small lock icon next to their label in the palette; on Basic plan, the locked nodes include "Send SMS" (Studio-only), "Sync to QuickBooks" (Essentials+ only), and contractor-related triggers and actions ("Contractor accepted job", "Assign contractor", etc.).
3.3.4 The owner attempts to drag a locked node into the builder canvas; the standard upgrade popup opens instead of placing the node.
3.3.5 The owner builds the automation using only accessible nodes and saves the automation; the automation runs normally with the saved configuration.
3.4 Owner Downgrades from Studio to Essentials with an Active SMS Automation
3.4.1 An Agency Owner on Studio has an active automation that sends an SMS reminder to clients three days before an event start date; the agency initiates a downgrade to Essentials per FRD 3.
3.4.2 At cycle end, the FRD 3 downgrade-to-Essentials job runs and the framework re-evaluates the automation against the new Essentials plan.
3.4.3 The framework detects that the SMS-sending action node is no longer accessible on Essentials and pauses the automation entirely per FRD 9A Section 4.10.
3.4.4 On the owner's next page navigation, the Automations module landing page displays a banner indicating that one or more automations contain locked steps and require manual review; the banner lists the affected automation by name.
3.4.5 The owner opens the affected automation in the builder; the SMS-sending node is rendered with a small lock icon and reduced opacity.
3.4.6 The owner edits the automation to remove the SMS node or replace it with an Email node, then saves and unpauses the automation manually; the automation resumes execution.
3.5 Owner on Free Tries to Send a Proposal Linked to a Locked Brand
3.5.1 An Agency Owner on Free has a previously-created proposal that was associated with a project in a brand that is now locked due to brand-cascade per FRD 9A Section 4.3.
3.5.2 The owner navigates to the Proposals module and the proposal list renders with accessible proposals above the divider and the locked-brand proposal below the "Locked · Upgrade to unlock" divider with row-lock visuals per the entity-row lock pattern.
3.5.3 The owner clicks the locked proposal and the standard upgrade popup opens; the proposal cannot be opened, edited, or sent.
3.5.4 The owner clicks an accessible proposal and the proposal detail surface renders normally for editing and sending.
3.6 Owner Creates an Invoice on Basic Plan
3.6.1 An Agency Owner on a Basic plan navigates to the Invoices module and clicks "+ New Invoice".
3.6.2 The new invoice form opens with fields for client recipient, line items, taxes, payment terms, and integration options.
3.6.3 The form's recipient field allows selecting from accessible clients; locked-brand clients are filtered out.
3.6.4 The form's invoice-type selector offers "Client Invoice" only because the Basic plan does not include Contractor Invoices per FRD 9A and FRD 1; the "Contractor Invoice" option is not present in the form on Basic.
3.6.5 The form's QuickBooks sync option is gated; on Basic, the QuickBooks sync toggle does not appear because QuickBooks integration is Essentials and Studio only.
3.6.6 The owner completes the form and saves the invoice; the invoice is created and behaves normally as a client-facing invoice.
4. Functional Logic
4.1 Email Center
- The Email Center module is accessible to all plans; the menu item is never locked.
- The Email Center page renders the standard email composition interface, conversation history, and template selector regardless of plan.
- Email recipients are filtered through the cascade rule per FRD 9A Section 4.3: contacts associated with projects in locked brands or with locked projects are not selectable in the recipient picker.
- Past emails sent from the agency are scoped to accessible projects in conversation history; emails sent to recipients of locked-brand or locked-project entities remain in the data store but are not surfaced in the conversation list per the Tier 3 hide rule when those entities are not accessible to the current plan.
- For agencies that downgraded with previously-sent emails tied to now-locked entities, those emails are preserved per FRD 9A Section 4.4 and reappear in conversation history if the agency re-upgrades.
- Email Center has no Tier 1 or Tier 2 plan-gating on the module itself; all gating in this module is cascade-based.
4.2 Email Templates
- The Email Templates module is accessible to all plans; the menu item is never locked.
- The Email Templates list renders all templates the agency has created; templates are agency-wide assets and are not tied to a specific brand or project, so brand-cascade and project-cascade rules do not apply to template entities.
- All template-creation, editing, deletion, and duplication actions are available on all plans.
- Email templates that reference plan-gated capabilities (for example, a template that includes an SMS-trigger merge tag) remain editable and saveable on all plans, but actually triggering an SMS from a template is gated at the SMS level per the Notifications module logic in Section 4.10.
- Email Templates has no Tier 1 or Tier 2 plan-gating on the module itself.
4.3 Lead Form
- The Lead Form module is accessible to all plans; the menu item is never locked.
- The Lead Form module allows the agency to create public-facing intake forms that capture lead information from prospective clients; the module is foundational to lead capture and is included in every plan.
- Lead Form creation, editing, publishing, and embedding are available on all plans without plan-specific gating.
- Lead Forms do not directly cascade with brands or projects; they are agency-wide assets that, when submitted, generate Lead entities that flow into the Leads & Clients Management module covered in FRD 9B-3.
- Lead Form has no Tier 1 or Tier 2 plan-gating.
4.4 Packages
- The Packages module is accessible to all plans; the menu item is never locked.
- The Packages module hosts pricing-package templates that the agency can attach to proposals, invoices, and project pricing structures.
- Packages are agency-wide template assets and do not cascade with brands or projects on creation.
- Package creation, editing, deletion, and duplication are available on all plans.
- For agencies that downgraded with packages that referenced contractor-related cost components, the packages themselves remain editable and saveable; the contractor cost line items are preserved but are not surfaced in proposals or invoices that are themselves cascade-locked.
- Packages has no Tier 1 or Tier 2 plan-gating.
4.5 Proposals
- The Proposals module is accessible to all plans; the menu item is never locked.
- The Proposals list page renders the agency's proposals with accessible proposals above the "Locked · Upgrade to unlock" divider and locked proposals (those tied to locked brands or locked projects) below the divider with row-lock visuals per the entity-row lock pattern in FRD 9A Section 4.2.
- The "+ New Proposal" call-to-action is available on all plans; the proposal creation flow allows linking the proposal to a project, and the project picker is filtered to accessible projects only per the cascade rule.
- A proposal's detail surface renders normally if the proposal is accessible; clicking a locked proposal in the list opens the standard upgrade popup.
- Proposals support template-based composition using Email Templates and Packages; the template selectors are not plan-gated.
- Proposals has no Tier 1 or Tier 2 plan-gating on the module itself; all gating is cascade-based.
4.6 Invoices
- The Invoices module is accessible to all plans for client-side invoicing; the menu item is never locked.
- The Invoices list page renders the agency's invoices with accessible invoices above the "Locked · Upgrade to unlock" divider and locked invoices (those tied to locked brands, locked projects, or contractor invoices on plans below Essentials) below the divider with row-lock visuals.
- The "+ New Invoice" call-to-action is available on all plans; the invoice creation form's invoice-type selector exhibits Tier 2 graceful degradation behavior:
- On Free and Basic plans, only "Client Invoice" is offered as an invoice type because Contractor Invoices are gated to Essentials and Studio per FRD 1 and FRD 9A.
- On Essentials and Studio plans, both "Client Invoice" and "Contractor Invoice" are offered.
- The invoice creation form's QuickBooks sync toggle is gated by plan: on Free and Basic plans, the QuickBooks sync option is not rendered in the form because QuickBooks integration is Essentials and Studio only; on Essentials and Studio plans, the QuickBooks sync toggle is available and applies the Tier 2 logic from the Invoices form-field perspective.
- For agencies that downgraded from Essentials or Studio to Basic and previously had QuickBooks-synced invoices, those invoices remain visible in the list with their QuickBooks sync history preserved per FRD 9A Section 4.4 (Universal Downgrade Rule); new invoices created on Basic do not have QuickBooks sync, but old ones retain their sync indicator in view-only mode.
- For agencies with previously-created Contractor Invoices that downgrade to Basic, those Contractor Invoice entities are individually locked in the Invoices list per the universal downgrade rule; clicking opens the upgrade popup.
- Invoice templates referenced in Email Templates and Packages are not plan-gated; the template assets remain available on all plans.
4.7 Client Contract
- The Client Contract module is accessible to all plans; the menu item is never locked.
- Client Contract creation, editing, sending for signature, and tracking are available on all plans.
- Contract entities are scoped to projects via the cascade rule: contracts tied to locked-brand or locked-project entities are individually locked in the contract list with row-lock visuals.
- The contract creation form's project picker is filtered to accessible projects only per the cascade rule.
- Client Contract has no Tier 1 or Tier 2 plan-gating on the module itself; all gating is cascade-based.
4.8 Service Agreement
- The Service Agreement module is accessible to all plans; the menu item is never locked.
- Service Agreement is functionally similar to Client Contract and follows identical cascade-based gating rules.
- Service agreements tied to locked-brand or locked-project entities are individually locked with row-lock visuals; clicking a locked service agreement opens the upgrade popup.
- Service Agreement has no Tier 1 or Tier 2 plan-gating on the module itself.
4.9 Questionnaires
- The Questionnaires module is accessible to all plans; the menu item is never locked.
- Questionnaires are agency-wide template assets that can be sent to clients as part of a project workflow; questionnaire templates are not tied to a specific brand or project.
- Questionnaire creation, editing, deletion, and sending are available on all plans.
- Questionnaire responses linked to locked-project entities are individually locked in the response list per the cascade rule and the universal downgrade rule.
- Questionnaires has no Tier 1 or Tier 2 plan-gating on the module itself.
4.10 Notifications
- The Notifications module surfaces in two places: as an in-app notification feed accessible from the top navigation bell icon, and as a Settings sub-page under Settings → Notifications that controls notification preferences.
- The in-app notification feed is accessible to all plans without lock interactions; notification entries are scoped to accessible entities via the cascade rule.
- The Settings → Notifications page exhibits Tier 2 graceful degradation behavior centered on the SMS notification channel:
- The page exposes two tabs: Personal Notifications and Company Notifications.
- Personal Notifications tab is accessible to all plans and contains rules for the individual user's own notification delivery preferences (email and in-app channels).
- Company Notifications tab is accessible to all plans and contains rules for agency-wide notification delivery, including notification rules for clients (Payment Reminders) and contractors (Contractor Reminders).
- On rows that include an SMS toggle column (Payment Reminders rows, Contractor Reminders rows, Snapshot rows), the SMS toggle is rendered with a small lock icon and reduced opacity on Free, Basic, and Essentials plans because SMS notifications are exclusive to Studio per FRD 1 and FRD 9A.
- Clicking a locked SMS toggle opens the standard upgrade popup; the toggle does not change state.
- Email and In-App toggles on the same rows are accessible to all plans and toggle freely.
- Default toggle states for new notification rules use Email by default; SMS is never a default channel.
- For agencies that downgraded from Studio with previously-enabled SMS notifications, the SMS toggles flip to off automatically and are locked; the underlying configuration is preserved and the SMS toggles re-enable on upgrade per the universal downgrade rule.
- Snapshot delivery (the daily activity summary toggle) is accessible to all plans for email and in-app delivery; the SMS option for Snapshot is Studio-only and follows the same Tier 2 lock pattern.
4.11 Automation
- The Automation module is accessible to all plans; the menu item is never locked.
- The Automation builder exhibits Tier 2 graceful degradation behavior on individual nodes in the trigger-action palette; the builder itself is accessible and the agency can construct automations on any plan.
- Plan-gated nodes include but are not limited to:
- "Send SMS" action — Studio only.
- "Sync to QuickBooks" action — Essentials and Studio only.
- Contractor-related triggers and actions ("Contractor accepted job", "Assign contractor automatically", "Contractor invoice approved", etc.) — Essentials and Studio only.
- Advanced reporting triggers tied to plan-gated reports (Income, Sales, Cash Ledger, Contractors report, Accounts Receivable, Expenses report, Financial Forecast) — Essentials and Studio only.
- Locked nodes are rendered in the palette with a small lock icon next to their label and reduced opacity; attempting to drag a locked node into the canvas opens the standard upgrade popup and does not place the node.
- An automation that contains one or more locked nodes after a plan downgrade takes effect is paused entirely per FRD 9A Section 4.10:
- At cycle-end execution that triggers the downgrade, the framework re-evaluates each automation's nodes against the new lower plan.
- Automations that contain at least one locked node are flagged paused and excluded from runtime execution until the owner manually unpauses them after editing.
- The Automations module landing page displays a banner listing the affected automations by name; the banner persists until all flagged automations are either edited and unpaused or permanently disabled.
- Editing a paused automation: the owner opens the automation in the builder; locked nodes are rendered with a small lock icon overlay; the owner can remove or replace the locked nodes with accessible alternatives; saving and unpausing manually re-enables runtime execution.
- The framework does not auto-replace locked nodes with fallback actions because doing so could silently change business behavior; the manual editing requirement ensures the owner consciously chooses how to adapt the automation to the new plan.
- New automations created on a lower plan can use only accessible nodes; locked nodes are visible in the palette but cannot be added to the canvas.
5. Field Details & Validations
5.1 Per-Module Plan Access Summary
Module
Free
Basic
Essentials
Studio
Tier
Lock Pattern
Email Center
✓
✓
✓
✓
n/a
Cascade-filtered recipients
Email Templates
✓
✓
✓
✓
n/a
None
Lead Form
✓
✓
✓
✓
n/a
None
Packages
✓
✓
✓
✓
n/a
None
Proposals
✓
✓
✓
✓
n/a
Entity-row lock per cascade
Invoices — Client Invoice
✓
✓
✓
✓
n/a
Entity-row lock per cascade
Invoices — Contractor Invoice creation
🔒
🔒
✓
✓
Tier 2
Hidden in form selector
Invoices — QuickBooks sync option
🔒
🔒
✓
✓
Tier 2
Hidden in form
Client Contract
✓
✓
✓
✓
n/a
Entity-row lock per cascade
Service Agreement
✓
✓
✓
✓
n/a
Entity-row lock per cascade
Questionnaires
✓
✓
✓
✓
n/a
Entity-row lock per cascade (responses)
Notifications — Personal tab
✓
✓
✓
✓
n/a
None
Notifications — Company tab — Email column
✓
✓
✓
✓
n/a
None
Notifications — Company tab — In-App column
✓
✓
✓
✓
n/a
None
Notifications — Company tab — SMS column
🔒
🔒
🔒
✓
Tier 2
Toggle lock + popup
Automation — module
✓
✓
✓
✓
n/a
Cascade-filtered
Automation — "Send SMS" node
🔒
🔒
🔒
✓
Tier 2
Node palette lock
Automation — "Sync to QuickBooks" node
🔒
🔒
✓
✓
Tier 2
Node palette lock
Automation — Contractor-related nodes
🔒
🔒
✓
✓
Tier 2
Node palette lock
Automation — Advanced report-trigger nodes
🔒
🔒
✓
✓
Tier 2
Node palette lock
5.2 Key Field-Level Validations
Field / CTA
Validation
Email Center recipient picker
Filters out contacts of locked-brand or locked-project entities; only accessible recipients are selectable.
Invoice creation form invoice-type selector
Renders only "Client Invoice" on Free and Basic; renders both "Client Invoice" and "Contractor Invoice" on Essentials and Studio.
Invoice creation form QuickBooks sync toggle
Not rendered on Free and Basic; rendered on Essentials and Studio.
Proposal/Contract/Service Agreement project picker
Filters out locked-brand and locked-project entities; only accessible projects are selectable.
Notifications Settings — SMS toggle
Rendered with lock icon and reduced opacity on Free, Basic, and Essentials; clicking opens upgrade popup; toggle state does not change.
Notifications Settings — Email and In-App toggles
Available on all plans; toggle freely.
Automation builder palette nodes
Plan-gated nodes render with small lock icon next to label; dragging onto canvas opens upgrade popup; node is not placed.
Automation builder canvas — existing locked node after downgrade
Node rendered with small lock icon overlay; automation paused at cycle-end; owner edits manually to unpause.
Automations module landing banner
Displayed when one or more automations are paused due to locked nodes; lists affected automations; persists until all are resolved.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Owner upgrades plan from any of the 11 modules in this group
No standalone success message; routes to Manage Subscription per FRD 3.
Owner clicks yellow Upgrade button.
Standard upgrade flow continues per FRD 3.
SM-2
Owner navigates to a previously-locked module after upgrading
No special message; module renders normally with previously-locked content unlocked.
After plan-change processing, on next page navigation.
All locks within the module are removed.
SM-3
Owner manually unpauses an automation after editing locked nodes
Standard "Automation activated" toast or banner per the Automation Module FRD.
Owner clicks Save and the automation has no remaining locked nodes.
Automation resumes runtime execution; banner updates to remove this automation from the affected list.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Owner clicks a locked SMS toggle in Notifications
Upgrade popup opens.
User clicks SMS column toggle on Free, Basic, or Essentials.
Owner upgrades to Studio or closes.
EM-2
Owner drags a locked node into the Automation builder canvas
Upgrade popup opens; node is not placed.
User drags a plan-gated node onto canvas.
Owner upgrades or chooses an accessible alternative node.
EM-3
Owner attempts to save an automation that still contains a locked node post-downgrade
Save is permitted but the automation remains paused; banner persists.
Owner clicks Save while at least one node is locked.
Owner must remove or replace all locked nodes to unpause.
EM-4
Owner clicks a locked proposal, contract, service agreement, invoice, or questionnaire response
Upgrade popup opens.
User clicks a row that is locked due to cascade or universal downgrade rule.
Owner upgrades or closes.
EM-5
Owner attempts to send an email to a locked-brand contact via Email Center recipient picker
Recipient is not selectable; no error message because the recipient does not appear in the picker.
Cascade rule filters recipient list.
Owner selects an accessible recipient or upgrades to access the locked-brand contact.
EM-6
Owner attempts to attach a contractor cost component to a proposal on Free
Selection is not available because contractor entities cascade rule excludes contractor-cost line items on Free.
Cascade rule filters contractor data.
Owner upgrades to Essentials or Studio to add contractor cost components.
EM-7
Non-owner role attempts any of the above on a locked element
Non-owner popup opens with "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and only Close button.
Non-owner clicks any locked element.
Non-owner contacts Owner.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Free Owner clicks Email Center menu item with zero past emails.
Email Center renders normally with the standard empty-state for conversation history; the lock framework does not apply because the module itself is accessible.
EC-2
Free Owner attempts to send an email; the contacts list shows only accessible-project contacts.
Locked-brand and locked-project contacts are filtered out of the picker; Owner sees only accessible recipients.
EC-3
Free Owner has past emails sent to a contact whose project is now locked.
Conversation history hides the locked-project conversation per Tier 3; underlying email data is preserved and reappears on upgrade.
EC-4
Owner on Basic creates a new invoice.
Invoice form opens with invoice-type selector showing only "Client Invoice"; QuickBooks sync option is not rendered.
EC-5
Owner on Essentials creates a new invoice.
Invoice form opens with both "Client Invoice" and "Contractor Invoice" type options and the QuickBooks sync toggle is available.
EC-6
Owner on Essentials downgrades to Basic with previously-created Contractor Invoices.
Contractor Invoices remain in the invoice list with row-lock visuals; clicking opens upgrade popup; Client Invoices are accessible normally.
EC-7
Owner on Essentials had QuickBooks-synced invoices and downgrades to Basic.
Existing invoices retain their QuickBooks sync indicator in view-only mode; new invoices created on Basic have no QuickBooks sync option.
EC-8
Owner on Free with proposals from a locked brand.
Proposals list shows accessible proposals above the divider; locked-brand proposals below the divider with row-lock visuals.
EC-9
Owner on Free attempts to create a new proposal.
New Proposal form opens; project picker filters out locked-brand and locked-project entities; only accessible projects are selectable.
EC-10
Free Owner navigates to Notifications Settings → Company Notifications.
Page renders normally; SMS toggles in Payment Reminders and Contractor Reminders rows show lock icon and reduced opacity; Email and In-App toggles work normally.
EC-11
Owner upgrades from Essentials to Studio and navigates back to Notifications Settings.
On next page navigation, SMS toggles render unlocked; Owner can toggle SMS on for any rule.
EC-12
Owner on Studio has SMS notifications enabled and downgrades to Essentials.
At cycle-end, SMS toggles flip to off automatically and lock; underlying configuration preserved; SMS re-enables on next upgrade to Studio per universal downgrade rule.
EC-13
Free Owner opens Automation Builder.
Builder renders normally; node palette displays all nodes with locked nodes shown with lock icons; Owner can build automations using accessible nodes only.
EC-14
Owner on Studio has an active automation that uses "Send SMS" node and downgrades to Essentials.
At cycle-end, automation is paused; banner appears on Automations landing; Owner edits the automation to remove or replace the SMS node before unpausing.
EC-15
Owner on Essentials has an active automation that uses "Sync to QuickBooks" node and downgrades to Basic.
At cycle-end, automation is paused; same banner-and-edit flow applies.
EC-16
Owner has an active automation that uses a contractor-trigger node ("Contractor accepted job") and downgrades to Basic.
At cycle-end, automation is paused; Owner removes the contractor-related node to unpause.
EC-17
Owner edits a paused automation but only partially removes locked nodes.
Save is permitted but the automation remains paused; the framework continues to flag it; Owner must remove or replace all locked nodes to unpause.
EC-18
Owner removes all locked nodes from a paused automation and clicks Save.
Automation transitions from paused to active; banner is updated to remove this automation from the affected list.
EC-19
Owner on Studio creates a new automation with SMS node, then immediately downgrades to Essentials.
At cycle-end the new automation is paused and added to the banner list with the rest.
EC-20
Owner upgrades from Basic to Studio while a paused-due-to-SMS automation exists.
At next page navigation, the automation no longer has any locked nodes; however, the automation remains paused until the Owner manually unpauses (the framework does not auto-resume because the Owner's previous editing state is unknown).
EC-21
Free Owner has zero active automations.
Automation Builder home renders the empty state for "No automations yet"; the lock framework does not apply because the module itself is accessible and there are no entities to lock.
EC-22
Owner on Free has a Lead Form published and a lead submission references a now-locked brand.
Lead submissions still arrive in the data store; on the Leads & Clients page (covered in FRD 9B-3), the lead may be cascade-locked if it is associated with a locked brand.
EC-23
Owner adds a contractor-related question to a Questionnaire on Studio, then downgrades to Basic.
The Questionnaire template remains editable on Basic; the contractor-related question text is preserved as plain text; the Questionnaire can still be sent to clients but cannot be sent to contractors because Contractor Management is locked on Basic.
EC-24
Owner clicks "+ New Email Template" while at the maximum number of templates.
No template count limit is enforced in Phase 1; the action proceeds normally.
EC-25
Owner attempts to use a Package that contains contractor cost line items in a Proposal on Basic.
Package can be selected; contractor cost line items are preserved in the package definition but are filtered out of the resulting Proposal because contractor data is cascade-locked on Basic.
EC-26
Non-owner role attempts to toggle a locked SMS notification or drag a locked Automation node.
Non-owner popup opens with "Please reach out to your agency owner" message and only Close button.
EC-27
Owner on Free has a paused automation from a previous Studio downgrade and the agency now reactivates a previous Studio plan via re-upgrade.
On next page navigation after upgrade, the automation's previously locked nodes (e.g., SMS) become accessible again; the automation remains paused until manually unpaused by the Owner.
9. Acceptance Criteria
- The eleven modules in this document apply the lock patterns and tier rules defined in FRD 9A consistently.
- Email Center, Email Templates, Lead Form, Packages, Client Contract, Service Agreement, and Questionnaires are accessible to all plans without Tier 1 or Tier 2 module-level gating; the only gating in these modules is cascade-based for entities tied to locked brands or locked projects.
- The Proposals module is accessible to all plans; proposal entities tied to locked brands or projects are individually locked with row-lock visuals.
- The Invoices module is accessible to all plans for client-side invoicing; the invoice creation form's invoice-type selector renders only "Client Invoice" on Free and Basic; "Contractor Invoice" is added on Essentials and Studio.
- The Invoices module's QuickBooks sync option is rendered only on Essentials and Studio; previously-synced invoices retain their sync history in view-only mode after downgrade.
- The Notifications Settings page applies Tier 2 graceful degradation: Email and In-App channels are accessible to all plans; SMS channel is gated to Studio only and renders with lock visuals on lower plans.
- The Automation builder is accessible to all plans with Tier 2 graceful degradation on individual nodes; locked nodes ("Send SMS", "Sync to QuickBooks", contractor-related triggers/actions, advanced report-trigger nodes) render in the palette with lock visuals and cannot be placed in the canvas on lower plans.
- Automations that contain at least one locked node after a plan downgrade are paused entirely; a banner on the Automations landing page lists the affected automations until they are edited and unpaused.
- The framework does not auto-replace locked nodes with fallback actions; the owner must manually edit and unpause each affected automation.
- All cascade-locked entities (proposals, invoices, contracts, service agreements, questionnaire responses tied to locked brands or projects) follow the entity-row lock pattern with the standard "Locked · Upgrade to unlock" divider and row-lock visuals.
- All non-owner roles see the same lock visuals as the Owner across all modules in this document; the yellow "Upgrade" button is hidden on locked cards and rows for non-owners; clicking opens the non-owner popup with "Close" only.
- Re-upgrading the agency restores access to all previously-locked entities across all modules in this document on next page navigation; paused automations remain paused until manually unpaused.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. Test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after FRD 9B-3 and 9B-4 are finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Subscription Impact Framework (FRD 9A)
Hard
Defines the seven lock patterns, three tiers, cascade rule, universal downgrade rule, and popup variants applied throughout this document.
Per-module behavior cannot be implemented consistently.
Subscription Plans Module (FRD 1)
Hard
Source of plan entitlements; specifies that SMS notifications are Studio-only and Contractor Invoices, QuickBooks sync, and contractor-related automation nodes are Essentials and Studio only.
Per-module access matrix cannot resolve.
Free Trial Module (FRD 2)
Hard
Source of trial-state behavior; trial agencies have Studio access including SMS notifications and all automation nodes during the 14-day window.
Trial transitions may not apply locks correctly.
Upgrade & Downgrade Module (FRD 3)
Hard
Source of cycle-end downgrade execution that triggers automation pausing and notification toggle re-evaluation.
Downgrades may not correctly pause automations or lock SMS toggles.
Failed Payment Management (FRD 7)
Hard
Source of grace-period and suspension state behaviors.
Grace and suspension states may not transition module behavior correctly.
Cancel Subscription Module (FRD 8)
Hard
Source of cancellation states.
Cancellation may not transition module behavior correctly.
Per-Module Functional FRDs — Email Center, Email Templates, Lead Form, Packages, Proposals, Invoices, Client Contract, Service Agreement, Questionnaires, Notifications, Automation
Hard
Each module's own functional spec is referenced for module-specific behavior outside subscription gating.
Module-specific behavior gaps.
Notification Module FRD
Hard
Defines the SMS, email, and in-app notification channels and their delivery infrastructure that the Tier 2 lock pattern overlays.
SMS gating cannot be enforced.
Automation Module FRD
Hard
Defines the workflow builder, node palette, trigger and action node taxonomy, automation runtime engine, and pause-unpause state machine.
Locked-node and paused-automation behavior cannot be enforced.
QuickBooks Integration Module FRD
Hard
Defines the QuickBooks sync option used in invoice creation and as an automation action node.
QuickBooks-related Tier 2 gating cannot be enforced.
Stripe Billing Integration
Soft
Provides plan-state webhooks that trigger automation re-evaluation and notification toggle state changes at cycle end.
Plan-state lag may delay automation pausing.
Frontend Component Library
Hard
Implements the seven visual lock patterns from FRD 9A as reusable components consumed by these modules.
Lock visuals will be inconsistent.
9B-3 Subscription Impact: Agency App
FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules
Module: Subscription Impact on Finance, Reports, Settings & Integrations Modules Version: 1.0 Date: April 22, 2026 Status: Draft for review
1. Module Overview
Module Name: Subscription Impact on Finance, Reports, Settings & Integrations Modules (FRD 9B Part 3 of 4)
Purpose: This document is the third of four sub-documents detailing how the Subscription Impact Framework defined in FRD 9A applies to each individual Pixally CRM module. This part covers the thirteen finance, reporting, settings, and integration modules of the agency-side application — Finance (parent module with six sub-pages), Reports (parent module with ten reports), Account Settings, Profile Management, Referral, QuickBooks Integration, Google Calendar Integration, Calendly Integration, Post Production, Global Search, Agency Auth, and Leads & Clients Management. This part contains the heaviest concentration of plan-gating in the Pixally application; nearly every Tier 1 (full lock) feature in the product lives in this group, including most Finance sub-pages, the Post Production module, the QuickBooks Integration, and the Reports module on Free plan. For each module, this document specifies the assigned behavior tier, the plan-by-plan access matrix, the specific lock pattern applied, the cascade dependencies, the behavior on plan downgrade for already-existing entities, and the behavior on plan upgrade. The companion documents are FRD 9B-1 (Core Workflow), FRD 9B-2 (Templates & Communication), and FRD 9B-4 (External Portals).
Business Goals: This part of FRD 9B serves as the implementation specification for the engineering teams building the most plan-gated surfaces of the Pixally application and as the QA reference for verifying that plan boundaries are correctly enforced where they have the most direct revenue impact. The Finance and Reports modules drive the business case for upgrading from Free to Basic and from Basic to Essentials; correctly applying lock patterns here directly affects upsell conversion. The Integrations modules drive the business case for upgrading from Free to Basic (Google Calendar, Calendly) and Basic to Essentials (QuickBooks); their lock behavior must align with the integration cards visible on the Integrations page covered in FRD 9B-1.
2. User Roles & Permissions
Role
Behavior in This Document
Reference
Agency Owner
Sees lock visuals; clicks open Owner upgrade popup with yellow Upgrade CTA.
FRD 9A Section 4.5
Agency Admin
Sees same lock visuals as Owner; yellow Upgrade button hidden on cards/rows; clicks open Non-Owner popup with Close only.
FRD 9A Section 4.6
Project Manager
Same as Agency Admin.
FRD 9A Section 4.6
Supervising Editor
Same as Agency Admin.
FRD 9A Section 4.6
Editor
Same as Agency Admin.
FRD 9A Section 4.6
Paid-Extras Seat User
Same as their assigned role above.
FRD 9A Section 4.6
Contractor (Contractor Portal)
Does not interact with these agency-side modules.
FRD 9B-4
Client (Client Portal)
Does not interact with these agency-side modules.
FRD 9B-4
Pixally Super Admin (Gawd Portal)
Sees agency-side module data in read-only views per FRD 9B-4.
FRD 9B-4
3. User Flow
3.1 Free Owner Navigates to the Reports Module
3.1.1 An Agency Owner on a Free plan clicks "Reports" in the left navigation.
3.1.2 The browser navigates to /reports and the page renders the full-page locked state per FRD 9A Section 4.5 because the Reports parent module is gated by Tier 1 full lock on Free.
3.1.3 The owner sees the centered upgrade card with the yellow "Upgrade" button; clicking Upgrade routes to Manage Subscription per FRD 3.
3.2 Basic Owner Navigates to the Reports Module
3.2.1 An Agency Owner on a Basic plan clicks "Reports" in the left navigation.
3.2.2 The browser navigates to /reports and the page renders the standard Reports grid view with all ten report cards present.
3.2.3 The three cards available on Basic — Booking Trend, Profit & Loss, and Sales Tax — render as accessible cards with the "View" button enabled.
3.2.4 The remaining seven cards — Financial Forecast, Income, Sales, Accounts Receivable, Expenses, Cash Ledger, and Contractors — render as locked cards per the card lock pattern in FRD 9A Section 4.2: each shows a small lock icon in the top-right corner and the "View" button is replaced with a yellow "Upgrade" button.
3.2.5 The owner clicks an accessible card and is routed to the report detail surface for that report.
3.2.6 The owner clicks a locked card anywhere on its surface; the standard upgrade popup opens.
3.3 Free Owner Navigates to the Finance Module
3.3.1 An Agency Owner on a Free plan clicks "Finances" in the left navigation; the menu expands to display its sub-items.
3.3.2 The Billing sub-item is rendered without a lock; the Profit & Loss, Taxes, Contractor Invoices, Expenses, and QuickBooks sub-items each render with a small lock icon at their right edge per the menu lock pattern in FRD 9A Section 4.2.
3.3.3 The owner clicks the Billing sub-item; the Billing sub-page opens normally and renders the agency's invoices and payments.
3.3.4 The owner clicks the locked Profit & Loss sub-item; the browser navigates to /finances/profit-loss and the page renders the full-page locked state.
3.4 Owner Connects QuickBooks Integration on Essentials
3.4.1 An Agency Owner on Essentials navigates to Tools → Integrations and sees three integration cards: Google Calendar, QuickBooks Online, and Calendly.
3.4.2 All three cards are accessible on Essentials with their respective Connect or Manage Integration buttons enabled.
3.4.3 The owner clicks "Connect" on the QuickBooks Online card; the standard QuickBooks OAuth flow per the QuickBooks Integration Module FRD launches.
3.4.4 After OAuth completes, the owner returns to Pixally and the QuickBooks Online card transitions to the connected state with a "Manage Integration" button.
3.5 Owner Downgrades from Essentials to Basic with QuickBooks Connected
3.5.1 An Agency Owner on Essentials with an active QuickBooks integration initiates a downgrade to Basic per FRD 3.
3.5.2 At cycle end, the framework re-evaluates QuickBooks against the new Basic plan; QuickBooks integration is locked because Basic does not include QuickBooks per FRD 1.
3.5.3 On the owner's next page navigation, the QuickBooks Online card on the Integrations page renders with card lock pattern (lock badge + yellow Upgrade button); the integration's saved OAuth credentials and sync history are preserved per FRD 9A Section 4.4.
3.5.4 The Finance → QuickBooks sub-page, the Finance → Contractor Invoices sub-page, the Finance → Expenses sub-page, and any QuickBooks-related toggles inside Invoices and Automations are also locked or hidden per the cascade rule and the universal downgrade rule.
3.5.5 If the owner re-upgrades to Essentials within a reasonable time, all QuickBooks state is restored without re-authentication on next page navigation.
3.6 Free Owner Navigates to Account Settings
3.6.1 An Agency Owner on a Free plan clicks "Settings" in the left navigation and lands on the Account Settings landing page.
3.6.2 The page renders the standard left side-menu of settings sections: My Profile, General, Business & Payment Details, Accepted Payment Methods, Team Management, 2-Step Verification, Referral System, Notifications, Brands, Data Management, and Subscription.
3.6.3 All settings sub-items are accessible to the owner; no settings sub-item is plan-gated at the menu level on the Account Settings page itself; plan-gated sub-pages such as Brands and Notifications expose their internal lock visuals on entry per FRD 9B-1 and FRD 9B-2.
3.6.4 The owner clicks "Subscription" in the settings side-menu and is routed to the Subscription page hosted in FRD 6; the framework does not duplicate Subscription page logic in this document.
3.7 Owner Globally Searches for an Entity Across Plans
3.7.1 An Agency Owner opens the global search modal (typically activated via the search icon in the top navigation or a keyboard shortcut) and types a query.
3.7.2 The search modal renders results grouped into sections (Projects, Clients and Companies, Contractors, Files, etc.); the framework applies the search behavior defined in FRD 9A Section 4.9.
3.7.3 Sections are rendered if and only if matching data exists for the agency; sections with zero entities are omitted.
3.7.4 Within each section, individual results that are plan-locked render with a small lock icon next to the result name and reduced opacity; clicking a locked result opens the standard upgrade popup; clicking an accessible result navigates to the entity's detail page.
3.7.5 If the agency is in Suspended state per FRD 7, the global search is disabled entirely because the entire application is gated to the Subscription page and the "Account is Suspended" screen.
3.8 New Owner Signs Up and Lands on Trial
3.8.1 A prospective customer visits the Pixally signup page and creates a new agency account.
3.8.2 The Agency Auth module routes the user through the standard signup flow and creates the agency record with the trial state per FRD 2.
3.8.3 The new agency starts on a 14-day Studio trial per FRD 2 with full Studio access; no locks apply during the trial window.
3.8.4 On Day 15 the auto-downgrade to Free executes per FRD 2; on the owner's next login or page navigation, all Free-plan locks become visible across every module covered in FRD 9B-1, FRD 9B-2, FRD 9B-3, and FRD 9B-4.
4. Functional Logic
4.1 Finance — Parent Module
- The Finance parent module is accessible to all plans; the Finance menu item in the left navigation is never locked because every plan needs at least the Billing sub-page.
- The Finance menu expands to expose six sub-items: Billing, Profit & Loss, Taxes, Contractor Invoices, Expenses, and QuickBooks.
- Each sub-item applies the menu lock pattern per FRD 9A Section 4.2 if the sub-item is gated on the current plan; locked sub-items show a small lock icon next to the label.
- Clicking a locked sub-item navigates to the sub-item's route and renders the full-page locked state per FRD 9A Section 4.5.
- The plan-gating per sub-item follows FRD 1 plan entitlements:
- Billing — accessible on all plans.
- Profit & Loss — accessible on Basic, Essentials, and Studio; locked on Free.
- Taxes — accessible on Basic, Essentials, and Studio; locked on Free.
- Contractor Invoices — accessible on Essentials and Studio; locked on Free and Basic.
- Expenses — accessible on Essentials and Studio; locked on Free and Basic.
- QuickBooks — accessible on Essentials and Studio; locked on Free and Basic.
4.2 Finance — Billing Sub-page
- The Billing sub-page is accessible to all plans without a Tier 1 lock.
- The Billing sub-page renders the agency's client invoices and payment records, scoped to accessible projects via the cascade rule per FRD 9A Section 4.3.
- For Free agencies, the Billing sub-page only displays records tied to the five accessible projects within the accessible brand; records tied to projects beyond the five-project limit or to locked brands are individually locked with row-lock visuals per the entity-row lock pattern.
- For agencies that downgraded with locked-brand projects, all billing records tied to those projects are individually locked in the list with row-lock visuals; clicking opens the upgrade popup.
- The Billing sub-page does not introduce module-level plan gating; all gating here is cascade-based.
4.3 Finance — Profit & Loss Sub-page
- The Profit & Loss sub-page is gated by Tier 1 full lock on Free plan.
- On Free plan, the Profit & Loss sub-item in the Finance menu shows a lock icon; clicking navigates to /finances/profit-loss and the page renders the full-page locked state.
- On Basic, Essentials, and Studio plans, the Profit & Loss sub-page is accessible and renders the standard P&L view with revenue, expenses, and net profit calculations scoped to accessible brands and projects via the cascade rule.
- For agencies on Basic or higher with locked brands due to a downgrade from Essentials or Studio, the P&L calculations exclude data from locked brands; the user sees a P&L for accessible data only.
4.4 Finance — Taxes Sub-page
- The Taxes sub-page is gated by Tier 1 full lock on Free plan.
- On Free plan, the Taxes sub-item shows a lock icon; clicking renders the full-page locked state.
- On Basic, Essentials, and Studio plans, the Taxes sub-page is accessible and renders tax calculations and tax-related forms scoped to accessible brands and projects via the cascade rule.
4.5 Finance — Contractor Invoices Sub-page
- The Contractor Invoices sub-page is gated by Tier 1 full lock on Free and Basic plans.
- On Free and Basic plans, the Contractor Invoices sub-item shows a lock icon; clicking renders the full-page locked state.
- On Essentials and Studio plans, the Contractor Invoices sub-page is accessible and renders the contractor invoicing workflow scoped to accessible contractors and accessible projects via the cascade rule.
- For Essentials agencies with the twenty-contractor cap, the sub-page operates on the twenty accessible contractors only; contractors beyond the cap (after a downgrade from Studio) are excluded from the contractor invoicing flow per FRD 9A Section 3.13.
- For agencies that downgraded from Essentials or Studio with previously-created contractor invoices, those invoices are preserved per the universal downgrade rule and reappear when the agency upgrades.
4.6 Finance — Expenses Sub-page
- The Expenses sub-page is gated by Tier 1 full lock on Free and Basic plans.
- On Free and Basic plans, the Expenses sub-item shows a lock icon; clicking renders the full-page locked state.
- On Essentials and Studio plans, the Expenses sub-page is accessible and renders expense tracking scoped to accessible brands and projects via the cascade rule.
- For agencies on Essentials or higher with locked brands, expense records tied to locked brands are individually locked in the list with row-lock visuals.
4.7 Finance — QuickBooks Sub-page
- The QuickBooks sub-page (within Finance, distinct from the QuickBooks Integration setup module) is gated by Tier 1 full lock on Free and Basic plans.
- On Free and Basic plans, the QuickBooks sub-item under Finance shows a lock icon; clicking renders the full-page locked state.
- On Essentials and Studio plans, the QuickBooks sub-page is accessible and renders the QuickBooks-synced financial view of agency data.
- The QuickBooks sub-page in Finance and the QuickBooks Integration setup module under Tools → Integrations are tied features per FRD 9A Section 4.17 cross-FRD reference; both unlock simultaneously when the agency upgrades to a plan that includes QuickBooks.
- For agencies that downgraded from Essentials or Studio with prior QuickBooks data, the underlying sync history is preserved and reappears on upgrade.
4.8 Reports — Parent Module
- The Reports parent module exhibits a hybrid of Tier 1 (full lock on Free) and Tier 2 (graceful degradation on Basic) per the plan entitlement matrix.
- On Free plan, the Reports menu item in the left navigation shows a lock icon; clicking navigates to /reports and the page renders the full-page locked state because the entire Reports module is gated to Basic and above.
- On Basic, Essentials, and Studio plans, the Reports menu item is accessible; clicking opens the Reports grid view per FRD 9B-1 patterns, with all ten report cards present and individual cards locked per plan.
- The Reports page is the canonical example of the card-lock pattern from FRD 9A Section 4.2: each card shows the report name, icon, brief description, and a "View" button (accessible) or "Upgrade" button (locked).
4.9 Reports — Individual Report Cards
- The ten report cards on the Reports page have plan-specific accessibility:
- Booking Trend — accessible on Basic, Essentials, and Studio; locked on Free (locked at parent level).
- Profit & Loss — accessible on Basic, Essentials, and Studio; locked on Free.
- Sales Tax — accessible on Basic, Essentials, and Studio; locked on Free.
- Financial Forecast — accessible on Essentials and Studio; locked on Free and Basic.
- Income — accessible on Essentials and Studio; locked on Free and Basic.
- Sales — accessible on Essentials and Studio; locked on Free and Basic.
- Accounts Receivable — accessible on Essentials and Studio; locked on Free and Basic.
- Expenses (report) — accessible on Essentials and Studio; locked on Free and Basic.
- Cash Ledger — accessible on Essentials and Studio; locked on Free and Basic.
- Contractors (report) — accessible on Essentials and Studio; locked on Free and Basic.
- On Basic plan, the Reports page renders all ten cards: three accessible and seven locked using the card lock pattern.
- On Essentials and Studio plans, all ten cards render as accessible.
- Locked card behavior follows FRD 9A Section 4.2: small lock badge in the top-right corner of the card, the card stays at full opacity for readability, the primary action button is replaced with a yellow "Upgrade" button, and the entire card surface is clickable as a single hit target opening the standard upgrade popup.
- For Agency Admin and other non-owner roles, the yellow "Upgrade" button on locked cards is hidden per FRD 9A Section 4.6; clicking the locked card opens the non-owner popup with Close only.
4.10 Account Settings
- The Account Settings module is accessible to all plans; the menu item is never locked.
- The Account Settings landing page renders a left side-menu with the standard settings sections including My Profile, General, Business & Payment Details, Accepted Payment Methods, Team Management, 2-Step Verification, Referral System, Notifications, Brands, Data Management, and Subscription.
- All settings sub-items are listed in the side-menu without lock visuals at the menu level; plan-related limitations within sub-pages (such as the SMS toggle gating in Notifications per FRD 9B-2) are surfaced inside the sub-page itself, not at the side-menu level.
- Specific sub-pages within Account Settings are documented in their respective FRDs:
- Team Management — FRD 9B-1 Section 4.8.
- Notifications — FRD 9B-2 Section 4.10.
- Brands — FRD 9B-1 Section 4.3.
- Subscription — FRD 6.
- Referral System — Section 4.12 of this document.
- Data Management — out of Phase 1 scope per FRD 8 data export decision (export feature deferred).
- Sub-pages not detailed elsewhere (My Profile, General, Business & Payment Details, Accepted Payment Methods, 2-Step Verification) are accessible to all plans without subscription-related gating.
4.11 Profile Management
- The Profile Management sub-page (typically accessed as "My Profile" inside Account Settings) is accessible to all plans without any lock interactions.
- Profile Management contains the individual user's personal settings (name, email, profile photo, time zone, password, language preference, etc.) and is independent of the agency's plan.
- Profile Management does not have plan-gated fields or sub-features in Phase 1.
4.12 Referral System
- The Referral System is accessible to all plans per FRD 1; the Referral menu item or Account Settings sub-page never shows a lock.
- Referral functionality (generating a referral code, viewing referral status, claiming referral rewards) is available on Free, Basic, Essentials, and Studio.
- Referral does not have cascade-based gating because referrals are independent of brands and projects.
4.13 QuickBooks Integration Module
- The QuickBooks Integration setup module is the standalone integration management surface accessed via Tools → Integrations → QuickBooks Online card; this is distinct from the Finance → QuickBooks sub-page covered in Section 4.7 but the two are tied features per FRD 9A.
- The QuickBooks Integration is gated by Tier 1 full lock on Free and Basic plans.
- On Free and Basic plans, the QuickBooks Online card on the Integrations page applies the card lock pattern from FRD 9A Section 4.2 and FRD 9B-1 Section 4.2 (Integrations sub-menu); the card shows a lock badge and a yellow Upgrade button.
- On Essentials and Studio plans, the QuickBooks Online card is accessible; clicking "Connect" launches the standard QuickBooks OAuth flow; clicking "Manage Integration" on a connected card opens the integration management surface.
- For agencies that downgraded with prior QuickBooks connection, the OAuth credentials and sync history are preserved per FRD 9A Section 4.4; on re-upgrade, the integration resumes without re-authentication on next page navigation.
- Inside the integration management surface (accessible on Essentials and Studio), the standard sync settings, account mapping, and sync logs are exposed without further plan-gating because reaching this surface already requires Essentials or Studio.
4.14 Google Calendar Integration
- The Google Calendar Integration is gated by Tier 1 full lock on Free plan.
- On Free plan, the Google Calendar card on the Integrations page applies the card lock pattern; clicking opens the standard upgrade popup.
- On Basic, Essentials, and Studio plans, the Google Calendar card is accessible; clicking "Connect" launches the standard Google OAuth flow; clicking "Manage Integration" on a connected card opens the integration management surface.
- For agencies that downgraded from a higher plan to Free with an active Google Calendar connection, the OAuth credentials are preserved per the universal downgrade rule; on upgrade back to Basic or higher, the integration resumes without re-authentication.
- The Google Calendar integration affects calendar event sync on the Calendar module per FRD 9B-1 Section 4.9; while Google Calendar is locked on Free, the in-app Calendar module remains accessible without sync.
4.15 Calendly Integration
- The Calendly Integration is gated by Tier 1 full lock on Free plan.
- On Free plan, the Calendly card on the Integrations page applies the card lock pattern; clicking opens the standard upgrade popup.
- On Basic, Essentials, and Studio plans, the Calendly card is accessible; clicking "Connect" launches the standard Calendly OAuth flow.
- The Calendly integration affects meeting scheduling within Project Details Meetings tab per FRD 9B-1 Section 4.5; while Calendly is locked on Free, the Meetings tab remains accessible with in-person and phone meeting types only (Tier 2 graceful degradation).
- For agencies that downgraded from a higher plan to Free with an active Calendly connection, the OAuth credentials are preserved per the universal downgrade rule; on upgrade back to Basic or higher, the integration resumes without re-authentication.
4.16 Post Production Module
- The Post Production module is gated by Tier 1 full lock on Free and Basic plans.
- On Free and Basic plans, the Post Production menu item in the left navigation shows a lock icon; clicking navigates to /post-production and the page renders the full-page locked state.
- On Essentials and Studio plans, the Post Production module is accessible as a dedicated workflow surface for managing editor assignments, deliverable creation, version control, client review rounds, and post-production project tracking.
- The Post Production module is also surfaced as a tab inside Project Details per FRD 9B-1 Section 4.5; the tab is gated by Tier 1 full lock on Free and Basic plans and renders the full-page locked state inside the tab content area when clicked.
- The Post Production module and the Project Details Post Production tab are tied features; both unlock simultaneously when the agency upgrades to Essentials or Studio.
- For agencies that downgraded from Essentials or Studio with prior Post Production data (existing deliverables, version histories, review rounds), all data is preserved per the universal downgrade rule and reappears on upgrade.
- Inside the Post Production module, sub-features such as advanced color grading workflows, AI-assisted tagging, and bulk media operations may have additional Tier 2 graceful degradation between Essentials and Studio; these sub-features are documented in the dedicated Post Production Module FRD and are out of scope for this document beyond the parent Tier 1 lock.
4.17 Global Search
- The Global Search module is accessible to all plans; the search trigger (typically a search icon in the top navigation or a keyboard shortcut) is never locked.
- The Global Search modal applies the search behavior defined in FRD 9A Section 4.9: results are grouped into sections by entity type; sections render only if matching data exists; locked entities within accessible sections are surfaced with the standard lock icon and reduced opacity.
- For agencies on plans where contractor management is locked (Free, Basic), the Contractors section in search results is omitted entirely if no contractor data exists, and rendered with all-locked rows if contractor data exists from a prior higher plan (per the universal downgrade rule).
- For agencies in the suspended state per FRD 7, the Global Search trigger is disabled or hidden entirely because the entire application is gated to the Subscription page and the "Account is Suspended" screen.
- For agencies in grace period per FRD 7, the Global Search behaves identically to the agency's paid plan because grace preserves full access.
- For agencies in cancellation pending state per FRD 8, the Global Search behaves identically to the agency's paid plan during the cancel-to-cycle-end window.
4.18 Agency Auth
- The Agency Auth module covers the pre-plan surfaces — sign up, log in, password reset, and email verification — and is accessible to all users regardless of plan because the user must authenticate before plan state is even evaluated.
- The Agency Auth module is not subject to subscription locks; the lock framework only applies after authentication and when the user lands inside the Pixally agency app.
- For new signups, the Agency Auth module creates the agency record and starts the 14-day Studio trial per FRD 2 automatically; the trial state is the default for new agencies.
- For trial agencies on Day 15, the framework's auto-downgrade execution per FRD 2 transitions the agency to Free; subsequent logins by the owner land them on a Free-plan agency with all Free-plan locks active.
- For suspended agencies per FRD 7, the Agency Auth module routes the owner to the Subscription page and routes non-owners to the "Account is Suspended" screen; the framework's per-module locks are bypassed by the suspension override.
4.19 Leads & Clients Management
- The Leads & Clients Management module is accessible to all plans; the menu item is never locked.
- The module contains two related entity types:
- Leads — prospective clients captured from Lead Forms or manually added.
- Clients — confirmed clients with active or completed projects.
- No plan-specific limit is enforced on the count of leads or clients in any plan in Phase 1.
- Lead and Client entities are subject to the cascade rule per FRD 9A Section 4.3: a lead or client tied to a locked-brand or locked-project entity is individually locked in the list with row-lock visuals.
- For Free agencies with leads or clients tied to projects beyond the five-project limit or locked brands, those entities are below the "Locked · Upgrade to unlock" divider with row-lock visuals.
- The "+ New Lead" and "+ New Client" call-to-actions are available on all plans without creation-limit gating.
- Lead and Client detail pages render normally if accessible; clicking a locked lead or client opens the standard upgrade popup.
- Lead and Client export operations and bulk actions follow the cascade rule and apply only to accessible entities; locked entities are excluded from bulk operations.
- For agencies that downgraded with leads or clients now in locked brands, the underlying entity records are preserved and reappear unlocked when the agency upgrades.
5. Field Details & Validations
5.1 Per-Module Plan Access Summary
Module
Free
Basic
Essentials
Studio
Tier
Lock Pattern
Finance — Billing
✓
✓
✓
✓
n/a
Cascade-filtered
Finance — Profit & Loss
🔒
✓
✓
✓
Tier 1
Menu lock + full-page state
Finance — Taxes
🔒
✓
✓
✓
Tier 1
Menu lock + full-page state
Finance — Contractor Invoices
🔒
🔒
✓
✓
Tier 1
Menu lock + full-page state
Finance — Expenses
🔒
🔒
✓
✓
Tier 1
Menu lock + full-page state
Finance — QuickBooks (sub-page)
🔒
🔒
✓
✓
Tier 1
Menu lock + full-page state
Reports — parent
🔒
✓
✓
✓
Tier 1 (Free)
Menu lock + full-page state
Reports — Booking Trend
🔒
✓
✓
✓
Card
Card lock
Reports — Profit & Loss
🔒
✓
✓
✓
Card
Card lock
Reports — Sales Tax
🔒
✓
✓
✓
Card
Card lock
Reports — Financial Forecast
🔒
🔒
✓
✓
Card
Card lock
Reports — Income
🔒
🔒
✓
✓
Card
Card lock
Reports — Sales
🔒
🔒
✓
✓
Card
Card lock
Reports — Accounts Receivable
🔒
🔒
✓
✓
Card
Card lock
Reports — Expenses (report)
🔒
🔒
✓
✓
Card
Card lock
Reports — Cash Ledger
🔒
🔒
✓
✓
Card
Card lock
Reports — Contractors (report)
🔒
🔒
✓
✓
Card
Card lock
Account Settings (parent)
✓
✓
✓
✓
n/a
None at side-menu level
Profile Management
✓
✓
✓
✓
n/a
None
Referral
✓
✓
✓
✓
n/a
None
QuickBooks Integration setup
🔒
🔒
✓
✓
Tier 1
Card lock + cascading sub-page
Google Calendar Integration
🔒
✓
✓
✓
Tier 1 (Free)
Card lock
Calendly Integration
🔒
✓
✓
✓
Tier 1 (Free)
Card lock
Post Production module
🔒
🔒
✓
✓
Tier 1
Menu lock + full-page state
Global Search
✓
✓
✓
✓
n/a
Search behavior per FRD 9A §4.9
Agency Auth
✓
✓
✓
✓
n/a
None (pre-plan)
Leads & Clients Management
✓
✓
✓
✓
n/a
Cascade-filtered + row lock
5.2 Key Field-Level Validations
Field / CTA
Validation
Finance sub-menu items (P&L, Taxes, Contractor Invoices, Expenses, QuickBooks)
Render with lock icon on plans where gated; clicking navigates to sub-page route and renders full-page locked state.
Reports parent menu item
Renders with lock icon on Free; clicking navigates to /reports and renders full-page locked state.
Reports grid cards (10 total)
Each card individually evaluated against current plan; locked cards apply card lock pattern with lock badge, full opacity, and yellow Upgrade button replacing the View button (Owner) or hidden button (non-owner).
Integrations cards (Google Calendar, QuickBooks, Calendly)
Each card individually evaluated; locked cards apply card lock pattern; click anywhere on locked card opens upgrade popup.
QuickBooks OAuth Connect button
Available on Essentials and Studio; not rendered on Free or Basic (the entire card is in card-lock state).
Google Calendar / Calendly Connect button
Available on Basic, Essentials, and Studio; not rendered on Free.
Post Production menu item
Renders with lock icon on Free and Basic; clicking navigates to /post-production and renders full-page locked state.
Global Search results
Sections rendered if data exists; locked entities within sections rendered with lock icon and reduced opacity; click opens upgrade popup; entire search disabled in suspended state.
Leads & Clients list rows
Cascade-locked entities rendered below "Locked · Upgrade to unlock" divider with row-lock visuals; click opens upgrade popup.
Account Settings sub-menu
All sub-items rendered without lock visuals at the menu level; lock visuals appear inside sub-pages where applicable per FRD 9B-1, FRD 9B-2, and FRD 6.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Owner upgrades plan from any of the modules in this group
No standalone success message; routes to Manage Subscription per FRD 3.
Owner clicks yellow Upgrade button.
Standard upgrade flow continues per FRD 3.
SM-2
Owner navigates to a previously-locked module after upgrading
No special message; module renders normally with previously-locked content unlocked.
After plan-change processing, on next page navigation.
All locks within the module are removed.
SM-3
Owner connects QuickBooks, Google Calendar, or Calendly integration after upgrading to a supporting plan
Standard OAuth completion message per the integration's own success flow.
OAuth flow completes successfully.
Card transitions from "Connect" state to "Manage Integration" state.
SM-4
Re-upgrade restores prior integration without re-authentication
No additional message; integration state appears connected on next navigation.
Upgrade processing completes for an agency that previously had the integration connected.
OAuth credentials and sync history restored.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Free Owner clicks Reports menu item
Browser navigates to /reports; full-page locked state renders.
Tier 1 lock for Reports parent on Free.
Owner upgrades to Basic or higher.
EM-2
Owner clicks a locked Finance sub-item
Browser navigates to the sub-page route; full-page locked state renders.
Tier 1 lock for the sub-page on the current plan.
Owner upgrades.
EM-3
Owner clicks a locked Report card
Standard upgrade popup opens.
Card lock pattern triggered.
Owner upgrades or closes.
EM-4
Owner clicks a locked Integration card
Standard upgrade popup opens.
Card lock pattern triggered on Integrations page.
Owner upgrades or closes.
EM-5
Free Owner clicks Post Production menu item
Browser navigates to /post-production; full-page locked state renders.
Tier 1 lock for Post Production on Free.
Owner upgrades.
EM-6
Owner attempts to use QuickBooks-related action when integration is locked
Standard upgrade popup opens; the action does not execute.
Action gated by QuickBooks Integration access.
Owner upgrades.
EM-7
Suspended agency owner attempts global search
Search trigger is disabled or hidden; clicking does nothing.
Suspension state per FRD 7.
Owner reactivates subscription or pays invoice per FRD 7.
EM-8
Non-owner role attempts any of the above on a locked element
Non-owner popup opens with "This feature requires a plan upgrade. Please reach out to your agency owner to enable it." and only Close button.
Non-owner clicks any locked element.
Non-owner contacts Owner.
EM-9
Owner attempts to access a locked lead or client via Leads & Clients list
Standard upgrade popup opens.
Cascade lock applied to lead or client tied to locked brand or project.
Owner upgrades or closes.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Free Owner clicks Finance menu and expands the sub-menu.
Finance menu expands; Billing is unlocked, Profit & Loss / Taxes / Contractor Invoices / Expenses / QuickBooks all show lock icons.
EC-2
Free Owner clicks Billing sub-item.
Billing sub-page opens; renders client invoices and payments scoped to accessible projects (top 5 most recently created).
EC-3
Free Owner clicks the Profit & Loss sub-item.
Browser navigates to /finances/profit-loss; full-page locked state renders.
EC-4
Basic Owner clicks the Profit & Loss sub-item.
Browser navigates to /finances/profit-loss; sub-page renders normally with P&L view scoped via cascade rule.
EC-5
Free Owner clicks Reports menu item.
Browser navigates to /reports; full-page locked state renders.
EC-6
Basic Owner clicks Reports menu item.
/reports loads with grid of 10 cards; 3 accessible (Booking Trend, P&L, Sales Tax) and 7 locked.
EC-7
Basic Owner clicks the Booking Trend card.
Card click navigates to the report detail surface for Booking Trend.
EC-8
Basic Owner clicks the Income card.
Card lock pattern; clicking opens standard upgrade popup.
EC-9
Essentials Owner clicks Reports menu item.
All 10 cards render as accessible.
EC-10
Studio Owner downgrades to Essentials with active QuickBooks connection.
QuickBooks remains accessible on Essentials; integration state is preserved without re-authentication.
EC-11
Essentials Owner downgrades to Basic with active QuickBooks connection.
At cycle-end, QuickBooks Online card on Integrations page transitions to card-lock state; integration state preserved per universal downgrade rule.
EC-12
Free Owner navigates to Tools → Integrations.
Per FRD 9B-1 Section 4.2 Integrations sub-menu logic, the Integrations sub-menu shows a lock icon on Free; clicking renders the full-page locked state because all three integrations are locked on Free.
EC-13
Basic Owner navigates to Tools → Integrations.
Integrations page renders with three cards: Google Calendar accessible (Connect button), Calendly accessible (Connect button), QuickBooks Online locked (card-lock pattern).
EC-14
Owner re-upgrades from Free to Basic with prior Google Calendar connection.
On next page navigation, Google Calendar card transitions to "Manage Integration" state; OAuth credentials preserved and integration resumes without re-authentication.
EC-15
Free Owner clicks Post Production menu item.
Browser navigates to /post-production; full-page locked state renders.
EC-16
Owner navigates to Account Settings.
Settings landing page renders with full side-menu; all sub-items listed without lock visuals at side-menu level.
EC-17
Owner clicks a sub-item in Account Settings whose sub-page has internal locks (e.g., Notifications).
Sub-page opens normally; internal locks render per FRD 9B-2 Section 4.10.
EC-18
Owner clicks "Subscription" sub-item in Account Settings side-menu.
Routes to Subscription page hosted in FRD 6; this document defers to FRD 6 for Subscription page logic.
EC-19
Free Owner opens Global Search and types a query.
Search modal opens; results grouped by section per FRD 9A Section 4.9; sections rendered if data exists; locked entities within sections shown with lock icons.
EC-20
Suspended Owner attempts to open Global Search.
Search trigger is disabled or hidden; entire app is gated to Subscription page per FRD 7 suspension override.
EC-21
Owner in 28-day grace period uses Global Search.
Search behaves identically to the agency's paid plan because grace preserves full access.
EC-22
New user signs up and creates a new agency.
Agency Auth flow runs; agency starts on 14-day Studio trial per FRD 2; all features accessible during trial.
EC-23
Trial Day 15 auto-downgrade triggers and owner logs in.
Agency Auth routes the owner to the Free-plan dashboard; on next page navigation all Free-plan locks render.
EC-24
Free Owner navigates to Leads & Clients Management.
Leads & Clients module loads; lead and client entities rendered with cascade-based lock visuals; entities tied to locked brands or projects appear below "Locked · Upgrade to unlock" divider.
EC-25
Owner clicks a locked lead in the Leads list.
Standard upgrade popup opens.
EC-26
Free Owner clicks "+ New Lead" in Leads & Clients.
New Lead form opens normally; no creation-limit gating applies in Phase 1.
EC-27
Owner re-upgrades from Free to Essentials with previously-locked QuickBooks data, contractor invoices, expenses, and reports.
On next page navigation, all previously-locked Finance sub-pages (Contractor Invoices, Expenses, QuickBooks) and all previously-locked report cards become accessible; underlying data is preserved and visible.
EC-28
Owner cancels subscription and transitions to Free per FRD 8.
All Free-plan locks apply on next navigation; Finance Billing remains accessible (cascade-filtered to top 5 projects); other Finance sub-pages, Reports beyond Free entitlement, Post Production, and integrations all lock per Free-plan rules.
EC-29
Non-owner Project Manager navigates to Reports on a Basic agency.
Same grid as Owner with 3 accessible + 7 locked cards; locked cards have hidden Upgrade button (no yellow CTA); clicking opens non-owner popup.
EC-30
Non-owner Editor navigates to Finance sub-menu on a Free agency.
Finance menu expands; locked sub-items show lock icons; clicking a locked sub-item navigates to the sub-page and renders full-page locked state with non-owner messaging.
EC-31
Owner has integration connected and global search includes integration-related results (e.g., synced QuickBooks customer name).
Search results scoped per FRD 9A Section 4.9; integration-related results appear if the integration is currently accessible; locked-after-downgrade results appear with lock icons.
9. Acceptance Criteria
- The thirteen modules in this document apply the lock patterns and tier rules defined in FRD 9A consistently.
- The Finance parent module is accessible to all plans; the Billing sub-page is accessible to all plans; the Profit & Loss and Taxes sub-pages apply Tier 1 full lock on Free; the Contractor Invoices, Expenses, and QuickBooks sub-pages apply Tier 1 full lock on Free and Basic.
- Locked Finance sub-items render with a small lock icon in the Finance sub-menu; clicking navigates to the sub-page route and renders the full-page locked state.
- The Reports parent module applies Tier 1 full lock on Free with menu lock + full-page locked state behavior.
- On Basic, Essentials, and Studio plans, the Reports page renders ten cards with individual cards applying the card lock pattern based on plan entitlement.
- Card lock pattern on Reports: lock badge in top-right corner, card stays at full opacity, "View" button replaced with yellow "Upgrade" button (Owner) or hidden (non-owner); entire card surface clickable.
- The Account Settings module is accessible to all plans without side-menu-level locks; sub-page locks are surfaced inside each sub-page per its respective FRD reference.
- Profile Management and Referral are accessible to all plans without lock interactions.
- The QuickBooks Integration setup module is gated by Tier 1 full lock on Free and Basic; the QuickBooks Online card on the Integrations page applies card lock pattern; OAuth credentials and sync history preserved across plan changes per universal downgrade rule.
- The Google Calendar and Calendly Integrations are gated by Tier 1 full lock on Free; accessible on Basic, Essentials, and Studio.
- The Post Production module is gated by Tier 1 full lock on Free and Basic; accessible on Essentials and Studio; the standalone Post Production module and the Post Production tab inside Project Details are tied features and unlock simultaneously.
- The Global Search module is accessible to all plans except suspended state; results grouped into sections per data presence; locked entities within sections show lock icons; entire search disabled in suspended state.
- The Agency Auth module is accessible to all users regardless of plan; new signups start on 14-day Studio trial per FRD 2.
- The Leads & Clients Management module is accessible to all plans; lead and client entities cascade-locked when tied to locked brands or projects; "+ New Lead" and "+ New Client" available without creation-limit gating in Phase 1.
- All non-owner roles see the same lock visuals as the Owner; yellow Upgrade button hidden on locked cards and rows for non-owners; clicking opens non-owner popup with Close only.
- Re-upgrading restores access to all previously-locked content across all modules in this document on next page navigation, with integration credentials and sync history preserved.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. Test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after FRD 9B-4 is finalized.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Subscription Impact Framework (FRD 9A)
Hard
Defines the seven lock patterns, three tiers, cascade rule, universal downgrade rule, and popup variants applied throughout this document.
Per-module behavior cannot be implemented consistently.
Subscription Plans Module (FRD 1)
Hard
Source of plan entitlements specifying which Finance sub-pages, reports, and integrations are on each plan.
Per-module access matrix cannot resolve.
Free Trial Module (FRD 2)
Hard
Source of trial-state behavior that grants Studio access during the 14-day window.
Trial transitions may not unlock these modules correctly.
Upgrade & Downgrade Module (FRD 3)
Hard
Source of cycle-end downgrade execution.
Downgrades may not lock these modules correctly.
Billing Dashboard + Payment Methods (FRD 6)
Hard
Hosts the Subscription page that the Account Settings → Subscription sub-item links to.
Subscription page navigation broken.
Failed Payment Management (FRD 7)
Hard
Suspension state disables global search and overrides per-module locks; grace state preserves access.
Suspension override may not apply correctly.
Cancel Subscription (FRD 8)
Hard
Cancellation states drive the Free-plan transition that triggers locks across these modules.
Cancellation transitions may not apply locks correctly.
FRD 9B-1 — Core Workflow Modules
Hard
Cross-references for Brands, Team Management, Project Details Post Production tab, Integrations sub-menu, and Calendar/Check Availability.
Module behavior gaps.
FRD 9B-2 — Templates & Communication Modules
Hard
Cross-references for Notifications, Automation, Invoices QuickBooks-sync interaction.
Module behavior gaps.
Per-Module Functional FRDs — Finance, Reports, Account Settings, Profile, Referral, QuickBooks Integration, Google Calendar Integration, Calendly Integration, Post Production, Global Search, Agency Auth, Leads & Clients
Hard
Each module's own functional spec is referenced for module-specific behavior outside subscription gating.
Module-specific behavior gaps.
QuickBooks API / OAuth
Hard
Powers the QuickBooks integration; OAuth state preserved across plan changes per universal downgrade rule.
Integration cannot connect or sync.
Google Calendar API / OAuth
Hard
Powers the Google Calendar integration.
Integration cannot connect or sync.
Calendly API / OAuth
Hard
Powers the Calendly integration.
Integration cannot connect or sync.
Frontend Component Library
Hard
Implements the seven visual lock patterns from FRD 9A.
Lock visuals will be inconsistent.
9B-4 Subscription Impact: External Portals)
FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)
Module: Subscription Impact on External Portals Version: 1.0 Date: April 22, 2026 Status: Draft for review
1. Module Overview
Module Name: Subscription Impact on External Portals (FRD 9B Part 4 of 4)
Purpose: This document is the fourth and final sub-document detailing how the Subscription Impact Framework defined in FRD 9A applies to each individual Pixally CRM module. This part covers the three external portals — the Contractor Portal (with seven sub-areas), the Client Portal (all functionalities), and the Gawd Portal (Pixally's super-admin internal tool with all features). The mental model for these portals differs fundamentally from the agency-side application covered in FRD 9B-1, FRD 9B-2, and FRD 9B-3: portal users (contractors and clients) never see lock icons, never see upgrade popups, and never see any reference to subscription state. Instead, when a portal user's access is affected by an agency-side subscription change (downgrade, suspension, brand-cascade lock), the portal surfaces neutral revocation messages such as "Your access is revoked. Please contact the agency." or "Please contact your agency." with no call-to-action to upgrade. The Gawd Portal is the inverse case: a Pixally-internal super-admin tool used to manage agencies' subscription states, it has full unrestricted access regardless of any agency's plan because it is the tool that controls those plans. The companion documents are FRD 9B-1 (Core Workflow), FRD 9B-2 (Templates & Communication), and FRD 9B-3 (Finance, Reports, Settings & Integrations).
Business Goals: This part of FRD 9B serves as the implementation specification for the engineering teams building the Contractor Portal, Client Portal, and Gawd Portal, and as the QA reference for verifying that subscription-driven access changes are surfaced appropriately to non-agency users. The contractor and client portals must protect Pixally's brand voice by avoiding any indication that the agency is on a lower-tier plan or has billing issues; revocation messages instead route the portal user to the agency directly so the agency owner can communicate the situation. The Gawd Portal must be unaffected by agency subscription state so Pixally support and operations teams can act on agencies in any state, including suspended and cancelled agencies.
2. User Roles & Permissions
Role
Behavior in This Document
Reference
Contractor
Sees neutral revocation messages when their access is affected; never sees lock icons or upgrade popups; never sees agency plan information.
Section 4.1 to 4.7
Client
Sees neutral "please contact your agency" messages when their content is affected; never sees lock icons or upgrade popups; never sees agency plan information.
Section 4.8
Pixally Super Admin (Gawd Portal)
Has full unrestricted access regardless of any agency's plan; uses this portal to manage subscription states across all agencies.
Section 4.9
Agency Owner / Admin / Other Roles
Do not interact with the Contractor or Client Portals as portal users; their interactions with these portals' configuration are agency-side and covered in FRD 9B-1 (Contractors Management) and the Client/Project Module FRDs.
FRD 9B-1, Per-Module FRDs
3. User Flow
3.1 Contractor Logs in to Contractor Portal When Agency Is on Studio
3.1.1 A contractor associated with a Pixally agency that is currently on Studio plan visits the Contractor Portal login URL.
3.1.2 The contractor enters their email and password and submits the login form.
3.1.3 The system authenticates the contractor and identifies the linked agency; the agency's plan state is Studio with the contractor record marked active and accessible.
3.1.4 The contractor is routed to their Contractor Portal Dashboard with full access to Events, Calendar, W9 Form / Tax Module, Payments, and Account Settings sub-areas.
3.1.5 No lock icons or upgrade prompts are displayed anywhere in the contractor's experience.
3.2 Contractor Logs in When Their Access Was Revoked Due to Studio-to-Essentials Downgrade
3.2.1 A contractor associated with an agency that downgraded from Studio to Essentials and whose contractor record was beyond the twenty-contractor cap retained on Essentials per FRD 9A Section 4.4 attempts to log in to the Contractor Portal.
3.2.2 The contractor enters their email and password and submits the login form.
3.2.3 The system authenticates the contractor's account but identifies that the linked agency's plan does not currently support this contractor's portal access; the contractor record is in the locked-due-to-cap state per FRD 9A Section 3.13.
3.2.4 The Contractor Portal renders a full-page revocation message: "Your access is revoked. Please contact the agency." with no Upgrade button, no agency plan information, and no other call-to-action.
3.2.5 The contractor cannot proceed beyond this screen; they must contact the agency directly out of band to understand the situation.
3.3 Contractor Logs in When Agency Is on Free or Basic Plan
3.3.1 A contractor whose record exists in an agency that has downgraded all the way to Free or Basic (where Contractor Management is fully Tier 1 locked) attempts to log in.
3.3.2 The system authenticates the contractor's account and identifies that the agency's current plan does not include any contractor portal access at all.
3.3.3 The Contractor Portal renders the same full-page revocation message: "Your access is revoked. Please contact the agency."
3.3.4 The contractor cannot proceed; this is identical to Section 3.2 from the contractor's perspective even though the underlying cause is different.
3.4 Contractor Logs in When Agency Is in Suspended State
3.4.1 A contractor associated with an agency that has entered Suspended state per FRD 7 (Day 29 or later of failed payment with no payment recovery) attempts to log in.
3.4.2 The system authenticates the contractor's account and identifies that the agency is in Suspended state.
3.4.3 The Contractor Portal renders the same full-page revocation message: "Your access is revoked. Please contact the agency."
3.4.4 The contractor's view is identical regardless of whether the cause is plan downgrade, contractor cap, or agency suspension; this consistency ensures portal users do not infer agency billing details.
3.5 Contractor with Access Encounters a Locked Event
3.5.1 A contractor whose Contractor Portal access is granted (agency on Essentials with this contractor in the retained twenty, or agency on Studio with full access) is assigned to multiple events across multiple brands.
3.5.2 One of the contractor's assigned events belongs to a project in a brand that the agency has now locked due to a downgrade or brand cascade per FRD 9A Section 4.3.
3.5.3 The contractor opens their Events list in the portal; the locked-brand event is rendered in the list with a disabled state (reduced opacity, no actionable buttons, no link to event detail).
3.5.4 The contractor clicks the disabled event row; the system displays a neutral message: "This event is unavailable. Please contact the agency."
3.5.5 The contractor's other accessible events function normally; only the locked-brand event is restricted.
3.6 Client Logs in to Client Portal When Agency Is on Any Plan
3.6.1 A client associated with a Pixally agency on any plan (Free, Basic, Essentials, or Studio) visits the Client Portal login URL because Client Portal is included in all plans per FRD 1.
3.6.2 The client enters their email and password and submits the login form.
3.6.3 The system authenticates the client and identifies the agency's current state; if the agency is in an active or grace state with the client's project accessible, the client is routed to their Client Portal Dashboard with full access.
3.6.4 If the client's brand or project is locked due to brand cascade, the client portal renders a neutral message on attempted access to the affected content: "Please contact your agency."
3.7 Client Logs in When Agency Is in Suspended State
3.7.1 A client associated with an agency in Suspended state attempts to log in.
3.7.2 The system authenticates the client's account and identifies the suspension state.
3.7.3 The Client Portal renders the message "Please contact your agency." with no further functionality available; access to the client's project, invoices, and other content is blocked.
3.8 Pixally Super Admin Uses Gawd Portal
3.8.1 A Pixally Super Admin logs in to the Gawd Portal at the dedicated internal admin URL.
3.8.2 The Gawd Portal renders the agency management interface with full unrestricted access regardless of any specific agency's plan or state.
3.8.3 The super admin can browse agencies in any plan or state including Active, Trial, Grace Period, Suspended, Cancelled, and Free; the Gawd Portal is the management tool for these states and is not gated by them.
3.8.4 The super admin performs administrative actions such as overriding plan state, manually triggering reactivation, applying refunds, or viewing audit logs without being blocked by any subscription-gating logic.
4. Functional Logic
4.1 Contractor Portal — Access Determination
- Contractor Portal access is determined at login based on the linked agency's current plan state and the contractor's individual record state per the cascade rule in FRD 9A Section 4.3 and Section 3.13.
- Access matrix:
- Agency on Free or Basic: no contractor has portal access; all contractors associated with the agency see the revocation message regardless of their record's age or activity.
- Agency on Essentials: only contractors within the agency's twenty-contractor cap have portal access; the cap is filled by the contractors with the longest agency relationship (oldest invitation date) per FRD 9A Section 4.4 and FRD 3 cascading downgrade logic.
- Agency on Studio: all contractors have portal access without limit.
- Agency in Suspended state: no contractor has portal access regardless of plan that was active before suspension.
- Agency in Trial Studio: all contractors have portal access (trial is full Studio access).
- A contractor invited to multiple agencies has independent access state per agency: a contractor may have portal access to Agency A (Studio) and not to Agency B (Free); the agency switcher inside the portal reflects only agencies where access is currently granted.
4.2 Contractor Portal — Login
- The Contractor Portal Login screen is the dedicated entry point for contractors and is hosted at a URL distinct from the agency app login.
- The login screen accepts the contractor's email and password and authenticates against the Pixally contractor identity store.
- After authentication, the system evaluates the linked agency or agencies' plan state and contractor record accessibility per Section 4.1.
- If the contractor has portal access to at least one agency, the contractor is routed to the Contractor Portal Dashboard for the active agency context (or to an agency switcher if multiple agencies grant access).
- If the contractor has no portal access to any agency they are linked to, the system renders the full-page revocation message: "Your access is revoked. Please contact the agency." with no agency plan information, no Upgrade button, no support contact link, and no other actionable elements.
- The revocation message uses neutral language that does not reveal whether the cause is plan downgrade, contractor cap, brand cascade, or agency suspension; the contractor must contact the agency out of band for clarification.
4.3 Contractor Portal — Dashboard
- The Contractor Portal Dashboard is the contractor's home screen after login when access is granted.
- The Dashboard displays the contractor's upcoming events, pending tasks, quick navigation links to Events, Calendar, Payments, and Account Settings, and welcome messaging from the agency.
- All Dashboard widgets are scoped to entities the contractor has access to within the linked agency: events in accessible brands and projects only; events in locked-brand or locked-project entities are excluded from the Dashboard widget data.
- The Dashboard does not render lock icons or upgrade prompts; agency-side cascade restrictions are surfaced only at the entity level (disabled events in the Events list, etc.) per Section 4.4 and Section 4.5.
4.4 Contractor Portal — Events
- The Events sub-area of the Contractor Portal lists all events assigned to the contractor across the linked agency's projects.
- Events are filtered through the cascade rule per FRD 9A Section 4.3:
- Events in accessible brands and accessible projects render normally with full event details, agency-defined service notes, and any actionable elements (accept assignment, reject assignment, view raw media uploads, etc., per the Contractor Portal Events Module FRD).
- Events in locked-brand or locked-project entities render in the list in a disabled state with reduced opacity and no actionable elements.
- Clicking a disabled (locked-cascade) event row displays a neutral message: "This event is unavailable. Please contact the agency."
- The contractor cannot view the locked-cascade event's details, accept or reject the assignment, upload raw media, or perform any other action; the event is read-only-disabled in the list.
- Past events that completed before any cascade lock took effect remain accessible if the contractor's overall portal access is still granted; the cascade lock only restricts events whose underlying brand or project is currently locked.
- Future events scheduled in a now-locked brand or project are disabled until the agency upgrades to restore access.
4.5 Contractor Portal — Calendar
- The Calendar sub-area of the Contractor Portal renders the contractor's schedule across all assigned events for the linked agency.
- Calendar entries are filtered through the cascade rule identically to the Events sub-area; events in locked-brand or locked-project entities are excluded from the calendar view.
- The Calendar does not render disabled-state placeholders for locked-cascade events; locked events are simply not included in the calendar visualization, consistent with the principle that the Calendar is an aggregation surface and not a source-of-truth listing.
- Sync to external calendars (Google Calendar, iCal, etc.) is governed by the Contractor Portal Calendar Module FRD and operates only on accessible events.
4.6 Contractor Portal — W9 Form / Tax Module
- The W9 Form / Tax Module sub-area is accessible to all contractors with portal access regardless of the linked agency's plan; this module is fundamental to the contractor's ability to receive payments legally and is not subject to subscription-cascade gating.
- The W9 form, tax identification information, and any agency-specific tax documents are stored and displayed in this module.
- The module is read-write for the contractor for their own personal tax information; the agency cannot modify the contractor's W9 from the agency side.
- If the contractor's portal access is fully revoked (per Section 4.1), the W9 module is inaccessible because the contractor cannot enter the portal at all; the underlying tax data is preserved per Pixally data retention policy and reappears if access is restored.
4.7 Contractor Portal — Payments
- The Payments sub-area of the Contractor Portal lists all payments the contractor has received or is scheduled to receive from the linked agency.
- Payments are filtered through the cascade rule:
- Payments tied to events in accessible brands and accessible projects render normally with full payment details, status (Paid, Pending, Scheduled), and any payment-related actions.
- Payments tied to locked-brand or locked-project entities render in a disabled state with reduced opacity and no actionable elements.
- Clicking a disabled payment row displays the same neutral message: "This payment is unavailable. Please contact the agency."
- Past completed payments that were issued before any cascade lock took effect remain visible in the contractor's payment history with their original status; the cascade lock only restricts payments tied to currently-locked entities.
- Pending or scheduled payments tied to now-locked entities are disabled and cannot be acted upon by the contractor; the agency must resolve the cascade (by upgrading) before the payment can proceed.
4.8 Contractor Portal — Account Settings
- The Account Settings sub-area of the Contractor Portal contains the contractor's personal profile (name, email, phone, profile photo, time zone), password change, notification preferences, and banking information used for receiving payments.
- All Account Settings are accessible to contractors with portal access regardless of the linked agency's plan; this module is foundational to the contractor's ability to manage their own credentials and preferences.
- If the contractor's portal access is fully revoked, the Account Settings sub-area is inaccessible because the contractor cannot enter the portal; the underlying account data is preserved.
- Notification preferences in the Contractor Portal control which agency-driven notifications the contractor receives (event invitations, payment notifications, schedule changes, etc.); these preferences are independent of the agency's notification configuration covered in FRD 9B-2.
4.9 Client Portal — Access Determination and Sub-Areas
- The Client Portal is included in all plans per FRD 1 and is therefore available to clients of agencies on Free, Basic, Essentials, and Studio plans.
- Client Portal access at the agency level is granted as long as the agency is not in Suspended state.
- The Client Portal exposes standard client-facing functionality including:
- Login screen with email and password authentication.
- Dashboard showing upcoming events, recent activity, and quick links.
- Project Details surface with read-only views of project information.
- Invoices list with payment functionality (pay invoice, view past payments).
- Contracts list with sign-and-submit functionality for active contracts.
- Questionnaires list with response functionality for assigned questionnaires.
- Files list with download functionality for client-shared files.
- Communication thread for messaging the agency.
- The Client Portal applies the cascade rule per FRD 9A Section 4.3 at the entity level:
- Projects, brands, invoices, contracts, questionnaires, and files tied to a locked brand or locked project are inaccessible to the client.
- Attempting to access locked-cascade content displays a neutral message: "Please contact your agency." with no further information or call-to-action.
- If the agency is in Suspended state per FRD 7, all client portal access is fully blocked; the login screen still loads but post-login the client sees only "Please contact your agency." across the entire portal.
- If the agency cancels and transitions to Free per FRD 8, the Client Portal remains accessible because Client Portal is included in Free; cascade-locked content (such as projects in archived brands) follows the standard cascade rule and shows the "Please contact your agency." message.
- If the agency is in cancellation pending state per FRD 8 with cancellation scheduled at cycle end, the Client Portal operates per the agency's current paid plan during the cancel-to-cycle-end window; the client experience is identical to a healthy paid agency until the cycle ends.
- If the agency is in 28-day grace period per FRD 7, the Client Portal operates per the agency's paid plan because grace preserves full access.
- The Client Portal never displays lock icons, upgrade popups, agency plan information, or any reference to the agency's billing state; all subscription-driven access changes are surfaced exclusively through the neutral "Please contact your agency." message.
4.10 Gawd Portal — Pixally Super Admin Internal Tool
- The Gawd Portal is Pixally's internal management tool used by Pixally super admins, customer support, operations, and engineering teams to manage agencies, monitor system health, perform manual interventions, and respond to support requests.
- The Gawd Portal is hosted at a Pixally-internal URL distinct from the agency app and the Contractor and Client Portals; access is restricted to authorized Pixally personnel via Pixally's internal authentication.
- The Gawd Portal has full unrestricted access to all agencies regardless of any specific agency's plan state, including agencies in Active, Trial, Grace Period, Suspended, Cancelled, and Free states; the portal is the tool that manages these states and is not subject to them.
- The Gawd Portal exposes the following capabilities relevant to subscription state:
- * Browse all agencies in the Pixally system with filtering by plan, state, sign-up date, and other attributes.
- * View detailed agency record including current plan, plan history, billing history, payment method status, trial state, grace state, suspension state, cancellation state, deletion-scheduled state, and reactivation history.
- * Manually override agency plan state in cases requiring intervention (apply temporary plan upgrade, restore access during dispute, etc.).
- * Manually trigger reactivation per FRD 7 Section 4.16 in cases where automated reactivation fails.
- * Apply manual refunds, write-offs, or invoice adjustments per FRD 7 and FRD 8\.
- * Read-only views of agency data (projects, events, invoices, etc.) for support and audit purposes.
- * View audit logs of all subscription-related state changes including upgrades, downgrades, cycle switches, payment failures, suspensions, cancellations, deletions, and reactivations.
- * Configure global failed-payment behavior via the "Adjust Failed Payments" popup, including Max retry attempts (1-10, default 3), Days between retries (1-30 or "Smart Retry", default Smart Retry), Send email and text reminders master toggle, custom reminder text, Suspend account after duration (default 4 weeks), and Delete account after duration (default 1 year).
- * Cancel a scheduled deletion for an individual agency in cases requiring manual intervention (e.g., agency reaches out to Pixally support requesting an extension).
- The Gawd Portal is not subject to the lock framework defined in FRD 9A; no lock icons, upgrade popups, or non-owner messages appear in the Gawd Portal because Pixally super admins are not agency users and the framework is not applicable to them.
- Actions performed in the Gawd Portal that affect an agency's plan state propagate to the agency app and to the Contractor and Client Portals via the standard plan-change deferred-update model in FRD 9A Section 4.11; agency users see the new state on their next page navigation.
4.11 Cross-Portal Communication of Revocation State
- The three portals (Contractor, Client, Gawd) coordinate their messaging conventions to ensure consistency:
- Contractor Portal full revocation: "Your access is revoked. Please contact the agency."
- Contractor Portal entity-level revocation (locked event, payment, etc.): "This event is unavailable. Please contact the agency." or "This payment is unavailable. Please contact the agency." (the noun adjusts to the entity type).
- Client Portal full or entity-level revocation: "Please contact your agency."
- Gawd Portal: no revocation messages because super admins have full access.
- These messages never include the word "Upgrade", never reference the agency's plan, never mention billing failure, and never link to the Pixally agency app or to a support form; the agency owner is the single point of contact for portal users in revocation scenarios.
- The framework's deferred-update model applies to revocation states: a contractor or client whose access state changes due to an agency's plan change sees the new state on their next portal page navigation or login, not in real time on a currently-open page.
5. Field Details & Validations
5.1 Per-Portal Plan Access Summary
Portal Component
Trial
Free
Basic
Essentials
Studio
Suspended
Cancelled (Free)
Contractor Portal — Login (full access)
All
None
None
Top 20
All
None
None
Contractor Portal — Dashboard
✓
🚫
🚫
✓
✓
🚫
🚫
Contractor Portal — Events
✓
🚫
🚫
✓ (cascade)
✓ (cascade)
🚫
🚫
Contractor Portal — Calendar
✓
🚫
🚫
✓ (cascade)
✓ (cascade)
🚫
🚫
Contractor Portal — W9 Form / Tax
✓
🚫
🚫
✓
✓
🚫
🚫
Contractor Portal — Payments
✓
🚫
🚫
✓ (cascade)
✓ (cascade)
🚫
🚫
Contractor Portal — Account Settings
✓
🚫
🚫
✓
✓
🚫
🚫
Client Portal — Login
✓
✓
✓
✓
✓
🚫
✓
Client Portal — Dashboard
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Client Portal — Project Details
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Client Portal — Invoices/Payments
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Client Portal — Contracts
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Client Portal — Questionnaires
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Client Portal — Files
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Client Portal — Communication
✓
✓ (cascade)
✓ (cascade)
✓
✓
🚫
✓ (cascade)
Gawd Portal — All Features
✓
✓
✓
✓
✓
✓
✓
Legend: ✓ = accessible; 🚫 = full revocation message displayed; (cascade) = entity-level cascade lock applies, accessible content shown normally and locked content shown disabled with neutral message.
5.2 Key Field-Level Validations
Field / Behavior
Validation
Contractor Portal Login response when no portal access
Renders full-page "Your access is revoked. Please contact the agency." with no Upgrade button, no agency information, no support link.
Contractor Portal Events list
Cascade-locked events render with reduced opacity and disabled state; click displays "This event is unavailable. Please contact the agency."
Contractor Portal Payments list
Cascade-locked payments render disabled; click displays "This payment is unavailable. Please contact the agency."
Client Portal Login response when agency suspended
Renders full-page "Please contact your agency." with no further functionality.
Client Portal entity navigation when content cascade-locked
Renders the "Please contact your agency." neutral message in place of the entity content.
Gawd Portal access
Always granted to authorized Pixally super admins; no agency plan state affects super admin access.
Revocation message language
Must use the exact wording defined in Section 4.11; must not mention "upgrade", "plan", "billing", or "subscription"; must direct portal users to the agency owner for clarification.
Deferred update on portal access change
Portal users see updated access state on next page navigation or next login, not in real time on a currently-open page; consistent with FRD 9A Section 4.11.
6. Success Message Handling
#
Operation
Success Message
Trigger Condition
Post-Success Action
SM-1
Contractor's portal access is restored after agency upgrades
No standalone success message in the Contractor Portal; on next login, the contractor sees the standard Dashboard normally.
Agency upgrades to a plan that includes the contractor's record.
Full Contractor Portal access resumes.
SM-2
Client's content is restored after agency upgrades or restores a brand
No standalone success message in the Client Portal; on next page navigation, the previously-locked content renders normally.
Agency upgrades or removes a cascade lock.
Client Portal content visible.
SM-3
Gawd Portal action successfully changes agency plan state
Standard Gawd Portal confirmation toast or banner per the Gawd Portal Module FRD.
Pixally super admin completes a plan-state action.
Agency app and external portals reflect the new state on next navigation per FRD 9A Section 4.11.
7. Error Message Handling
#
Error Scenario
Error Message
Trigger Condition
Required Action
EM-1
Contractor logs in with valid credentials but no portal access (cap exceeded, agency on Free/Basic, or agency suspended)
"Your access is revoked. Please contact the agency." (full-page)
Authentication succeeds; access evaluation fails.
Contractor contacts agency owner directly.
EM-2
Contractor with portal access clicks a cascade-locked event
"This event is unavailable. Please contact the agency."
Event tied to locked brand or locked project.
Contractor contacts agency.
EM-3
Contractor with portal access clicks a cascade-locked payment
"This payment is unavailable. Please contact the agency."
Payment tied to locked brand or locked project.
Contractor contacts agency.
EM-4
Client logs in but agency is suspended
"Please contact your agency." (full-page post-login)
Authentication succeeds; agency in Suspended state.
Client contacts agency.
EM-5
Client navigates to a project, invoice, contract, etc. that is cascade-locked
"Please contact your agency." (renders in place of entity content)
Entity tied to locked brand or locked project.
Client contacts agency.
EM-6
Contractor or client attempts password reset while portal access is revoked
Password reset flow is generally permitted per the underlying auth module; after successful password reset, the post-login state still renders the appropriate revocation message because the underlying access state has not changed.
Password reset flow runs; access state unchanged.
Contractor/client contacts agency.
EM-7
Contractor or client receives an email link to a locked entity
Email link redirects to the portal; portal renders the appropriate revocation message instead of the entity.
User clicks email deep-link to revoked content.
User contacts agency.
EM-8
Pixally super admin attempts a Gawd Portal action that fails for non-subscription reasons (network error, invalid state transition)
Standard Gawd Portal error message per the Gawd Portal Module FRD.
Action fails for technical or business-rule reasons.
Super admin retries or escalates per Pixally internal procedures.
8. Edge Cases
#
Edge Case
Expected System Behaviour
EC-1
Contractor invited to two agencies: Agency A (Studio) and Agency B (Free) attempts to log in.
Authentication succeeds; agency switcher inside the Contractor Portal lists Agency A only (where access is granted); Agency B is omitted because the contractor has no portal access there.
EC-2
Contractor in the same scenario: agency switcher logic.
If Agency A also revokes access (e.g., contractor cap or suspension), the switcher would have zero agencies and the system displays the full-page revocation message.
EC-3
Contractor's portal access is revoked due to Studio-to-Essentials downgrade contractor cap; their event from a now-completed past project is in the system.
The contractor cannot log in to view the past event because portal access is fully revoked; the underlying event data is preserved; if the agency upgrades back to Studio later, the contractor regains access including the past event.
EC-4
Contractor with full portal access on Studio agency; one specific event in their list is in a brand the agency just locked due to a manual plan change.
Events list renders all events; the locked-brand event is disabled with reduced opacity; click displays "This event is unavailable. Please contact the agency."
EC-5
Contractor with full portal access; their next scheduled payment is for a locked-brand project.
Payments list renders all payments; the locked-cascade payment is disabled; click displays the unavailable-payment message; contractor cannot dispute or follow up via the portal.
EC-6
Client whose only project is in a now-locked brand attempts Client Portal login.
Authentication succeeds; the client lands on a Dashboard that renders "Please contact your agency." because all of the client's content is cascade-locked; no other functionality is available.
EC-7
Client whose two projects span an accessible brand and a locked brand.
Authentication succeeds; Dashboard shows accessible-brand content normally; navigating to the locked-brand project displays "Please contact your agency." for that project only.
EC-8
Client logs in during agency's 28-day grace period after a failed payment.
Client experiences full access per the agency's paid plan; grace state preserves access per FRD 7. No revocation messages displayed.
EC-9
Client logs in during agency's cancellation-pending window.
Client experiences full access per the agency's current paid plan; the cancellation has not yet taken effect; no revocation messages displayed until cycle end.
EC-10
Client logs in on Day 1 after agency cancellation transitioned to Free (post-cycle-end).
Client Portal still accessible because Client Portal is included on Free; cascade-locked content (such as archived brands) shows "Please contact your agency." for those entities.
EC-11
Client portal user receives an email reminder for an invoice that is now cascade-locked.
Email link routes to portal; portal renders "Please contact your agency." instead of the invoice; client contacts agency to understand.
EC-12
Contractor completes a job, payment is approved by agency, agency downgrades to Basic before payment is processed.
Payment is cascade-locked because contractor record is no longer accessible on Basic; the underlying payment record is preserved; agency must upgrade to process the payment, or process the payment via an out-of-band method.
EC-13
Pixally super admin in Gawd Portal applies a manual plan upgrade to an agency.
Agency app and external portals see the new plan on next page navigation per FRD 9A Section 4.11; previously-revoked contractors regain access on next login attempt.
EC-14
Pixally super admin manually triggers reactivation for a Suspended agency.
Suspension override lifts; agency-side users see normal access on next navigation; client and contractor portals resume normal access on next login.
EC-15
Contractor logged in with valid session when agency owner downgrades the agency.
Contractor's currently-open portal page does not update in real time; on next portal page navigation or refresh, the access state re-evaluates and may transition to revoked or to disabled-event states per the new plan.
EC-16
Client logged in with valid session when agency owner cancels subscription.
Client's currently-open portal page does not update in real time; cancellation does not take effect until cycle end; client continues to see normal access until then; on cycle-end, on next page navigation, cascade-locked content displays the neutral message.
EC-17
Contractor whose record was deleted from the agency-side Contractors module attempts to log in.
This is a hard-delete scenario distinct from the cascade-lock scenario; the contractor's account on Pixally still exists but the linked agency relationship is deleted; the system displays the same neutral revocation message because the access evaluation finds no active link.
EC-18
Client whose record was deleted from the agency-side attempts to log in.
Similar to EC-17; the client's portal access is fully revoked because no agency relationship exists; client sees "Please contact your agency."
EC-19
Pixally super admin browses an agency that has been cancelled and is past the data retention window.
Gawd Portal displays the agency record with appropriate state indicators; data retention may have removed certain entity-level details per FRD 8 retention policy; super admin sees what data remains.
EC-20
Contractor opens their Account Settings while their portal access is fully revoked.
Account Settings is inaccessible because the revocation message blocks the entire portal post-login; contractor cannot reach Account Settings until access is restored.
EC-21
Multiple contractors share the same agency; one is in the retained-twenty cap, one is not.
The retained contractor logs in and sees full Dashboard; the cap-excluded contractor logs in and sees "Your access is revoked. Please contact the agency." The two contractors have completely different experiences for the same agency.
EC-22
Pixally super admin issues an emergency lockout from Gawd Portal (temporary suspension override for fraud or compliance).
Gawd Portal action propagates to all portals; agency users, contractors, and clients see the suspension treatment per their respective portal flows on next navigation.
EC-23
Contractor or client receives a notification email about a Pixally subscription event (e.g., agency cancelled).
Per the framework's neutral-language principle, the email content does not mention the agency's plan change or billing status; the email simply directs the user to contact the agency for status updates.
EC-24
Contractor with full access uses the W9 / Tax module to update tax info while the agency is in grace period.
W9 module functions normally because grace preserves agency's full access; updates are saved.
EC-25
Contractor's Account Settings stores a banking detail that triggers a payment workflow during a downgrade.
The banking info itself remains intact in Account Settings; the payment may be cascade-locked per Section 4.7; the agency must resolve the cascade before payment can proceed, but the contractor's banking info is not affected.
9. Acceptance Criteria
- The Contractor Portal evaluates access at login based on the linked agency's plan state and the contractor's record state per Section 4.1; portal users with no access see the full-page revocation message.
- The revocation message in the Contractor Portal reads "Your access is revoked. Please contact the agency." with no Upgrade button, no agency plan information, no support link, and no other actionable elements.
- Contractor Portal users with access see entity-level cascade locks on Events, Calendar entries, and Payments; locked entities are disabled with reduced opacity; click displays the appropriate noun-specific neutral message.
- Contractor Portal Dashboard, W9 Form / Tax Module, and Account Settings are accessible to all contractors with portal access regardless of cascade state on individual events or projects.
- The Client Portal is accessible to all clients of agencies in any active state (Free, Basic, Essentials, Studio, Trial, Grace, Cancellation Pending, post-cancellation Free); access is fully blocked only in Suspended state.
- The Client Portal applies cascade locks at the entity level; locked content renders the message "Please contact your agency." in place of entity content.
- Client Portal and Contractor Portal never display lock icons, upgrade popups, agency plan information, or any reference to billing state.
- The Gawd Portal has full unrestricted access to all agencies regardless of any specific agency's plan or state; super admin actions in Gawd Portal propagate to agency app and external portals on next navigation per FRD 9A Section 4.11.
- The deferred-update model applies to portals: portal users see updated access state on next portal page navigation or login, not in real time on a currently-open page.
- All revocation messages use the exact wording defined in Section 4.11 and use neutral language that does not reveal the underlying cause (downgrade, cap, cascade, suspension); the agency owner is the single point of contact for portal users.
- The Contractor Portal supports multi-agency contractors with an agency switcher that lists only agencies where access is currently granted.
- The Client Portal cascade-lock messaging is consistent across all entity types (projects, invoices, contracts, questionnaires, files); all use "Please contact your agency."
- Gawd Portal is not subject to the lock framework defined in FRD 9A.
10. Manual Test Cases
Manual test cases for this module are maintained in a separate Excel sheet for QA execution. Test cases follow the standard format (Test Case ID, Test Category, Module/Feature, Test Scenario, Preconditions, Test Steps, Test Data, Expected Result, Priority, Status) as used in the Proposal Module FRD.
Test Case Sheet Link: (To be generated after this final part of FRD 9B is approved.)
11. Dependencies
Module / Service
Dependency Type
Purpose
Impact if Unavailable
Subscription Impact Framework (FRD 9A)
Hard
Defines the cascade rule, deferred-update model, and the principle that portal users do not see lock visuals or upgrade popups.
Portal access evaluation cannot reference framework rules.
Subscription Plans Module (FRD 1)
Hard
Source of plan entitlements specifying that Client Portal is included in all plans and Contractor Portal access depends on contractor count caps per plan.
Access matrix cannot resolve.
Free Trial Module (FRD 2)
Hard
Trial state grants full Studio access; portal users see full access during trial.
Trial portal behavior may be incorrect.
Upgrade & Downgrade Module (FRD 3)
Hard
Cycle-end downgrade execution triggers contractor cap re-evaluation, brand cascade locks, and other state changes affecting portal access.
Portal access state may not transition correctly at cycle end.
Failed Payment Management (FRD 7)
Hard
Suspension state fully blocks Contractor and Client Portal access; grace state preserves access.
Suspended agencies' portal users may incorrectly retain or lose access.
Cancel Subscription (FRD 8)
Hard
Cancellation states drive transitions to Free that affect portal cascade and contractor cap; defines the contractor "access revoked" messaging convention.
Cancellation portal transitions may not apply correctly.
FRD 9B-1 — Core Workflow Modules
Hard
Defines agency-side Contractors Management, Brands Management, and Project entity behavior that drives cascade rules into portals.
Portal cascade state cannot resolve.
FRD 9B-2 — Templates & Communication Modules
Soft
Defines agency-side notification rules that trigger emails to contractors and clients; the emails routed via these rules are subject to the neutral-language principle.
Limited impact on portals directly.
FRD 9B-3 — Finance, Reports, Settings & Integrations
Soft
Cross-references for Account Settings agency-side and any data shared with portal Account Settings.
Limited impact.
Contractor Portal Module FRD
Hard
Defines the full Contractor Portal functional behavior outside subscription gating.
Module-specific behavior gaps.
Client Portal Module FRD
Hard
Defines the full Client Portal functional behavior outside subscription gating.
Module-specific behavior gaps.
Gawd Portal Module FRD
Hard
Defines the Gawd Portal's complete management capabilities for Pixally super admins.
Gawd Portal-specific behavior gaps.
Pixally Authentication Service
Hard
Authenticates contractors, clients, and Pixally super admins for their respective portals.
Portals cannot operate.
Pixally Internal Authorization Service
Hard
Restricts Gawd Portal access to authorized Pixally personnel.
Gawd Portal access control cannot be enforced.
Calculator Link
https://sehalm-aveosoft.github.io/pixally-billing-calculator/
Deprecated
0. MASTER TABLE OF CONTENTS (20 Features)
MASTER TABLE OF CONTENTS (20 Features)
References
- Figma Link: Click Here
1. Module 1 — Subscription Lifecycle
Defines the complete customer journey from trial → paid subscription → cancellation → retention → restoration → permanent deletion.
Includes trial rules, verification requirements, state transitions, retention timers, restoration conditions, data deletion, and related notifications.
2. Module 2 — Plan Management (Upgrade, Downgrade, Billing Cycle Switch)
Controls plan changes, including:
-
Immediate upgrades with proration
-
Scheduled downgrades with resource-limits validation
-
Billing-cycle switches (monthly ↔ annual)
-
Stripe subscription updates, proration rules, upgrade overrides, downgrade scheduling, and cycle-change logic.
3. Module 3 — Failed Payment & Suspension System
Manages payment failures through a defined 21-day grace period with automated retries (Days 0, 2, 4, 7, 14, 21).
Includes:
-
Past due state
-
Suspension at Day 21
-
Access restrictions during suspension
-
Restoration upon payment success
-
Integrated Stripe webhook response handling.
4. Module 4 — Add-Ons, Extra Seats, Discounts & Tax Management
Defines all price modifiers and add-ons:
-
Extra seat purchases ($9/seat/month) with prorated billing
-
Discount code validation and restrictions
-
Recurring and fixed discounts
-
Stripe Tax calculation (global tax compliance, reverse-charge, USD enforcement)
5. Module 5 — Access Control & Limits Enforcement
Defines subscription-aware access and plan-based resource enforcement for:
-
Projects
-
Brands
-
Seats
-
Contractors
-
Multi-agency contractor access
Also includes downgrade-limit validations, limit-enforcement modals, overrides, and concurrency controls.
6. Module 6 — Billing Dashboard & Summary View
Central hub for all billing visibility.
Includes:
-
Subscription summary
-
Renewal amounts
-
Payment method status
-
Usage metrics
-
Invoice snapshot
-
Real-time state banners (active, past_due, suspended, canceled)
Provides quick actions for upgrades, seat purchases, payment method updates, and invoice history.
7. Module 7 — Payment Method Management
Defines all secure card-handling interactions with Stripe:
-
Add payment method
-
Set default
-
Remove non-default methods
-
Card validation & expiration handling
-
Stripe Elements integration
Ensures PCI-compliant storage and billing readiness.
8. Module 8 — Billing Notifications & Alerts
Covers all billing-related communications:
-
Payment success & failures
-
Retry alerts
-
Suspension warnings
-
Trial ending notices
-
Renewal reminders
-
Invoice-ready alerts
Delivered via email, in-app messages, and push notifications.
9. Module 9 — Billing API & Webhook Processing
Backend engine that synchronizes Stripe with Pixally.
Handles:
-
Payment succeeded
-
Payment failed
-
Subscription updates
-
Cancellation
-
Refunds
-
Invoice creation
Includes signature validation, idempotency checks, raw payload storage, and reconciliation routines.
10. Module 10 — Super Admin (God Mode) Billing Controls
Internal control panel for Pixally leadership/support.
Capabilities include:
- Adding free days
- Manual discounts
- Forced payment retries
- Plan overrides
- Status overrides (activate, suspend, cancel)
- Hard sync with Stripe
All actions require justification and are fully logged for compliance.
1. SUBSCRIPTION LIFECYCLE
MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)
1. Module Overview
Module Name: Subscription Lifecycle Management
**Purpose:
**This module defines the complete end-to-end lifecycle of an agency subscription from initial free trial creation, through paid activation, cancellation, retention, and restoration. It governs how a user enters the system, how they move between lifecycle states, and how the system enforces billing and access rules across each phase.
Business Goals:
-
To provide a reliable and predictable subscription lifecycle flow.
-
To ensure accurate state transitions governed by Stripe billing events and internal rules.
-
To retain user data for the legally required window and enable frictionless restoration.
-
To ensure the platform behaves consistently across trial, paid, canceled, suspended, retained, and restored states.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Lifecycle-Specific)
Agency Owner
Can start trial, purchase subscription, cancel subscription, and restore subscription within the retention window.
Admin
Read-only access to subscription status; cannot initiate lifecycle transitions.
Team Member
Access determined by subscription state; no lifecycle actions permitted.
Contractor
Access determined at agency level; loses access upon cancellation or suspension.
Client
Access restricted when subscription is canceled or suspended.
Super Admin
Can override lifecycle states, extend retention windows, or manually restore accounts.
3. User Flow
High-Level Lifecycle Sequence:
-
User signs up and completes email verification.
-
System creates a 14-day free trial and displays trial dashboard.
-
User may add a payment method at any time during trial.
-
User initiates paid subscription purchase, enters payment method (if not already stored), and completes payment.
-
Subscription enters active paid state with full feature access.
-
User may later cancel subscription, triggering immediate access removal.
-
System enters a 365-day retention period where data remains stored but inaccessible.
-
Within 365 days, user may restore subscription, triggering immediate access reinstatement.
-
After Day 365, system permanently deletes all agency data and disables login.
4. Functional Logic
4.1 Trial Initiation
4.1.1 The agency owner initiates account creation through the signup form containing name, email, password, and optional payment method fields.
4.1.2 The system validates the email format and ensures it is not already associated with an existing account.
4.1.3 If the email is unverified, the system sends a verification link and postpones trial creation until verification occurs.
4.1.4 Upon successful verification, the system creates the trial record, sets the start timestamp, and calculates the end timestamp at 11:59 PM in the user’s local timezone on Day 14.
4.1.5 The system schedules trial reminder notifications for Days 10, 12, 13, and 14.
4.2 Optional Payment Method Collection During Trial
4.2.1 If the user adds a payment method during signup or trial, the frontend collects card data through Stripe Elements.
4.2.2 Stripe tokenizes the card, attaches it to the Stripe Customer, and the system stores only the card metadata (brand, last4, expiry).
4.2.3 No charge is performed until the user explicitly purchases a paid plan.
4.3 Trial Experience and Restrictions
4.3.1 The user receives a dashboard banner showing the trial countdown.
4.3.2 The system enforces trial-level restrictions that differentiate free trial users from paid subscribers (e.g., limitations in contractors or other modules if applicable).
4.3.3 Trial does not automatically convert to a paid plan; the user must explicitly initiate purchase.
4.4 Paid Subscription Activation
4.4.1 The agency owner selects a paid plan and billing cycle (monthly or annual), after which the system checks for a valid payment method.
4.4.2 If no payment method exists, the system displays a modal requesting card entry via Stripe Elements.
4.4.3 The system calculates the final payable amount using base plan price, first-year promotions, any valid discount code, and Stripe Tax.
4.4.4 The system triggers a Stripe payment; on success, the system updates the subscription status to active, sets the plan, billing cycle, and renewal date.
4.4.5 On payment success, the system unlocks all paid features immediately and sends a confirmation email with invoice details.
4.4.6 If the payment fails, no subscription is activated and the user remains in the trial or free state.
4.5 Cancellation Logic
4.5.1 The user initiates cancellation from the subscription settings page.
4.5.2 The system displays a mandatory cancellation reason modal, requiring selection from predefined reasons or additional notes when “Other” is selected.
4.5.3 Upon confirmation, the system immediately disables access to all platform features except the Billing Page.
4.5.4 The system calls the Stripe API to cancel the subscription.
4.5.5 The system transitions the subscription status to canceled, records the cancellation timestamp, and calculates the retention expiration timestamp (canceled_at + 365 days).
4.5.6 The system sends a cancellation confirmation email outlining the retention policy and restoration instructions.
4.6 Retention Period Management (Day 1–364)
4.6.1 Retention mode begins immediately after cancellation and continues for 365 days.
4.6.2 During retention, the agency owner may log in but is always redirected to the Billing Page for restoration actions.
4.6.3 Team members, contractors, and clients immediately lose all access to agency resources.
4.6.4 All agency data (projects, files, brands, galleries, contractors, invoices metadata) remains stored but inaccessible.
4.6.5 On Day 360 at 9:00 AM local time, the system sends a 5-day deletion warning email.
4.6.6 On Day 364 at 9:00 AM, the system sends a final deletion warning email.
4.7 Hard Deletion Logic (Day 365)
4.7.1 The system automatically triggers a deletion job at 11:59 PM local time on Day 365.
4.7.2 The deletion job removes all agency data including projects, brands, team assignments, contractor mappings, automations, galleries, and stored assets.
4.7.3 The system updates the subscription status to permanently_deleted and disables all user logins.
4.7.4 Any bookmarked client or contractor links display a standardized “Agency no longer exists” message.
4.8 Restoration Logic (Within 365 Days)
4.8.1 Restoration is only allowed if the current date is earlier than the retention expiration timestamp.
4.8.2 If no payment method exists, the system requires card entry before proceeding.
4.8.3 The system creates a new Stripe subscription using the previous plan and billing cycle.
4.8.4 On successful payment, the system updates subscription_status to active, clears canceled_at and retention fields, and restores all access immediately.
4.8.5 All team members, contractors, and client-facing features regain access automatically.
4.8.6 If payment fails, the system displays an error message and remains in canceled state.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
trial_start_at
datetime
Required; set after email verification; user timezone.
trial_end_at
datetime
Must equal trial_start_at + 14 days at 11:59 PM local.
subscription_status
enum
Must be one of: trial, active, past_due, suspended, canceled, permanently_deleted.
plan
enum
Required for paid subscriptions; must match available plans.
billing_cycle
enum
Required for paid; monthly or annual.
canceled_at
datetime
Auto-set on cancellation; cannot be null for canceled state.
data_retention_expires_at
datetime
Must equal canceled_at + 365 days.
previous_plan
enum
Used for restoration; required if restoration is attempted.
payment_method_on_file
boolean
Must be true to activate paid subscription or restore.
stripe_customer_id
string
Required for all billing actions.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success System Behaviour
Trial Created
“Your 14-day free trial has started.”
Email verified; trial timestamps generated.
Redirect to trial dashboard; schedule reminders.
Payment Method Added
“Payment method saved successfully.”
Stripe token attached successfully.
Mark payment_method_on_file = true; update UI.
Paid Subscription Activated
“Your subscription is now active.”
Stripe charge succeeded.
Unlock paid features; send invoice email.
Cancellation Completed
“Your subscription has been canceled.”
Stripe cancellation succeeded.
Restrict access; set retention window; send cancellation email.
Restoration Successful
“Your subscription has been restored.”
Stripe payment succeeded within 365 days.
Restore access; clear retention fields; send confirmation.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Invalid signup data
“Please enter valid account details.”
Invalid name, email, or password.
Correct fields and resubmit.
Email verification not completed
“Please verify your email to continue.”
User attempts to access dashboard before verification.
Verify email.
Trial creation failure
“We couldn’t start your trial. Try again.”
DB or internal failure during trial creation.
Retry or contact support.
Payment failure
“Your payment could not be processed.”
Stripe declines charge during paid subscription or restoration.
Enter new payment method.
Cancellation API error
“Unable to cancel your subscription. Try again.”
Stripe cancel call fails.
Retry later.
Restoration expired
“Your account can no longer be restored.”
Attempt to restore after Day 365.
Must create new subscription.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-LC-001
User verifies email after long delay
Trial begins only at verification; schedule reminders based on actual verification timestamp.
EC-LC-002
User adds payment method but Stripe tokenization fails
Retry tokenization; allow user to continue trial without card.
EC-LC-003
User cancels subscription while a downgrade was previously scheduled
Cancellation overrides all pending lifecycle events.
EC-LC-004
User attempts restoration at 11:58 PM on Day 365
Restoration must succeed as long as timestamp < expiration.
EC-LC-005
Deletion job partially fails due to API error
Retry deletion segments until completed; log failure and resolution.
9. Acceptance Criteria
-
The system must require email verification before creating a trial.
-
Trial duration must always be 14 days ending at 11:59 PM local time.
-
Paid subscription activation must only occur after successful Stripe payment.
-
Cancellation must be immediate with no remaining feature access except Billing.
-
Retention must always run for exactly 365 days from cancellation.
-
Restoration must only be allowed within the 365-day retention period.
-
Hard deletion must permanently remove all agency data on Day 365.
-
All state transitions must be logged and traceable.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Billing API
Create, cancel, and restore subscriptions
Subscription cannot activate or update.
Stripe Payments
Charge for paid plan or restoration
Paid activation/restoration cannot complete.
Stripe Customer API
Store and manage payment methods
Cannot attach cards or process payments.
Email Service
Send verification, trial reminders, cancellation and deletion warnings
Users may miss critical lifecycle information.
Database
Store lifecycle states, timestamps, and retention metadata
Lifecycle transitions cannot be persisted.
Scheduler / Cron
Trigger reminders and deletion jobs
Reminders or deletion may not execute correctly.
2. PLAN MANAGEMENT
MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)
1. Module Overview
Module Name: Plan Management
**Purpose:
**This module governs all changes to an agency’s active subscription plan, including upgrading to higher tiers, scheduling downgrades to lower tiers, and switching between monthly and annual billing cycles. It ensures all plan changes follow financial, operational, and access-control rules, while maintaining consistency with Stripe billing and internal resource limits.
Business Goals:
-
To enable frictionless upgrades that unlock additional features instantly.
-
To enforce safe downgrades by validating resource limits before scheduling a plan reduction.
-
To support billing-cycle flexibility while maintaining accurate proration and renewal alignment.
-
To preserve financial integrity across Stripe charges, credits, taxes, and proration adjustments.
-
To ensure the platform always reflects the correct plan state and feature entitlements.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Plan Management)
Agency Owner
Perform upgrades, schedule downgrades, switch billing cycles, and manage required resource selections.
Admin
Read-only access to plan details; cannot perform upgrades or downgrades.
Team Member
No access to plan management.
Contractor
No access.
Client
No access.
Super Admin
Can override plan changes, perform immediate downgrades, bypass proration, and adjust limits manually.
3. User Flow
High-Level Plan Change Sequence:
-
User opens Subscription → Manage Plan.
-
System displays the current plan, available upgrade options, downgrade options, and billing cycle controls.
-
User selects an upgrade, downgrade, or billing cycle change.
-
System validates payment method status and resource usage as required.
-
For upgrades and monthly→annual switches, system processes a Stripe charge immediately.
-
For downgrades and annual→monthly switches, system schedules changes for the next renewal.
-
System updates plan metadata and displays appropriate banners if future changes are pending.
-
System logs all plan-change actions and sends confirmation emails.
4. Functional Logic
4.1 Upgrade Logic
4.1.1 Eligibility Validation
4.1.1.1 The system confirms that the selected plan is higher than the current plan.
4.1.1.2 The billing cycle remains unchanged; upgrades cannot alter cycle type.
4.1.1.3 Scheduled downgrades are automatically canceled when an upgrade is initiated.
4.1.2 Payment Method Validation
4.1.2.1 If the user does not have a saved payment method, the system displays the Add Payment Method modal.
4.1.2.2 The system tokenizes new card data using Stripe Elements and attaches it to the Stripe Customer.
4.1.2.3 The upgrade cannot proceed without a valid stored payment method.
4.1.3 Proration Calculation
4.1.3.1 The system determines the price difference between the current plan and upgraded plan.
4.1.3.2 The proration amount is calculated using the formula:
(price difference × remaining cycle days) ÷ total cycle days.
4.1.3.3 If the proration amount is below Stripe’s minimum charge threshold, the minimum charge is applied.
4.1.3.4 Stripe Tax is applied to the calculated or minimum charge.
4.1.4 Charge and Activation
4.1.4.1 The system initiates a Stripe payment for the prorated amount.
4.1.4.2 On payment success, the system updates the plan tier, updates plan_start_at to the current timestamp, and keeps next_renewal_at unchanged.
4.1.4.3 All features associated with the higher tier are unlocked immediately.
4.1.4.4 The system sends an upgrade confirmation email with invoice and proration details.
4.1.5 Upgrade Failure Handling
4.1.5.1 If Stripe returns a failed payment response, the upgrade is not applied.
4.1.5.2 The system displays a payment failure message and prompts the user to update their payment method.
4.1.5.3 No changes are made to plan tier, limits, or billing cycle.
4.2 Downgrade Logic
4.2.1 Eligibility and Scheduling
4.2.1.1 Downgrades can only target plans lower than the active plan.
4.2.1.2 All downgrades are scheduled for the next renewal date; no immediate downgrades are allowed.
4.2.1.3 The system sets scheduled_downgrade_plan and scheduled_downgrade_date to next_renewal_at.
4.2.2 Resource Limit Evaluation
4.2.2.1 The system evaluates current usage of Projects, Brands, Team Members, Contractors, and Automations against the limits of the target downgraded plan.
4.2.2.2 If the agency exceeds any limit, the system displays a Resource Selection Modal.
4.2.2.3 The user must select which projects, brands, team members, or contractors to retain based on lowered limits.
4.2.2.4 The system validates the selections before allowing downgrade scheduling to continue.
4.2.3 Scheduled Downgrade Banner
4.2.3.1 After scheduling, the system displays a persistent banner:
“Your plan will downgrade to {plan} on {date}.”
4.2.3.2 The banner remains until the renewal occurs or the downgrade is overridden by an upgrade.
4.2.4 Downgrade Execution
4.2.4.1 At the renewal timestamp, the system updates the plan to the downgraded tier.
4.2.4.2 The system restricts access according to new limits, deactivating excess resources, disabling automations (if applicable), and deactivating additional team seats.
4.2.4.3 The renewal invoice is generated using the downgraded plan price with no proration.
4.3 Billing Cycle Switch Logic
4.3.1 Monthly → Annual Conversion
4.3.1.1 When switching from monthly to annual, the change is immediate.
4.3.1.2 The system calculates unused monthly credit based on remaining days in the current cycle.
4.3.1.3 The adjusted annual price = annual price – unused credit.
4.3.1.4 If no payment method exists, the Add Payment Method modal is displayed.
4.3.1.5 The system charges the adjusted annual price immediately.
4.3.1.6 Upon successful payment, billing_cycle is updated to annual and next_renewal_at is set to today + 365 days.
4.3.2 Annual → Monthly Conversion
4.3.2.1 Switching from annual to monthly cannot occur immediately and must be scheduled.
4.3.2.2 The system sets scheduled_cycle_change = “monthly” and scheduled_cycle_change_date = next_renewal_at.
4.3.2.3 No charge or refund occurs at the time of scheduling.
4.3.2.4 The system displays a banner:
“Your billing cycle will switch to monthly on your next renewal date: {date}.”
4.3.3 Execution of Scheduled Billing Cycle Change
4.3.3.1 On the renewal date, the system updates billing_cycle to monthly.
4.3.3.2 The renewal invoice is created using monthly rates and applied discounts or promotions.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
selected_upgrade_plan
enum
Must be higher than current plan.
selected_downgrade_plan
enum
Must be lower than current plan.
billing_cycle
enum
Must be monthly or annual.
unused_monthly_credit
number
Required for monthly→annual calculation; must be ≥ 0.
adjusted_annual_price
number
Calculated as annual price minus unused credit.
scheduled_downgrade_date
datetime
Must equal next_renewal_at.
scheduled_cycle_change
enum
Allowed: monthly only.
scheduled_cycle_change_date
datetime
Must equal next renewal date.
payment_method_on_file
boolean
Must be true for upgrades and monthly→annual.
proration_amount
number
Must follow Stripe formula and minimum-charge rule.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Upgrade Completed
“Your plan has been upgraded.”
Stripe payment succeeded.
Unlock features immediately; send confirmation email.
Downgrade Scheduled
“Your downgrade has been scheduled for your next renewal.”
Resource limits validated and user confirmed.
Display downgrade banner.
Monthly → Annual Switch
“Your billing cycle is now annual.”
Payment succeeded.
Update renewal date to 12 months from today.
Annual → Monthly Switch Scheduled
“Your billing cycle will switch to monthly on your next renewal.”
User confirmed scheduling.
Display cycle-change banner.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Invalid upgrade selection
“Select a higher-tier plan to continue.”
User selects equal or lower plan.
Choose a valid upgrade.
Missing payment method
“Add a payment method to continue.”
Upgrade or monthly→annual initiated without a stored card.
Add payment method.
Stripe payment failure
“We could not process your payment. Try again.”
Upgrade or billing cycle charge fails.
Update payment method and retry.
Resource selection incomplete
“Please complete all required resource selections.”
User exceeds limits for downgrade.
Select allowed resources.
Immediate annual→monthly attempt
“You can switch to monthly at your next renewal date.”
User attempts immediate cycle change.
Accept scheduled change.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-PM-001
Upgrade initiated twice rapidly
System enforces idempotency; only one charge and plan change occur.
EC-PM-002
Scheduled downgrade exists when upgrade occurs
Upgrade overrides and deletes the scheduled downgrade.
EC-PM-003
Stripe webhook delayed after upgrade
Cron or webhook sync reconciles plan state within 15 minutes.
EC-PM-004
User exceeds multiple limits during downgrade
Resource Selection Modal displays all limit groups requiring resolution.
EC-PM-005
Billing cycle switch scheduled and user upgrades
Upgrade proceeds; cycle-change scheduling remains valid unless policy dictates otherwise.
9. Acceptance Criteria
-
Users must be able to upgrade only to higher-tier plans.
-
All upgrades must charge prorated amounts following Stripe’s formula and minimum thresholds.
-
All downgrades must be scheduled for the next renewal; immediate downgrades are prohibited.
-
Downgrade scheduling must require resolving all exceeded resource limits.
-
Monthly→annual switches must trigger immediate charges and cycle activation.
-
Annual→monthly switches must always be scheduled, never immediate.
-
Banners must clearly indicate scheduled downgrades or billing-cycle changes.
-
All plan changes must be logged and confirmed via email.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Billing
Update subscription plan and items
Upgrades/downgrades cannot be applied.
Stripe Payments
Charge prorated and cycle-switch fees
User cannot upgrade or switch billing cycle.
Stripe Tax
Compute accurate tax on prorated charges
Incorrect or missing tax calculations.
Resource Limit Service
Evaluate usage against plan limits
Downgrades cannot be validated.
DB
Store scheduled plan changes and plan states
Plan changes cannot be persisted.
Email Service
Send plan-change notifications
Users may miss confirmations.
3. FAILED PAYMENT & SUSPENSION SYSTEM
MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM
1. Module Overview
Module Name: Failed Payment & Suspension System
**Purpose:
**This module governs all subscription behaviors triggered after a failed renewal payment. It defines the 21-day grace period, retry schedule, notifications, access restrictions, suspension workflow, and restoration upon successful payment.
Business Goals:
-
To ensure predictable, automated handling of failed renewal charges through Stripe and internal retry mechanisms.
-
To protect platform integrity by restricting access to non-paying agencies while allowing owner-level remediation.
-
To minimize involuntary churn through clear messaging, retry attempts, and immediate restoration upon successful payment.
-
To maintain consistent subscription states that synchronize fully with Stripe billing events.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Failed Payment & Suspension)
Agency Owner
Update payment method, trigger restoration, view banners, resolve past-due or suspended status.
Admin
May view billing warnings if permitted; cannot update billing or resolve suspension.
Team Member
Access automatically restricted during suspension; no ability to resolve payment issues.
Contractor
Access removed for the affected agency during past_due or suspended states (other agencies remain accessible).
Client
All client-facing links (galleries, questionnaires) disabled during suspension.
Super Admin
May force retry, override suspension, or grant temporary extensions.
3. User Flow
High-Level Workflow After Payment Failure:
-
Stripe renewal attempt fails → webhook triggers system update to past_due.
-
System starts 21-day grace period and displays Past-Due Banner.
-
Retry attempts occur on Days 0, 2, 4, 7, 14, and 21.
-
User may update payment method at any time to retry charge immediately.
-
If a retry succeeds → subscription returns to active and access is restored.
-
If all attempts fail → system schedules suspension at 11:59 PM on Day 21.
-
After suspension, only Billing access remains available.
-
Successful payment at any time during or after suspension restores full access.
4. Functional Logic
4.1 Initial Failed Payment Event
4.1.1 Stripe sends invoice.payment_failed webhook to the system.
4.1.2 The system updates subscription_status to past_due immediately.
4.1.3 The system initializes grace_period_day = 0 and retry_attempt_count = 1.
4.1.4 The system displays a Past-Due Banner to the agency owner after login, explaining urgency.
4.1.5 The system logs the failure event for audit and triggers a payment-failed notification.
4.2 Retry Schedule Logic
4.2.1 The system schedules retries on Days 0, 2, 4, 7, 14, and 21 relative to the original failure date.
4.2.2 On each scheduled attempt, the system retrieves the most recent payment method from Stripe.
4.2.3 The system attempts to charge the outstanding invoice.
4.2.4 If the retry succeeds, the system immediately sets subscription_status = active, clears grace_period_day, removes banners, and restores access.
4.2.5 If the retry fails, retry_attempt_count increments and the system updates grace_period_day accordingly.
4.2.6 The system logs each retry attempt and sends updated failed-payment notifications.
4.3 User-Initiated Payment Method Update
4.3.1 The agency owner may update their card at any time during the grace period.
4.3.2 Upon card update, Stripe attempts to charge the outstanding invoice automatically.
4.3.3 If the payment succeeds, the past-due state is immediately removed and subscription_status updates to active.
4.3.4 If the payment fails, the system prompts the user to add a different card.
4.4 Suspension Trigger Logic
4.4.1 The system performs the final retry on Day 21 in the morning.
4.4.2 If this attempt fails, the system schedules suspension at 11:59 PM local time of Day 21.
4.4.3 At the suspension timestamp, subscription_status updates to suspended.
4.4.4 The system removes access for all non-owner users and restricts owner access to only the Billing Page.
4.4.5 Contractors lose access to this agency but retain access to other agencies associated with their global identity.
4.4.6 Automations, jobs, and scheduled tasks pause until suspension is resolved.
4.5 Post-Suspension Behaviour
4.5.1 The agency owner may still log in but is immediately redirected to the Billing Page.
4.5.2 All dashboards, automations, media assets, and project functionality remain blocked.
4.5.3 Client and contractor external links return an “Access temporarily unavailable” message.
4.5.4 Super Admins may perform manual billing overrides or temporary reinstatements.
4.6 Restoration After Successful Payment
4.6.1 When payment succeeds—either initiated by user card update or system retry—the system sets subscription_status back to active.
4.6.2 All past-due or suspension banners clear automatically.
4.6.3 All user access (owner, team, contractors, clients) is fully reinstated.
4.6.4 Automations resume and queued jobs restart where applicable.
4.6.5 The system logs restoration and sends a payment-success notification.
4.7 State Synchronization and Auditing
4.7.1 All events (payment_failed, retry_attempted, retry_success, retry_failure, suspension_triggered, subscription_restored) are recorded in audit logs.
4.7.2 If Stripe webhook delays occur, the system reconciles subscription states through periodic cron jobs.
4.7.3 The system ensures that UI always reflects the updated subscription state, even during webhook delays.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
subscription_status
enum
Must be one of: active, past_due, suspended.
grace_period_day
integer
Must be between 0 and 21 inclusive.
retry_attempt_count
integer
Auto-incremented; must reflect number of attempts.
last_retry_at
datetime
Updated after each attempt; must be valid timestamp.
payment_method_on_file
boolean
Must be true for retries; otherwise user must add card.
suspension_at
datetime
Must equal Day 21 at 11:59 PM local.
card_token
string
Required when user updates payment method.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Payment retried successfully
“Your payment was successful and your subscription is now active.”
Stripe returns success on any retry.
Removes past-due/suspension banners; restores access.
Payment method updated
“Your payment method has been updated.”
New card token accepted by Stripe.
Stripe auto-attempts payment; may trigger restoration.
Suspension lifted
“Your account has been reactivated.”
Payment succeeds while suspended.
Full feature access restored.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Initial payment failure
“Your payment of {amount} USD failed. Update your card to avoid suspension.”
invoice.payment_failed event received.
Update card.
Final retry failure
“Your account will be suspended today at 11:59 PM unless payment is completed.”
Final retry on Day 21 fails.
Update payment method urgently.
Suspended state access
“Your account is suspended due to non-payment.”
User attempts to access non-billing pages while suspended.
Provide new valid payment method.
Expired card
“Your saved card has expired. Add a new payment method.”
Stripe detects expired card during retry.
Add new card.
Stripe API unreachable
“Unable to process payment. Try again shortly.”
Stripe outage or network error.
Retry later.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-FPS-001
User updates card at 11:58 PM on Day 21
System retries immediately; if successful, suspension is prevented.
EC-FPS-002
Stripe webhook delayed
Cron sync reconciles state within 15 minutes.
EC-FPS-003
User switches timezone during grace period
Suspension still occurs using original timezone.
EC-FPS-004
Payment succeeds but UI does not update
Background webhook sync corrects UI state.
EC-FPS-005
User attempts restoration without valid card
System blocks restoration and prompts card update.
9. Acceptance Criteria
-
Subscription must enter past_due immediately upon failed Stripe renewal.
-
Retry schedule must execute on Days 0, 2, 4, 7, 14, and 21.
-
Suspension must occur at exactly 11:59 PM local time on Day 21 if all retries fail.
-
Past-due and suspension banners must display correctly and consistently.
-
User access must be restricted during suspension except for Billing Page access.
-
Successful payment must immediately restore subscription and access.
-
All lifecycle events must be logged.
-
System must remain fully synchronized with Stripe through webhook or cron processes.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Payments
Process renewal and retry charges
Payment cannot succeed; subscription stuck in past_due/suspended.
Stripe Webhooks
Update system on failures or successes
State may not sync; inconsistent subscription behavior.
Cron Scheduler
Execute retry attempts and suspension timers
Retry schedule and suspension timing may fail.
DB
Store subscription state, timestamps, retry count
Grace logic cannot be maintained.
Email Service
Notify user of failures, retries, and suspension
User may remain unaware of payment issues.
4. ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEM
MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT
1. Module Overview
Module Name: Add-Ons, Extra Seats, Discounts & Tax Management
**Purpose:
**This module defines the rules, workflows, and system behaviors for add-on purchases (specifically extra seats), discount code validation and application, and tax calculation using Stripe Tax. It governs how the platform calculates pricing, applies discounts, manages prorated add-on charges, and ensures all taxation follows Stripe’s jurisdictional requirements.
Business Goals:
-
To enable agencies to scale team capacity through frictionless purchase of additional seats.
-
To ensure accurate and compliant financial calculations through Stripe Tax and standardized pricing rules.
-
To support promotions and discount codes with strict validation, preventing misuse.
-
To maintain a unified pricing engine that ensures consistency across upgrades, add-ons, and renewals.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Add-Ons, Discounts, Tax)
Agency Owner
Purchase extra seats, apply discount codes during checkout or upgrade flows, provide tax information.
Admin
View seat usage; cannot purchase seats or apply discounts.
Team Member
No access to billing add-ons.
Contractor
No access.
Client
No access.
Super Admin
Override seat counts, apply/remove discounts directly, update tax settings for support purposes.
3. User Flow
High-Level Add-On & Price Adjustment Sequence:
-
User opens Billing → Seats or Checkout / Upgrade screen.
-
System displays current seat usage, pricing, tax requirements, and discount input field (if applicable).
-
User purchases extra seats or enters a discount code.
-
System validates payment method and calculates proration and tax.
-
Stripe processes the charge instantly.
-
System updates seat availability or discount assignment.
-
User receives confirmation email and updated billing details.
4. Functional Logic
4.1 Extra Seat Management Logic
4.1.1 Seat Purchase Initiation
4.1.1.1 The user navigates to Billing or Team Settings and selects “Add Seat.”
4.1.1.2 The system displays current seat usage (used seats vs. included + extra seats).
4.1.1.3 The system validates whether a payment method exists; if missing, it requires the user to add one.
4.1.2 Proration Calculation
4.1.2.1 Each extra seat costs $9/month in USD.
4.1.2.2 The system determines remaining days in the current billing cycle.
4.1.2.3 Proration amount = 9 × (remaining_days ÷ total_cycle_days).
4.1.2.4 If the prorated charge is below $0.50, the minimum charge of $0.50 is applied.
4.1.2.5 The prorated amount is passed to Stripe with tax calculation parameters.
4.1.3 Stripe Subscription Item Update
4.1.3.1 The system increments the subscription item quantity associated with extra seats.
4.1.3.2 Stripe immediately generates an invoice for the prorated amount.
4.1.3.3 On payment success, the system increments extra_seat_count and updates seat availability.
4.1.4 Post-Purchase Behavior
4.1.4.1 The newly purchased seat becomes available immediately for team member assignment.
4.1.4.2 The system logs the event and sends a receipt email.
4.1.4.3 If payment fails, no seat is added and the system displays an error message.
4.2 Discount Code & Promotion Logic
4.2.1 Discount Code Input Validation
4.2.1.1 The system validates discount code format (alphanumeric + hyphens; 3–30 characters).
4.2.1.2 The system checks that the code is not expired and has not exceeded customer redemption limits.
4.2.1.3 The system retrieves discount metadata from Pixally DB and Stripe Coupons.
4.2.2 Restriction Validation
4.2.2.1 The system validates plan-tier eligibility (e.g., code only valid for annual plans).
4.2.2.2 The system checks billing cycle restrictions if applicable.
4.2.2.3 If code is marked first-time-only, the system checks whether the customer has previously redeemed a discount.
4.2.2.4 If stacking is not permitted (default), the system blocks application if another discount is active.
4.2.3 Discount Application Logic
4.2.3.1 If the code is percentage-based, the system calculates discount = subtotal × percentage.
4.2.3.2 If fixed-amount, discount = fixed USD amount.
4.2.3.3 If trial-extension code, the system adjusts trial_end_at accordingly.
4.2.3.4 For recurring promotions, the system assigns remaining_cycles and decrements them at each renewal.
4.2.3.5 The system applies the Stripe coupon to the subscription or payment intent.
4.2.4 Discount Behavior Across Lifecycle Events
4.2.4.1 Discounts persist only while the subscription remains active.
4.2.4.2 Canceling the subscription permanently removes all active and future-cycle discounts.
4.2.4.3 Upgrades and prorations use new plan prices but apply the existing discount percentage or amount proportionally.
4.3 Tax Calculation Logic (Stripe Tax)
4.3.1 Billing Address Collection
4.3.1.1 The system requires the user to provide country, state, city, and postal code before completing any paid checkout.
4.3.1.2 The system prompts the user to enter or update billing address if missing or invalid.
4.3.2 Tax Determination
4.3.2.1 The system calls Stripe Tax to determine jurisdiction-specific tax rates.
4.3.2.2 Stripe returns tax percentage, tax amount, and jurisdiction metadata.
4.3.2.3 The system always charges in USD, regardless of user region.
4.3.3 Reverse-Charge Logic (VAT / GST)
4.3.3.1 If user provides a tax ID, the system validates it using Stripe.
4.3.3.2 If reverse-charge applies, tax is removed from the invoice and a “VAT/GST Reverse Charge – 0%” note is applied.
4.3.3.3 The system stores the tax ID and validation status.
4.3.4 Tax Storage & Reporting
4.3.4.1 The system stores tax_amount, tax_rate, subtotal, and final total for all invoices.
4.3.4.2 Tax details appear in invoice breakdown and history.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
extra_seat_count
integer
Must be ≥ 0; increments only on successful payment.
proration_amount
decimal
Must follow proration formula; minimum $0.50.
discount_code
string
Alphanumeric + hyphens; 3–30 chars.
discount_type
enum
percentage / fixed / free_trial.
percent_off
decimal
Must be 0–100 if used.
amount_off
decimal
Must be ≥ 0 if used.
recurring_cycles
integer
Optional; must decrement at renewal.
tax_rate
decimal
Returned by Stripe Tax.
tax_amount
decimal
Must be ≥ 0.
billing_country
string
Required for all paid operations.
tax_id
string
Optional; must validate when provided.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Seat Added Successfully
“Your extra seat has been added.”
Payment successful.
Seat available immediately; receipt emailed.
Discount Applied
“Your discount has been applied.”
Code validated and Stripe coupon attached.
UI updates showing discounted total.
Tax ID Validated
“Your tax information has been updated.”
Stripe validates tax ID.
Reverse-charge applied if eligible.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Missing payment method
“Add a payment method to purchase seats.”
No saved card.
Add payment method.
Invalid card
“Enter a valid payment method.”
Stripe tokenization fails.
Re-enter card details.
Discount invalid
“Invalid or expired promo code.”
Code not found or expired.
Try another code.
Discount restrictions violated
“This code cannot be applied to your plan.”
Code fails plan/cycle rules.
Select eligible plan or remove code.
Invalid tax ID
“The tax ID entered is invalid.”
Stripe validation fails.
Correct tax ID.
Stripe unreachable
“Unable to process your request. Try again shortly.”
Network or Stripe outage.
Retry later.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-ADT-001
User buys multiple seats rapidly
System uses row-locking to prevent duplicate increments; Stripe quantity updates sequentially.
EC-ADT-002
Webhook for seat update delayed
Cron reconciling updates seat count within 15 minutes.
EC-ADT-003
Discount applied during proration event
Discount applies proportionally to prorated amount.
EC-ADT-004
Stripe Tax API timeout
System retries; if unresolved, blocks checkout.
EC-ADT-005
User with reverse-charge tax ID changes countries
System invalidates tax ID and recalculates taxes.
9. Acceptance Criteria
-
Extra seat charges must always prorate according to the remaining cycle days.
-
Seat additions must activate immediately after successful charge.
-
All discounts must validate against plan, billing cycle, expiration, and eligibility rules.
-
Only one discount may be active per subscription at a time.
-
Tax must always be calculated using Stripe Tax and charged in USD.
-
Reverse-charge must remove tax when a valid tax ID applies.
-
All add-on, discount, and tax events must be fully logged and auditable.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Billing
Update subscription quantity for extra seats
Seats cannot be added.
Stripe Payments
Charge prorated costs
Add-on purchases fail.
Stripe Coupons
Apply discounts
Discount codes become unusable.
Stripe Tax
Calculate correct tax
Incorrect or missing tax amounts.
DB
Store seat counts, discounts, tax metadata
UI shows incorrect information.
Email Service
Send receipts & confirmations
User may not receive notifications.
6. BILLING DASHBOARD & SUMMARY VIEW
MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW
1. Module Overview
Module Name: Billing Dashboard & Summary View
**Purpose:
**This module defines the central billing landing page that provides the Agency Owner (and Admin in read-only mode) with a consolidated, real-time summary of subscription status, renewal details, payment method information, usage metrics, invoices, and actionable billing controls.
It acts as the authoritative surface for understanding the financial and operational standing of an agency’s subscription.
Business Goals:
-
To provide a clear and accurate single source of truth for subscription status and financial obligations.
-
To reduce billing-related support inquiries by making all critical billing data visible and understandable.
-
To guide users toward corrective actions when issues arise (e.g., adding payment methods, resolving past-due status).
-
To improve transparency around renewal amounts, tax calculations, and the impact of add-ons or discounts.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Billing Dashboard)
Agency Owner
Full dashboard access; can manage plans, add seats, update payment methods, and view invoices.
Admin
Read-only access; cannot modify subscription or payment methods.
Team Member
No access to billing dashboard.
Contractor
No access.
Client
No access.
Super Admin
Can view any agency’s dashboard for support purposes.
3. User Flow
High-Level Flow:
-
User navigates to Billing → Dashboard.
-
System loads subscription overview, plan details, renewal data, payment method status, usage metrics, and invoice snapshot.
-
System evaluates subscription_status and displays appropriate warning banners or redirects.
-
User may take additional actions (e.g., change plan, add seats, update payment method, view full history).
-
System updates dashboard components dynamically based on latest data from Stripe and internal services.
4. Functional Logic
4.1 Subscription Overview Retrieval
4.1.1 Upon page load, the system retrieves current_plan, billing_cycle, renewal_date, subscription_status, and renewal_amount.
4.1.2 renewal_amount must include: base plan price, extra seats, discounts, and tax (Stripe Tax calculation).
4.1.3 The system displays the information in a summary widget, ensuring all values are shown in USD.
4.2 Payment Method Summary
4.2.1 The system retrieves the default payment method from Stripe Customer settings.
4.2.2 The system displays card brand, last four digits, expiry, and validity status.
4.2.3 If no payment method exists, the system displays a yellow “Add Payment Method” warning tile and CTA button.
4.2.4 If the card is expired or expiring soon, the system displays a warning banner instructing the user to update the method.
4.3 Invoice Snapshot Logic
4.3.1 The system retrieves the last invoice from Stripe.
4.3.2 The dashboard displays invoice amount, status (paid/failed/void), and invoice date.
4.3.3 A “View All Invoices” link routes to the Invoice History Module (Module 11 equivalent in original FRD).
4.3.4 If no invoices exist, the system displays a placeholder message: “No invoices available yet.”
4.4 Usage Metrics Display
4.4.1 The system loads project_count, brand_count, seat_count, contractor_count, and their corresponding limits.
4.4.2 The system displays usage as “X of Y used” for each metric.
4.4.3 If any metric exceeds its limit, the system displays a usage warning banner that links to the Limit Enforcement flow (Module 5).
4.4.4 Usage tiles must update in real-time following plan upgrades, downgrades, or add-on purchases.
4.5 Subscription Status Handling
4.5.1 Active Status
4.5.1.1 If subscription_status = active, no critical banner is shown.
4.5.1.2 All dashboard actions are available.
4.5.2 Past Due Status
4.5.2.1 If subscription_status = past_due, the dashboard displays a red warning banner:
“Your payment failed. Update your card to avoid suspension.”
4.5.2.2 Dashboard remains accessible, but sensitive actions (e.g., major plan changes) may display a warning.
4.5.3 Suspended Status
4.5.3.1 If subscription_status = suspended, user is immediately redirected to the Payment Fix Page (Module 3 interaction).
4.5.3.2 Dashboard content is not displayed until payment succeeds.
4.5.4 Canceled Status
4.5.4.1 If subscription_status = canceled, user is redirected to the Restore Subscription page (Module 1 interaction).
4.5.4.2 Dashboard elements are replaced by restoration messaging.
4.6 Quick Actions & Navigation Controls
4.6.1 Change Plan → Redirects to Plan Management (Module 2).
4.6.2 Switch Billing Cycle → Opens billing-cycle controls within Module 2.
4.6.3 Add Extra Seats → Opens seat-purchase flow in Module 4.
4.6.4 Manage Payment Methods → Opens Payment Method module (Module 7).
4.6.5 Download Invoice → Opens full invoice detail via Stripe-hosted PDF.
4.6.6 View Subscription History → Opens event timeline (Module 11 equivalent).
4.7 Dynamic Data Refresh
4.7.1 The dashboard must refresh upon receiving webhook updates from Stripe (payment success/failure, plan change, invoice creation).
4.7.2 The system re-fetches summary data if:
-
A payment method is updated
-
A seat is purchased
-
A plan is changed
-
A renewal occurs
4.7.3 The UI updates relevant widgets without requiring a page refresh where technically feasible.
4.8 Logging
4.8.1 System logs dashboard_viewed events for usage analytics.
4.8.2 System logs when warning banners are displayed.
4.8.3 System logs when users navigate from dashboard to any billing-related sub-module.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
plan_name
string
Required; must match active plan.
billing_cycle
enum
monthly or annual.
renewal_date
datetime
Required; must be ≥ current date.
renewal_amount_usd
decimal
Must be ≥ 0; includes tax & add-ons.
payment_method_status
enum
valid / expired / missing.
usage_projects
integer
Must be ≥ 0.
usage_brands
integer
Must be ≥ 0.
usage_seats
integer
Must be ≥ 0.
usage_contractors
integer
Must be ≥ 0.
subscription_status
enum
active / past_due / suspended / canceled.
last_invoice_id
string
Must be valid Stripe invoice ID if present.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Payment method updated
“Your payment method has been saved.”
Stripe accepts new card.
Dashboard refreshes payment method tile.
Plan changed
“Your subscription plan has been updated.”
Plan upgrade/downgrade completes.
Dashboard reloads summary and usage limits.
Seat added
“Your extra seat is now available.”
Purchase succeeds.
Seat usage tile updates instantly.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Billing fetch failure
“Unable to load billing information. Try again.”
Stripe or DB unavailable.
Retry or contact support.
Missing payment method
“Add a payment method to continue.”
No default card found.
Add new card.
Suspended access
“Your account is suspended due to non-payment.”
User attempts to access dashboard while suspended.
Provide valid payment method.
Unauthorized access
“Only agency owners can access billing.”
Non-owner attempts access.
Change role or contact owner.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-BD-001
Stripe temporarily unavailable
Show fallback error tile and retry automatically.
EC-BD-002
Card expired during renewal window
Dashboard displays urgent warning banner.
EC-BD-003
Multiple overdue invoices
Banner displays aggregated overdue amount.
EC-BD-004
Usage exceeds limits after webhook updates
Dashboard shows limit warning and links to enforcement.
EC-BD-005
Agency canceled but attempts to view dashboard
Redirect to restoration page.
9. Acceptance Criteria
-
Dashboard must show accurate real-time subscription, payment, invoice, and usage data.
-
Dashboard must adapt correctly to all subscription states (active, past_due, suspended, canceled).
-
Warning banners must appear only when relevant and must be unambiguous.
-
Usage metrics must accurately reflect plan limits and real-time usage.
-
Quick actions must route to correct modules.
-
Dashboard must refresh upon webhook-driven updates.
-
Unauthorized roles must be prevented from accessing the dashboard.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Billing
Retrieve plan, renewal, and invoice data
Dashboard shows stale or missing data.
Stripe Payments
Validate card status
Payment method info may be outdated.
Stripe Tax
Calculate renewal tax
Renewal amounts become inaccurate.
Resource Limit Service
Fetch usage metrics
Usage tiles become inaccurate.
DB
Store plan metadata and past actions
Summary cannot load.
Email Service
Send billing alerts
User may miss critical warnings.
10. SUPER ADMIN (GAWD MODE) BILLING CONTROLS
FEATURE 10 — MULTI-AGENCY CONTRACTOR ACCESS LOGIC
1. MODULE OVERVIEW
This module defines how a single contractor account can access multiple agencies inside Pixally.
Key principles:
-
Contractor identity is global across Pixally.
-
Contractors may be invited by multiple agencies.
-
The contractor uses the same login for all agencies.
-
A contractor can switch between agency workspaces using an Agency Switcher.
-
Access is agency-dependent and directly tied to each agency’s subscription status.
-
If an agency is suspended/past_due/canceled, access is blocked for that agency only.
-
The contractor continues full access to other active agencies.
Not included:
-
Contractor onboarding (covered in Contractor Module)
-
Payment logic
-
Seat management
-
Agency suspension logic (handled in Feature 6)
2. USER ROLES & PERMISSIONS
Role
Permissions (Specific to this Feature)
Contractor
May access multiple agencies based on each agency’s subscription status.
Agency Owner
Controls contractor access inside their own agency only.
Admin
Can manage contractors within their agency.
Team Member
No special rights with respect to contractor access.
Client
Not involved.
Super Admin
Can override agency-contractor relationships and view mappings.
3. USER FLOW (WITH FLOWCHART)
F10_multi_agency_contractor_access.png
4. FUNCTIONAL LOGIC
4.1 Global Contractor Identity
-
Contractor creates one account which becomes their master contractor identity.
-
Each additional agency invitation attaches a new Contractor-Agency Mapping record:
contractor_id
agency_id
role (e.g., photo, video, editor)
status (active, removed)
4.2 Agency Switcher Initialization
- After login, system fetches:
SELECT agency_id FROM contractor_agency_mappings
WHERE contractor_id = <id> AND status = active
- Agencies displayed in a selector (Agency Switcher UI).
4.3 Subscription-Dependent Access
4.3.1 If Agency is ACTIVE
Contractor gains FULL access:
-
Assigned Projects
-
Uploads
-
Deliverables
-
Calendar
-
Messaging
-
Task List
-
Project Notes
-
File Viewer
4.3.2 If Agency is PAST_DUE
Access becomes restricted:
-
No uploads
-
No file actions
-
No calendar edits
-
Project list view may be read-only
-
Contractor sees:
“This agency is experiencing billing issues. Some features may be unavailable.”
4.3.3 If Agency is SUSPENDED
Contractor is fully blocked from this agency:
-
Cannot view projects
-
Cannot access calendar or tasks
-
Cannot upload files
-
Cannot access links
-
System shows:
“This agency’s subscription is suspended. You cannot access this workspace.”
But contractor can still access other agencies.
4.3.4 If Agency is CANCELED
Access permanently blocked:
- All contractor-agency links move to inactive state.
4.4 Switching Agencies
When contractor selects another agency:
System reruns subscription validation:
check subscription_status for selected agency
- Based on status (active/past_due/suspended), access is granted or blocked.
4.5 Logging
Events recorded:
-
contractor_login
-
contractor_switch_agency
-
agency_access_blocked
-
agency_access_granted
-
subscription_status_checked_for_contractor
4.6 Security Handling
-
Each agency context loads only its own data.
-
No cross-agency data leakage allowed.
-
Hard isolation enforced by agency_id filter on all contractor queries.
5. FIELD DETAILS & VALIDATIONS
Field
Type
Validation
contractor_id
uuid
Must exist in contractor table
agency_id
uuid
Must exist, and contractor must be invited
subscription_status
enum
active, past_due, suspended, canceled
contractor_agency_status
enum
active or removed
role
enum
photography / videography / editing / etc.
last_switched_at
datetime
Auto-update
6. ERROR MESSAGES
Code
Condition
Message
ERR-CX-001
Suspended agency
This agency is suspended. Please contact the agency owner.
ERR-CX-002
Past due limited access
This agency has billing issues. Some actions are disabled.
ERR-CX-003
Removed from agency
You no longer have access to this agency.
ERR-CX-004
Invalid agency selection
Unable to switch agency. Try again.
ERR-CX-005
No agencies linked
You are not assigned to any agency yet.
7. EDGE CASES
ID
Scenario
Expected Behavior
EC-CX-001
Contractor invited to many agencies
Agency Switcher lists all active mappings
EC-CX-002
Contractor tries to switch to suspended agency
Block and show suspension message
EC-CX-003
Agency restores subscription while contractor is logged in
Contractor regains access after refresh
EC-CX-004
Contractor removed from agency mid-session
Auto-logout from that agency context
EC-CX-005
Contractor uses old bookmarked URL
Subscription validation still applied
8. TEST CASES
TC ID
Steps
Expected
TC-CX-001
Contractor selects active agency
Full access granted
TC-CX-002
Switch to past_due agency
Read-only/limited access
TC-CX-003
Switch to suspended agency
Access blocked
TC-CX-004
Switch between multiple agencies
Context switches correctly
TC-CX-005
Removed from one agency, still active in others
Access removed only from removed agency
9. ACCEPTANCE CRITERIA
-
AC-CX-001: Contractor can log in using a global master account.
-
AC-CX-002: Contractor can view all assigned agencies.
-
AC-CX-003: Access is permissioned per subscription status of each agency.
-
AC-CX-004: Active agencies permit full access; suspended agencies block access completely.
-
AC-CX-005: Contractor must still be able to work for other agencies even if one is suspended.
-
AC-CX-006: All access events must be logged.
-
AC-CX-007: No cross-agency data leakage allowed.
10. DEPENDENCIES
Dependency
Purpose
Impact
DB — contractor_agency_mappings
Track contractor → agency relationships
Contractor cannot switch agencies
Subscription Service
Validate agency subscription status
Incorrect access permissions
Stripe Webhooks
Update subscription status
Outdated status → wrong access
Auth Service
Manage contractor sessions
Improper session context
Logging Service
Audit access
Missing audit trail
7. PAYMENT METHOD MANAGEMENT
MODULE 7 — PAYMENT METHOD MANAGEMENT
1. Module Overview
Module Name: Payment Method Management
**Purpose:
**This module defines all workflows, rules, and validations related to adding, storing, updating, and removing payment methods within Pixally. It ensures that users can securely manage their payment instruments through Stripe while maintaining system integrity around default payment method usage, failed payment handling, and billing actions that require an active payment method.
Business Goals:
-
To ensure secure, PCI-compliant card handling via Stripe Elements.
-
To enable seamless updating of payment information for billing continuity.
-
To prevent accidental deletion of a required default payment method.
-
To maintain accurate Stripe Customer configurations for all subscription charges.
-
To provide users with clear guidance when card issues block billing flows.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Payment Methods)
Agency Owner
Add, remove, and set default payment methods; view full payment method list.
Admin
Read-only access to payment methods; cannot modify them.
Team Member
No access.
Contractor
No access.
Client
No access.
Super Admin
Can override, replace, or remove payment methods for support purposes.
3. User Flow
High-Level Workflow:
-
User navigates to Billing → Payment Methods.
-
System retrieves and displays all saved Stripe payment methods.
-
User selects one of the following actions:
a. Add new payment method
b. Set default method
c. Remove existing non-default method -
System validates the action and interacts with Stripe APIs to apply updates.
-
System refreshes the list and displays success or error messages.
4. Functional Logic
4.1 Fetching Stored Payment Methods
4.1.1 Upon page load, the system retrieves all saved card-type Stripe Payment Methods associated with the Stripe Customer.
4.1.2 The system identifies the default payment method by comparing payment_method.id to the customer’s invoice_settings.default_payment_method value.
4.1.3 The system displays each card with brand, last four digits, expiry month/year, and whether it is set as default.
4.2 Adding a Payment Method
4.2.1 Displaying Card Entry Form
4.2.1.1 When the user selects “Add Payment Method,” the system displays a secure form built with Stripe Elements.
4.2.1.2 The user enters card number, expiry date, CVC, and billing postal code (if applicable).
4.2.2 Tokenization
4.2.2.1 Stripe Elements tokenizes card input and returns a payment_method_id.
4.2.2.2 The system does not store raw card data; only metadata is stored locally.
4.2.3 Attaching Card to Customer
4.2.3.1 The system calls stripe.payment_methods.attach(payment_method_id, customer_id) to save the card.
4.2.3.2 If the user checks “Set as default,” the system updates invoice_settings.default_payment_method accordingly.
4.2.4 Post-Add Behaviour
4.2.4.1 The system refreshes the card list to show the new card.
4.2.4.2 The system logs payment_method_added.
4.3 Setting a Default Payment Method
4.3.1 The user selects an existing card and clicks “Set as Default.”
4.3.2 The system updates Stripe Customer settings with the selected card.
4.3.3 All future subscription invoices use this card automatically.
4.3.4 The system refreshes the UI and logs payment_method_set_default.
4.4 Removing a Payment Method
4.4.1 Default Method Protection
4.4.1.1 The system verifies whether the selected card is the default payment method.
4.4.1.2 If it is default, removal is blocked with a clear error message.
4.4.1.3 The system instructs the user to select a new default before removing this one.
4.4.2 Removal Logic for Non-Default Cards
4.4.2.1 The system calls stripe.payment_methods.detach(payment_method_id) to remove the payment method from the customer.
4.4.2.2 The system refreshes the card list and logs payment_method_removed.
4.5 Handling Card Issues and Expiration
4.5.1 The system displays a warning tile if the default payment method is expired or expiring soon.
4.5.2 If renewal or retry attempts fail due to card errors, Module 3 processes the failure, but Module 7 provides the interface to resolve the issue.
4.5.3 The dashboard must always reflect accurate card expiration status.
4.6 Data Synchronization & Logging
4.6.1 UI refreshes occur immediately after Stripe confirmation for add, remove, or update actions.
4.6.2 The system logs every change for compliance, including user_id, card metadata, and action type.
4.6.3 A periodic sync reconciles mismatches between local metadata and Stripe’s authoritative data.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
payment_method_id
string
Must be a valid Stripe Payment Method ID.
card_brand
string
Returned by Stripe; must be non-empty.
card_last4
string
Must be 4 digits.
exp_month
integer
Must be 1–12.
exp_year
integer
Must be ≥ current year.
is_default
boolean
True only for default payment method.
card_token
string
Required for new card additions.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Payment method added
“Your payment method has been added.”
Stripe attaches method successfully.
Card appears in list; default applied if selected.
Payment method set as default
“This card is now your default payment method.”
Stripe updates invoice_settings.
UI updates default indicator.
Payment method removed
“Your payment method has been removed.”
Card is non-default and successfully detached.
Card disappears from list.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Invalid card details
“Enter a valid card.”
Stripe tokenization error.
Re-enter information and retry.
Tokenization failure
“We couldn’t save your payment method. Try again.”
Stripe Elements fails.
Retry or use another card.
Attempt to remove default card
“Set a new default payment method before removing this card.”
User selects Remove on default card.
Choose a new default.
Stripe unreachable
“Unable to update your payment methods. Try again.”
Stripe API unavailable.
Retry later.
Unauthorized access
“Only account owners can manage payment methods.”
Non-owner attempts modification.
Switch account role.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-PM-001
User adds multiple cards in rapid sequence
Stripe deduplication ensures each card is recorded once; UI lists updated accordingly.
EC-PM-002
Expired default card remains on account
System displays warning; billing attempts will fail until updated.
EC-PM-003
Removal attempt fails due to Stripe error
System retries once before surfacing error.
EC-PM-004
Wrong Stripe customer ID stored locally
UI shows error; system attempts to refresh customer_id.
EC-PM-005
User changes default card mid-checkout
New default is applied in real time for upcoming charges.
9. Acceptance Criteria
-
Users must be able to add, remove, and update payment methods securely using Stripe Elements.
-
System must prevent removal of the default payment method.
-
Stripe must always remain the source of truth for stored cards.
-
The dashboard must display accurate card metadata and default status.
-
All billing actions requiring a payment method must validate payment_method_on_file = true.
-
All actions must be logged for audit and support purposes.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Elements
Tokenize card data
Cannot add new cards.
Stripe PaymentMethods API
Attach/remove methods
Payment methods cannot be managed.
Stripe Customer API
Update default method
Invoice routing breaks.
DB
Store card metadata (local caching)
UI may display outdated data.
Email Service
Optional payment method update notifications
Owner may miss confirmation.
5. ACCESS CONTROL & LIMITS ENFORCEMENT
MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT
1. Module Overview
Module Name: Access Control & Limits Enforcement
**Purpose:
**This module defines all rules governing access permissioning and resource-limit enforcement across the subscription system. It manages (a) how contractors access multiple agencies, and (b) how plan-level limits constrain the creation and usage of resources such as Projects, Brands, Seats, and Contractors. It ensures that all access is subscription-aware, that agency context is correctly applied, and that resource creation is strictly bound by the plan’s entitlement rules.
Business Goals:
-
To guarantee accurate role-based access for agencies, contractors, and team members across multiple workspaces.
-
To enforce subscription limits consistently across all resource creation operations.
-
To provide clear user-remediation options when limits are exceeded (upgrade, remove resources, or request extension).
-
To maintain strict isolation between agencies and avoid cross-agency data leakage.
-
To ensure downgrade and suspension states properly restrict functionality.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Access Control & Limits Enforcement)
Agency Owner
Full access to create resources; can upgrade plan, remove resources, or request extensions when limits are exceeded.
Admin
Can create resources within limits; cannot override limits or upgrade plan.
Team Member
Can create resources only if their role permits and limits are not exceeded.
Contractor
Access depends on agency subscription state; cannot create resources or influence limits.
Client
No backend access; only interacts with published client-facing content.
Super Admin
Can override limits, grant temporary extensions, remove restrictions, and adjust contractor-agency mappings.
3. User Flow
High-Level Workflow for Access + Limits Enforcement:
-
User opens a resource-creation flow (e.g., create project / brand / add contractor).
-
System loads current subscription limits and real-time usage counts.
-
System checks if the requested action remains within limits.
-
If within limits → resource is created and usage increments.
-
If limits exceeded → system displays remediation options (upgrade, remove resources, or request extension).
-
If user chooses upgrade → redirect to upgrade flow (Module 2).
-
If user selects resource removal → display Resource Selection Modal.
-
If user selects extension → send request to Super Admin or apply temporary override if allowed.
-
For contractors switching agencies → system validates subscription status of selected agency before granting access.
4. Functional Logic
4.1 Multi-Agency Contractor Access Logic
4.1.1 Global Contractor Identity
4.1.1.1 Each contractor has a global identity used across all agencies.
4.1.1.2 When invited to an agency, the system creates a Contractor–Agency Mapping record linking identity to agency with an assigned role.
4.1.1.3 Removing a contractor from an agency updates only the mapping, not the global identity.
4.1.2 Agency Selection & Switcher
4.1.2.1 After login, the system retrieves all active mappings associated with the contractor.
4.1.2.2 The Agency Switcher displays all agencies where the contractor maintains an active relationship.
4.1.2.3 When a contractor selects an agency, the system loads agency-specific context (projects, tasks, assets) filtered by agency_id.
4.1.3 Subscription-Aware Access Enforcement
4.1.3.1 If the agency subscription_status = active, contractor receives full access for their assigned role.
4.1.3.2 If subscription_status = past_due, contractor experiences restricted access (read-only on selected areas; uploads disabled).
4.1.3.3 If subscription_status = suspended, contractor is fully blocked from accessing that agency.
4.1.3.4 Contractors retain access to other agencies even if one agency becomes suspended or canceled.
4.1.3.5 If subscription_status = canceled or permanently_deleted, all contractor-agency mappings for that agency become inactive.
4.2 Subscription Limit Enforcement Logic
4.2.1 Limits Source of Truth
4.2.1.1 The subscription record defines: max_projects, max_brands, included_seats, extra_seats, max_contractors, and plan_tier.
4.2.1.2 effective_seat_limit = included_seats + extra_seats.
4.2.1.3 If max_contractors = null, the contractor limit is treated as unlimited.
4.2.2 Pre-Action Enforcement
4.2.2.1 On each create/increment action (project, brand, seat usage, contractor assignment), the system loads real-time usage counts.
4.2.2.2 The system compares current usage against effective limits.
4.2.2.3 If usage is within limits → action proceeds normally.
4.2.2.4 If usage exceeds limits → system blocks the action and displays a Limit Enforcement Modal.
4.3 Limit Enforcement Modal Logic
4.3.1 Modal Presentation
4.3.1.1 The modal displays the exceeded category (projects, brands, seats, contractors).
4.3.1.2 The modal explains the available resolution options with required steps.
4.3.2 Resolution Options
4.3.2.1 Upgrade Plan → redirects to Module 2 upgrade flow with appropriate target plans.
4.3.2.2 Remove/Archive Resources → opens Resource Selection Modal for selecting items to remove.
4.3.2.3 Request Temporary Extension → sends request to Super Admin or applies auto-extensions if configured.
4.3.3 Validation
4.3.3.1 The system prevents progression until all limits are resolved.
4.3.3.2 The modal may require selection of specific resources (e.g., choose which brand to keep).
4.4 Resource Removal / Selection Modal Logic
4.4.1 Project-Level Resolution
4.4.1.1 The system displays all projects and highlights those eligible for archival.
4.4.1.2 User selects the projects to keep within plan limits.
4.4.2 Brand-Level Resolution
4.4.2.1 Basic plan requires exactly one active brand.
4.4.2.2 User must select a single brand; other brands are archived on downgrade execution or immediately if enforcing limits mid-action.
4.4.3 Team & Seat Resolution
4.4.3.1 If seats_used exceeds effective_seat_limit, the system requires removing team members or purchasing additional seats (Module 4).
4.4.3.2 Deactivated team members lose access immediately.
4.4.4 Contractor Resolution
4.4.4.1 If contractors exceed the limit, the system displays contractor list with selection options.
4.4.4.2 Removing a contractor deactivates their agency mapping but does not delete the global identity.
4.5 Downgrade Interaction Logic
4.5.1 Pre-Downgrade Validation
4.5.1.1 When a downgrade is scheduled (Module 2), limits for the new plan are computed immediately.
4.5.1.2 If limits are exceeded, the system requires resolving them before allowing downgrade scheduling.
4.5.2 Execution-Time Enforcement
4.5.2.1 At the downgrade effective timestamp, the system re-evaluates limits.
4.5.2.2 Excess resources are archived or deactivated based on limit type.
4.5.2.3 Contractor access and automations are restricted per new tier limitations.
4.6 Concurrency & Race Condition Handling
4.6.1 The system uses row-level locking (SELECT … FOR UPDATE) or optimistic concurrency during resource creation.
4.6.2 If two simultaneous resource-creation attempts exceed limits, the system allows only the first and returns an error to the second.
4.6.3 All limit-enforcement logic must remain idempotent.
4.7 Temporary Extensions (Super Admin Overrides)
4.7.1 Super Admin may grant temporary limit increases by setting override_flag and override_expiration.
4.7.2 The system must accept the override until expiration.
4.7.3 When override expires, the system re-evaluates resource usage and notifies the owner if usage exceeds standard limits.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
plan_tier
enum
Must be free, basic, essentials, or studio.
max_projects
integer
≥ 0.
max_brands
integer
≥ 0.
included_seats
integer
≥ 0.
extra_seats
integer
≥ 0.
effective_seat_limit
integer
Computed; must equal included_seats + extra_seats.
max_contractors
integer/null
Null allowed for unlimited.
projects_count
integer
Retrieved at runtime.
brands_count
integer
Retrieved at runtime.
seats_used
integer
Retrieved at runtime.
contractors_assigned
integer
Retrieved at runtime.
override_flag
boolean
True only when extension applied.
override_expires_at
datetime
Must be future timestamp if override_flag = true.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Resource Created Within Limits
“Resource created successfully.”
Usage does not exceed limits.
Resource appears in lists instantly.
Limits Resolved
“Your limits have been updated.”
User completes resolution steps.
Action that triggered enforcement resumes.
Contractor Access Granted
“You now have access to this agency.”
Subscription active and mapping valid.
Contractor sees agency dashboard.
Override Applied
“A temporary limit extension has been granted.”
Super Admin approves extension.
System recalculates limits with override.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Project limit exceeded
“You have reached your project limit. Upgrade or archive projects to continue.”
Creating project would exceed max_projects.
Upgrade plan or archive.
Brand limit exceeded
“Your plan allows fewer brands. Select the allowed brand to continue.”
Creating brand exceeds max_brands.
Select allowed brand or upgrade.
Seat limit exceeded
“No seats available. Add an extra seat or remove a team member.”
seats_used > effective_seat_limit.
Purchase seat or remove member.
Contractor limit exceeded
“Contractor limit reached. Remove contractors or upgrade your plan.”
Assignment exceeds max_contractors.
Remove contractor or upgrade.
Agency suspended
“This agency’s subscription is suspended and cannot be accessed.”
Contractor selects suspended agency.
Contact agency owner.
Concurrency conflict
“Another action was completed first. Please try again.”
Concurrent creation conflict.
Retry action.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-ACL-001
Multiple users create resources simultaneously
Only first succeeds; others receive concurrency error.
EC-ACL-002
Contractor uses bookmarked link to suspended agency
System blocks access and displays suspension message.
EC-ACL-003
Override expires while resources exceed limit
System notifies owner and requires remediation.
EC-ACL-004
Contractor removed mid-session
Contractor is auto-logged out of that agency context.
EC-ACL-005
Agency restored after cancellation
Contractor and resource access reinstated instantly.
9. Acceptance Criteria
-
System must block any resource creation that exceeds plan limits.
-
Modal-driven remediation must always provide upgrade, removal, and extension options.
-
Contractors must only access agencies where the subscription is active or past_due (limited).
-
Suspended or canceled agencies must always block contractor access.
-
Override logic must safely expand limits and expire cleanly.
-
Access must never leak across agencies; all queries must be scoped by agency_id.
-
All limit checks and access changes must be logged.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Subscription DB
Stores plan limits and overrides
Cannot evaluate limits accurately.
Auth & RBAC System
Enforce role-based permissions
Incorrect access or unauthorized actions.
Contractor Mapping DB
Retrieve agency relationships
Contractor access becomes inconsistent.
Resource Services (Projects, Brands, etc.)
Provide real-time resource counts
Cannot enforce limits correctly.
Billing System
Evaluate upgrades and seat purchases
Cannot resolve limit violations.
Logging Service
Audit access/limit events
Missing compliance trail.
8. BILLING NOTIFICATIONS & ALERTS
MODULE 8 — BILLING NOTIFICATIONS & ALERTS
1. Module Overview
Module Name: Billing Notifications & Alerts
**Purpose:
**This module governs all automated billing-related communications delivered through email, push notifications, and in-app alerts. It ensures that users receive timely, accurate, and context-aware messaging for all billing lifecycle events, including payments, failures, suspensions, trial expirations, renewals, invoice availability, card expirations, and subscription changes.
Business Goals:
-
To proactively reduce involuntary churn by informing users when action is needed.
-
To ensure transparency around billing activity and invoice availability.
-
To support critical alerts such as payment failure, suspension, and expiring trial or card.
-
To maintain a consistent communication framework across email templates, push notifications, and in-app alerts.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Billing Notifications)
Agency Owner
Receives all relevant billing emails, in-app alerts, and push notifications.
Admin
May receive certain billing emails (optional); receives selected in-app alerts based on permission settings.
Team Member
Does not receive billing notifications.
Contractor
Does not receive billing notifications.
Client
Does not receive billing notifications.
Super Admin
Can resend notifications manually for support purposes; can view delivery logs.
3. User Flow
High-Level Notification Sequence:
-
Billing event occurs (payment success, payment failure, trial ending, invoice ready, etc.).
-
System identifies event type and selects the appropriate communication template.
-
System merges dynamic variables into the template (e.g., name, plan, amount).
-
Notification is sent via Email, Push, and/or In-App channel depending on event severity.
-
Delivery status is logged and monitored for bounce or failure.
-
User receives notification and takes corrective or informational action as required.
4. Functional Logic
4.1 Event Detection Logic
4.1.1 Triggering Events
4.1.1.1 The system listens for the following billing events:
-
Payment success
-
Payment failure
-
Final retry failure (suspension event)
-
Trial ending warnings (Days 10, 12, 13, 14)
-
Subscription restored
-
Subscription canceled
-
Billing cycle switched
-
Seat purchased
-
Plan upgraded or downgraded
-
Invoice generated or invoice ready
-
Card expiring soon
-
Renewal reminder (3 days before renewal)
4.1.1.2 Events are captured through webhooks (Stripe), internal processes (scheduler), or user actions.
4.2 Template Selection Logic
4.2.1 The system maintains a template registry mapping event types to template IDs (e.g., BILL-001, BILL-002).
4.2.2 When an event triggers, the system retrieves the appropriate template.
4.2.3 Each email or notification template contains placeholders for dynamic variables such as:
{name}, {plan}, {amount_usd}, {invoice_date}, {retry_date}, {renewal_date}, {card_last4}, {seat_count}, {tax_amount}.
4.2.4 The system must validate that all required variables are present before sending.
4.3 Email Delivery Workflow
4.3.1 Sending Logic
4.3.1.1 The system sends billing emails using the configured Email Service Provider (ESP).
4.3.1.2 Each email send includes event metadata, user ID, and variable payload.
4.3.1.3 ESP returns delivery status: queued, delivered, bounced, or failed.
4.3.2 Handling Delivery Outcomes
4.3.2.1 If status = delivered → system logs success.
4.3.2.2 If status = bounced → user_email is flagged as invalid.
4.3.2.3 If status = failed → system retries once, then logs failure.
4.3.2.4 If user has disabled emails → system logs “email suppressed.”
4.4 In-App Notification Logic
4.4.1 The system generates an in-app notification for selected billing events (e.g., trial ending, renewal reminder, payment failure).
4.4.2 The notification record stores: user_id, title, message, type=billing, status=unread, and created_at.
4.4.3 Notifications appear in the user’s notification center until dismissed.
4.5 Push Notification Logic
4.5.1 Push notifications are used only for critical billing events:
-
Payment failure
-
Final retry failure (suspension imminent)
-
Account suspended
-
Card expiring badge alerts
4.5.2 Push notifications are sent through FCM/APNs using the stored device token.
4.5.3 If a device token is invalid, it is removed and logged.
4.6 Compliance and Logging
4.6.1 The system logs every communication event, template used, variables injected, user target, and delivery result.
4.6.2 The system does not log full email content to preserve privacy; only metadata is logged.
4.6.3 Notifications are version-controlled to ensure template consistency across updates.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
template_id
string
Must map to an existing template.
event_type
enum
Must be a supported billing event.
user_email
string
Must be valid RFC-compliant email.
variables
JSON
Must contain all required placeholders.
push_enabled
boolean
Must be true for device to receive push alerts.
email_enabled
boolean
Must be true unless suppressed intentionally.
status
enum
queued, sent, delivered, failed.
device_token
string
Required for push notifications; must be valid.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Notification sent successfully
“Your notification has been delivered.”
ESP returns delivered status.
Log as delivered; update message center.
Push delivered
“A billing alert has been sent to your device.”
Push provider returns success.
Mark notification as delivered.
In-app alert created
“A new billing update is available.”
Notification saved to DB.
Appears in user notification center.
7. Error Message Handling (Table Format Only)
Error Scenario
Error Message
Trigger Condition
Required User Action
Missing template
“Notification template not found.”
Template ID missing or invalid.
Admin must correct mapping.
Invalid email
“Unable to send notification. Email address invalid.”
ESP rejects address.
User must update email.
Email provider error
“We could not send your billing email. Try again.”
ESP failure.
Retry later.
Invalid push token
“Push notification failed.”
Token expired or invalid.
User must re-enable push permissions.
Missing required placeholders
“Notification cannot be sent due to missing data.”
Variables incomplete.
System should retry after rebuilding variables.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-NOT-001
User unsubscribed from emails
System suppresses email but still logs event.
EC-NOT-002
Email bounces repeatedly
System flags email_invalid and stops further attempts.
EC-NOT-003
Multiple billing events occur in the same minute
System queues all notifications sequentially.
EC-NOT-004
Template updated mid-send
System uses version-controlled template snapshot.
EC-NOT-005
User changes email before delivery
System sends notification to most recent email.
9. Acceptance Criteria
-
All billing events must generate correct notifications based on event type.
-
Notification content must use correct template and variables.
-
Push notifications must be triggered for critical billing events only.
-
Email, in-app, and push channels must each log delivery actions.
-
Users with disabled or invalid emails must not receive suppressed notifications.
-
All notification records must be auditable and searchable.
-
System must guarantee template consistency and prevent partial sends.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Email Service Provider
Deliver billing emails
Users may not receive critical billing alerts.
Push Notification Service
Deliver mobile/web push alerts
Critical alerts cannot reach users.
Database
Store notification records and logs
Notifications cannot be tracked or audited.
Stripe Webhooks
Trigger events such as payment success/failure
Notifications may not be triggered at all.
Scheduler / Cron
Trigger trial-ending and renewal reminders
Users may not receive timely reminders.
9. BILLING API & WEBHOOK PROCESSING
MODULE 9 — BILLING API & WEBHOOK PROCESSING
1. Module Overview
Module Name: Billing API & Webhook Processing
**Purpose:
**This module governs all backend-facing APIs that handle inbound Stripe webhook events and synchronize subscription, invoice, and payment data between Pixally and Stripe. It ensures that all billing states remain consistent, secure, and auditable across the platform.
This module is responsible for validating Stripe webhook signatures, parsing event payloads, updating subscription state machine values (active, past_due, suspended, canceled), invoking retry or suspension workflows, syncing invoice information, and logging all billing events.
Business Goals:
-
To maintain perfect synchronization between Stripe billing events and internal subscription states.
-
To ensure secure processing of Stripe webhook events using signature validation and idempotency.
-
To support automated lifecycle transitions such as payment success, failure, cancellation, and restoration.
-
To ensure all billing operations are fully auditable through persistent logging.
2. User Roles & Permissions (Table Format Only)
Role
Permissions (Billing API & Webhooks)
System (Automated Service)
Sole processor of Stripe webhooks; capable of updating billing states and triggering workflows.
Super Admin
Can view webhook logs, inspect event payloads, and replay/retrigger webhook processing for support purposes.
Agency Owner / Admin
Indirectly affected by changes but do not interact with this module.
Team Member / Contractor / Client
No interaction with or visibility into webhook events.
3. User Flow
High-Level Processing Flow:
-
Stripe sends a webhook event to the Pixally webhook endpoint.
-
System validates webhook signature.
-
If signature is invalid → event rejected with 400.
-
If valid → system parses payload and identifies event type.
-
System processes event using the appropriate handler logic.
-
System updates subscription status, invoice data, or payment state based on event.
-
System logs event metadata and persists raw payload for auditing.
-
System returns 200 OK to Stripe regardless of internal failures (Stripe will retry).
4. Functional Logic
4.1 Webhook Reception
4.1.1 The system exposes the secure endpoint: /api/billing/webhooks.
4.1.2 All inbound requests from Stripe are expected to be POST requests with a signed header: Stripe-Signature.
4.1.3 The system rejects non-POST or malformed requests with a 400 response.
4.2 Signature Validation
4.2.1 The system uses Stripe’s signing secret to validate the signature.
4.2.2 If the signature does not match, the event is rejected, no processing occurs, and a 400 response is returned.
4.2.3 Valid signatures proceed to payload parsing.
4.3 Payload Parsing
4.3.1 The system extracts the following fields:
-
event_id
-
event_type
-
subscription_id
-
invoice_id
-
customer_id
-
line items
-
timestamps
4.3.2 If required fields are missing, the system logs an error and skips processing for that event.
4.4 Event-Type Handling Logic
4.4.1 invoice.payment_succeeded
4.4.1.1 System updates subscription_status to active.
4.4.1.2 System updates next_renewal_at using Stripe invoice period data.
4.4.1.3 Grace periods, retry counters, and suspension flags are cleared.
4.4.1.4 System triggers payment-success notification (Module 8).
4.4.1.5 System logs success event.
4.4.2 invoice.payment_failed
4.4.2.1 System updates subscription_status to past_due.
4.4.2.2 System increments retry_attempt_count.
4.4.2.3 System initiates retry schedule workflow (Module 3).
4.4.2.4 System triggers payment-failure notification.
4.4.2.5 System logs failure event.
4.4.3 customer.subscription.updated
4.4.3.1 System synchronizes plan tier, billing cycle, trial period, and add-on quantities.
4.4.3.2 If plan or billing cycle changed, the system triggers relevant confirmations.
4.4.3.3 System logs all subscription-level changes.
4.4.3.4 System updates any pending scheduled downgrade or billing-cycle changes if necessary.
4.4.4 customer.subscription.deleted
4.4.4.1 System updates subscription_status to canceled.
4.4.4.2 The retention timer is initialized (365 days from cancellation).
4.4.4.3 System sends cancellation confirmation email.
4.4.4.4 System logs cancellation and retention-start events.
4.4.5 invoice.upcoming
4.4.5.1 The system calculates the projected renewal amount, including taxes and add-ons.
4.4.5.2 System triggers renewal reminder notification (3-day notice).
4.4.5.3 System logs invoice-upcoming event.
4.4.6 charge.refunded
4.4.6.1 System updates affected invoice status to refunded.
4.4.6.2 System stores refund details (amount, timestamp).
4.4.6.3 System triggers refund confirmation notification.
4.4.6.4 System logs refund event.
4.5 Idempotency Protection
4.5.1 The system stores each Stripe event_id to prevent reprocessing of the same event.
4.5.2 If an event with the same event_id is received again, the system returns 200 OK without reprocessing.
4.5.3 This prevents double charges, duplicate invoice updates, or multiple state transitions.
4.6 Raw Payload Storage
4.6.1 System stores raw JSON payload for every processed webhook event.
4.6.2 Stored metadata includes event_id, event_type, signature_valid, payload, processed_at.
4.6.3 This enables audit, debugging, and compliance reporting.
4.7 Internal Failure Handling
4.7.1 If payload parsing fails or DB update fails, the system logs error details internally.
4.7.2 System still returns 200 OK to Stripe to prevent repeated webhook attempts.
4.7.3 Internal retry jobs reconcile state inconsistencies every 15 minutes.
4.8 Logging Requirements
4.8.1 The system logs every webhook event with structured metadata.
4.8.2 The system logs all state transitions triggered by webhook events (e.g., active → past_due → suspended).
4.8.3 Logs must be searchable by event_id, subscription_id, and customer_id.
5. Field Details & Validations (Table Format Only)
Field Name
Type
Validation Rules
stripe_event_id
string
Must be unique per event; used for idempotency.
event_type
enum
Must match supported Stripe event types.
subscription_status
enum
active, past_due, suspended, canceled.
invoice_id
string
Must be valid Stripe invoice ID if present.
customer_id
string
Required; must match stored Stripe Customer.
payload
JSON
Raw webhook payload; must be stored intact.
processed_at
datetime
Auto-stamped during processing.
signature_valid
boolean
Must be true for event to be processed.
6. Success Message Handling (Table Format Only)
Action
Success Message
Conditions
Post-Success Behaviour
Webhook processed successfully
“Webhook event processed.”
Signature valid and event handled.
Internal logs updated; state changes applied.
Subscription updated
“Subscription details synced.”
customer.subscription.updated processed.
UI reflects updated plan/billing info.
Payment success
“Payment recorded successfully.”
invoice.payment_succeeded handled.
Retry workflow cleared; subscription marked active.
7. Error Message Handling (Table Format Only)
(Errors here are internal system logs; users do not see these.)
Error Scenario
Logged Error Message
Trigger Condition
System Behaviour
Invalid signature
“Webhook rejected: invalid signature.”
Signature mismatch.
Return 400; do not process event.
Unsupported event
“Event skipped: unsupported event type.”
Unknown event_type.
Return 200; no processing.
Missing fields
“Webhook payload incomplete.”
Critical fields absent.
Log and skip event.
DB update failure
“Billing sync failed due to DB error.”
DB write failure.
Log; background job retries.
Duplicate event
“Duplicate event ignored.”
event_id already processed.
Return 200; no reprocessing.
8. Edge Cases (Table Format Only)
Edge Case ID
Scenario
Expected Behaviour
EC-WEB-001
Duplicate webhook due to Stripe retry
Idempotency prevents reprocessing.
EC-WEB-002
Events arrive out of order
System uses timestamps to enforce latest state.
EC-WEB-003
Webhook arrives during downtime
System stores payload when service resumes and processes it.
EC-WEB-004
Subscription updated while failed payment retry in progress
Latest timestamp wins; retry/suspension logic reconciled accordingly.
EC-WEB-005
Refund issued for old invoice
History updated; refund email triggered.
9. Acceptance Criteria
-
All Stripe webhook events must be validated using signature verification.
-
All supported events must be parsed and processed without manual intervention.
-
Internal subscription states must always match Stripe’s authoritative values.
-
Idempotency must prevent any duplicate billing state transitions.
-
Raw webhook payloads must be stored for audit and debugging.
-
Internal logs must capture every event and state change.
-
Any internal failure must be recoverable through scheduled synchronization.
10. Dependencies (Table Format Only)
Dependency
Purpose
Impact if Unavailable
Stripe Webhooks
Provide subscription, invoice, and payment events
Billing state becomes outdated or incorrect.
DB
Store state transitions, payloads, and idempotency keys
Events cannot be processed or audited.
Scheduler / Cron
Reconcile delayed or failed events
State may drift from Stripe.
Email Service
Notify users of payment or subscription events
Users remain uninformed of billing outcomes.
Logging Service
Maintain audit trail
Billing events cannot be tracked.
Free Plan Access List
Pixally — Free Tier Plan Access
Organized by the Pixally left-nav.
Legend: ✓ = accessible · 🔒 = locked · ◐ = visible but grayed-out/disabled · Full-page = opens the full-page "Upgrade your plan" screen · Pop-up = a button/tab inside an accessible page that opens the "Upgrade your plan" pop-up on click · Greyed-out = item stays visible in the list but is disabled/non-interactive until upgrade
1. Free-Tier Access
Module
Feature / Item
Free
Lock Behavior
Dashboard
Page (overview)
✓ Accessible
—
Dashboard
Pending Contractor Agreement
🔒 Locked
Pop-up
Dashboard
Pending Counter Sign
🔒 Locked
Pop-up
Dashboard
New Contractors
🔒 Locked
Pop-up
Dashboard
Profit & Loss
🔒 Locked
Pop-up
Dashboard
Overdue Payments → Contractor tab
🔒 Locked
Pop-up
Dashboard
Events → Next 7 Days → Reminder button
🔒 Locked (SMS not available)
Pop-up
Calendar
Entire module
✓ Accessible
—
Projects
Project list — first 5 booked/active projects
✓ Accessible
—
Projects
Leads from Lead Form (beyond the 5)
◐ Visible, grayed out
Greyed-out
Projects
Create Project button (at 5 active projects)
🔒 Locked
Pop-up
Project Details
Activity tab
✓ Accessible
—
Project Details
Files & Documents tab
✓ Accessible
—
Project Details
Notes tab
✓ Accessible
—
Project Details
Finance tab
✓ Accessible
—
Project Details
Finance → Payment to Contractor
🔒 Locked
Pop-up
Project Details
Meetings tab
🔒 Locked
Pop-up
Project Details
Post Production tab
🔒 Locked
Pop-up
Project Details › Events
Service tab
✓ Accessible
—
Project Details › Events
Service → Assign Contractor button
🔒 Locked
Pop-up
Project Details › Events
Contractors tab
🔒 Locked
Full-page
Project Details › Events
Raw Media tab
🔒 Locked
Full-page
Post Production
Entire tab
🔒 Locked
Full-page
Clients & Contractors
Clients
✓ Accessible
—
Clients & Contractors
Contractors tab
🔒 Locked
Full-page
Clients & Contractors
Check Availability
🔒 Locked
Full-page
Templates
Service Agreement
🔒 Locked
Full-page
Templates
Contractor Questionnaires
🔒 Locked
Full-page
Templates
All other templates
✓ Accessible
—
Tools
Integrations tab
🔒 Locked
Full-page
Tools
All other tools
✓ Accessible
—
Finances
Billing
✓ Accessible
—
Finances
Contractor Invoices
🔒 Locked
Full-page
Finances
Expenses
🔒 Locked
Full-page
Finances
QuickBooks
🔒 Locked
Full-page
Finances
Profit & Loss
🔒 Locked
Full-page
Finances
Taxes
🔒 Locked
Full-page
Automations
Entire module
✓ Accessible
—
Reports
Entire tab
🔒 Locked
Full-page
Settings
My Profile
✓ Accessible
—
Settings
General
✓ Accessible
—
Settings
Business Payment
✓ Accessible
—
Settings
Notifications
✓ Accessible
SMS column → Pop-up (Studio only)
Settings
Team Management
✓ 1 member (additional are paid)
Add beyond 1 → Pop-up
Settings
2-Step Verification
✓ Accessible
—
Settings
Stripe Integration
✓ Accessible
—
Settings
Brands
✓ 1 brand
Create New Brand → Pop-up
Settings
Data Management
✓ Accessible
—
Note on Post Production: the top-level Post Production nav item opens a Full-page upgrade screen (per screenshot 1), while the Post Production tab inside Project Details now opens a Pop-up.
2. Downgrade to Free — Locked Scenarios
These describe what a user experiences when they move down to Free from a higher plan and previously had content or usage that exceeds Free-tier limits.
Uniform principle: On downgrade, no user data is deleted. Content created on a higher plan is retained but access-restricted to Free limits, and is fully restored on re-upgrade. When the user interacts with a restricted item, they see the "Upgrade your plan" prompt (Full-page or Pop-up per the pattern below).
#
Area
Scenario on downgrade (had more than Free allows)
Result on Free
Lock Behavior
1
Projects
More than 5 booked projects
The 5 booked projects stay accessible; projects beyond the cap and incoming Lead-Form leads appear grayed out in the list. The Create Project button is locked while at the cap.
Grayed-out (excess / leads) · Create Project → Pop-up
2
Brand
More than 1 brand
Only 1 brand stays active; additional brands are locked. Creating a new brand is blocked.
Pop-up
3
Team
Multiple team members / seats
Seats reduced to the Free allowance; extra members are deactivated but retained (not removed).
Admin notice on Team page
4
Post Production
Existing Post Production content
Data retained; module locked.
Top-level → Full-page · Project Details tab → Pop-up
5
Reports
Report history
Data retained; Reports tab locked.
Full-page
6
Finances (Contractor Invoices, Expenses, QuickBooks, Profit & Loss, Taxes)
Records / reports in these sub-modules
Records retained; each sub-module locked. Billing stays accessible.
Full-page
7
Finance → Payment to Contractor
Contractor payments made
Finance tab accessible; existing records read-only; the action is locked.
Pop-up
8
Meetings (Project Details)
Meetings scheduled
Data retained; Meetings tab locked.
Pop-up
9
Events → Assign Contractor
Contractors assigned to events
Service tab accessible; already-assigned contractors visible read-only; the button is locked.
Pop-up
10
Events → Contractors tab / Raw Media tab
Data in these tabs
Data retained; tabs locked.
Full-page
11
Clients & Contractors → Contractors tab / Check Availability
Contractor records / availability
Data retained; locked.
Full-page
12
Templates → Service Agreement / Contractor Questionnaires
These templates created
Templates retained; locked.
Full-page
13
Tools → Integrations
Active integrations (e.g., QuickBooks, Calendar)
Integrations tab locked; active connections paused / disconnected until re-upgrade.
Full-page
14
Dashboard widgets
Data behind Profit & Loss, contractor agreements, new contractors, overdue contractor payments, pending counter-sign
Widgets show a locked state; underlying data retained / read-only
Pop-up
3. Notes / Assumptions
- Lock Behavior (Section 1): Confirmed explicitly — Create New Brand, Assign Contractor, Meetings tab, and Project Details → Post Production tab are Pop-ups; top-level Post Production is Full-page (screenshot 1). For the rest, the rule applied is: locked tab/page → Full-page, locked button/action → Pop-up.
- Settings: Brand management and Team Management were folded into Settings (they aren't top-level nav items). On Free, Settings → Brands is capped at 1 brand and Team Management at 1 member.
- Settings items assumed accessible (not in the source FRD): Business Payment, 2-Step Verification, Stripe Integration, and Data Management are marked ✓ — confirm if any should be locked on Free. Notifications is accessible but its SMS column is locked until Studio.
- Assumed accessible (not in the source list): the Clients tab.
- Dashboard widgets: the five locked widgets are assumed to render as a locked card that opens the upgrade Pop-up on click. If they should instead be hidden or greyed-out/disabled, let me know.
- Downgrade behavior to confirm: (a) whether excess items are read-only vs hidden, and (b) the rule for which 5 projects / which 1 brand remain accessible when over the cap (recommend: most recently active). Integration disconnect-vs-pause behavior on downgrade also needs product confirmation.
Basic plan Access List
Pixally — Basic Tier Plan Access
Organized by the Pixally left-nav.
Legend: ✓ = accessible · 🔒 = locked · Full-page = opens the full-page "Upgrade your plan" screen · Pop-up = a button/tab inside an accessible page that opens the "Upgrade your plan" pop-up on click
What Basic adds over Free: unlimited projects (Create Project unlocked, no grayed-out leads) · up to 2 team members · Google Calendar + Calendly integrations · Reports: Booking Trend, Profit & Loss, Sales Tax · Finance: Profit & Loss + Taxes · Dashboard: Profit & Loss widget.
1. Basic-Tier Access
Module
Feature / Item
Basic
Lock Behavior
Dashboard
Page (overview)
✓ Accessible
—
Dashboard
Profit & Loss
✓ Accessible
—
Dashboard
Pending Contractor Agreement
🔒 Locked
Pop-up
Dashboard
Pending Counter Sign
🔒 Locked
Pop-up
Dashboard
New Contractors
🔒 Locked
Pop-up
Dashboard
Overdue Payments → Contractor tab
🔒 Locked
Pop-up
Dashboard
Events → Next 7 Days → Reminder button
🔒 Locked (SMS not available)
Pop-up
Calendar
Entire module
✓ Accessible
—
Projects
Project list (unlimited projects)
✓ Accessible
—
Projects
Create Project button
✓ Accessible
—
Project Details
Activity tab
✓ Accessible
—
Project Details
Files & Documents tab
✓ Accessible
—
Project Details
Notes tab
✓ Accessible
—
Project Details
Finance tab
✓ Accessible
—
Project Details
Finance → Payment to Contractor
🔒 Locked
Pop-up
Project Details
Meetings tab
🔒 Locked
Pop-up
Project Details
Post Production tab
🔒 Locked
Pop-up
Project Details › Events
Service tab
✓ Accessible
—
Project Details › Events
Service → Assign Contractor button
🔒 Locked
Pop-up
Project Details › Events
Contractors tab
🔒 Locked
Full-page
Project Details › Events
Raw Media tab
🔒 Locked
Full-page
Post Production
Entire tab
🔒 Locked
Full-page
Clients & Contractors
Clients
✓ Accessible
—
Clients & Contractors
Contractors tab
🔒 Locked
Full-page
Clients & Contractors
Check Availability
🔒 Locked
Full-page
Templates
Service Agreement
🔒 Locked
Full-page
Templates
Contractor Questionnaires
🔒 Locked
Full-page
Templates
All other templates
✓ Accessible
—
Tools
Integrations tab
✓ Accessible
—
Tools
Integrations → Google Calendar
✓ Accessible
—
Tools
Integrations → Calendly
✓ Accessible
—
Tools
Integrations → QuickBooks
🔒 Locked
Pop-up
Tools
All other tools
✓ Accessible
—
Finances
Billing
✓ Accessible
—
Finances
Profit & Loss
✓ Accessible
—
Finances
Taxes
✓ Accessible
—
Finances
Contractor Invoices
🔒 Locked
Full-page
Finances
Expenses
🔒 Locked
Full-page
Finances
QuickBooks
🔒 Locked
Full-page
Automations
Entire module
✓ Accessible
—
Reports
Reports tab
✓ Accessible
—
Reports
Booking Trend
✓ Accessible
—
Reports
Profit & Loss
✓ Accessible
—
Reports
Sales Tax
✓ Accessible
—
Reports
Other reports (Income, Sales, Financial Forecast, Accounts Receivable, Expenses, Cash Ledger, Contractors)
🔒 Locked
Full-page
Settings
My Profile
✓ Accessible
—
Settings
General
✓ Accessible
—
Settings
Business Payment
✓ Accessible
—
Settings
Notifications
✓ Accessible
SMS column → Pop-up (Studio only)
Settings
Team Management
✓ Up to 2 (additional are paid)
Add beyond 2 → Pop-up
Settings
2-Step Verification
✓ Accessible
—
Settings
Stripe Integration
✓ Accessible
—
Settings
Brands
✓ 1 brand
Create New Brand → Pop-up
Settings
Data Management
✓ Accessible
—
Note on Post Production: the top-level Post Production nav item opens a Full-page upgrade screen, while the Post Production tab inside Project Details opens a Pop-up — same as Free.
2. Downgrade to Basic — Locked Scenarios
What a user experiences when they move down to Basic from a higher plan (Essentials / Studio) and previously had content or usage beyond Basic limits.
Uniform principle: On downgrade, no user data is deleted. Content is retained but access-restricted to Basic limits and fully restored on re-upgrade. Restricted items show the "Upgrade your plan" prompt (Full-page or Pop-up per the pattern).
Note: projects are unlimited on Basic, so there is no project-cap lockout on downgrade (unlike Free).
#
Area
Scenario on downgrade (had more than Basic allows)
Result on Basic
Lock Behavior
1
Team
More than 2 members
Reduced to 2; extra members deactivated but retained (not removed).
Admin notice on Team page
2
Brand
More than 1 brand
Only 1 brand stays active; additional brands locked.
Pop-up
3
Contractor management (Contractors tab, Assign Contractor, Contractor Invoices, Payment to Contractor, contractor Dashboard widgets)
Contractor records / assignments / invoices
Data retained; all contractor features locked.
Tabs → Full-page · Buttons/widgets → Pop-up
4
Post Production
Post Production content
Retained; module locked.
Top-level → Full-page · Project Details tab → Pop-up
5
Reports (beyond the 3 included)
Advanced report history (Income, Sales, Financial Forecast, Accounts Receivable, Expenses, Cash Ledger, Contractors)
Retained; only Booking Trend, Profit & Loss, Sales Tax remain — the rest locked.
Full-page
6
Finances → Expenses, QuickBooks
Expense records / QuickBooks sync
Retained; locked. Billing, Profit & Loss, Taxes remain accessible.
Full-page
7
Tools → QuickBooks integration
Active QuickBooks connection
Integration locked; connection paused until re-upgrade. Google Calendar + Calendly remain.
Pop-up
8
Clients & Contractors → Check Availability
Availability data
Retained; locked.
Full-page
9
Templates → Service Agreement / Contractor Questionnaires
These templates
Retained; locked.
Full-page
3. Notes / Assumptions
- Inferred unlocks (confirm): Finance → Profit & Loss and Taxes, plus the Dashboard Profit & Loss widget, are marked unlocked on Basic — this follows from the P&L / Sales-Tax reports you granted and the source FRD. Tell me if Finance P&L/Taxes should stay locked instead.
- Kept locked on Basic (carried from Free) — confirm: Meetings tab, Service Agreement, and Contractor Questionnaires. The source FRD hints the Meetings tab may open on Basic once Google Calendar / Calendly are available (its integrations) — confirm whether Meetings should unlock on Basic.
- Brands: Basic is still limited to 1 brand (same as Free); Create New Brand stays a Pop-up.
- QuickBooks: both the QuickBooks integration and QuickBooks sync/invoice options remain locked on Basic — only Google Calendar + Calendly are included.
- Lock behavior (assumed): individual locked reports → Full-page; the QuickBooks integration on the now-open Integrations tab → Pop-up; adding a 3rd team member → Pop-up.
- Settings: Brand management and Team Management now live under Settings (not top-level nav). On Basic, Settings → Brands is capped at 1 brand and Team Management at 2 members.
- Settings items assumed accessible (not in the source FRD): Business Payment, 2-Step Verification, Stripe Integration, and Data Management are marked ✓ — confirm if any should be locked. Notifications is accessible but its SMS column is locked until Studio.
- Assumed accessible (not specified): the Clients tab (same as Free).
Essentials Plam Access List
Pixally — Essentials Tier Plan Access
Organized by the Pixally left-nav.
Legend: ✓ = accessible · 🔒 = locked · Full-page = opens the full-page "Upgrade your plan" screen · Pop-up = a button/tab inside an accessible page that opens the "Upgrade your plan" pop-up on click
What Essentials adds over Basic: contractor management (up to 20 contractors) · Post Production · QuickBooks (integration, sync + Finance page) · Expenses · all remaining reports · Payment to Contractor · Assign Contractor · Contractors & Raw Media tabs · Check Availability · Contractor Invoices · Meetings tab · Service Agreement + Contractor Questionnaires · 2nd brand · 3rd team member. (SMS features remain for Studio.)
1. Essentials-Tier Access
Module
Feature / Item
Essentials
Lock Behavior
Dashboard
Page (overview)
✓ Accessible
—
Dashboard
Profit & Loss
✓ Accessible
—
Dashboard
Pending Contractor Agreement
✓ Accessible
—
Dashboard
Pending Counter Sign
✓ Accessible
—
Dashboard
New Contractors
✓ Accessible
—
Dashboard
Overdue Payments → Contractor tab
✓ Accessible
—
Dashboard
Events → Next 7 Days → Reminder button
🔒 Locked (SMS not available)
Pop-up
Calendar
Entire module
✓ Accessible
—
Projects
Project list (unlimited projects)
✓ Accessible
—
Projects
Create Project button
✓ Accessible
—
Project Details
Activity tab
✓ Accessible
—
Project Details
Files & Documents tab
✓ Accessible
—
Project Details
Notes tab
✓ Accessible
—
Project Details
Finance tab
✓ Accessible
—
Project Details
Finance → Payment to Contractor
✓ Accessible
—
Project Details
Meetings tab
✓ Accessible
—
Project Details
Post Production tab
✓ Accessible
—
Project Details › Events
Service tab
✓ Accessible
—
Project Details › Events
Service → Assign Contractor button
✓ Accessible
—
Project Details › Events
Contractors tab
✓ Accessible
—
Project Details › Events
Raw Media tab
✓ Accessible
—
Post Production
Entire tab
✓ Accessible
—
Clients & Contractors
Clients
✓ Accessible
—
Clients & Contractors
Contractors (management)
✓ Up to 20 contractors
Add beyond 20 → Pop-up
Clients & Contractors
Check Availability
✓ Accessible
—
Templates
Service Agreement
✓ Accessible
—
Templates
Contractor Questionnaires
✓ Accessible
—
Templates
All other templates
✓ Accessible
—
Tools
Integrations → Google Calendar
✓ Accessible
—
Tools
Integrations → Calendly
✓ Accessible
—
Tools
Integrations → QuickBooks
✓ Accessible
—
Tools
All other tools
✓ Accessible
—
Finances
Billing
✓ Accessible
—
Finances
Profit & Loss
✓ Accessible
—
Finances
Taxes
✓ Accessible
—
Finances
Contractor Invoices
✓ Accessible
—
Finances
Expenses
✓ Accessible
—
Finances
QuickBooks
✓ Accessible
—
Automations
Entire module (all nodes, incl. Sync to QuickBooks, contractor & advanced report nodes)
✓ Accessible
—
Automations
"Send SMS" node
🔒 Locked
Pop-up
Reports
All reports (Booking Trend, Profit & Loss, Sales Tax, Income, Sales, Financial Forecast, Accounts Receivable, Expenses, Cash Ledger, Contractors)
✓ Accessible
—
Settings
My Profile
✓ Accessible
—
Settings
General
✓ Accessible
—
Settings
Business Payment
✓ Accessible
—
Settings
Notifications
✓ Accessible
SMS column → Pop-up (Studio only)
Settings
Team Management
✓ Up to 3 (additional are paid)
Add beyond 3 → Pop-up
Settings
2-Step Verification
✓ Accessible
—
Settings
Stripe Integration
✓ Accessible
—
Settings
Brands
✓ Up to 2 brands
3rd brand → Pop-up
Settings
Data Management
✓ Accessible
—
2. Downgrade to Essentials — Locked Scenarios
What a user experiences when they move down to Essentials from Studio and previously had usage beyond Essentials limits.
Uniform principle: On downgrade, no user data is deleted. Content is retained but access-restricted to Essentials limits and fully restored on re-upgrade. Restricted items show the "Upgrade your plan" prompt (Full-page or Pop-up per the pattern).
Note: projects are unlimited on Essentials, so there is no project-cap lockout on downgrade.
#
Area
Scenario on downgrade (had more than Essentials allows)
Result on Essentials
Lock Behavior
1
Brand
More than 2 brands
Only 2 brands stay active; additional brands locked.
Pop-up
2
Team
More than 3 members
Reduced to 3; extra members deactivated but retained (not removed).
Admin notice on Team page
3
Contractors
More than 20 contractors
Top 20 remain accessible; contractors beyond the cap become locked / read-only.
Locked contractor → Full-page · Add → Pop-up
4
SMS features
SMS notifications / "Send SMS" automations active
SMS column and Send SMS node locked; existing SMS automations paused until re-upgrade.
Pop-up
3. Notes / Assumptions
- Resolves earlier Basic questions: the Meetings tab, Service Agreement, and Contractor Questionnaires — flagged as uncertain on Basic — are unlocked on Essentials per the source FRD.
- Only remaining locks (all SMS-dependent): the Settings → Notifications SMS column, the "Send SMS" automation node, and the Dashboard → Events → Next 7 Days reminder button are the only items still locked on Essentials; all unlock on Studio once SMS becomes available. This comes from the source FRD — tell me if SMS shouldn't be gated to Studio.
- Caps: 2 brands · 3 team members · 20 contractors (all managed under Settings for brands/team). Exceeding any cap triggers the upgrade Pop-up on the create/add action.
- Settings: Brand management and Team Management now live under Settings (not top-level nav). Settings items Business Payment, 2-Step Verification, Stripe Integration, and Data Management aren't in the source FRD — marked ✓; confirm if any should be locked.
- Contractor Portal (out of scope here): the source FRD notes that on Essentials the Contractor Portal exposes the top 20 contractors — kept out of the main table to match the scope of the Free/Basic sheets, but flagging it in case you want portals documented too.
- Assumed accessible (not specified): the Clients tab (same as Free/Basic).
No tickets linked — generate test cases directly from this FRD instead.