Files
Dena/docs/zagros/referral.md
2026-08-13 19:50:53 +03:30

2.3 KiB

Market: referral

Sprint: ?

Outcome:

users can invite other users.if an user sign up with another user invitation code, exchange gives inviter a bonus to encourage people to join our exchange. bonus amount is a percent of trade fee.

File destination:

{$Dena_Path}/app/jobs/referral_bonus.rb

{$Dena_Path}/app/models/bonus.rb

Commits:

What did we implement:

first of we need a table to save bonuses. we create bonus table.its columns are:

  1. trade_id: foreign key to trade tables.this shows that this bonus was created from which trade.
  2. sender_member_id: foreign key to members tables.this shows bonus was created from which member trade(invited memebr).
  3. bonus_member_id: foreign key to members tables.this shows bonus was sent to which member(inviter member).
  4. amount: amoutn of bonus
  5. state: state of bonus { pending: 0, payed: 1, rejected: 2 }
  • we have an validation on creating bonus for avoiding duplication and double paying.
validates_uniqueness_of :trade, :scope => [:sender_member_id]

this means that can not create bonus with same trade AND same sender.





  • we created a cron job that runs every 24 hour (we plan to run it in midnights to avoid putting pressure on server) This is how it works:
  1. select all last 24 hour revenues and process them in batch of 1000.
  2. get them one by one and convert them to rial and multiply them with referral bonus percent.
  3. create bonus, update users balance(with lock version) and create on revenue debit for accounting system(we cant lost money in system)
  • all calculations and db updates that related about money(critical calculations) are in transaction so if one of them blocked or rejected all changes rollbacked .
graph TD
    title:referral_job
    A[loop:batch 1000] -->|1000 of last 24h| B(one of revenue)
    B -->|revenue| D{has referral}
    D -->|no| B
    D -->|yes| F{is in rial}
    F -->|yes| I
    F -->|no| H[convert to irt]
    H --> I[calculation bonus amount]
    I --> J[changes balance]
    J --> K[create bonus and accounting things]
    K --> L{error happend?}
    L --> |yes| M[roll back everything]
    L --> |no| P
    M --> O[create bonus with pending state]
    O --> P{1000 ended?}
    P -->|yes| A
    P -->|no| B