← 33. Subscription_Management_Final
Chunks — 33. Subscription_Management_Final
The FRD markdown is the source of truth; these chunks are the derived retrieval index used to give the test-case generator only the relevant slices. Rebuilt automatically when the FRD is saved.
841 chunks · ~198,602 tokens
#1
(intro)
~3 tok
Subscription
#2
(intro)
~1 tok
#
#3
(intro)
~1 tok
#
#4
(intro)
~122 tok
# **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**
#5
(intro)
~1 tok
#
#6
(intro)
~1 tok
#
#7
(intro)
~1 tok
#
#8
(intro)
~1 tok
#
#9
**FRD 1 — Subscription Plans with Access Control**
~37 tok
# **FRD 1 — Subscription Plans with Access Control** **Module:** Subscription Plans with Access Control **Version:** 2.0 **Date:** April 23, 2026
#10
**FRD 1 — Subscription Plans with Access Control** > **1\. Module Overview**
~258 tok
## **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.
#11
**FRD 1 — Subscription Plans with Access Control** > **2\. User Roles & Permissions**
~152 tok
## **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
#12
**FRD 1 — Subscription Plans with Access Control** > **3\. User Flow**
~756 tok
## **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.
#13
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#14
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.1 Plan Tier Structure**
~375 tok
### **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.
#15
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.2 Plan Resource Limits**
~367 tok
### **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.
#16
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.3 Plan Feature Entitlement Matrix**
~305 tok
### **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.
#17
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.4 Promotional Pricing — 50% Off First Year**
~462 tok
### **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).
#18
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.5 Referral Discount**
~131 tok
### **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.
#19
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.6 Stripe Transaction Fees Per Plan**
~252 tok
### **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.
#20
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.7 Plan Usage Matrix Display Logic**
~555 tok
### **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.
#21
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.8 Feature Gating Behaviour**
~241 tok
### **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).
#22
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.9 Role-Based Subscription Access**
~271 tok
### **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.
#23
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.10 Subscription Page Display Elements**
~575 tok
### **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.
#24
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.11 Trial Plan Access Control**
~171 tok
### **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.
#25
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.12 Impact of Plan Changes on Access Control**
~228 tok
### **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.
#26
**FRD 1 — Subscription Plans with Access Control** > **4\. Functional Logic** > **4.13 Gawd Portal-Applied Discounts**
~129 tok
### **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.
#27
**FRD 1 — Subscription Plans with Access Control** > **5\. Field Details & Validations**
~800 tok
## **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.
#28
**FRD 1 — Subscription Plans with Access Control** > **5\. Field Details & Validations**
~79 tok
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.
#29
**FRD 1 — Subscription Plans with Access Control** > **6\. Success Message Handling**
~331 tok
## **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.
#30
**FRD 1 — Subscription Plans with Access Control** > **7\. Error Message Handling**
~736 tok
## **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.
#31
**FRD 1 — Subscription Plans with Access Control** > **8\. Edge Cases**
~790 tok
## **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
#32
**FRD 1 — Subscription Plans with Access Control** > **8\. Edge Cases**
~457 tok
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.
#33
**FRD 1 — Subscription Plans with Access Control** > **9\. Acceptance Criteria**
~603 tok
## **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.
#34
**FRD 1 — Subscription Plans with Access Control** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#35
**FRD 1 — Subscription Plans with Access Control** > **11\. Dependencies**
~601 tok
## **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.
#36
**FRD 1 — Subscription Plans with Access Control** > **12\. References**
~66 tok
## **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**
#37
(intro)
~1 tok
#
#38
(intro)
~1 tok
#
#39
(intro)
~1 tok
#
#40
(intro)
~1 tok
#
#41
**FRD 2 — Free Trial**
~23 tok
# **FRD 2 — Free Trial** **Module:** Free Trial **Version:** 2.0 **Date:** April 23, 2026
#42
**FRD 2 — Free Trial** > **1\. Module Overview**
~325 tok
## **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.
#43
**FRD 2 — Free Trial** > **2\. User Roles & Permissions**
~177 tok
## **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
#44
**FRD 2 — Free Trial** > **3\. User Flow**
~768 tok
## **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.
#45
**FRD 2 — Free Trial** > **3\. User Flow**
~257 tok
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.
#46
**FRD 2 — Free Trial** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#47
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.1 Trial Eligibility and Plan Assignment**
~341 tok
### **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.
#48
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.2 Trial Clock and Duration**
~134 tok
### **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.
#49
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.3 No Credit Card Requirement**
~66 tok
### **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.
#50
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.4 Email Verification Gate**
~466 tok
### **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.
#51
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.5 Trial Feature Access**
~419 tok
### **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).
#52
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.6 Trial Countdown Banner**
~164 tok
### **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.
#53
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.7 Subscription Page Behavior During Trial**
~290 tok
### **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.
#54
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.8 Trial Reminder Email Schedule**
~424 tok
### **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.
#55
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.9 Trial Expiry and Fallback to Free Plan**
~285 tok
### **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.
#56
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.10 Trial Extension by Pixally Super Admin**
~185 tok
### **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.
#57
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.11 Automatic Trial Reset for Returning Expired-Trial Users**
~260 tok
### **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.
#58
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.12 Trial State Tracking in Gawd Portal**
~155 tok
### **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.
#59
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.13 Trial Purchase Edge Behavior**
~149 tok
### **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.
#60
**FRD 2 — Free Trial** > **4\. Functional Logic** > **4.14 Marketing Website Plan Selection Handoff**
~139 tok
### **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.
#61
**FRD 2 — Free Trial** > **5\. Field Details & Validations**
~601 tok
## **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.
#62
**FRD 2 — Free Trial** > **6\. Success Message Handling**
~373 tok
## **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.
#63
**FRD 2 — Free Trial** > **7\. Error Message Handling**
~606 tok
## **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.
#64
**FRD 2 — Free Trial** > **8\. Edge Cases**
~788 tok
## **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.
#65
**FRD 2 — Free Trial** > **8\. Edge Cases**
~504 tok
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.
#66
**FRD 2 — Free Trial** > **9\. Acceptance Criteria**
~640 tok
## **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.
#67
**FRD 2 — Free Trial** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#68
**FRD 2 — Free Trial** > **11\. Dependencies**
~714 tok
## **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**
#69
**FRD 3 — Upgrade & Downgrade**
~27 tok
# **FRD 3 — Upgrade & Downgrade** **Module:** Upgrade & Downgrade **Version:** 2.0 **Date:** April 23, 2026
#70
**FRD 3 — Upgrade & Downgrade** > **1\. Module Overview**
~335 tok
## **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.
#71
**FRD 3 — Upgrade & Downgrade** > **2\. User Roles & Permissions**
~139 tok
## **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)
#72
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#73
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.1 Upgrade User Flow**
~731 tok
### **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.
#74
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.2 Downgrade User Flow — No Selection Required (Simple Path)**
~260 tok
### **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.
#75
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.3 Downgrade User Flow — With Selection Required (Wizard Path)**
~735 tok
### **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.
#76
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.3 Downgrade User Flow — With Selection Required (Wizard Path)**
~222 tok
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.
#77
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.4 Cancel Scheduled Downgrade Flow**
~166 tok
### **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.
#78
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.5 Re-scheduling a Different Downgrade Flow**
~164 tok
### **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.
#79
**FRD 3 — Upgrade & Downgrade** > **3\. User Flow** > **3.6 Upgrade When Scheduled Downgrade Exists Flow**
~165 tok
### **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.
#80
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#81
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.1 Plan Change Timing Matrix**
~332 tok
### **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.
#82
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.2 Upgrade Flow Entry Points**
~187 tok
### **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.
#83
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.3 Proration Logic — Core Pricing Definitions**
~208 tok
### **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.
#84
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.4 Year Determination Logic**
~238 tok
### **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).
#85
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.5 Upgrade Proration — Year 2+ (Simple)**
~278 tok
### **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.
#86
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.6 Upgrade Proration — Year 1 with 50% Promo**
~352 tok
### **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.
#87
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.7 Upgrade Proration — Monthly to Monthly (Same Cycle)**
~133 tok
### **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.
#88
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.8 Upgrade Plus Monthly-to-Annual Simultaneously**
~174 tok
### **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.
#89
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.9 Upgrade Plus Annual-to-Monthly Simultaneously**
~182 tok
### **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.
#90
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.10 Upgrade from Free to Paid Plan**
~155 tok
### **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.
#91
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.11 Downgrade Timing and Scheduling**
~290 tok
### **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.
#92
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.12 Downgrade Evaluation — Simple vs Wizard Path**
~333 tok
### **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.
#93
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.13 Downgrade Wizard — Step 1 Team Members (Two-Pool Model)**
~695 tok
### **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.
#94
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.14 Downgrade Wizard — Contractor Handling on Studio to Essentials**
~260 tok
### **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).
#95
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.15 Downgrade Wizard — Step 2 Brands**
~136 tok
### **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.
#96
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.16 Downgrade Wizard — Step 3 Summary**
~304 tok
### **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.
#97
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.17 Downgrade to Free Plan**
~397 tok
### **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.
#98
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.18 Deselected Team Members on Downgrade Execution**
~241 tok
### **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.
#99
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.19 Deselected Brands on Downgrade Execution**
~178 tok
### **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.
#100
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.20 Module Lock List by Downgrade Path**
~538 tok
### **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:
#101
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.20 Module Lock List by Downgrade Path**
~583 tok
* 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:
#102
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.20 Module Lock List by Downgrade Path**
~564 tok
* 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)**
#103
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.20 Module Lock List by Downgrade Path**
~243 tok
* 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.
#104
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.22 Auto-Cancellation of Scheduled Downgrade on Upgrade**
~192 tok
### **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.
#105
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.23 Re-scheduling a Different Downgrade**
~168 tok
### **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.
#106
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.24 Cancel Scheduled Downgrade by Owner**
~181 tok
### **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.
#107
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.25 Price Summary Preview Popup (Upgrade Path)**
~339 tok
### **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.
#108
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.26 Coupon Application at Upgrade**
~152 tok
### **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.
#109
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.27 Post-Upgrade Confirmation**
~157 tok
### **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.
#110
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.28 Post-Downgrade Confirmation**
~126 tok
### **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.
#111
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.29 Plan Comparison Page (Manage Subscription)**
~332 tok
### **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."
#112
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.30 Studio Plan — No Upgrade Option**
~139 tok
### **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.
#113
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.31 Payment Method Routing**
~175 tok
### **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.
#114
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.32 Year 1 Discount Window Handling Across Changes**
~191 tok
### **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.
#115
**FRD 3 — Upgrade & Downgrade** > **4\. Functional Logic** > **4.33 Notifications Generated by Upgrade/Downgrade Events**
~208 tok
### **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.
#116
**FRD 3 — Upgrade & Downgrade** > **5\. Field Details & Validations**
~792 tok
## **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
#117
**FRD 3 — Upgrade & Downgrade** > **5\. Field Details & Validations**
~53 tok
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.
#118
**FRD 3 — Upgrade & Downgrade** > **6\. Success Message Handling**
~492 tok
## **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.
#119
**FRD 3 — Upgrade & Downgrade** > **7\. Error Message Handling**
~603 tok
## **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.
#120
**FRD 3 — Upgrade & Downgrade** > **8\. Edge Cases**
~794 tok
## **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
#121
**FRD 3 — Upgrade & Downgrade** > **8\. Edge Cases**
~778 tok
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.
#122
**FRD 3 — Upgrade & Downgrade** > **8\. Edge Cases**
~769 tok
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
#123
**FRD 3 — Upgrade & Downgrade** > **8\. Edge Cases**
~71 tok
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.
#124
**FRD 3 — Upgrade & Downgrade** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#125
**FRD 3 — Upgrade & Downgrade** > **9\. Acceptance Criteria**
~800 tok
* 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 be
#126
**FRD 3 — Upgrade & Downgrade** > **9\. Acceptance Criteria**
~261 tok
tween $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.
#127
**FRD 3 — Upgrade & Downgrade** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#128
**FRD 3 — Upgrade & Downgrade** > **11\. Dependencies**
~714 tok
## **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**
#129
**FRD 4 — Billing Cycle Management**
~30 tok
# **FRD 4 — Billing Cycle Management** **Module:** Billing Cycle Management **Version:** 1.0 **Date:** April 23, 2026
#130
**FRD 4 — Billing Cycle Management** > **1\. Module Overview**
~315 tok
## **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.
#131
**FRD 4 — Billing Cycle Management** > **2\. User Roles & Permissions**
~103 tok
## **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
#132
**FRD 4 — Billing Cycle Management** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#133
**FRD 4 — Billing Cycle Management** > **3\. User Flow** > **3.1 Monthly to Annual Switch Flow**
~420 tok
### **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.
#134
**FRD 4 — Billing Cycle Management** > **3\. User Flow** > **3.2 Annual to Monthly Switch Flow**
~433 tok
### **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.
#135
**FRD 4 — Billing Cycle Management** > **3\. User Flow** > **3.3 Cancel Scheduled Cycle Switch Flow**
~196 tok
### **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.
#136
**FRD 4 — Billing Cycle Management** > **3\. User Flow** > **3.4 Coexistence with Scheduled Downgrade Flow**
~220 tok
### **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.
#137
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#138
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.1 Billing Cycle Options**
~164 tok
### **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.
#139
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.2 Plan Change Timing Reference**
~129 tok
### **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.
#140
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.3 Monthly to Annual Switch — Timing and Billing Anchor**
~164 tok
### **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.
#141
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.4 Monthly to Annual Switch — Year 1 Proration (Blended)**
~393 tok
### **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.
#142
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.5 Monthly to Annual Switch — Year 2+ Proration (Simple)**
~137 tok
### **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.
#143
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.6 Annual to Monthly Switch — Timing**
~155 tok
### **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.
#144
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.7 Annual to Monthly Switch — First Monthly Charge Rate**
~162 tok
### **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.
#145
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.8 Switch to Monthly Warning Popup**
~264 tok
### **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.
#146
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.9 Monthly to Annual Direct Flow**
~101 tok
### **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.
#147
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.10 Price Summary Preview Popup (Cycle Switch)**
~284 tok
### **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.
#148
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.11 Paid Extra Seats on Cycle Switch**
~346 tok
### **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.
#149
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.12 Subscription Page Display During Scheduled Cycle Switch**
~145 tok
### **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.
#150
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.13 Cancel Scheduled Cycle Switch**
~212 tok
### **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.
#151
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.14 Coexistence of Scheduled Cycle Switch and Scheduled Tier Downgrade**
~308 tok
### **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.
#152
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.15 Annual Renewal Pricing Rule**
~158 tok
### **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.
#153
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.16 Year Determination at Switch Time**
~158 tok
### **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.
#154
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.17 Payment Method Routing**
~156 tok
### **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.
#155
**FRD 4 — Billing Cycle Management** > **4\. Functional Logic** > **4.18 Notifications Generated by Cycle Switch Events**
~161 tok
### **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.
#156
**FRD 4 — Billing Cycle Management** > **5\. Field Details & Validations**
~502 tok
## **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.
#157
**FRD 4 — Billing Cycle Management** > **6\. Success Message Handling**
~360 tok
## **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.
#158
**FRD 4 — Billing Cycle Management** > **7\. Error Message Handling**
~556 tok
## **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.
#159
**FRD 4 — Billing Cycle Management** > **8\. Edge Cases**
~799 tok
## **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
#160
**FRD 4 — Billing Cycle Management** > **8\. Edge Cases**
~766 tok
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.
#161
**FRD 4 — Billing Cycle Management** > **9\. Acceptance Criteria**
~626 tok
## **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.
#162
**FRD 4 — Billing Cycle Management** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#163
**FRD 4 — Billing Cycle Management** > **11\. Dependencies**
~574 tok
## **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**
#164
**FRD 5 — Add-ons (Team Members)**
~33 tok
# **FRD 5 — Add-ons (Team Members)** **Module:** Add-ons — Team Members (Paid Extra Seats) **Version:** 1.0 **Date:** April 23, 2026
#165
**FRD 5 — Add-ons (Team Members)** > **1\. Module Overview**
~330 tok
## **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.#166
**FRD 5 — Add-ons (Team Members)** > **2\. User Roles & Permissions**
~142 tok
## **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
#167
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#168
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow** > **3.1 Invite Team Member — Plan-Included Slots Available**
~290 tok
### **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.
#169
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow** > **3.2 Invite Team Member — Plan-Included Slots Full (Owner)**
~335 tok
### **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.
#170
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow** > **3.3 Invite Team Member — Plan-Included Slots Full (Admin)**
~95 tok
### **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.
#171
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow** > **3.4 Delete Team Member (and Auto-Promote if Applicable)**
~348 tok
### **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.
#172
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow** > **3.5 Resend Invite or Edit Invite Email (Paid Extra Seat Not Yet Accepted)**
~223 tok
### **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.
#173
**FRD 5 — Add-ons (Team Members)** > **3\. User Flow** > **3.6 Auto-Promote on Plan Upgrade**
~220 tok
### **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.
#174
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#175
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.1 Extra Seat Availability by Plan**
~182 tok
### **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.
#176
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.2 Extra Seat Pricing**
~108 tok
### **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.
#177
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.3 Always-Monthly Billing Cadence**
~186 tok
### **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.
#178
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.4 Extra Seat Proration on Purchase**
~160 tok
### **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.
#179
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.5 Extras Billing Anchor**
~165 tok
### **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.
#180
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.6 Extra Seat Proration on Deletion**
~194 tok
### **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.
#181
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.7 Invite Flow When Plan-Included Slots Full (Owner)**
~274 tok
### **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.
#182
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.8 Invite Flow When Plan-Included Slots Full (Admin)**
~136 tok
### **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.
#183
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.9 Role Assignment on Invite**
~135 tok
### **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.
#184
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.10 Invite Email and Join Link Expiry**
~139 tok
### **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.
#185
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.11 Resend Invite and Edit Invite Email**
~206 tok
### **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.
#186
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.12 Auto-Promote Trigger 1 — Main-Plan Seat Vacated**
~248 tok
### **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.
#187
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.13 Auto-Promote Trigger 2 — Plan Upgrade With Existing Extras**
~262 tok
### **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.
#188
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.14 Auto-Promote Notification**
~178 tok
### **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.
#189
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.15 Delete Team Member Equals Cancel Seat**
~124 tok
### **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.
#190
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.16 Subscription Page Display of Seats**
~231 tok
### **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).
#191
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.17 Admin Role Capabilities**
~151 tok
### **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.
#192
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.18 Payment Method Routing for Seat Purchase**
~134 tok
### **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.
#193
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.19 Paid Seats Behavior on Plan Downgrade**
~159 tok
### **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.
#194
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.20 Notifications Generated by Seat Events**
~171 tok
### **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**
#195
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.20 Notifications Generated by Seat Events**
~800 tok
* 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#196
**FRD 5 — Add-ons (Team Members)** > **4\. Functional Logic** > **4.20 Notifications Generated by Seat Events**
~488 tok
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.#197
**FRD 5 — Add-ons (Team Members)** > **5\. Field Details & Validations**
~496 tok
## **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).
#198
**FRD 5 — Add-ons (Team Members)** > **6\. Success Message Handling**
~432 tok
## **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.
#199
**FRD 5 — Add-ons (Team Members)** > **7\. Error Message Handling**
~572 tok
## **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.
#200
**FRD 5 — Add-ons (Team Members)** > **8\. Edge Cases**
~788 tok
## **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.
#201
**FRD 5 — Add-ons (Team Members)** > **8\. Edge Cases**
~768 tok
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.
#202
**FRD 5 — Add-ons (Team Members)** > **9\. Acceptance Criteria**
~613 tok
## **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.
#203
**FRD 5 — Add-ons (Team Members)** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#204
**FRD 5 — Add-ons (Team Members)** > **11\. Dependencies**
~566 tok
## **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**
#205
**FRD 6 — Billing Dashboard + Payment Methods**
~35 tok
# **FRD 6 — Billing Dashboard + Payment Methods** **Module:** Billing Dashboard + Payment Methods **Version:** 1.0 **Date:** April 23, 2026
#206
**FRD 6 — Billing Dashboard + Payment Methods** > **1\. Module Overview**
~426 tok
## **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.
#207
**FRD 6 — Billing Dashboard + Payment Methods** > **2\. User Roles & Permissions**
~168 tok
## **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
#208
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#209
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.1 First-time Visit — Free Trial State (No Payment Method Yet)**
~307 tok
### **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).
#210
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.2 First-time Visit — Paid Subscription Active**
~249 tok
### **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.
#211
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.3 Add Payment Method Flow**
~290 tok
### **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.
#212
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.4 Set as Primary Payment Method Flow**
~179 tok
### **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.
#213
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.5 Delete Payment Method Flow**
~233 tok
### **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.
#214
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.6 Edit Billing Information Flow**
~169 tok
### **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.
#215
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.7 Download Invoice / Receipt Flow**
~108 tok
### **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.
#216
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.8 Failed Invoice Retry Flow**
~92 tok
### **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.
#217
**FRD 6 — Billing Dashboard + Payment Methods** > **3\. User Flow** > **3.9 Gawd Portal — Pixally Super Admin Read-Only View**
~136 tok
### **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.
#218
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#219
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.1 Page Scope — Unified Subscription Page**
~187 tok
### **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).
#220
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.2 Plan Card — Free Trial State**
~297 tok
### **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.#221
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.3 Plan Card — Active Paid Subscription**
~326 tok
### **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.
#222
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.4 Plan Card — Free Plan (No Trial, No Paid Extras)**
~115 tok
### **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.
#223
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.5 Plan Card — Free Plan with Paid Extras**
~162 tok
### **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.
#224
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.6 Payment Method Section — Structure**
~254 tok
### **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.
#225
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.7 Payment Method — Credit Card Only for Subscription**
~184 tok
### **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.
#226
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.8 Primary Payment Method Rule**
~188 tok
### **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.
#227
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.9 Delete Primary Method Block**
~192 tok
### **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.
#228
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.10 Add Payment Method via Stripe Elements**
~185 tok
### **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.
#229
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.11 Stripe Elements — No In-Place Edit**
~117 tok
### **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.
#230
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.12 Billing Information — Fields and Capture**
~282 tok
### **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.
#231
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.12.1 Trial with Saved Payment Method**
~173 tok
### **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.
#232
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.13 Tax Calculation via Stripe Tax**
~197 tok
### **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.
#233
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.14 Subscription Receipts Section**
~293 tok
### **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.
#234
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.14.1 Invoice Structure for Mixed-Cycle Billing (Annual Main + Monthly Extras)**
~259 tok
### **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.
#235
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.15 Failed Invoice Retry Action**
~139 tok
### **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.
#236
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.16 Credit Balance Display**
~124 tok
### **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.
#237
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.17 Admin Role — No Billing Visibility**
~127 tok
### **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.
#238
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.18 Gawd Portal — Read-Only Billing View**
~209 tok
### **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.
#239
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.18.1 Refund Flow — Pixally Super Admin Only**
~245 tok
### **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.
#240
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.19 Payment Method Routing from Other Flows**
~149 tok
### **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.
#241
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.19.1 Stripe Webhook Handling for Async Events**
~259 tok
### **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.
#242
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.20 Transactional Email — No Opt-Out**
~149 tok
### **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.
#243
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.21 Currency Scope**
~66 tok
### **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.
#244
**FRD 6 — Billing Dashboard + Payment Methods** > **4\. Functional Logic** > **4.22 Notifications Generated by Billing Events**
~152 tok
### **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.
#245
**FRD 6 — Billing Dashboard + Payment Methods** > **5\. Field Details & Validations**
~683 tok
## **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.
#246
**FRD 6 — Billing Dashboard + Payment Methods** > **6\. Success Message Handling**
~297 tok
## **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.
#247
**FRD 6 — Billing Dashboard + Payment Methods** > **7\. Error Message Handling**
~545 tok
## **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.
#248
**FRD 6 — Billing Dashboard + Payment Methods** > **8\. Edge Cases**
~794 tok
## **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
#249
**FRD 6 — Billing Dashboard + Payment Methods** > **8\. Edge Cases**
~736 tok
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.
#250
**FRD 6 — Billing Dashboard + Payment Methods** > **8\. Edge Cases**
~324 tok
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.
#251
**FRD 6 — Billing Dashboard + Payment Methods** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#252
**FRD 6 — Billing Dashboard + Payment Methods** > **9\. Acceptance Criteria**
~800 tok
* 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
#253
**FRD 6 — Billing Dashboard + Payment Methods** > **9\. Acceptance Criteria**
~137 tok
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.
#254
**FRD 6 — Billing Dashboard + Payment Methods** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#255
**FRD 6 — Billing Dashboard + Payment Methods** > **11\. Dependencies**
~569 tok
## **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.
#256
**FRD 6 — Billing Dashboard + Payment Methods** > **12\. References**
~430 tok
## **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**#257
(intro)
~1 tok
#
#258
(intro)
~1 tok
#
#259
(intro)
~1 tok
#
#260
(intro)
~1 tok
#
#261
**FRD 7 — Failed Payment Management**
~30 tok
# **FRD 7 — Failed Payment Management** **Module:** Failed Payment Management **Version:** 1.0 **Date:** April 24, 2026
#262
**FRD 7 — Failed Payment Management** > **1\. Module Overview**
~613 tok
## **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.
#263
**FRD 7 — Failed Payment Management** > **2\. User Roles & Permissions**
~335 tok
## **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
#264
**FRD 7 — Failed Payment Management** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#265
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.1 First Failed Payment — Stripe Smart Retries**
~265 tok
### **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.
#266
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.2 All Stripe Retries Exhausted — Grace Banner Appears**
~296 tok
### **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.
#267
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.3 Grace Period Email Reminders**
~179 tok
### **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.
#268
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.4 Retry Payment Action — User-Initiated During Grace**
~325 tok
### **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.
#269
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.5 Payment Method Updated During Grace — Automatic Retry**
~220 tok
### **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.
#270
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.6 Grace Period Ends — Account Suspended**
~169 tok
### **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.
#271
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.7 Suspended Account Login — Owner**
~402 tok
### **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.
#272
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.8 Pay Invoice — Reactivation Flow**
~463 tok
### **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.
#273
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.9 Admin and Team Member Login During Suspension**
~298 tok
### **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.
#274
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.10 Cancel Subscription During Grace or Suspension**
~200 tok
### **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.
#275
**FRD 7 — Failed Payment Management** > **3\. User Flow** > **3.11 Pixally Super Admin Reactivation via Gawd Portal**
~153 tok
### **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.
#276
**FRD 7 — Failed Payment Management** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#277
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.1 Scope of Failed Payment Handling**
~265 tok
### **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.
#278
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.2 Day 1 — First Failed Charge**
~195 tok
### **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.
#279
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.3 Stripe Smart Retries**
~367 tok
### **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.
#280
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.4 Grace-Period Banner Display — After Stripe Retries Exhausted**
~396 tok
### **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.
#281
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.5 Grace-Period Banner Visibility by Role**
~183 tok
### **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.
#282
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.6 Email and In-App Notification Schedule**
~480 tok
### **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).#283
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.7 Retry Payment — User-Initiated**
~230 tok
### **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.
#284
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.8 Automatic Retry on Primary Card Change**
~230 tok
### **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.
#285
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.9 Grace Period Protects Full Access**
~240 tok
### **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).
#286
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.10 Day 29 — Suspension Begins**
~795 tok
### **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).
#287
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.11 Multiple Failed Invoices Share Single Grace Period**
~219 tok
### **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).
#288
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.12 Suspended State Behavior — Owner**
~513 tok
### **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.
#289
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.13 Suspended State Behavior — Non-Owner Roles**
~343 tok
### **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.
#290
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.14 Reactivation Logic — Amount Due**
~396 tok
### **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.
#291
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.15 Reactivation Logic — New Billing Cycle Anchor and Paid Extras Restoration**
~479 tok
### **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.
#292
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.16 Reactivation Flow — Payment Processing**
~548 tok
### **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.
#293
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.17 Cancellation During Grace or Suspension**
~237 tok
### **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.
#294
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.18 Pixally Super Admin Manual Reactivation**
~265 tok
### **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.
#295
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.19 One-Time Charge Failures and Other Non-Grace Events — No Grace Period**
~336 tok
### **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.
#296
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.19.1 Owner Self-Delete Blocked During Suspension**
~178 tok
### **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.
#297
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.20 Interaction with Scheduled Downgrade**
~211 tok
### **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.
#298
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.21 Interaction with Scheduled Cycle Switch**
~122 tok
### **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.
#299
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.21.1 Interaction with Pending Team Member Invites**
~148 tok
### **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.
#300
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.21.2 Active Admin Session During Day 29 Suspension Transition**
~145 tok
### **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.
#301
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.21.3 Currency**
~56 tok
### **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.
#302
**FRD 7 — Failed Payment Management** > **4\. Functional Logic** > **4.22 Stripe Webhook Events Consumed**
~152 tok
### **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.
#303
**FRD 7 — Failed Payment Management** > **5\. Field Details & Validations**
~707 tok
## **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.
#304
**FRD 7 — Failed Payment Management** > **6\. Success Message Handling**
~328 tok
## **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.
#305
**FRD 7 — Failed Payment Management** > **7\. Error Message Handling**
~587 tok
## **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.
#306
**FRD 7 — Failed Payment Management** > **8\. Edge Cases**
~779 tok
## **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.
#307
**FRD 7 — Failed Payment Management** > **8\. Edge Cases**
~799 tok
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
#308
**FRD 7 — Failed Payment Management** > **8\. Edge Cases**
~479 tok
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.
#309
**FRD 7 — Failed Payment Management** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#310
**FRD 7 — Failed Payment Management** > **9\. Acceptance Criteria**
~800 tok
* 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
#311
**FRD 7 — Failed Payment Management** > **9\. Acceptance Criteria**
~698 tok
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.
#312
**FRD 7 — Failed Payment Management** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#313
**FRD 7 — Failed Payment Management** > **11\. Dependencies**
~631 tok
## **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**
#314
(intro)
~1 tok
#
#315
(intro)
~1 tok
#
#316
(intro)
~1 tok
#
#317
(intro)
~1 tok
#
#318
**FRD 8 — Cancel Subscription**
~27 tok
# **FRD 8 — Cancel Subscription** **Module:** Cancel Subscription **Version:** 1.0 **Date:** April 24, 2026
#319
**FRD 8 — Cancel Subscription** > **1\. Module Overview**
~561 tok
## **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.
#320
**FRD 8 — Cancel Subscription** > **2\. User Roles & Permissions**
~215 tok
## **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) — — — —
#321
**FRD 8 — Cancel Subscription** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#322
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.1 Cancel Subscription Initiation — Paid Active State**
~88 tok
### **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.
#323
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.2 Step 1 — Cancellation Reason Selector**
~334 tok
### **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.
#324
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.3 Step 2 — Before You Cancel Retention Offer**
~239 tok
### **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.
#325
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.4 Step 3 — Confirm Cancellation with Features-Lost List**
~385 tok
### **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.
#326
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.5 Step 4 — Cancellation Success Confirmation**
~239 tok
### **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.
#327
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.6 Reactivate Subscription Before Cycle End**
~229 tok
### **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.
#328
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.7 Cycle End — Transition to Free Plan**
~364 tok
### **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.
#329
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.8 Re-Subscribe Within Retention Window**
~221 tok
### **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.
#330
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.9 Deletion Warning and Hard Delete — 365-Day Inactivity**
~367 tok
### **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.
#331
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.10 Cancel During Failed-Payment Grace Period**
~267 tok
### **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.
#332
**FRD 8 — Cancel Subscription** > **3\. User Flow** > **3.11 Cancel During Suspension**
~247 tok
### **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.
#333
**FRD 8 — Cancel Subscription** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#334
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.1 Scope of Cancellation**
~211 tok
### **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.
#335
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.2 Cancel Subscription Call-to-Action Placement**
~119 tok
### **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.
#336
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.3 Four-Step Modal Flow**
~154 tok
### **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.
#337
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.4 Reason Selector — Required Selection**
~175 tok
### **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.
#338
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.5 Retention Offer — Two Alternatives**
~527 tok
### **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.
#339
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.7 Cancellation Commit — Stripe Cancel at Period End**
~238 tok
### **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.
#340
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.8 No Refund Policy**
~128 tok
### **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.
#341
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.9 Subscription Canceled Success Message — Two Variants**
~333 tok
### **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.
#342
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.10 Post-Cancellation Plan Card State**
~174 tok
### **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.
#343
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.11 Reactivate Subscription Before Cycle End**
~339 tok
### **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.
#344
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.11.1 Team Invites During Cancel-to-Cycle-End Window**
~249 tok
### **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.
#345
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.12 Cycle End Execution — Cancellation to Free Plan Transition**
~279 tok
### **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.
#346
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.13 Paid Extras at Cycle End**
~550 tok
### **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.
#347
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.14 Contractor Access After Cancellation**
~187 tok
### **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.
#348
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.15 Client Access After Cancellation**
~128 tok
### **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.
#349
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.16 Team Member Access After Cancellation**
~155 tok
### **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.
#350
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.17 365-Day Data Retention Window**
~179 tok
### **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.
#351
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.18 Deletion Warning Email Schedule**
~414 tok
### **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.
#352
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.19 Hard Deletion at Day 365**
~275 tok
### **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.
#353
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.20 Re-Subscribe Within Retention — Data Restoration**
~386 tok
### **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.
#354
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.21 Re-Signup After Hard Deletion**
~149 tok
### **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.
#355
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.22 Cancellation Email Notifications**
~357 tok
### **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.
#356
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.22.1 Super Admin-Initiated Cancellation — Owner-Facing Impact**
~250 tok
### **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.
#357
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.23 Cancellation During Grace Period**
~346 tok
### **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.
#358
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.24 Cancellation During Suspension**
~322 tok
### **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.
#359
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.25 Scheduled Downgrade and Cycle Switch Auto-Cancellation**
~176 tok
### **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.
#360
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.26 Owner Transfer Out of Scope**
~99 tok
### **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.
#361
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.27 Grace-Period Banner Visibility During Cancel Flow Modals**
~231 tok
### **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.
#362
**FRD 8 — Cancel Subscription** > **4\. Functional Logic** > **4.28 Access to Historical Invoices and Receipts Post-Cancellation**
~232 tok
### **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.
#363
**FRD 8 — Cancel Subscription** > **5\. Field Details & Validations**
~535 tok
## **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.
#364
**FRD 8 — Cancel Subscription** > **6\. Success Message Handling**
~376 tok
## **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.
#365
**FRD 8 — Cancel Subscription** > **7\. Error Message Handling**
~536 tok
## **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.
#366
**FRD 8 — Cancel Subscription** > **8\. Edge Cases**
~788 tok
## **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
#367
**FRD 8 — Cancel Subscription** > **8\. Edge Cases**
~788 tok
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
#368
**FRD 8 — Cancel Subscription** > **8\. Edge Cases**
~573 tok
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.
#369
**FRD 8 — Cancel Subscription** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#370
**FRD 8 — Cancel Subscription** > **9\. Acceptance Criteria**
~800 tok
* 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 contac
#371
**FRD 8 — Cancel Subscription** > **9\. Acceptance Criteria**
~464 tok
t 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.
#372
**FRD 8 — Cancel Subscription** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#373
**FRD 8 — Cancel Subscription** > **11\. Dependencies**
~769 tok
## **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**
#374
**FRD 9A — Subscription Impact Framework**
~48 tok
# **FRD 9A — Subscription Impact Framework** **Module:** Subscription Impact Framework (Cross-Cutting Consistency Layer) **Version:** 1.0 **Date:** April 22, 2026 **Status:** Draft for review
#375
**FRD 9A — Subscription Impact Framework** > **1\. Module Overview**
~506 tok
## **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.
#376
**FRD 9A — Subscription Impact Framework** > **2\. User Roles & Permissions**
~317 tok
## **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
#377
**FRD 9A — Subscription Impact Framework** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#378
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.1 Owner Clicks a Locked Menu Item**
~204 tok
### **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.
#379
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.2 Owner Clicks a Locked Card on a Grid-of-Cards Page**
~173 tok
### **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.
#380
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.3 Owner Clicks a Locked Entity Row in a List**
~122 tok
### **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.
#381
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.4 Owner Clicks a Locked Tab Inside a Page**
~143 tok
### **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.
#382
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.5 Owner Clicks a Locked Action Button**
~97 tok
### **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".
#383
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.6 Owner Hits an Entity Creation Limit**
~127 tok
### **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.
#384
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.7 Owner Types a Direct URL to a Locked Page**
~142 tok
### **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.
#385
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.8 Non-Owner Role Clicks Any Locked Element**
~208 tok
### **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.
#386
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.9 Owner Searches for an Entity Across Plans**
~201 tok
### **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.
#387
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.10 Plan Change Takes Effect**
~211 tok
### **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.
#388
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.11 Cascading Lock from a Locked Brand**
~176 tok
### **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.
#389
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.12 Cascading Lock from a Locked Project**
~142 tok
### **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.
#390
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.13 Contractor Portal Access After Cascade**
~276 tok
### **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.
#391
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.14 Client Portal Access After Cascade**
~154 tok
### **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.
#392
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.15 Trial Day 15 Auto-Downgrade Triggers Locks**
~242 tok
### **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.
#393
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.16 Failed Payment Grace and Suspension State Overrides**
~218 tok
### **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.
#394
**FRD 9A — Subscription Impact Framework** > **3\. User Flow** > **3.17 Cancellation Pending and Post-Cycle-End**
~186 tok
### **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.
#395
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#396
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.1 The Three Behavior Tiers**
~402 tok
### **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.
#397
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.2 The Seven Visual Lock Patterns**
~577 tok
### **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.
#398
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.3 The Cascading Lock Rule**
~327 tok
### **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).
#399
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.4 The Universal Downgrade Rule**
~462 tok
### **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.#400
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.5 Owner Upgrade Popup and Full-Page Locked State**
~341 tok
### **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.
#401
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.6 Non-Owner Upgrade Popup**
~423 tok
### **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.
#402
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.7 Visual Specifications for Lock Icons and Colors**
~307 tok
### **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.
#403
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.8 Trigger Behavior Summary by Pattern**
~216 tok
### **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.
#404
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.9 Search Behavior with Locks**
~224 tok
### **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.
#405
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.10 Automation with Locked Nodes**
~290 tok
### **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.
#406
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.11 Plan Change Visibility and Timing**
~291 tok
### **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.
#407
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.12 Multi-Agency Lock Scoping**
~140 tok
### **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.
#408
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.13 Grace Period State Override**
~194 tok
### **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.
#409
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.14 Suspension State Override**
~314 tok
### **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\\.
#410
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.15 Cancellation State Behavior**
~170 tok
### **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.
#411
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.16 Trial State and Trial-End Transition**
~160 tok
### **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.
#412
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.17 Cross-FRD Reference Map**
~280 tok
### **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.#413
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.18 Sort and Filter Behavior with Locked Rows**
~289 tok
### **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.
#414
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.19 Pagination with Mixed Accessible and Locked Rows**
~152 tok
### **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.
#415
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.20 Empty State Behavior**
~166 tok
### **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.
#416
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.21 Plan Downgrade During Grace Period**
~243 tok
### **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.
#417
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.22 Floating Action Buttons and Quick Actions**
~164 tok
### **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.
#418
**FRD 9A — Subscription Impact Framework** > **4\. Functional Logic** > **4.23 Per-User Deferred Update on Plan Change**
~158 tok
### **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.
#419
**FRD 9A — Subscription Impact Framework** > **5\. Field Details & Validations**
~525 tok
## **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.
#420
**FRD 9A — Subscription Impact Framework** > **6\. Success Message Handling**
~200 tok
## **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.
#421
**FRD 9A — Subscription Impact Framework** > **7\. Error Message Handling**
~379 tok
## **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.
#422
**FRD 9A — Subscription Impact Framework** > **8\. Edge Cases**
~752 tok
## **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.
#423
**FRD 9A — Subscription Impact Framework** > **8\. Edge Cases**
~784 tok
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.
#424
**FRD 9A — Subscription Impact Framework** > **8\. Edge Cases**
~786 tok
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
#425
**FRD 9A — Subscription Impact Framework** > **8\. Edge Cases**
~429 tok
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.
#426
**FRD 9A — Subscription Impact Framework** > **9\. Acceptance Criteria**
~8 tok
## **9\. Acceptance Criteria**
#427
**FRD 9A — Subscription Impact Framework** > **9\. Acceptance Criteria**
~800 tok
* 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
#428
**FRD 9A — Subscription Impact Framework** > **9\. Acceptance Criteria**
~429 tok
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.
#429
**FRD 9A — Subscription Impact Framework** > **10\. Manual Test Cases**
~119 tok
## **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.)_
#430
**FRD 9A — Subscription Impact Framework** > **11\. Dependencies**
~693 tok
## **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.
#431
**FRD 9A — Subscription Impact Framework** >
~12 tok
## 9B-1 Subscription Impact: Agency App Core
#432
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules**
~50 tok
# **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
#433
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **1\. Module Overview**
~454 tok
## **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.
#434
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **2\. User Roles & Permissions**
~240 tok
## **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
#435
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#436
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.1 Owner Navigates Through a Free Plan with Existing Higher-Plan Data**
~259 tok
### **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.
#437
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.2 Owner Switches Brands When Multiple Brands Exist with Some Locked**
~178 tok
### **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.
#438
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.3 Owner on Free Tries to Add a New Project Beyond Limit**
~125 tok
### **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.
#439
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.4 Owner on Free Opens a Project Details Page**
~342 tok
### **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.
#440
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.5 Owner on Free Opens an Event Details Page**
~261 tok
### **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.
#441
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.6 Owner Downgrades from Essentials to Basic with Active Contractors and Brand B**
~309 tok
### **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.
#442
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.7 Owner on Free Reaches the Team Member Limit**
~135 tok
### **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.
#443
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **3\. User Flow** > **3.8 Owner on Free Tries to Use Check Availability**
~110 tok
### **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.
#444
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#445
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.1 Dashboard**
~354 tok
### **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.
#446
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.2 Brand Setup**
~197 tok
### **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.
#447
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.3 Brands Management**
~366 tok
### **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.
#448
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.4 Events / Projects Listing**
~532 tok
### **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.
#449
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.5 Project Details**
~7 tok
### **4.5 Project Details**
#450
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.5 Project Details**
~800 tok
* 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
#451
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.5 Project Details**
~195 tok
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.
#452
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.6 Event Details**
~476 tok
### **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.
#453
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.7 Contractors Management & Setup**
~535 tok
### **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.
#454
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.8 Team Management**
~538 tok
### **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.#455
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.9 Calendar & Check Availability**
~376 tok
### **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.
#456
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.10 Tasks Management**
~203 tok
### **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.
#457
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **4\. Functional Logic** > **4.11 Library**
~170 tok
### **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.
#458
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#459
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **5\. Field Details & Validations** > **5.1 Per-Module Plan Access Summary Table**
~588 tok
### **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
#460
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **5\. Field Details & Validations** > **5.2 Key Field-Level Validations**
~403 tok
### **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.
#461
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **6\. Success Message Handling**
~215 tok
## **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.
#462
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **7\. Error Message Handling**
~481 tok
## **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.
#463
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **8\. Edge Cases**
~795 tok
## **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".#464
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **8\. Edge Cases**
~799 tok
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#465
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **8\. Edge Cases**
~271 tok
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.#466
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **9\. Acceptance Criteria**
~732 tok
## **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.
#467
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **10\. Manual Test Cases**
~112 tok
## **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.)_
#468
**FRD 9B-1 — Subscription Impact: Agency App Core Workflow Modules** > **11\. Dependencies**
~739 tok
## **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
#469
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules**
~56 tok
# **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
#470
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **1\. Module Overview**
~508 tok
## **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.
#471
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **2\. User Roles & Permissions**
~275 tok
## **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
#472
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#473
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow** > **3.1 Owner Drafts an Email in Email Center on Free Plan**
~218 tok
### **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.
#474
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow** > **3.2 Owner Configures Notifications on Free Plan**
~250 tok
### **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.
#475
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow** > **3.3 Owner Builds a Workflow Automation on Basic Plan**
~275 tok
### **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.#476
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow** > **3.4 Owner Downgrades from Studio to Essentials with an Active SMS Automation**
~284 tok
### **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.
#477
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow** > **3.5 Owner on Free Tries to Send a Proposal Linked to a Locked Brand**
~190 tok
### **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.
#478
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **3\. User Flow** > **3.6 Owner Creates an Invoice on Basic Plan**
~227 tok
### **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.
#479
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#480
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.1 Email Center**
~275 tok
### **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.
#481
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.2 Email Templates**
~205 tok
### **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.
#482
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.3 Lead Form**
~174 tok
### **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.
#483
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.4 Packages**
~190 tok
### **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.
#484
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.5 Proposals**
~252 tok
### **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.
#485
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.6 Invoices**
~487 tok
### **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.#486
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.7 Client Contract**
~158 tok
### **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.
#487
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.8 Service Agreement**
~124 tok
### **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.
#488
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.9 Questionnaires**
~155 tok
### **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.
#489
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.10 Notifications**
~525 tok
### **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.#490
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **4\. Functional Logic** > **4.11 Automation**
~601 tok
### **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.#491
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#492
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **5\. Field Details & Validations** > **5.1 Per-Module Plan Access Summary**
~360 tok
### **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
#493
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **5\. Field Details & Validations** > **5.2 Key Field-Level Validations**
~354 tok
### **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.
#494
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **6\. Success Message Handling**
~232 tok
## **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.
#495
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **7\. Error Message Handling**
~483 tok
## **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.
#496
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **8\. Edge Cases**
~793 tok
## **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.
#497
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **8\. Edge Cases**
~774 tok
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.#498
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **9\. Acceptance Criteria**
~639 tok
## **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.#499
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **10\. Manual Test Cases**
~104 tok
## **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.)_
#500
**FRD 9B-2 — Subscription Impact: Agency App Templates & Communication Modules** > **11\. Dependencies**
~685 tok
## **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
#501
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules**
~64 tok
# **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
#502
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **1\. Module Overview**
~538 tok
## **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.
#503
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **2\. User Roles & Permissions**
~225 tok
## **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
#504
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#505
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.1 Free Owner Navigates to the Reports Module**
~114 tok
### **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.
#506
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.2 Basic Owner Navigates to the Reports Module**
~234 tok
### **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.
#507
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.3 Free Owner Navigates to the Finance Module**
~176 tok
### **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.
#508
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.4 Owner Connects QuickBooks Integration on Essentials**
~163 tok
### **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.
#509
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.5 Owner Downgrades from Essentials to Basic with QuickBooks Connected**
~264 tok
### **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.
#510
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.6 Free Owner Navigates to Account Settings**
~228 tok
### **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.
#511
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.7 Owner Globally Searches for an Entity Across Plans**
~252 tok
### **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.
#512
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **3\. User Flow** > **3.8 New Owner Signs Up and Lands on Trial**
~159 tok
### **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.
#513
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#514
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.1 Finance — Parent Module**
~294 tok
### **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.#515
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.2 Finance — Billing Sub-page**
~215 tok
### **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.
#516
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.3 Finance — Profit & Loss Sub-page**
~183 tok
### **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.
#517
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.4 Finance — Taxes Sub-page**
~99 tok
### **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.
#518
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.5 Finance — Contractor Invoices Sub-page**
~235 tok
### **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.
#519
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.6 Finance — Expenses Sub-page**
~139 tok
### **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.
#520
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.7 Finance — QuickBooks Sub-page**
~220 tok
### **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.
#521
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.8 Reports — Parent Module**
~211 tok
### **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).
#522
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.9 Reports — Individual Report Cards**
~432 tok
### **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.#523
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.10 Account Settings**
~325 tok
### **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.#524
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.11 Profile Management**
~115 tok
### **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.
#525
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.12 Referral System**
~108 tok
### **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.
#526
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.13 QuickBooks Integration Module**
~341 tok
### **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.
#527
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.14 Google Calendar Integration**
~243 tok
### **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.
#528
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.15 Calendly Integration**
~224 tok
### **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.
#529
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.16 Post Production Module**
~392 tok
### **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.
#530
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.17 Global Search**
~322 tok
### **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.
#531
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.18 Agency Auth**
~266 tok
### **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.
#532
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **4\. Functional Logic** > **4.19 Leads & Clients Management**
~357 tok
### **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.#533
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#534
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **5\. Field Details & Validations** > **5.1 Per-Module Plan Access Summary**
~454 tok
### **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
#535
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **5\. Field Details & Validations** > **5.2 Key Field-Level Validations**
~440 tok
### **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.
#536
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **6\. Success Message Handling**
~295 tok
## **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.
#537
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **7\. Error Message Handling**
~465 tok
## **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.
#538
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **8\. Edge Cases**
~788 tok
## **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.
#539
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **8\. Edge Cases**
~680 tok
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.
#540
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **9\. Acceptance Criteria**
~732 tok
## **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.
#541
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **10\. Manual Test Cases**
~102 tok
## **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.)_
#542
**FRD 9B-3 — Subscription Impact: Agency App Finance, Reports, Settings & Integrations Modules** > **11\. Dependencies**
~674 tok
## **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)
#543
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)**
~51 tok
# **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
#544
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **1\. Module Overview**
~556 tok
## **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.
#545
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **2\. User Roles & Permissions**
~229 tok
## **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
#546
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow**
~5 tok
## **3\. User Flow**
#547
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.1 Contractor Logs in to Contractor Portal When Agency Is on Studio**
~181 tok
### **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.
#548
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.2 Contractor Logs in When Their Access Was Revoked Due to Studio-to-Essentials Downgrade**
~252 tok
### **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.
#549
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.3 Contractor Logs in When Agency Is on Free or Basic Plan**
~170 tok
### **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.
#550
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.4 Contractor Logs in When Agency Is in Suspended State**
~170 tok
### **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.
#551
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.5 Contractor with Access Encounters a Locked Event**
~227 tok
### **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.
#552
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.6 Client Logs in to Client Portal When Agency Is on Any Plan**
~193 tok
### **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."
#553
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.7 Client Logs in When Agency Is in Suspended State**
~105 tok
### **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.
#554
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **3\. User Flow** > **3.8 Pixally Super Admin Uses Gawd Portal**
~180 tok
### **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.
#555
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#556
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.1 Contractor Portal — Access Determination**
~323 tok
### **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.#557
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.2 Contractor Portal — Login**
~298 tok
### **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.
#558
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.3 Contractor Portal — Dashboard**
~199 tok
### **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.
#559
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.4 Contractor Portal — Events**
~337 tok
### **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.#560
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.5 Contractor Portal — Calendar**
~196 tok
### **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.
#561
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.6 Contractor Portal — W9 Form / Tax Module**
~217 tok
### **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.
#562
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.7 Contractor Portal — Payments**
~285 tok
### **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.#563
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.8 Contractor Portal — Account Settings**
~248 tok
### **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.
#564
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.9 Client Portal — Access Determination and Sub-Areas**
~645 tok
### **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.#565
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.10 Gawd Portal — Pixally Super Admin Internal Tool**
~735 tok
### **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.
#566
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **4\. Functional Logic** > **4.11 Cross-Portal Communication of Revocation State**
~302 tok
### **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.#567
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **5\. Field Details & Validations**
~10 tok
## **5\. Field Details & Validations**
#568
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **5\. Field Details & Validations** > **5.1 Per-Portal Plan Access Summary**
~379 tok
### **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.
#569
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **5\. Field Details & Validations** > **5.2 Key Field-Level Validations**
~352 tok
### **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.
#570
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **6\. Success Message Handling**
~251 tok
## **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.
#571
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **7\. Error Message Handling**
~551 tok
## **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.
#572
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **8\. Edge Cases**
~773 tok
## **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
#573
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **8\. Edge Cases**
~780 tok
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).
#574
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **8\. Edge Cases**
~261 tok
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.
#575
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **9\. Acceptance Criteria**
~613 tok
## **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.
#576
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **10\. Manual Test Cases**
~106 tok
## **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.)_
#577
**FRD 9B-4 — Subscription Impact: External Portals (Contractor, Client, Gawd)** > **11\. Dependencies**
~761 tok
## **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/](https://sehalm-aveosoft.github.io/pixally-billing-calculator/) Deprecated 0\. MASTER TABLE OF CONTENTS (20 Features)
#578
**MASTER TABLE OF CONTENTS (20 Features)**
~11 tok
# **MASTER TABLE OF CONTENTS (20 Features)**
#579
**MASTER TABLE OF CONTENTS (20 Features)** > **References**
~38 tok
## **References** * **Figma Link**: [Click Here](https://www.figma.com/design/ej0kxwP45mDKmZCZfAJ5O8/Pixally?node-id=30546-17179&t=cn2RKfDfrhelfBbY-0)
#580
**1\. Module 1 — Subscription Lifecycle**
~84 tok
# **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.
#581
**2\. Module 2 — Plan Management (Upgrade, Downgrade, Billing Cycle Switch)**
~99 tok
# **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.#582
**3\. Module 3 — Failed Payment & Suspension System**
~97 tok
# **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.#583
**4\. Module 4 — Add-Ons, Extra Seats, Discounts & Tax Management**
~90 tok
# **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)#584
**5\. Module 5 — Access Control & Limits Enforcement**
~90 tok
# **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.#585
**6\. Module 6 — Billing Dashboard & Summary View**
~106 tok
# **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.#586
**7\. Module 7 — Payment Method Management**
~85 tok
# **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.#587
**8\. Module 8 — Billing Notifications & Alerts**
~86 tok
# **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.#588
**9\. Module 9 — Billing API & Webhook Processing**
~95 tok
# **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.#589
**10\. Module 10 — Super Admin (God Mode) Billing Controls**
~103 tok
# **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#590
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)**
~24 tok
# **MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)**
#591
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **1\. Module Overview**
~213 tok
## **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.#592
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **2\. User Roles & Permissions (Table Format Only)**
~175 tok
## **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.
#593
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **3\. User Flow**
~215 tok
## **3\. User Flow**
**High-Level Lifecycle Sequence:**
1. **User signs up** and completes email verification.
2. System **creates a 14-day free trial** and displays trial dashboard.
3. User may **add a payment method** at any time during trial.
4. User initiates **paid subscription purchase**, enters payment method (if not already stored), and completes payment.
5. Subscription enters **active paid state** with full feature access.
6. User may later **cancel subscription**, triggering immediate access removal.
7. System enters a **365-day retention period** where data remains stored but inaccessible.
8. Within 365 days, user may **restore subscription**, triggering immediate access reinstatement.
9. After Day 365, system permanently **deletes all agency data** and disables login.#594
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#595
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.1 Trial Initiation**
~172 tok
### **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.
#596
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.2 Optional Payment Method Collection During Trial**
~100 tok
### **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.
#597
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.3 Trial Experience and Restrictions**
~100 tok
### **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.
#598
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.4 Paid Subscription Activation**
~208 tok
### **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.
#599
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.5 Cancellation Logic**
~188 tok
### **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.
#600
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.6 Retention Period Management (Day 1–364)**
~164 tok
### **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.
#601
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.7 Hard Deletion Logic (Day 365)**
~127 tok
### **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.
#602
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **4\. Functional Logic** > **4.8 Restoration Logic (Within 365 Days)**
~173 tok
### **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.
#603
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **5\. Field Details & Validations (Table Format Only)**
~232 tok
## **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.
#604
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **6\. Success Message Handling (Table Format Only)**
~225 tok
## **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.
#605
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **7\. Error Message Handling (Table Format Only)**
~237 tok
## **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.
#606
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **8\. Edge Cases (Table Format Only)**
~189 tok
## **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.
#607
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **9\. Acceptance Criteria**
~165 tok
## **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.#608
**MODULE 1 — SUBSCRIPTION LIFECYCLE (TRIAL → PAID → CANCELLATION → RETENTION → RESTORATION)** > **10\. Dependencies (Table Format Only)**
~194 tok
## **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
#609
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)**
~19 tok
# **MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)**
#610
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **1\. Module Overview**
~242 tok
## **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.#611
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **2\. User Roles & Permissions (Table Format Only)**
~132 tok
## **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.
#612
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **3\. User Flow**
~191 tok
## **3\. User Flow**
**High-Level Plan Change Sequence:**
1. User opens **Subscription → Manage Plan**.
2. System displays the current plan, available upgrade options, downgrade options, and billing cycle controls.
3. User selects an upgrade, downgrade, or billing cycle change.
4. System validates payment method status and resource usage as required.
5. For upgrades and monthly→annual switches, system processes a Stripe charge immediately.
6. For downgrades and annual→monthly switches, system schedules changes for the next renewal.
7. System updates plan metadata and displays appropriate banners if future changes are pending.
8. System logs all plan-change actions and sends confirmation emails.#613
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#614
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.1 Upgrade Logic**
~6 tok
### **4.1 Upgrade Logic**
#615
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.1 Upgrade Logic** > **4.1.1 Eligibility Validation**
~73 tok
#### **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.
#616
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.1 Upgrade Logic** > **4.1.2 Payment Method Validation**
~83 tok
#### **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.
#617
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.1 Upgrade Logic** > **4.1.3 Proration Calculation**
~111 tok
#### **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.
#618
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.1 Upgrade Logic** > **4.1.4 Charge and Activation**
~109 tok
#### **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.
#619
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.1 Upgrade Logic** > **4.1.5 Upgrade Failure Handling**
~75 tok
#### **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.
#620
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.2 Downgrade Logic**
~7 tok
### **4.2 Downgrade Logic**
#621
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.2 Downgrade Logic** > **4.2.1 Eligibility and Scheduling**
~80 tok
#### **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.
#622
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.2 Downgrade Logic** > **4.2.2 Resource Limit Evaluation**
~126 tok
#### **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.
#623
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.2 Downgrade Logic** > **4.2.3 Scheduled Downgrade Banner**
~65 tok
#### **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.#624
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.2 Downgrade Logic** > **4.2.4 Downgrade Execution**
~97 tok
#### **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.
#625
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.3 Billing Cycle Switch Logic**
~10 tok
### **4.3 Billing Cycle Switch Logic**
#626
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.3 Billing Cycle Switch Logic** > **4.3.1 Monthly → Annual Conversion**
~139 tok
#### **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.
#627
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.3 Billing Cycle Switch Logic** > **4.3.2 Annual → Monthly Conversion**
~109 tok
#### **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}.”#628
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **4\. Functional Logic** > **4.3 Billing Cycle Switch Logic** > **4.3.3 Execution of Scheduled Billing Cycle Change**
~58 tok
#### **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.
#629
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **5\. Field Details & Validations (Table Format Only)**
~205 tok
## **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.
#630
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **6\. Success Message Handling (Table Format Only)**
~177 tok
## **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.
#631
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **7\. Error Message Handling (Table Format Only)**
~215 tok
## **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.
#632
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **8\. Edge Cases (Table Format Only)**
~180 tok
## **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.
#633
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **9\. Acceptance Criteria**
~177 tok
## **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.#634
**MODULE 2 — PLAN MANAGEMENT (UPGRADE, DOWNGRADE, BILLING CYCLE SWITCH)** > **10\. Dependencies (Table Format Only)**
~161 tok
## **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.
#635
(intro)
~11 tok
# 3\. FAILED PAYMENT & SUSPENSION SYSTEM
#636
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM**
~13 tok
# **MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM**
#637
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **1\. Module Overview**
~210 tok
## **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.#638
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **2\. User Roles & Permissions (Table Format Only)**
~185 tok
## **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.
#639
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **3\. User Flow**
~181 tok
## **3\. User Flow**
**High-Level Workflow After Payment Failure:**
1. Stripe renewal attempt fails → webhook triggers system update to **past\_due**.
2. System starts **21-day grace period** and displays Past-Due Banner.
3. Retry attempts occur on Days **0, 2, 4, 7, 14, and 21**.
4. User may update payment method at any time to retry charge immediately.
5. If a retry succeeds → subscription returns to **active** and access is restored.
6. If all attempts fail → system schedules suspension at **11:59 PM on Day 21**.
7. After suspension, only Billing access remains available.
8. Successful payment at any time during or after suspension restores full access.#640
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#641
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.1 Initial Failed Payment Event**
~116 tok
### **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.
#642
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.2 Retry Schedule Logic**
~167 tok
### **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.
#643
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.3 User-Initiated Payment Method Update**
~106 tok
### **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.
#644
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.4 Suspension Trigger Logic**
~152 tok
### **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.
#645
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.5 Post-Suspension Behaviour**
~102 tok
### **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.
#646
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.6 Restoration After Successful Payment**
~120 tok
### **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.
#647
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **4\. Functional Logic** > **4.7 State Synchronization and Auditing**
~107 tok
### **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.
#648
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **5\. Field Details & Validations (Table Format Only)**
~159 tok
## **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.
#649
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **6\. Success Message Handling (Table Format Only)**
~151 tok
## **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.
#650
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **7\. Error Message Handling (Table Format Only)**
~221 tok
## **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.#651
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **8\. Edge Cases (Table Format Only)**
~154 tok
## **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.
#652
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **9\. Acceptance Criteria**
~171 tok
## **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.#653
**MODULE 3 — FAILED PAYMENT & SUSPENSION SYSTEM** > **10\. Dependencies (Table Format Only)**
~161 tok
## **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.
#654
(intro)
~13 tok
# 4\. ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEM
#655
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT**
~16 tok
# **MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT**
#656
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **1\. Module Overview**
~230 tok
## **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.#657
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **2\. User Roles & Permissions (Table Format Only)**
~129 tok
## **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.
#658
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **3\. User Flow**
~148 tok
## **3\. User Flow**
**High-Level Add-On & Price Adjustment Sequence:**
1. User opens **Billing → Seats** or **Checkout / Upgrade** screen.
2. System displays current seat usage, pricing, tax requirements, and discount input field (if applicable).
3. User purchases extra seats or enters a discount code.
4. System validates payment method and calculates proration and tax.
5. Stripe processes the charge instantly.
6. System updates seat availability or discount assignment.
7. User receives confirmation email and updated billing details.#659
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#660
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.1 Extra Seat Management Logic**
~10 tok
### **4.1 Extra Seat Management Logic**
#661
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.1 Extra Seat Management Logic** > **4.1.1 Seat Purchase Initiation**
~80 tok
#### **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.
#662
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.1 Extra Seat Management Logic** > **4.1.2 Proration Calculation**
~104 tok
#### **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.
#663
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.1 Extra Seat Management Logic** > **4.1.3 Stripe Subscription Item Update**
~79 tok
#### **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.
#664
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.1 Extra Seat Management Logic** > **4.1.4 Post-Purchase Behavior**
~70 tok
#### **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.
#665
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.2 Discount Code & Promotion Logic**
~11 tok
### **4.2 Discount Code & Promotion Logic**
#666
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.2 Discount Code & Promotion Logic** > **4.2.1 Discount Code Input Validation**
~83 tok
#### **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.
#667
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.2 Discount Code & Promotion Logic** > **4.2.2 Restriction Validation**
~110 tok
#### **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.
#668
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.2 Discount Code & Promotion Logic** > **4.2.3 Discount Application Logic**
~118 tok
#### **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.
#669
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.2 Discount Code & Promotion Logic** > **4.2.4 Discount Behavior Across Lifecycle Events**
~87 tok
#### **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.
#670
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.3 Tax Calculation Logic (Stripe Tax)**
~12 tok
### **4.3 Tax Calculation Logic (Stripe Tax)**
#671
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.3 Tax Calculation Logic (Stripe Tax)** > **4.3.1 Billing Address Collection**
~65 tok
#### **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.
#672
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.3 Tax Calculation Logic (Stripe Tax)** > **4.3.2 Tax Determination**
~68 tok
#### **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.
#673
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.3 Tax Calculation Logic (Stripe Tax)** > **4.3.3 Reverse-Charge Logic (VAT / GST)**
~76 tok
#### **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.
#674
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **4\. Functional Logic** > **4.3 Tax Calculation Logic (Stripe Tax)** > **4.3.4 Tax Storage & Reporting**
~49 tok
#### **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.
#675
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **5\. Field Details & Validations (Table Format Only)**
~184 tok
## **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.
#676
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **6\. Success Message Handling (Table Format Only)**
~129 tok
## **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.
#677
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **7\. Error Message Handling (Table Format Only)**
~199 tok
## **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.
#678
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **8\. Edge Cases (Table Format Only)**
~161 tok
## **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.
#679
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **9\. Acceptance Criteria**
~149 tok
## **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.#680
**MODULE 4 — ADD-ONS, EXTRA SEATS, DISCOUNTS & TAX MANAGEMENT** > **10\. Dependencies (Table Format Only)**
~147 tok
## **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
#681
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW**
~12 tok
# **MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW**
#682
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **1\. Module Overview**
~249 tok
## **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.#683
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **2\. User Roles & Permissions (Table Format Only)**
~117 tok
## **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.
#684
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **3\. User Flow**
~141 tok
## **3\. User Flow**
**High-Level Flow:**
1. User navigates to **Billing → Dashboard**.
2. System loads subscription overview, plan details, renewal data, payment method status, usage metrics, and invoice snapshot.
3. System evaluates subscription\_status and displays appropriate warning banners or redirects.
4. User may take additional actions (e.g., change plan, add seats, update payment method, view full history).
5. System updates dashboard components dynamically based on latest data from Stripe and internal services.#685
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#686
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.1 Subscription Overview Retrieval**
~98 tok
### **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.
#687
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.2 Payment Method Summary**
~113 tok
### **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.
#688
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.3 Invoice Snapshot Logic**
~100 tok
### **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.”
#689
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.4 Usage Metrics Display**
~115 tok
### **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.
#690
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.5 Subscription Status Handling**
~10 tok
### **4.5 Subscription Status Handling**
#691
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.5 Subscription Status Handling** > **4.5.1 Active Status**
~37 tok
#### **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.
#692
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.5 Subscription Status Handling** > **4.5.2 Past Due Status**
~74 tok
#### **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.
#693
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.5 Subscription Status Handling** > **4.5.3 Suspended Status**
~56 tok
#### **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.
#694
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.5 Subscription Status Handling** > **4.5.4 Canceled Status**
~55 tok
#### **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.
#695
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.6 Quick Actions & Navigation Controls**
~120 tok
### **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).
#696
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.7 Dynamic Data Refresh**
~110 tok
### **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.#697
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **4\. Functional Logic** > **4.8 Logging**
~58 tok
### **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.
#698
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **5\. Field Details & Validations (Table Format Only)**
~173 tok
## **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.
#699
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **6\. Success Message Handling (Table Format Only)**
~127 tok
## **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.
#700
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **7\. Error Message Handling (Table Format Only)**
~160 tok
## **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.
#701
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **8\. Edge Cases (Table Format Only)**
~141 tok
## **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.
#702
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **9\. Acceptance Criteria**
~149 tok
## **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.#703
**MODULE 6 — BILLING DASHBOARD & SUMMARY VIEW** > **10\. Dependencies (Table Format Only)**
~139 tok
## **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.
#704
(intro)
~12 tok
# 10\. SUPER ADMIN (GAWD MODE) BILLING CONTROLS
#705
**FEATURE 10 — MULTI-AGENCY CONTRACTOR ACCESS LOGIC**
~14 tok
# **FEATURE 10 — MULTI-AGENCY CONTRACTOR ACCESS LOGIC**
#706
**1\. MODULE OVERVIEW**
~221 tok
# **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)#707
**2\. USER ROLES & PERMISSIONS**
~124 tok
# **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.
#708
**3\. USER FLOW (WITH FLOWCHART)**
~42 tok
# **3\. USER FLOW (WITH FLOWCHART)** [F10\_multi\_agency\_contractor\_access.png](https://drive.google.com/file/d/15w0spmij1DYXNM55ZjwTlRBeO5_ZdFwO/view?usp=drive_link)
#709
**4\. FUNCTIONAL LOGIC**
~7 tok
# **4\. FUNCTIONAL LOGIC**
#710
**4\. FUNCTIONAL LOGIC** > **4.1 Global Contractor Identity**
~80 tok
### **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)#711
**4\. FUNCTIONAL LOGIC** > **4.2 Agency Switcher Initialization**
~61 tok
### **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).#712
**4\. FUNCTIONAL LOGIC** > **4.3 Subscription-Dependent Access**
~10 tok
### **4.3 Subscription-Dependent Access**
#713
**4\. FUNCTIONAL LOGIC** > **4.3 Subscription-Dependent Access** > **4.3.1 If Agency is ACTIVE**
~60 tok
#### **4.3.1 If Agency is ACTIVE**
Contractor gains FULL access:
* Assigned Projects
* Uploads
* Deliverables
* Calendar
* Messaging
* Task List
* Project Notes
* File Viewer#714
**4\. FUNCTIONAL LOGIC** > **4.3 Subscription-Dependent Access** > **4.3.2 If Agency is PAST\_DUE**
~79 tok
#### **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.”#715
**4\. FUNCTIONAL LOGIC** > **4.3 Subscription-Dependent Access** > **4.3.3 If Agency is SUSPENDED**
~102 tok
#### **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**.#716
**4\. FUNCTIONAL LOGIC** > **4.3 Subscription-Dependent Access** > **4.3.4 If Agency is CANCELED**
~32 tok
#### **4.3.4 If Agency is CANCELED** Access permanently blocked: * All contractor-agency links move to **inactive** state.
#717
**4\. FUNCTIONAL LOGIC** > **4.4 Switching Agencies**
~61 tok
### **4.4 Switching Agencies** When contractor selects another agency: System reruns subscription validation: check subscription\_status for selected agency 1. Based on status (active/past\_due/suspended), access is granted or blocked.
#718
**4\. FUNCTIONAL LOGIC** > **4.5 Logging**
~57 tok
### **4.5 Logging**
Events recorded:
* contractor\_login
* contractor\_switch\_agency
* agency\_access\_blocked
* agency\_access\_granted
* subscription\_status\_checked\_for\_contractor#719
**4\. FUNCTIONAL LOGIC** > **4.6 Security Handling**
~54 tok
### **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.#720
**5\. FIELD DETAILS & VALIDATIONS**
~103 tok
# **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
#721
**6\. ERROR MESSAGES**
~118 tok
# **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.
#722
**7\. EDGE CASES**
~135 tok
# **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
#723
**8\. TEST CASES**
~104 tok
# **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
#724
**9\. ACCEPTANCE CRITERIA**
~143 tok
# **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.#725
**10\. DEPENDENCIES**
~123 tok
# **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
#726
**MODULE 7 — PAYMENT METHOD MANAGEMENT**
~11 tok
# **MODULE 7 — PAYMENT METHOD MANAGEMENT**
#727
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **1\. Module Overview**
~226 tok
## **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.#728
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **2\. User Roles & Permissions (Table Format Only)**
~109 tok
## **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.
#729
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **3\. User Flow**
~125 tok
## **3\. User Flow**
**High-Level Workflow:**
1. User navigates to **Billing → Payment Methods**.
2. System retrieves and displays all saved Stripe payment methods.
3. User selects one of the following actions:
a. Add new payment method
b. Set default method
c. Remove existing non-default method
4. System validates the action and interacts with Stripe APIs to apply updates.
5. System refreshes the list and displays success or error messages.#730
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#731
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.1 Fetching Stored Payment Methods**
~111 tok
### **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.
#732
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.2 Adding a Payment Method**
~9 tok
### **4.2 Adding a Payment Method**
#733
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.2 Adding a Payment Method** > **4.2.1 Displaying Card Entry Form**
~64 tok
#### **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).
#734
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.2 Adding a Payment Method** > **4.2.2 Tokenization**
~48 tok
#### **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.
#735
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.2 Adding a Payment Method** > **4.2.3 Attaching Card to Customer**
~68 tok
#### **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.
#736
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.2 Adding a Payment Method** > **4.2.4 Post-Add Behaviour**
~37 tok
#### **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.
#737
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.3 Setting a Default Payment Method**
~84 tok
### **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.
#738
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.4 Removing a Payment Method**
~9 tok
### **4.4 Removing a Payment Method**
#739
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.4 Removing a Payment Method** > **4.4.1 Default Method Protection**
~73 tok
#### **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.
#740
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.4 Removing a Payment Method** > **4.4.2 Removal Logic for Non-Default Cards**
~64 tok
#### **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.
#741
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.5 Handling Card Issues and Expiration**
~94 tok
### **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.
#742
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **4\. Functional Logic** > **4.6 Data Synchronization & Logging**
~87 tok
### **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.
#743
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **5\. Field Details & Validations (Table Format Only)**
~119 tok
## **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.
#744
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **6\. Success Message Handling (Table Format Only)**
~143 tok
## **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.
#745
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **7\. Error Message Handling (Table Format Only)**
~192 tok
## **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.
#746
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **8\. Edge Cases (Table Format Only)**
~170 tok
## **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.
#747
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **9\. Acceptance Criteria**
~133 tok
## **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.#748
**MODULE 7 — PAYMENT METHOD MANAGEMENT** > **10\. Dependencies (Table Format Only)**
~120 tok
## **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.
#749
(intro)
~11 tok
# 5\. ACCESS CONTROL & LIMITS ENFORCEMENT
#750
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT**
~13 tok
# **MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT**
#751
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **1\. Module Overview**
~279 tok
## **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.#752
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **2\. User Roles & Permissions (Table Format Only)**
~190 tok
## **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.
#753
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **3\. User Flow**
~225 tok
## **3\. User Flow**
**High-Level Workflow for Access + Limits Enforcement:**
1. User opens a resource-creation flow (e.g., create project / brand / add contractor).
2. System loads current subscription limits and real-time usage counts.
3. System checks if the requested action remains within limits.
4. If within limits → resource is created and usage increments.
5. If limits exceeded → system displays remediation options (upgrade, remove resources, or request extension).
6. If user chooses upgrade → redirect to upgrade flow (Module 2).
7. If user selects resource removal → display Resource Selection Modal.
8. If user selects extension → send request to Super Admin or apply temporary override if allowed.
9. For contractors switching agencies → system validates subscription status of selected agency before granting access.#754
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#755
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.1 Multi-Agency Contractor Access Logic**
~12 tok
### **4.1 Multi-Agency Contractor Access Logic**
#756
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.1 Multi-Agency Contractor Access Logic** > **4.1.1 Global Contractor Identity**
~88 tok
#### **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.
#757
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.1 Multi-Agency Contractor Access Logic** > **4.1.2 Agency Selection & Switcher**
~96 tok
#### **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.
#758
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.1 Multi-Agency Contractor Access Logic** > **4.1.3 Subscription-Aware Access Enforcement**
~165 tok
#### **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.
#759
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.2 Subscription Limit Enforcement Logic**
~12 tok
### **4.2 Subscription Limit Enforcement Logic**
#760
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.2 Subscription Limit Enforcement Logic** > **4.2.1 Limits Source of Truth**
~81 tok
#### **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.
#761
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.2 Subscription Limit Enforcement Logic** > **4.2.2 Pre-Action Enforcement**
~102 tok
#### **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.
#762
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.3 Limit Enforcement Modal Logic**
~10 tok
### **4.3 Limit Enforcement Modal Logic**
#763
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.3 Limit Enforcement Modal Logic** > **4.3.1 Modal Presentation**
~52 tok
#### **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.
#764
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.3 Limit Enforcement Modal Logic** > **4.3.2 Resolution Options**
~86 tok
#### **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.
#765
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.3 Limit Enforcement Modal Logic** > **4.3.3 Validation**
~49 tok
#### **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).
#766
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.4 Resource Removal / Selection Modal Logic**
~13 tok
### **4.4 Resource Removal / Selection Modal Logic**
#767
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.4 Resource Removal / Selection Modal Logic** > **4.4.1 Project-Level Resolution**
~47 tok
#### **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.
#768
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.4 Resource Removal / Selection Modal Logic** > **4.4.2 Brand-Level Resolution**
~58 tok
#### **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.
#769
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.4 Resource Removal / Selection Modal Logic** > **4.4.3 Team & Seat Resolution**
~60 tok
#### **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.
#770
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.4 Resource Removal / Selection Modal Logic** > **4.4.4 Contractor Resolution**
~61 tok
#### **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.
#771
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.5 Downgrade Interaction Logic**
~10 tok
### **4.5 Downgrade Interaction Logic**
#772
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.5 Downgrade Interaction Logic** > **4.5.1 Pre-Downgrade Validation**
~62 tok
#### **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.
#773
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.5 Downgrade Interaction Logic** > **4.5.2 Execution-Time Enforcement**
~70 tok
#### **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.
#774
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.6 Concurrency & Race Condition Handling**
~91 tok
### **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.
#775
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **4\. Functional Logic** > **4.7 Temporary Extensions (Super Admin Overrides)**
~88 tok
### **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.
#776
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **5\. Field Details & Validations (Table Format Only)**
~194 tok
## **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.
#777
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **6\. Success Message Handling (Table Format Only)**
~170 tok
## **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.
#778
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **7\. Error Message Handling (Table Format Only)**
~270 tok
## **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.
#779
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **8\. Edge Cases (Table Format Only)**
~161 tok
## **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.
#780
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **9\. Acceptance Criteria**
~153 tok
## **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.#781
**MODULE 5 — ACCESS CONTROL & LIMITS ENFORCEMENT** > **10\. Dependencies (Table Format Only)**
~162 tok
## **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.
#782
(intro)
~10 tok
# 8\. BILLING NOTIFICATIONS & ALERTS
#783
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS**
~12 tok
# **MODULE 8 — BILLING NOTIFICATIONS & ALERTS**
#784
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **1\. Module Overview**
~222 tok
## **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.#785
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **2\. User Roles & Permissions (Table Format Only)**
~147 tok
## **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.
#786
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **3\. User Flow**
~152 tok
## **3\. User Flow**
**High-Level Notification Sequence:**
1. Billing event occurs (payment success, payment failure, trial ending, invoice ready, etc.).
2. System identifies event type and selects the appropriate communication template.
3. System merges dynamic variables into the template (e.g., name, plan, amount).
4. Notification is sent via Email, Push, and/or In-App channel depending on event severity.
5. Delivery status is logged and monitored for bounce or failure.
6. User receives notification and takes corrective or informational action as required.#787
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#788
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.1 Event Detection Logic**
~8 tok
### **4.1 Event Detection Logic**
#789
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.1 Event Detection Logic** > **4.1.1 Triggering Events**
~163 tok
#### **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.#790
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.2 Template Selection Logic**
~135 tok
### **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.#791
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.3 Email Delivery Workflow**
~9 tok
### **4.3 Email Delivery Workflow**
#792
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.3 Email Delivery Workflow** > **4.3.1 Sending Logic**
~70 tok
#### **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.
#793
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.3 Email Delivery Workflow** > **4.3.2 Handling Delivery Outcomes**
~76 tok
#### **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.”
#794
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.4 In-App Notification Logic**
~91 tok
### **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.
#795
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.5 Push Notification Logic**
~101 tok
### **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.#796
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **4\. Functional Logic** > **4.6 Compliance and Logging**
~86 tok
### **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.
#797
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **5\. Field Details & Validations (Table Format Only)**
~150 tok
## **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.
#798
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **6\. Success Message Handling (Table Format Only)**
~133 tok
## **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.
#799
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **7\. Error Message Handling (Table Format Only)**
~187 tok
## **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.
#800
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **8\. Edge Cases (Table Format Only)**
~145 tok
## **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.
#801
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **9\. Acceptance Criteria**
~146 tok
## **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.#802
**MODULE 8 — BILLING NOTIFICATIONS & ALERTS** > **10\. Dependencies (Table Format Only)**
~149 tok
## **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.
#803
(intro)
~10 tok
# 9\. BILLING API & WEBHOOK PROCESSING
#804
**MODULE 9 — BILLING API & WEBHOOK PROCESSING**
~12 tok
# **MODULE 9 — BILLING API & WEBHOOK PROCESSING**
#805
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **1\. Module Overview**
~272 tok
## **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.#806
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **2\. User Roles & Permissions (Table Format Only)**
~139 tok
## **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.
#807
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **3\. User Flow**
~160 tok
## **3\. User Flow**
**High-Level Processing Flow:**
1. Stripe sends a webhook event to the Pixally webhook endpoint.
2. System validates webhook signature.
3. If signature is invalid → event rejected with 400.
4. If valid → system parses payload and identifies event type.
5. System processes event using the appropriate handler logic.
6. System updates subscription status, invoice data, or payment state based on event.
7. System logs event metadata and persists raw payload for auditing.
8. System returns 200 OK to Stripe regardless of internal failures (Stripe will retry).#808
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic**
~7 tok
## **4\. Functional Logic**
#809
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.1 Webhook Reception**
~73 tok
### **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.
#810
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.2 Signature Validation**
~69 tok
### **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.
#811
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.3 Payload Parsing**
~85 tok
### **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.#812
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic**
~9 tok
### **4.4 Event-Type Handling Logic**
#813
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic** > **4.4.1 invoice.payment\_succeeded**
~89 tok
#### **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.
#814
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic** > **4.4.2 invoice.payment\_failed**
~77 tok
#### **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.
#815
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic** > **4.4.3 customer.subscription.updated**
~94 tok
#### **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.
#816
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic** > **4.4.4 customer.subscription.deleted**
~75 tok
#### **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.
#817
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic** > **4.4.5 invoice.upcoming**
~60 tok
#### **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.
#818
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.4 Event-Type Handling Logic** > **4.4.6 charge.refunded**
~62 tok
#### **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.
#819
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.5 Idempotency Protection**
~83 tok
### **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.
#820
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.6 Raw Payload Storage**
~67 tok
### **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.
#821
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.7 Internal Failure Handling**
~73 tok
### **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.
#822
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **4\. Functional Logic** > **4.8 Logging Requirements**
~74 tok
### **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.
#823
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **5\. Field Details & Validations (Table Format Only)**
~158 tok
## **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.
#824
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **6\. Success Message Handling (Table Format Only)**
~138 tok
## **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.
#825
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **7\. Error Message Handling (Table Format Only)**
~186 tok
## **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.
#826
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **8\. Edge Cases (Table Format Only)**
~152 tok
## **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.
#827
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **9\. Acceptance Criteria**
~148 tok
## **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.#828
**MODULE 9 — BILLING API & WEBHOOK PROCESSING** > **10\. Dependencies (Table Format Only)**
~146 tok
## **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.
#829
(intro)
~6 tok
# Free Plan Access List
#830
**Pixally — Free Tier Plan Access**
~105 tok
# **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
#831
**Pixally — Free Tier Plan Access** > **1\. Free-Tier Access**
~728 tok
## **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**.
#832
**Pixally — Free Tier Plan Access** > **2\. Downgrade to Free — Locked Scenarios**
~715 tok
## **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
#833
**Pixally — Free Tier Plan Access** > **3\. Notes / Assumptions**
~362 tok
## **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
#834
**Pixally — Basic Tier Plan Access**
~142 tok
# **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.
#835
**Pixally — Basic Tier Plan Access** > **1\. Basic-Tier Access**
~795 tok
## **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.
#836
**Pixally — Basic Tier Plan Access** > **2\. Downgrade to Basic — Locked Scenarios**
~528 tok
## **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
#837
**Pixally — Basic Tier Plan Access** > **3\. Notes / Assumptions**
~411 tok
## **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
#838
**Pixally — Essentials Tier Plan Access**
~182 tok
# **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.)_
#839
**Pixally — Essentials Tier Plan Access** > **1\. Essentials-Tier Access**
~729 tok
## **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 —
#840
**Pixally — Essentials Tier Plan Access** > **2\. Downgrade to Essentials — Locked Scenarios**
~310 tok
## **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
#841
**Pixally — Essentials Tier Plan Access** > **3\. Notes / Assumptions**
~354 tok
## **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).