Backend: Subscription & Plan Management
Relevant source files
The following files were used as context for generating this wiki page:
The Subscription & Plan Management system is a core backend module responsible for handling user subscriptions, processing payments, and managing plan statuses. It acts as an intermediary between the application and external payment providers like Paddle and Apple. The system's primary functions are to initiate subscription requests, create payment links or records, and verify payment completion via webhooks to update a user's plan accordingly.
This module is designed to be flexible, supporting different plan types, billing cycles, and payment providers. The main entry points for its functionalities are the subscribe and verify functions, which orchestrate the entire subscription lifecycle from initiation to activation.
Core Concepts & Data Models
The system is built around a set of well-defined data structures that represent plans, subscriptions, and their states. These types are shared between the client and server.
Sources: shared/types/plan.type.ts
User Plan (IUserPlan)
The IUserPlan interface is the central data model for a user's subscription. It stores all relevant information about the user's current plan, billing cycle, status, and payment history.
| Field | Type | Description |
|---|---|---|
id | string | The unique identifier for the plan record. |
plan | PlanType | The type of plan the user is subscribed to (e.g., CLOUD_SYNC, NUCLEUS). |
cycle | BillingCycle | The billing frequency (e.g., MONTHLY, YEARLY, LIFETIME). |
status | PlanStatus | The current status of the subscription (e.g., active, past_due). |
provider | PaymentProvider | The payment gateway used for the subscription (e.g., paddle, apple). |
providerId | string | The subscription ID from the external payment provider. |
providerData | object | A flexible object to store additional data from the provider. |
startsAt | string | The date the subscription period starts. |
endsAt | string | The date the subscription period ends. |
renewsAt | string | The date the subscription is scheduled to renew. |
Sources: shared/types/plan.type.ts:25-42
Enumerations
The system uses several enums to define the possible values for plan properties.
| Enum | Values | Description |
|---|---|---|
PlanType | FREE, CLOUD_SYNC, NUCLEUS | Defines the available subscription tiers. |
BillingCycle | MONTHLY, YEARLY, LIFETIME | Defines the billing intervals. |
PlanStatus | active, past_due, deleted, trialing | Represents the current state of a subscription. |
PaymentProvider | paddle, apple, stripe | Lists the supported payment providers. |
Sources: shared/types/plan.type.ts:3-23
Subscription Flow
The process of a user subscribing to a plan involves the client, the Nucleus backend, and an external payment provider.
High-Level Subscription Sequence
This diagram shows the general sequence of events when a user initiates a subscription from the client application.
Core Functions
The module exposes two primary functions that manage the subscription lifecycle.
Sources: server/common/plan/index.ts:5-6
1. Subscription Creation (subscribe)
The subscribe function is the entry point for creating a new subscription or modifying an existing one. It validates the request, determines the correct price, and delegates the payment creation to the appropriate provider.
Sources: server/common/plan/subscribe/index.ts
Logic Flow
Parameters
| Parameter | Type | Description | Required |
|---|---|---|---|
plan | PlanType | The desired plan type. | Yes |
cycle | BillingCycle | The desired billing cycle. | Yes |
product | string | The product context (e.g., memotron). | No |
billing | object | User's billing address information. | No |
provider | string | Explicitly specifies the payment provider (e.g., apple). Defaults to paddle. | No |
context | object | Contains contextual information like the request origin. | No |
Sources: server/common/plan/subscribe/index.ts:18-35, server/common/plan/subscribe/subscribe.test.ts:40-49
2. Payment Verification (verify)
The verify function is designed to be called by payment provider webhooks. Its purpose is to validate the incoming webhook data, parse it, and update the user's IUserPlan record in the database to reflect the successful payment. Currently, it primarily handles webhooks from Paddle.
Sources: server/common/plan/verify/index.ts
Logic Flow
- Webhook Reception: The server receives a POST request from Paddle containing payment data.
- Signature Verification: It verifies the
Paddle-Signatureheader to ensure the webhook is authentic and originated from Paddle. - Data Parsing: The function parses the webhook body to extract event details, such as
subscription_id,customer_id, and event type (e.g.,subscription.created,subscription.updated). - Plan Update: It finds the corresponding
IUserPlanrecord using theproviderId(which matches Paddle'ssubscription_id). - Database Update: The user's plan status, renewal date, and other relevant fields are updated in the database based on the webhook data.
Sources: server/common/plan/verify/index.ts:17-64
Payment Providers
The system is architected to support multiple payment providers.
Paddle (Default)
Paddle is the default payment provider. When a subscription is initiated without a specified provider, the system generates a Paddle checkout link. The verification process relies on receiving and validating webhooks from Paddle to activate and update subscriptions.
Sources: server/common/plan/subscribe/index.ts:59, server/common/plan/verify/index.ts:20-24
Apple In-App Purchase
The system includes a dedicated ApplePaymentProvider to handle subscriptions made via Apple's In-App Purchase mechanism.
Sources: server/common/plan/applePaymentProvider.ts, server/common/plan/subscribe/index.ts:57
ApplePaymentProvider Class
This class implements the IPaymentProvider interface for Apple-specific logic.
createPayment(data): This method is called when a user initiates an Apple-based subscription. Unlike Paddle, it doesn't generate a checkout URL. Instead, it creates a newIUserPlanrecord in the database with apendingstatus and aproviderofapple. The actual payment is handled on the client-side with the App Store, and the verification happens later when the client sends the transaction receipt.verifyPayment(data): This method is intended to verify a transaction receipt from Apple. It updates the user's plan status toactiveupon successful verification.
Sources: server/common/plan/applePaymentProvider.ts:12-36
Summary
The Backend Subscription & Plan Management module provides a robust and extensible framework for handling user payments and plans. By abstracting payment provider logic and using a standardized data model (IUserPlan), it effectively manages the entire subscription lifecycle. The system's reliance on webhooks for payment verification ensures that user plans are updated automatically and reliably upon successful payment. Support for multiple providers like Paddle and Apple demonstrates its flexibility in accommodating different payment ecosystems.