Ubercart Affiliate v2 Drupal Module
For countless organizations — especially large commercial companies — affiliate marketing is a key component of their e-commerce strategies. In the United States alone, affiliate marketing spending is projected to reach $4.1 billion by 2014, according to Forrester Research. In the Drupal world, Ubercart is still the most popular e-commerce system, with over 43,000 websites reported to be utilizing it. Thus, it is astonishing that, as of this writing, there is only a single module that provides affiliate functionality for Ubercart and Drupal 7.
The module is the Ubercart Affiliate v2 project, originally developed by Bojan Živanović, and now maintained and sponsored by Rahul Khanna. As you will see, the module offers a lot of valuable functionality. But an obvious weakness is its lack of documentation. Perhaps this article can help alleviate that problem.
As with any affiliate system, this one is designed to allow website owners to generate and provide web links that uniquely identify affiliates, who are partners in a marketing program. When Internet users follow these links, their clicks are recorded, and typically used to provide some sort of reward to the associated affiliates — such as earned commissions commensurate with the sales made to the customers. In particular, Ubercart Affiliate v2 offers a number of features:
- click tracking by user and by role
- tracking of return visits even if not done through the affiliate's link
- fixed and percentage-based commissions
- multiple commission levels, by product and by role
- affiliate reports that show links statistics, sales, and commissions
- admin reports that show sales, commissions, and payouts
- admin management of commissions, including creating, editing, and deleting
- multiple affiliate levels, allowing an upline affiliate to earn a portion of the commissions generated by downline affiliates
- integration with the Conditional Action and Token modules
Ubercart Affiliate v2 has versions for both Drupal 6 and Drupal 7. In this article, I examine how to set up and use the module, on a clean installation of Drupal 7.15 and Ubercart 7.x-3.1, the most recent releases at this time. Subsequent releases may change the appearance of what you see on the screen versus the screenshots below, should you choose to follow along; but the concepts will likely remain valid for some time.
Module Installation
In order to be installed and to function properly, Ubercart Affiliate v2 requires numerous other modules: four Drupal core modules (Image, File, Field, and Field SQL storage), three key Ubercart core modules (Order, Product, and Store), and four non-Ubercart contrib modules (Chaos tools suite, Entity API [including Entity tokens], Rules, and Views).
As soon as these prerequisite modules have been installed and enabled — whether performed using the Drupal user interface or Drush — the same can be done for Ubercart Affiliate v2. Its project name is "uc_affiliate2", and it is part of the "Ubercart - extra" module package.
Configuring an Affiliate Program
The configuration page is located at the Drupal path admin/store/settings/affiliate, and can be found via the menu options Administration > Store > Configuration > Affiliates. That page's contents are organized into five tabs: Manage, Reports, Banner/Links, Commissions, and Settings. The first two are results pages, and thus are empty when the module is first enabled. (I will return to those later.)

On the "Banner/Links" page, one can specify one or more image HTML elements, in the "Affiliate Banner Templates" textarea, which will be given affiliate links. Unfortunately, there's no explanation of what directory to which the image file paths will be relative. In the "Affiliate Text Link Template" field, one can specify some raw text or HTML, which will also be given an affiliate link. It is not clear as to why only one can be specified, even though multiple images can be. The third field is the template for the HTML code generated by the export capability in the affiliate's panel. It supports placeholders — [LINK], [TITLE], [IMG], [DESCRIPTION], [PRICE] — which sadly uses a nonstandard format for its tokens.
For illustrative purposes, I will create a couple example affiliate banner templates and a text template. The export template will be left as is.

