Skip to main content

SPEC 010 — Payments


1. Feature Purpose

Payments handles the commercial side of the Equa platform: subscription plan selection, checkout, payment profile management (credit cards and bank accounts), billing history, promotional discounts, and EquaCash (in-platform credits). The backend integrates with Chargify (not Stripe) for all payment processing, subscription lifecycle, and billing.

2. Current State (Verified)

2.1 Backend

2.2 Frontend


3. Data Model

3.1 Chargify Integration (External)

Payments does not store subscription or payment data in the Equa database. All payment state lives in Chargify. The backend acts as a proxy/adapter between the Equa API and Chargify’s REST API. ChargifyConfig (billing/types.ts lines 2–5): ChargifySubscription (billing/types.ts lines 30–38): ChargifyCreditCard (billing/types.ts lines 17–24):

3.2 EquaCash

EquaCash is an in-platform credits/balance system that offsets subscription costs during checkout. When total_in_cents is covered by EquaCash, no external payment is required.

3.3 UserCoupons (Database)

Source: schema.ts (UserCoupons entity)

4. API Endpoints

Product and Pricing

Subscriptions

Payment Profiles

Payment profiles are scoped to entities (not organizations), allowing the same entity to manage payment methods across multiple organizations.

Billing History and Promo

Source: billing-endpoints.ts lines 34–161

5. Frontend Components

Pages

Components

Routes

Checkout Flow

The checkout page (check-out-page.tsx) follows a multi-step process:
  1. Select payment profile — User picks from existing profiles or adds new one
  2. Apply EquaCash — Platform credits offset the total
  3. Enter promo code — Optional coupon discount
  4. Preview purchase — Calls /subscription/preview to show final price
  5. Submit — Creates subscription via POST /organization/:organization/subscription
  6. Modals — Processing spinner, success confirmation, or error notification
State:
  • selectedProfile: number — Currently selected payment profile ID
  • couponValue: number — Applied coupon discount
  • remove: boolean — Whether removing a profile
Checkout enums (helpers/enum.ts):
Submit validation: Disabled when total_in_cents !== 0 and no profile is selected, or when total is fully covered by EquaCash.

Request/Response Types


6. Business Rules and Validation


7. Acceptance Criteria

  • Users can view available plans with feature comparison on SelectYourPlanPage
  • Credit card payment profiles can be created with billing address and card details
  • One payment profile can be set as default per entity
  • Checkout page shows cart summary with line items and total
  • Promo codes can be validated and applied to reduce the total
  • EquaCash balance is applied to reduce or fully cover the subscription cost
  • When EquaCash covers the total, checkout proceeds without a payment profile
  • Subscription preview shows the exact charge before committing
  • Subscription creation succeeds and shows confirmation
  • Billing history page displays past transactions
  • Only users with canEditOrganizationBilling can manage subscriptions
  • Only users with canEditEntityBilling can manage payment profiles
  • Product listing and pricing endpoints work without authentication
  • Payment profiles are scoped to entities, not organizations
  • Subscription cancellation works and is confirmed

8. Risks and Edge Cases


9. Dependencies