Skip to main content
Teun van Veggel's picture
Posted by Teun van Veggel on July 17th, 2014

Commerce Account Balance: deposit money and purchase stuff using your online account.

What if your website sells lots of small items for even smaller fees and you don't want them to have to literally pay every time they purchase them? Instead you want them to deposit money to their account once, which they can then use to purchase the different items quickly. I built a module that does just that: Commerce Account Balance.

The module (download here) allows users to deposit money to their account which then can be used to purchase 'stuff' on the website. By stuff I mean anything, since 'purchasing' means in fact 'executing a Rules Action Set', from granting access to part of the website to sending a specific email.

Most of the module blends in nicely with Rules and Commerce, trying to leave all the options for customization open. I built this module as part of an E-learning platform we're currently developing for a client. The E-learning platform is going to offer many small courses for the price of 1 or 2 euros each. Apart from saving the customer the hassle of having to pay for each course, it has obvious marketing advantages. Smaller prices are attractive and the user can decide how much money he will deposit: most likely he will deposit more than he needs. You might promote higher amounts by giving away extra money in case the user deposits more than, let's say, 50 euros.

We had a close look at websites like iconfinder.com and Shutterstock since they are good examples of what we are trying to achieve. At Iconfinder you deposit money first which you then use to purchase the access to paid icons, which are usually under a dollar. With every purchase of an icon your account balance is reduced. The same happens at Shutterstock, which gives you access to download photos a certain amount of photos after depositing money.  

So how does this module work technically? 

1. Depositing money to your account

The brilliant Commerce module chops up all the different parts of a regular commerce process and allows you only use part of the whole thing and to tweak each and every aspect of it. I didn't need Commerce Products or stand Commerce Line Items for products. Instead I created a custom Commerce Line item called Deposit using the commerce_line_item_type_info hook, that registers information about how much the user wants to deposit. The hook calls a couple of custom callbacks, one of which is the configuration callback which we use to add a new field, commerce_deposit_amount, a numeric field that sets the amount to deposit.

You can tweak the field like any other field, using different widgets, such as a select list or a textfield (or both using the Select or other module). The /deposit page renders the form for creating a 'deposit' line item with the field for the amount. Filling in the amount and clicking the 'deposit cash' button saves the new line item with the right amount set by the user and creates a new 'Commerce Order'.

The user is redirected to the checkout page and from here the Commerce module takes over. After the user finishes the order and checkout process and the payment is finished, we actually add the amount to the Users account balance. For this we use Commerce's commerce_payment_order_paid_in_full hook. The process of adding the amount to a user's account is actually a simple Rules Action. By declaring a Rules Action I give web administrators to deposit money to people's accounts by using, for example, Views Bulk Operations.

2. The purchase field

The deposit naturally increases the user's account balance. We want him/her to purchase stuff to and reduce the account balance (so he or she eventually deposits money again).

For the purchasing of things we created a new field type using the field_info hook. The new field type is called a commerce_purchase field and basically saves two values: the price of the purchase and the ID of the Rules Action to execute upon purchase. It is a field type that can be attached to anything. I won't go over the details of how to create a new field type, with it's own widget and formatter, but please leave a comment if you want to know more.

Once the purchase field is added to an entity you will see a 'buy for 10€' button as a field of the entity, where 10 € could be any amount naturally. Btw, these are localized strings and can be overriden with the Strings Overrides module. Clicking that button will cause a Modal box to pop up with 3 possible options: 1. You don't have enough money on your account, in which case you will have to deposit more. 2. You are not logged in. You can use the same Modal to log in. 3. You can purchase the item, you just need to confirm it. The Modal will inform you about how much money you have currently on your account and how much money will be left after purchasing.

The purchase Modal is wrapped in a theme function so if you don't like modals, please do change it to your needs.

3. The transaction entity

So now we have the deposits and the purchases, both of which are saved as Transaction Entites, a new entity type defined using the entity_info hook and powerful EntityAPI module. The Entity API allows you to very easily link data to other entities and automizes for example the declaration of relations in views. The 'deposit' transaction saves the Commerce Order as a property, therefore all the information related to the order, such as an invoice, can be directly linked using relations in Views.

I already thougt about adding another transaction type to be implemented soon, called the 'Redeem' transaction. With a special 'Redeem' gift code you can top up your account. The website owner can use these codes for promotional purposes.

4. Calculating the Account Balance

One of the niftiest features of the Entity API is the computed property. As powerful Views may be, if you ever had to build a custom Views Handler, you know what a nightmare it can be learning and understanding how to do this and what all the diferent methods on the Views handler classes actually do. The entity API allows you to create a new property on an entity, and all the Views handlers are build automatically.

I added the 'Account Balance' property on the User Entity, that on the fly adds and  substracts all the transaction values, giving you your accurate balance, which immediately is a new views field that can be added to any views on the user entity. Still have to look into caching this property.
 
I hope this blog post gives you a bit of insight about how to setup a module and the power that modules like EntityAPI, Commerce and Rules bring to Drupal. Please let me know in the comments if you like to know more about the technical details or if you have any questions or suggestions.