The "Commissions" page has settings for the affiliate referral structure. The first field defines "the depth to which affiliates referrals and commissions are tracked". Presumably this means that an affiliate who joins the program without referral, is at the top of any upline containing her. Anyone else who becomes an affiliate directly from her recommendation, would be immediately under her. In addition, the commission structure can be set up so that she receives a commission when one is awarded to an affiliate under her in the referral structure. The second field, "Default Affiliate Commission Structure", should contain a number for each of the hierarchy levels. If the number has a "%" suffix, then that represents the percentage commission to be received by affiliates at that level. If the number has no "%", then it represents a fixed amount of money, in the default currency of the Ubercart store.
The default global commission structure consists of the percentages 5%, 3%, 2%, 2%, 1%, for levels 1 through 5, respectively. The first number is the commission for the affiliate corresponding to the link used by the visitor. This is referred to as the "Level 1" commission, on the reports and Ubercart order pages. The second number is a commission for his immediate upline affiliate. In other words, he would earn five percent commission, and the affiliate who brought him into the program would earn three percent.

These commission numbers are the global values, which can be overridden on a per-role basis and/or per-affiliate basis (more on that later).
On the Settings page, one can configure all of the miscellaneous settings not covered by the previously-described pages: display of upline affiliates, the order status to trigger a commission, a destination URL for invalid affiliate links, the format of affiliate URLs, the disclosure level for customer IP addresses, and settings for affiliate cookies. Most people will likely find the default values to be optimal.

Creating the Affiliate Role and Initial Members
In order to add affiliates to your marketing program, you must create a role, which in this example I will name "affiliate". To do that, go to People > Permissions > Roles.

The next step is to set the appropriate permissions for the affiliates and for managing them. At People > Permissions, in the "Ubercart Affiliate v2" section, there are three permissions. For the first one, "Act as an Affiliate", enable the new "affiliate" role. For the other two permissions — "Adjust User Commissions" and "Administer Affiliates" — enable them for whatever administrative role you had planned to perform affiliate management.

Existing users can now be made affiliates who will be at the top of any upline. I will create an example user, named "upline_affiliate", and assign to it the "affiliate" role.

The affiliate role, like any other role, can be assigned to user/1. Thus developers may be confused by the statement in the README.txt file (for the Ubercart Affiliate v2 module) that "The admin (user uid: 1) can't be an affiliate". What this means is that the superuser, even when given an affiliate role, has no affiliate referral capabilities, even though he can certainly see all of the affiliate data (as with any other module).
That same README.txt file warns one to not "assign two roles with affiliate permissions to a user", because "When the user is assigned to multiple roles, the last one with affiliate permissions is taken as the current one." Do the authors mean that only the permissions of the last affiliate role are granted to the user, while the permissions of the other affiliate roles are not granted? If so, how does one determine which role is the last one? Is at the last one granted? Also, why wouldn't the user be granted the union of all the permissions of all the roles, as is typically done with Drupal roles?
Once an affiliate role is created, then an additional commission structure field appears on the aforementioned "Commissions" page, allowing one to assign different commission percentages/values specifically to affiliates of that particular role.

Affiliate Management
Once a user has been assigned an affiliate role, many new settings are available in the user management section for that user. On the Edit page, at the bottom, there is a new "Affiliate Commissions Settings" field, where one can specify a user-specific percentage commission to override the global and role-specific commission structures.

