Composr Tutorial: eCommerce

Written by Chris Graham (ocProducts)
Use Composr's eCommerce system to sell things through your website. Our eCommerce system has a wide scope, covering:
  • Usergroup subscription (i.e. sell site access)
  • Member invoicing
  • Online store / shopping cart
  • Programmers may also add new product types, including things with digital delivery

eCommerce support is tied to a payment gateway, such as PayPal.

The system is highly extensible, where new dynamically handled and integrated products or services can be added by minimal coding by a programmer.


Payment gateways

Important – research your gateway

It is the webmaster's responsibility to research any payment system before use, to convince themselves they are happy with the quality and terms of service.

While Composr by default only supports particular payment gateways, this should not be considered an endorsement of any of those services.
To accept payment in the modern world, an organisation must obviously have some kind of 'tie in' to the banking system.
The banking system runs with international standards for things such as:
  • credit cards
  • debit cards
  • cheques ('checks' in American English)

Cheque processing is relatively straight forward, but more infrastructure is needed to process credit or debit cards. This is accomplished by using a payment gateway in one of two ways:
  1. By getting an agent to fully handle the transaction and relay the funds
  2. By having a merchant account with a bank, using the banks infrastructure and your bank account to manage the transaction yourself

Composr, by default, allows payment via PayPal & WorldPay & SecPay & CCBill, although it could be extended to support any kind of payment gateway if extended and customised by an appropriate professional. PayPal is fully supported; WorldPay and SecPay are not regularly tested.

PayPal was chosen because it is without doubt the leading form of payment on the Internet, easy to setup, and flexible in that it can provide support for funding direct from bank accounts, or cheque, as well as debit and credit card processing. Lots of people do not like PayPal policies, but we have no official position on this – development priorities simply follow funding.
WorldPay and SecPay are popular alternatives to PayPal. There are many other alternatives that Composr doesn't currently support, but could.

Specific gateway notes

PayPal

To accept website payments via credit card, or to take subscriptions, you will need a Business Account. The business accounts are free, but the fees are higher.

You will need to have SSL set up for your site, as PayPal requires IPN messages to go via SSL from Sep 30, 2016, and we have already imposed this in our default code.

You must not lock down PayPal to only accept encrypted forms.

Configuration

To configure the payment gateway settings go to Admin Zone > Setup > Configuration > eCommerce options.

Config options

The option requirements for PayPal are as follows:

