Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lat4732's avatar
Level 12

Need suggestion how to build some kind of credits system

Hello everyone!

I need some suggestions for my app. Here's the deal - when a user is subscribed to a plan he collect his actions that will decrement by 1 every time the user do an action. So for example the user paid for a plan that gives him 50 actions. If he changes his profile picture his actions will lower to 49 and like that till 0 actions where the user gets "middlewared" to a page which cannot be skipped - buy more actions. What will be the best method to store these actions in the database? How should i store them - starting from 0 with increments up to 50 or starting from 50 with decrements to 0? Also can you suggest me how to organize all the processes, for example - create functions that will be called when necessary which functions will increment/decrement the user's credits.

Thanks in advance!

Best Regards, Alex

0 likes
13 replies
lat4732's avatar
Level 12

@Sinnbeck Thanks for your answer! Feel like I'm looking for different (simplier) solution.

Sinnbeck's avatar

@LarAlex ok. Just be aware that if a user looses 10 points and need to pay real money to get new, they might want you to show exactly how they were lost. So be sure to keep track of that.

Snapey's avatar

put a credits column on the user model and decrement it on each action. Middleware can then just check if credits =0

This way around then allows you to have users with more than 50, eg they got an offer or extras for something else

you could create a method on the user model to decrement credits and just call it whenever an action occurs since you always have access to the auth user model

You might want to add an audit trail. write a note into a log each time the credits go down and for what reason so that the user can understand why their account is zero

lat4732's avatar
Level 12

@Snapey Okay, that's a great solution! Absolutely what I imagined in my head. But I have another problem. Users actually SUBSCRIBE to a plan for a specific period of time which actually means that they pay every month for the privileges that their plan includes. For example their plan let them collect 100 credits and they started their subscription on 08.11.2021. How am I gonna reset their credits on every 8th day of every month for the specific time of the plan (for example 6 months)? Because they don't top-up their account, they subscribe for 100 credits every month.

Snapey's avatar

every user has a renewal date. you have a daily scheduled task that runs and copies their plan credits to their actual credits.

so in your task you check for all users that have renewal on the current day and then reset their credits

the only trick part is people that sign up on the 29, 30, 31 because there are months where this date does not occur. I would give them 100 credits on the 28th but put the renewal as the 1st so that they get reset back to 100 on the 1st and get a couple of days free. From then on they will always be on the 1st

lat4732's avatar
Level 12

@Snapey So helpful! I'll start building everything and if I encounter any difficulties I'll reply back. Thanks!

martinbean's avatar

@laralex Credits is just a form of currency. So you’ll need to create a ledger that records both debits and credits.

You should have credits_adjustments table with a foreign key pointing to a user and a column to hold an amount. This amount can either be positive (a credit) or negative (a debit). The user’s balance is the sum of these adjustments. So when a user subscribes, create a credit row.

If a user receives credits every time for each cycle in their subscription, then you can probably listen to a webhook from your payment processor. When you received a subscription renewed-type webhook, credit the user again.

Similarly, when a user performs an action, create a debit (-1 if it costs the user 1 credit to perform an action). You’ll also need to check the user’s balance to avoid them running into a negative balance.

This way, you’ll record an entire history of users’ credit transactions (earnings and spendings) so a user can both see all the credits they’ve been awarded, plus all the credits they’ve spent.

lat4732's avatar
Level 12

I've successfully created everything, except the plan renewal date. Your suggestions for setting renewal date and checking everyday at 00:00 sounds good to me. But how am I gonna build that? I heard about Laravel Scheduler but I have no idea how to use it. Any ideas how to check daily for any renewals that should happen?

lat4732's avatar
Level 12

@Sinnbeck Okay, I've created this schedule:

$schedule->call(function () {
            $users = DB::table('users')->get();
            foreach($users as $user) {

                $start_renewal_date = $user->renewal_date;
                $next_renewal_date = Carbon::createFromTimestamp(strtotime($start_renewal_date))->addMonth();

                if($next_renewal_date->isToday()) {
                    DB::table('user_set_ups')->where('user_id', $user->id)->update([
                        'renewal_required' => 1
                    ]);
                }

            }
        })->everyMinute();

but when I run php artisan schedule:run I get a success message Running scheduled command: Callback but nothing happens. (I've set the schedule time to everyMinute() so I can test it. When the app is in live production I'll change it to daily())

EDIT!!!!: The schedules are working, the problem is probably in my code.

Sinnbeck's avatar

@LarAlex this seems to be a new issue. The question is how to design such a system, but how to get that code snippet to work

Please or to participate in this conversation.