Unfortunately, testing shows that the number provided is not used as a straightforward percentage per the field's help information. Instead, the percentage used for calculations is only 1/100th of the given number. In this example, I set it to 15. But rather than applying a 15 percent commission, the system only applied 0.15 percent to arrive at the affiliate's commission. To compensate for this problem, until it is fixed in the code, simply move the decimal point two places to the right when entering a desired commission percentage.
Another problem with this field is that its help text instructs the developer: "Leave blank to use either product or global commissions." But once a value has been entered and saved, the field can no longer be set to blank, because trying to do so always results in an SQL error. (Both problems have been reported to the module's issue queue.)
Most of the affiliate configuration and management are performed in the "Affiliate Center", which is found on a new tab in the user management section. One will immediately notice that the page does not use the admin theme (Seven, in this article), but instead the public-facing theme, which by default is Bartik.

The affiliate center is organized into six pages: Dashboard, Generate Links, Commissions, Unique Click Count, All Orders, and Downline. The dashboard page shows the user's history of sales and of clicks by unique visitors. It also shows the affiliate links, as well as the banner code for all of the banner image elements entered earlier. In this example, a URL should contain the string "affiliate/15/" for the website to give credit to this affiliate for whomever goes to that link. For instance, the link http://drupal_7_dev/affiliate/15/ would take a visitor to the home page, at which point the web address in the visitor's browser would change to http://drupal_7_dev/, thus providing some anonymity for the affiliate.
The "Generate Links" page allows an affiliate to get an HTML or CSV file for all of the selected products. In the case of the HTML file, it contains an HTML table with the product name, image, description, price, and some HTML code for displaying the image, description, and price, with an affiliate link to the image. The CSV file contains the product name, price, description, image link, and affiliate product link.
The "Commissions", "Unique Click Count", and "All Orders" pages each contain a table listing the corresponding information for the current affiliate. Of course, to see at least some results in your own testing, there needs to be at least one order. For testing purposes, you can quickly create an example product, and configure Ubercart to allow payments using a test credit card gateway.
Unfortunately, there appears to be a bug in the affiliate commission being automatically applied to the affiliate user, upon completion of the customer's purchase. One apparently has to apply each commission manually. To do so, go to the Ubercart order page; in the "Affiliate Commissions" section near the bottom of the page, set the Operation list box to "Re-apply affiliate commission"; and click the "Update" button. This is not intuitive, and would be a significant inconvenience for any online store that is generating a large number of affiliate sales. (This issue has been reported.)
Now that I have some example affiliate sales and commissions applied, there is now data at Administration > Store > Configuration > Affiliates > Manage, which summarizes some of the information for all of the affiliates.

The second tab, labeled "Reports", shows the affiliates' sales, commissions earned, and commissions paid.

The label text for that third column promises the ability to edit the paid amount, by clicking on it. However, clicking on the value for any affiliate merely takes one back to the "Manage" page, with no facility for paying the commission. Apparently the module has no integration with the Ubercart payment systems for making affiliate payments.
Creating Downline Members
For someone to be made part of the downline of an existing affiliate, the former must, before registering as a new user, visit the website using a link that gives credit to the existing affiliate. To illustrate this, first verify that a visitor to the website can create his own account (which is set at Configuration > People > Account settings). Then, as an anonymous user, go to a web address containing the identifier for the existing affiliate (in our example, "affiliate/15/"), and register for a new account. A website administrator must then grant the affiliate role to the new user.
Testing indicates that once an affiliate has been associated with a visitor's browser, it cannot be dislodged by another affiliate, even if the visitor goes to a link containing the second affiliate's identifier — unless the browser's cookies are deleted beforehand. This is true regardless of the relative levels of the two affiliates. Consequently, if a visitor first lands on a website using a referral link from one affiliate, but then revisits the site specifically using a referral link from a second affiliate who is downline from the first (so as to give credit to both affiliates), then only the first affiliate will receive any credit — unless the browser's cookies are cleared before the second affiliate's link is used.
The project's README.txt file states that the default format for affiliate links — "/affiliate/[uid]" — can be overridden by adding to the site's settings.php file a line such as the following: $conf['uc_affiliate2_path'] = 'my_affiliate_path';
Presumably, this would change the affiliate link format to "/my_affiliate_path/[uid]". Such a change is reflected at Administration > Store > Configuration > Affiliates > Settings. Unfortunately, testing reveals that using the new link format does not work, and results in a "Page not found" error. (This issue has been reported.)
In light of all of the problems identified in this article, as well as the many unresolved problems reported in the project's issue queue, one may wonder if this module is robust enough for use in a production e-commerce website. Assuming that one is able to work around all of these problems, or at least the applicable ones are fixed by future patches and module releases, then Ubercart Affiliate v2 is probably a better choice than trying to re-create all the functionality with a custom module.