Payment gateway paypal
Use local payment This must be disabled
Gateway password This should be blank
Gateway VPN username This should be blank
Gateway VPN password This should be blank
Callback password This should be blank
Postal address This should be blank
Gateway username For PayPal it is your PayPal e-mail address, but for other gateways it probably is just be any you receive e-mail on
Phone number This should be blank.
[Testing mode] Gateway username Your PayPal e-mail address (for the testing mode one, it's your sandbox PayPal e-mail address).


Documentation for other Payment gateways is provided in notes at the top of the sources/hooks/systems/ecommerce_via/<gateway>.php file. Payment systems tend to be a bit complex and ones other than PayPal are best set up by programmers who know the particular ways messages and security works between your site and the gateway.

Test mode

All supported payment gateways provide a test mode, which is turned on from the Admin Zone Configuration. Test mode allows you to make purchases from your website using the full eCommerce architecture of Composr and the payment gateway, except no money will actually be charged (it's a simulation mode) – the ideal way to test your setup without risking real money.

To prevent purchases being made by real people that you don't receive real money for, only members in a usergroup with the 'Access eCommerce system when in test mode' permission may purchase when test mode is enabled ("Purchasing is temporarily offline for maintenance. It should be back online within 24 hours: please try again later." will be seen by others). You have two supported testing choices:
  1. Enable this permission for all usergroups and test the eCommerce when the website is closed (using the SU feature, see the Testing access and privileges tutorial, Access control and privileges section)
  2. Test the eCommerce from your own admin account

For PayPal test mode goes through the PayPal sandbox. Sign up on the sandbox (this is your test account for making the sale), log in, and create a test user (this is your test account for purchasing).
Be advised that we have found the PayPal sandbox to be buggy. If your tests fail with errors like "The link you have used to enter the PayPal system is invalid. Please review the link and try again." then you may be experiencing bugs in the PayPal sandbox. By all means, please complain to PayPal about it – we have run tests and found the sandbox fails midway through purchases on configurations that work correctly for live payments.

Products

Image

The eCommerce layering in Composr for usergroup subscriptions

The eCommerce layering in Composr for usergroup subscriptions

(Click to enlarge)

Composr has an abstract system of 'products' that may be 'purchased'. These Composr products are not the same as products that are available from shopping-cart systems, but rather, special types of purchasable product or service that have their own code to handle their purchase.

In Composr by default there are the following 'kinds' of 'product':
  • usergroup subscription: you may configure as many usergroup subscriptions as you wish, and these are all handled by the 'Usergroup' product kind. Each configured subscription is considered a 'product' for sale on your site.
  • catalogue items: these are items for sale from the online store
  • orders: these products are a collection of other products bound into a group, and generated when someone finalises an order from the shopping cart
  • work: this is a generic kind of product used to represent something that has been invoiced
  • Various kinds of non-purchasable product that exist for accounting purpose – interest, tax, wage and other. These aren't for sale on your site but positive or negative transaction sums can be entered against them in the Admin Zone, so your profit/loss and cash-flow charts can be accurate.

Product kinds fit into the following general categories:
  • Invoice: requests for payment created from the Admin Zone, paid for from the invoices module (site:invoices page-link, linked from member accounts) (above: work)
  • Subscription: one-off purchases made from the purchase module (site:purchase page-link, Content > Purchasing on the default menus) and managed from the subscriptions module (site:subscriptions page-link, linked from member accounts) (above: usergroup subscriptions)
  • Shopping cart: an item purchased from the catalogue/shopping modules (site:catalogues/site:shopping page-links, Content > Products and Content > Shopping Cart, on the default menus) (above: catalogue items)
  • Other (above: interest, tax, wage, other)
  • Purchase wizard: one-off purchases made from the purchase module (site:purchase page-link, Content > Purchasing on the default menus) (above: none available out-of-the-box)

For programmers

In the code these are defined via a PRODUCT_* constant from the ecommerce code file.

While the abstraction of this may be confusing, it is very beneficial as all kinds of automatically handled products may be programmed to integrate with Composr functionality.
For example, a programmer could create the following with relative ease:
  • a product that increases the number of available hits on banners
  • a product that sends out an e-mail to a dispatch warehouse instructing them to mail out a copy of a bands latest album to the address specified in the member profile of the purchaser.
Most useful kinds of purchase can, however, be achieved with the default usergroup product: a usergroup for which membership can be bought could be given additional permissions that reflect access to features or areas of the website that would not otherwise be available. This is how most websites will use the eCommerce system because it is simple, effective, works well with PayPal, and does not require programmers to implement.

In more detail

The eCommerce system has a central transactional framework. Each type of product is sold by putting through transactions that have three key things that correspond to that product:
  1. product name (a codename, not intended for humans to read)
  2. product ID
  3. amount
Any transaction that goes through is matched to a product that will then verify the payment and dispatch the sale. The product is matched via the product name – i.e. the product name in the transaction matches the name of a product for sale. The product will usually see if the amount is correct for that product, and it will use the ID to find how to dispatch the sale. For example, on our old site (when Composr was commercial software) the 'lifetime registration' product stores the site-ID in this, and thus when the transaction went through it knew what site has been registered and could go and then send out the key etc.

Actual code (for programmers)

This is an abbreviated line of code from within the get_products method defining a product in sources/hooks/systems/ecommerce/usergroup.php:

Code (PHP)

$products['USERGROUP' . strval($sub['id'])] = array(PRODUCT_SUBSCRIPTION, $sub['s_cost'], 'handle_usergroup_subscription', array(...), $item_name);
 

The 'product name' would be USERGROUP<id>. You can see how we have created a separate product for each different kind of usergroup subscription.

The 'product ID' is actually specified via the set_needed_fields function for most product hooks. In the case of usergroup subscriptions there is no set_needed_fields method because the ID of a row in the subscriptions table will be used in this case (subscriptions are a little different). i.e. it provides the information needed to link the purchased product back to a member's actual subscription record. Actually, the 'product ID' is always a string, so it has gone through the PHP strval function, and gets converted back via the PHP intval function.

You will see we essentially have two kinds of ID here. There's an ID embedded into the product name, and the 'product ID'. Typically we generate different product names when the prices will be different in each case, while the 'product ID' typically is either the purchaser's member ID or is the ID of another table that defines the specifics about the member's customised purchase. So in this case the different configured usergroup subscriptions in Composr have different prices, so are different products – but the ID of the actual purchased subscription is not price-determining. It is possible you won't have both – for example, the 'product name' may fully distinguish the purchase – in this case you probably should just use the purchaser's member ID as the 'product ID'.

Custom product hooks that are selling many individually priced items related to a specific user will often have a get_products function that lists a large number of items. There is a mechanism for get_products to only list products matching a specific 'product name' / product title, for performance reasons. If you have 1000s of products (or more) and are linking to purchase from custom code then you should return no products unless a filter is requested, and then use that filter to determine what products to show.

Composr basically flows like follows:
  1. User goes to the purchase module in Composr, and selects a product. Alternatively some custom code or link may bypass this step and direct them deep into the purchase module, i.e. to a known product.
  2. Product message is shown, if the hook defines a get_message method.
  3. Product agreement is shown that the user must agree to, if the hook defines a get_agreement method.
  4. User details what 'product ID' they are purchasing. This happens by them filling out a form determined by the product hook's get_needed_fields method. Actually for manual transactions in the Admin Zone there may be a get_identifier_manual_field_inputter method too, because admin's typically need more control when putting through a manual purchase. get_needed_fields does not have to be defined in a hook, so this step is optional too.
  5. A 'product ID' is generated via the hooks set_needed_fields method. If there was a get_needed_fields method then this typically works by taking the form input from the previous step and saving it, and getting an ID. However sometimes hooks may just generate an ID via some other known mechanism, or will just return the purchaser's member ID. It very much depends on the necessary purchasing process for the particular kind of product.
  6. An availability check is performed, if the hook defines a is_available function. This can do things such as stock checks, sanity checks, and permission checks. It returns one of a number of possible ECOMMERCE_PRODUCT_* values, ECOMMERCE_PRODUCT_AVAILABLE if purchase may happen.
  7. The user is directed to go pay off-site
  8. An IPN (i.e. background message) is sent back to Composr when the payment has happened, and/or when the user clicks to return back to Composr.
  9. Composr interprets the IPN to get back the 'product name' and 'purchase ID'. This is very hook-dependent. For PayPal it will look at the human item-name, find the matching 'product name' (i.e. codename), and it will already know the 'product ID'. For WorldPay and possibly other payment gateways it will have to look up a specific transaction in the trans_expecting table that Composr used to track the purchase, because WorldPay doesn't route through full information as PayPal does.
  10. Composr looks in all the product hooks to find a matching defined product, checks the price, then dispatches a call to the specified handler function for that product (e.g. handle_usergroup_subscription).
  11. The handler function then does what is necessary to make the purchase happen. For a usergroup subscription this means putting the purchasing member into the appropriate usergroup.

Subscriptions and invoices have some custom handling. Subscriptions can also end, so they are separately tracked with life-time details, and there are cancellation signals that are also fed through. Each separate invoice is not given a separate product even though each has a separate price, as it would get potentially too out-of-hand, so the handling of invoice price checking is hard-coded. Invoice products could actually be taken advantage of for this – you could generate custom invoices for particular purchasable items, if very large quantities of potentially differently-priced items are involved.

Manual transactions

Normally a transaction would go through via PayPal/etc. i.e. Composr sends a user off to PayPal, and then PayPal calls back saying the transaction has happened.

However, we've designed it to be modular. In Composr another method of doing a transaction is the 'manual transaction'. The manual transaction form just allows you to simulate a transaction from the Admin Zone; the idea is that you've received a cheque (or SMS payment, or whatever) and are manually telling Composr about it so that Composr can dispatch the sale. To perform a manual transaction you need to:
  1. access the manual transaction screen (Admin Zone > Audit > eCommerce > Manual transaction).
  2. select the right product
  3. enter the correct ID number that the product will use to dispatch for this sale
  4. enter the sale amount that the product expects to be receiving (which you can leave blank for it to work this out itself).

Subscriptions

Image

Adding a capability for a usergroup subscription

Adding a capability for a usergroup subscription

(Click to enlarge)

Image

A link to the payment gateway to purchase.

A link to the payment gateway to purchase.

(Click to enlarge)

Image

The description of the usergroup subscription is shown. You'd normally put a more extensive description here, explaining why someone should upgrade.

The description of the usergroup subscription is shown. You&#039;d normally put a more extensive description here, explaining why someone should upgrade.

(Click to enlarge)

Image

Link to upgrade via a usergroup subscription.

Link to upgrade via a usergroup subscription.

(Click to enlarge)

Usergroup subscriptions are implemented on top of subscriptions.

Usergroup subscriptions are only available if the forum system is Conversr .

Set up a usergroup description as follows:
  1. Add a usergroup that members will be able to subscribe to from Admin Zone > Security > Usergroups > Add usergroup. Make sure it is not 'Open membership', otherwise people could join it without paying.
  2. Assign additional access to this usergroup (or remove access from some of the other usergroups!).
  3. Go to Admin Zone > Setup > Usergroup subscription > Add usergroup subscription
  4. Fill in the form. Be aware that a '5' 'monthly' subscription means someone pays 'every 5 months'. It does not mean a subscription is paid every month and lasts for 5 months – subscriptions last indefinitely until the user chooses to cancel them.
  5. Provide a path for members to visit the purchase module so that they may activate their subscription, if one does not already exist (it does exist by default). By default this is possible via upgrade links shown in the logged-in box as per the above screenshot. You do also this via the purchase module (site:purchase page-link, Content > Purchasing on the default menus).

You can add as many usergroup subscriptions as you like, even multiple to the same usergroup. For example, [by adding more subscriptions] you could make it cheaper to subscribe yearly than monthly.

You can edit a usergroup subscription from:
Admin Zone > Setup > Usergroup subscription > Edit usergroup subscription
You can delete a usergroup subscription from the bottom of its edit form.

You can manually put someone into a subscription using a "Manual transaction". If you do so, it is up to you to manually expire members if they cease payments. You can do this from:
Admin Zone > Audit > eCommerce > View manual subscriptions

Invoices

Image

Invoicing a member

Invoicing a member

(Click to enlarge)

Members may be invoiced by the staff. To do this, go to the Admin Zone > Audit > eCommerce > Create invoice.

Members may view their invoicing history via links in their member profiles.

Staff may quickly locate unpaid invoices and invoices for which the work has not yet been fulfilled from:
Admin Zone > Audit > eCommerce > Invoices

Online store

The Composr online store works via the existing Composr catalogues system. Out-of-the-box there is the shopping cart catalogue (called products). You can access this catalogue for modifications, and adding products to, from Content Management > Products.

The Composr store has intentionally been kept lightweight. We're not trying to compete with the dedicated eCommerce systems on features, we're trying to provide something with fantastic Composr integration and extendibility that meets the majority of people's needs. This way we are able to compete by providing eCommerce as a part of the full Composr package, rather than a standalone eCommerce system that is bloated in its own way but lacking the features needed for a wider website.

Product fields

Image

Viewing a store product

Viewing a store product

(Click to enlarge)

Image

Adding a store product

Adding a store product

(Click to enlarge)

This catalogue has some hard-coded fields:
  • Product title – the product title / name
  • Item code – a code of your choice for the item, probably taken from your internal labelling system
  • Price – the item's price (pre-tax)
  • Stock level – the number in stock
  • Stock level warning point – the point at which you should be e-mailed if the stock level reaches
  • Whether stock is being maintained – whether you want stock control (as above)
  • Tax rate – the tax rate, a percentage chosen from a list (you may edit the catalogue to change what is shown in the list)
  • Weight – the item's weight, in units of your choosing (but all items must consistently use the same units); the weight will operate with the config option that specifies how much it costs to ship a unit of weight ("Shipping cost factor")
  • Description – a description for the item

By default the catalogue is configured to allow product reviews, but you may turn these off if you wish.

You may add additional fields, such as extra product images or specifications. However do not reorder the original fields (or delete, or change the field type), as the system uses the order of these fields internally to know what they refer to. If you wish to change how they are shown do it via template editing.

Product options

A popular request is to be able to specify options when purchasing a product, such as size or colour.
This would be a major task for us to implement, and complicate the system, so we are not currently planning to add it.
There are, however, two workarounds:
  1. Simply add the different product options as separate products.
  2. If you are using PayPal a template edit can be used to let the PayPal buy button carry through an option selection. We have left an example in the ECOM_CART_BUTTON_VIA_PAYPAL.tpl template. This workaround shifts the configuration burden over to being a template editing task, and shifts the administration burden onto PayPal's end.

If you need more flexibility than this (perhaps many different product options for different kinds of product), you should consider either sponsoring extended Composr development, or using a dedicated third-party eCommerce system.

Categories and entries (i.e. the contents of your product catalogue)

Once you are happy with your set of fields, you can add categories and entries to your catalogue. As this is exactly the same as adding entries to a normal catalogue, I'll refer you to the Custom structured content (via catalogues) tutorial.

Deleting shopping cart items

Be aware that once ordered, a catalogue entry shouldn't usually be deleted. You can unvalidate the entries instead (unselect 'Validated'), and/or move it into an archive category and/or set the stock to zero. This is vital to your ledger integrity. There is an option to forcibly purge an item from the database and all past order history for it, but it's not usually recommended.

Store front

Image

Viewing the shopping cart

Viewing the shopping cart

(Click to enlarge)

Once you have entries, and your eCommerce configuration is configured, users can start using your store from the products catalogue (Content > Products, on the default menus). From here they will be able to navigate to the shopping cart (site:shopping page-link, Content > Shopping cart on the default menus) and finalise and pay for their order.

You may customise the appearance of the store in the usual way of editing catalogue templates (the products catalogue already has most of the templates overridden with eCommerce-tuned styles, so you do not need to worry about accidentally altering the look of non-eCommerce catalogues).

Guests

Guests may make purchases, if they have the right Composr permissions (to the catalogues module, the products catalogue, and the shopping module).

Guest users have no member ID, so Composr will store the order against their 'session ID' instead. Session IDs work using cookies, secured against the user's IP address. The session can be lost in many circumstances:
  • if the user has their browser set to empty cookies when closed
  • after the session expiry time (the default for this is 1 hour, but it's a config option)
  • if the user's IP address changes (router's can sometimes do this, or ISPs may expire them routinely)
  • if the user switches web browsers or machines

We can't tie the purchases to IP addresses because often thousands of users can be on the same IP address.

If you think users may be making delayed purchases as guests, you may want to consider removing Guest permissions to the shopping module, to force logins.

Handling orders

When orders are purchased, an e-mail is sent out to the staff so they can fulfil the order, and the stock level is adjusted.

Orders may be reviewed by the purchaser from their shopping module (linked from their member profile)

Order status can be changed (e.g. marked as dispatched) from:
Audit > eCommerce > eCommerce orders

Advanced tax and shipping

Tax and shipping calculations have intentionally been kept very simple, but programmers may extend them. We intentionally have architected the calculations to go through some simple common functions that you can override to addon additional behaviour if you need to.

Shipping addresses

Some custom profile fields are preinstalled to allow members to set their shipping address in their regular profile settings (instead of having to define it each time when they pay on the payment gateway). However by default these fields are not enabled, so you would need to edit them to enable 'Owner viewable' and 'Owner settable' for each field.

You can find and edit the fields from:
Admin Zone > Tools > Members > Custom Profile Fields > Edit Custom Profile Field

Currencies

The currency the website works in is defined in the configuration. If you use PayPal you need to make sure your account can accept this currency and is not set up to allow people to choose which currency to pay in (as it stops Composr being able to verify the payment if they use this feature).

Charts

Image

A profit/loss account for a fresh install

A profit/loss account for a fresh install

(Click to enlarge)

Composr includes some basic accountancy charting support. This is not intended as a replacement for a proper accountancy system, but does serve as a very useful overview of finances and a record of activity.

Composr can generate the following charts over a custom specified period:
  • Profit and loss account (Admin Zone > Audit > eCommerce > Profit/Loss account)
  • Cash flow diagram (Admin Zone > Audit > eCommerce > Cash flow diagram)

Not for formal accounting purposes

The developers do not accept any responsibility for the financial accounts of users of the Composr eCommerce system. Accountancy features are provided as an aid only and are not guaranteed to perform to match any legislative, tax, or accountancy conventions.

Logs

Transaction logs can be viewed from:
Admin Zone > Audit > eCommerce > Logs

Payment system

Image

Inputting a manual transaction

Inputting a manual transaction

(Click to enlarge)

Composr supports manual transactions to be entered. This is possible in the Admin Zone module. Entering a manual transaction will trigger any code associated with the purchase of a product (such as a usergroup promotion).

Manual transactions may also be used to input transactions that are totally external to Composr, and thus otherwise immeasurable by the charting. For example, an organisations expenditure may be recorded by manually inputting a negative transaction for the special 'Other' product.

Concepts

PayPal
The most popular online payment gateway
Payment gateway
The infrastructure for performing advanced financial transactions
Instant Payment Notification
A system, originally created by PayPal, for determining the progress of a financial transaction or ongoing subscription.
Product
An item in the eCommerce system that defines everything relating to the natural view of a product or service, including handling of any actions associated with a sale being completed or retracted; these products are not like supermarket products – they are very aggrandised and dynamic

See also


Feedback

Please rate this tutorial:

Have a suggestion? Report an issue on the tracker.