Adding affiliate marketing #4684
Replies: 5 comments
-
sequenceDiagram
participant User
participant Application
participant Commission
User->>Application: Makes a purchase using a discount
Application->>DiscountRule: Applies discount
DiscountRule->>DiscountCondition: Checks conditions
DiscountRule->>Commission: Calculate commission
DiscountRule-->>Application: Apply discount and commission
Commission-->>Application: Store commission
Application-->>User: Complete purchase with discount and commission
Extending Medusa JS for Affiliate Program with CommissionIntroductionIn this documentation, we will discuss how to extend the Medusa JS open-source application to support an affiliate program with commission functionality. The goal is to enable discounts to be linked to users, where these users can earn commissions when a sale is made using the applied discount. This feature enhancement requires adapting the existing structure, primarily focusing on entities such as DiscountRule and DiscountCondition. Feature OverviewThe extended functionality aims to allow users to earn commissions through discounts, with the following key features:
Adaptation StepsTo achieve this, follow these adaptation steps:
Medusa required modules |
Beta Was this translation helpful? Give feedback.
-
import { Entity, Column, Index, ManyToOne, JoinColumn, BeforeInsert, OneToMany } from "typeorm"; @entity() // Dynamic Discount: Indicates if the discount is dynamic. // Related DiscountRule: ID of the associated DiscountRule. // Rule Entity: Reference to the related DiscountRule entity. // Disabled Status: Indicates if the discount is currently disabled. // Parent Discount: ID of the parent discount if applicable. // Parent Discount Entity: Reference to the parent discount entity. // Start Date: The date when the discount becomes effective. // End Date: The date when the discount expires (nullable for ongoing discounts). // Validity Duration: Duration of validity (nullable for open-ended discounts). // Usage Limit: Maximum number of times the discount can be used (nullable for unlimited use). // Usage Count: Current count of how many times the discount has been used. // User Link: Reference to the related User entity for user-specific discounts. // Commission Percentage: Percentage of sale amount earned as commission (nullable). // Fixed Commission Amount: Fixed amount commission (default: 0). // Related Commissions: Commission records associated with this discount. // Related Orders: Orders associated with earned Commissions. /**
/**
// Additional Functionality: |
Beta Was this translation helpful? Give feedback.
-
Medusa Commerce Application - Discount Entity DocumentationIntroductionThe Discount entity in the Medusa commerce application represents a discount offered to customers. This document provides detailed information about the Discount entity, including its attributes, relationships, and customization options. Entity OverviewThe Discount entity is responsible for managing various aspects of discounts, such as code, eligibility, and associated rules. We have made some modifications to accommodate additional functionality related to commission types. Attributes
Relationships
BeforeInsert MethodThe BeforeInsert method ensures that discount codes are consistently formatted for storage and retrieval. It converts the discount code to uppercase and trims whitespace. Commission ConfigurationTo accommodate commission-related changes, we have introduced two commission configuration attributes:
The Additional FunctionalityYou can enhance the Discount entity by adding utility methods for total calculations related to commission types, cascading deletes for DiscountRule-related Commissions, or any other custom functionality as needed. MigrationTo add the fixed commission columns and reflect the changes in the database, you may need to create a migration script. Below is an example of a migration script that adds these columns: // src/migrations/20230306000300-add-commission-columns-to-discount.js
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddCommissionColumnsToDiscount20230306000300 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
// Add user_id column
await queryRunner.query(`
ALTER TABLE "discount"
ADD COLUMN "user_id" uuid NULL
`);
// Add foreign key constraint
await queryRunner.query(`
ALTER TABLE "discount"
ADD CONSTRAINT "fk_discount_user"
FOREIGN KEY ("user_id")
REFERENCES "user"("id")
ON DELETE CASCADE
`);
// Add commission_percentage column
await queryRunner.query(`
ALTER TABLE "discount"
ADD COLUMN "commission_percentage" numeric(5,2) NULL
`);
// Add fixed_commission_amount column
await queryRunner.query(`
ALTER TABLE "discount"
ADD COLUMN "fixed_commission_amount" numeric(10,2) DEFAULT 0 NOT NULL
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
// Drop commission_percentage column
await queryRunner.query(`
ALTER TABLE "discount"
DROP COLUMN "commission_percentage"
`);
// Drop fixed_commission_amount column
await queryRunner.query(`
ALTER TABLE "discount"
DROP COLUMN "fixed_commission_amount"
`);
// Drop foreign key constraint
await queryRunner.query(`
ALTER TABLE "discount"
DROP CONSTRAINT "fk_discount_user"
`);
// Drop user_id column
await queryRunner.query(`
ALTER TABLE "discount"
DROP COLUMN "user_id"
`);
}
} TypeScript Declaration FileA TypeScript declaration file is used to make TypeScript aware of the custom attributes. Here's an example declaration file: // src/index.d.ts
declare module "@medusajs/medusa" {
interface Discount {
user: User;
commission_percentage: number;
fixed_commission_amount: number;
}
} Model ExtensionTo create an extended Discount entity with the changes, you can create a model file as follows: // src/models/discount.ts
import { Entity } from "typeorm";
import { Discount as BaseDiscount } from "@medusajs/medusa";
@Entity()
export class Discount extends BaseDiscount {
// Custom attributes and relations can be added here.
} Loader FileA loader file allows custom attributes to be returned from API routes. Here's an example loader file: // src/loaders/discount-fields.ts
export default async function () {
const imports = await import("@medusajs/medusa/dist/api/routes/store/discounts");
imports.allowedDiscountFields = [
...imports.allowedDiscountFields,
"user",
"commission_percentage",
"fixed_commission_amount"
];
} BuildingYou can compile the TypeScript files by adding a build script to your project: {
"scripts": {
"build": "tsc"
}
} This documentation covers the Discount entity in the Medusa commerce application, along with the changes related to commission types and customization options for specific needs. |
Beta Was this translation helpful? Give feedback.
-
Extending the Medusa JS Admin UI to Add a Discount Extension MenuThis guide will illustrate the logic of extending the Medusa JS Admin UI to add a discount extension menu. The extension menu will allow users to create discounts that are applied to a specific user. Prerequisites:
Steps:
|
Beta Was this translation helpful? Give feedback.
-
hi @adamekthe |
Beta Was this translation helpful? Give feedback.
-
The Idea
I think it would be a great idea to add affiliate marketing system to Medusa. So we can leverage this for better store performance and more sales. Signed-in users would be able to share their generated medusa link for other customers and would be able to get parts of the profit from item sales.
Flow
-User creates an account and generates unique affiliate link for example www.mystore.com/affiliate/UniqueID
-When other user enters the link a cookie is placed storing the ID
-If user makes a purchase a % of the sale is awarded to the affiliate account
-Affiliates could be tracked and managed in Admin panel
Possible problems
Sending funds to the affiliates could be problematic. But it could be resolved with stripe integration or manual payments.
Beta Was this translation helpful? Give feedback.
All reactions