Referral programs are one of the most effective ways to lower Customer Acquisition Cost (CAC) and drive organic growth. However, integrating third-party referral SaaS tools can be expensive. Connecting these external tools to your app's native database often results in disjointed user experiences and synchronization errors.
By leveraging a structured relational database and visual logic, you can build a native, fully customizable referral code system directly in Momen. This approach lets you retain total control over your data and reward logic without writing a single line of code.
A referral code system is a native workflow that generates unique identifiers for your existing users. It tracks new user registrations associated with those specific identifiers and securely issues rewards like credits, discounts, or status upgrades.
Building this natively solves a major operational bottleneck. It eliminates the need for expensive third-party affiliate software and keeps all user relationship data centralized in your own database.
Typical Use Cases:
Two-sided SaaS rewards (e.g., "Give $10, Get $10").
E-commerce discount generation for brand ambassadors.
Unlocking premium features or VIP roles when a user invites 3 friends.
When NOT To Use It: Avoid using this basic referral logic for highly regulated, complex multi-tier affiliate programs (MLM). Those require strict fraud prevention and compliance constraints that go beyond standard tracking.
To understand how user accounts function natively, read the documentation on User Actions. For designing the robust foundation needed for this architecture, read about the Data Model.
First, we need to set up the relational structure to track who owns which code and who invited whom.
account (system table): Add a one-to-one self-referential relationship.
Field Name | Type | Note |
|---|---|---|
referrer_id | Bigint | Stores the ID of the person who invited this user. |
activity_invite_code: Create this table to store generated credentials.
Field Name | Type | Note |
|---|---|---|
invite_code | Text | Unique random string(Must enable "Unique" constraint). |
owner_account_id | Bigint | Links the code to its creator. |

We need two primary Actionflows: one to generate the code and one to verify it.
1. Generate Referral Code
This flow ensures every user gets a unique code. Since random strings can theoretically collide, we implement a Retry Loop to guarantee uniqueness.
Variable: Create an Actionflow variable is_generated (Boolean) to track success status.

Get ID: Use the "Get ID" node to fetch the current_account_id.
Set Variable: Use a "Set Variable" node to initialize is_generated to false.

Loop: Use the SEQUENCE(0, 3, 1) formula as the data source. This generates the array [0, 1, 2], meaning the logic will retry up to 3 times (the formula includes the start value but excludes the end value).

Condition: Inside the loop, check if is_generated is false.
If False (Not Yet Generated): Proceed to the generation branch.
If True (Already Generated): Skip the iteration.

Insert Data: Add a record to the activity_invite_code table.
invite_code: Bind to the RANDOM_STRING formula.
owner_account_id: Bind to the current_account_id.
On Conflict: Set to None.

Success Check: Add a Condition node to check if the ID from the "Insert Data" node is not null.
If the ID exists, it means the database successfully saved a unique code. Set is_generated to true.
If the ID is null (collision occurred), is_generated stays false, and the loop retries.


Output: After the loop ends, query the code for the current user.
Note: Unique constraints at the database level are the most reliable way to prevent duplicate codes. By setting conflict handling to "None" and using a loop, the system will automatically "retry" until a non-repeating code is stored.
2. Verify Referral Code
This flow validates the user's input and establishes the permanent attribution link in the database.
Input: Receive the code string from the UI.
Variable: Define a Text variable status to store feedback messages.

Identity Fetch: Use "Get ID" and "Query Record" to retrieve the current user's profile data.
Pre-check: Check if the current user's referrer_id is not null.
Not Null: Already bound to an inviter. Set status to "Already Bound" and exit.

Query Code: Search the activity_invite_code table where invite_code equals the input code.

Validation Branches:
Case 1: If the Query result ID is null, set status to "Invalid Code".

Case 2: Compare the code's owner_account_id with the current_account_id. If they are the same, set status to "Cannot invite yourself".

Case 3: If the previous conditions aren't met, set status to "Verification Successful".
Update Attribution: In the Valid branch, use an Update Data node on the account table.
Update the referrer_id field with the code owner's ID.

Output: Return the status variable to the UI.

Page Variable: Define invite_code (Text) to store the result.
Display: Bind a Text component to Page Variable.invite_code.

Generate Button:
Action: OnClick -> Call Generate Referral Code.
On Success: Update invite_code variable and "Show Toast" with the result message.

Verify Button:
Action: OnClick -> Call Verify Referral Code (passing the Input value).
On Success: "Show Toast" with the returned status.

To confirm the system works as intended, use the Preview mode combined with Momen's "Login Simulation" feature. This allows you to test the logic from the perspective of multiple different users.
Step 1: Generating the Code (User 1)
Open the Preview and use the Login Simulation bar at the bottom to create or log in as User 1.
Click the "Generate" button.
Expected Result: The retry loop executes, a unique 8-character string (e.g., SKGMlszc) is displayed via the page variable, and a "Generation Successful" toast appears.
Step 2: Testing Anti-Cheating Logic (User 1)
While still logged in as User 1, enter your own generated code into the input box.
Click the "Verify" button.
Expected Result: The system identifies that the owner_account_id matches the current_account_id and triggers the "Self-Referral" branch. A toast should display: "Cannot invite yourself."
Step 3: Successful Attribution (User 2)
Switch the Login Simulation to User 2.
Enter the code generated by User 1 (SKGMlszc) and click **"Verify"**.
Expected Result: The system validates the code, updates the database, and displays: "Verification Successful."
Repeat Check: Try clicking "Verify" again. The flow should trigger the "Already Bound" condition and display: "Already Bound."
Step 4: Invalid Input (User 3)
Switch to User 3.
Enter a non-existent or "fake" code (e.g., ABC12345) and click **"Verify"**.
Expected Result: The query returns a null ID, triggering the "Code Not Found" branch. The toast should display: "Invalid Code."
Step 5: Database Final Inspection Go to Data Center -> Database to perform the final audit of the records:
**activity_invite_code Table**: Confirm that the code SKGMlszc exists and its owner_account_id matches the system ID of User 1.
**account Table**: Locate User 2’s record. The referrer_id field should now contain User 1’s ID, and the referrer relationship field should correctly point to User 1’s account profile.


You do not need to build this complex relationship architecture from scratch. We have prepared a functional template that you can use immediately.
Simply clone the project directly into your Momen workspace. Once duplicated, you can customize the reward logic (e.g., changing from credit balances to subscription extensions) and adjust the UI to perfectly match your brand.
By building natively in Momen, non-technical founders avoid the "no-code tax" of third-party integrations and maintain absolute structural control over their business logic. Clone the template today, explore the Actionflow logic, and launch your scalable growth loop with Momen.