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

stueynet's avatar

Credit system structure

I am considering implementing a credits system in my new application. Yes the one I have been constantly posting questions for here.

I am trying to wrap my head around the models and relationships that must be involved. The app allows users to pay for consultations. Consultations have a cost and the cost varies on the options one selects. So lets call that consultation type. Assume bronze, silver, and gold.

So originally I was going to just give each a cost and the user could just stripe pay upon creating the consultation request. But thinking about it more I am starting to like the idea of a credits system. The nature of the app has people likely transacting more than once. So a user would buy credits and then those would be used when they create consultation requests. So structurally....

We have a

App\Consult

model and the consult has a type. My thought was that in order for a Consult to be active, it must have a transaction associated with it. So then we need a

App\Transaction 

Consult hasMany Transaction

Transaction belongsToOne Consult

But I am going bugeyed trying to figure out how credits should fit into all this. Credits are not really a model. They are really just a tally of transactions. So there will be transactions that add credits and those that remove credits.

But now the Transaction model stats to get muddy. Can it manage both the storing of new credits as well as the transactions for assigning credits to consultations?

Or do I need whole other entity for this as well? I know this is kind of general but its less about specific code and more about the overall strategy. Would love to hear people's thoughts on this since I found exactly nothing relating to it on these discuss boards.

0 likes
3 replies
ltrain's avatar

I don't understand how credits are a "tally of transactions" in your example.

Why don't you just have a total_credits col on the user table and just add/sub from it when they are bought and used. For transactions you can just have different types of transactions, and its either negative or positive in terms of being used to pay for a consultation or refunded. Yes, your app code has to keep that data in sync but otherwise it seems like your forcing credit storage into transactions because you don't want to put it somewhere else.

stueynet's avatar

Ok so each time a transaction occurs, the user's credits also need to be updated. I don't love the idea of having 2 sources of the credit total. Really if I need to get a user's credit total you just grab the transactions with that user id and add up the credit column from the transactions get the user's current available credits.

But yeah this is much simpler than I thought. So overall we would need a transactions table with transaction types:

purchase (add credits from payment source) redemption (spend credits)

I would have a simple Model method on User to get the user's credit balance. This would be derived from user()->transactions. (I will probably make a new thread for that one).

Consults would be active/paid if there is a transaction associated with that consult.

I guess then I would also have a payments table to keep track of payments for credit purchases.

Sometimes just talking (typing) it out helps to wrap my head around it. Thanks for the response!

igorblumberg's avatar

Hello, I've developed something similar, let me paste here what I'm currently doing (the difference is that the credits belong the a company, not to an user)

class Transaction extends \Eloquent {

        public function save(array $options = array())
        {
            if(parent::save($options)) {
                $company = Company::find($this->company_id);
                $company->balance += $this->value;
                return $company->save();
            }
        }
}

So, everytime I save a new transaction on the DB I also recalculate the balance of the company. My data is written in a way that all debits are negative and all credits are positive so I don't need to check the "transaction type" before updating the balance.

I am also writting a job to run daily that will recalculate the balance (based on the transactions) and if the result is different than what it's saved on company->balance I will receive an email.

1 like

Please or to participate in this conversation.