View from inside the viper

Checkout Options – Release 1.1.0

  October 21, 2010 11:47
by Nigel

Based on user feedback we have also added some new checkout options that you can configure in version 1.1.0 of Cart Viper to give you all the flexibility you need. If you have any feature requests please contact us and we would be happy to discuss them with you.

Anonymous Checkout

The store admin can now define if they would like to allow users to checkout anonymously or if they must register for an account before they can checkout.

Display Basket After Add To Cart

It is now also possible for the store admin to decide to send the user to the cart details page after an item has been added to cart, rather than stay on the current page.

Optionally Disable Modal Popup Window After Add To Cart

Once a user has added an item to their cart the admin has the option to disable the modal popup window that confirms the item has been added to cart, see below:


Instead they can display a less intrusive message that appears in the top right hand side of the website and fades out after a few seconds, see below:


In both cases all text is stored in .ascx.resx files so they can be altered to suit your needs or translated into the language of your choice.

Product News Letter

  October 20, 2010 10:21
by Nigel

Following on our discussion of new features in release 1.1.0 of our DotNetNuke ecommerce solution Cart Viper, this blog will focus on the product news letter feature.

CropperCapture[60]To allow a user to receive the product newsletter they must first enter their email address in the module on the left and then click the randomly generated link that is emailed to them to confirm they own the email address. They can also unsubscribe via this module or by clicking the link that is included in the product email newsletter.

Once they have subscribed to the newsletter they will automatically receive the product newsletter via email. The newsletter is HTML enabled and contains product title, description, images, price / special offers and links to the product details page on your store.

The below screenshot highlights the options the store admin has when they configure the newsletter:


Within the settings you can define how often in days the newsletter is sent, how old the products should be that are included in the newsletter as well as the website domain that Cart Viper is hosted on.

So in our example above we will send out the newsletter every 10 days, include products that have been added to the store within the last 5 days of the newsletter being sent and we are defining our domain to be

Release 1.1.0 – New Features

  October 18, 2010 12:52
by Nigel

After another hectic few weeks of coding we are close to the release of 1.1.0 of Cart Viper our DotNetNuke ecommerce solution. This release is packed full of new features that we are proud of, like in our previous releases we will post a blog on each new feature, this post will cover Coupons:

The store admin can now create an unlimited amount of coupons that can be then used by customers to receive the predefined discount of their purchases. When defining the coupon the admin has the ability to configure rules on how the coupon can be used.

For example they can define:

  • Minimum subtotal before the coupon can be used.
  • An expiry date.
  • If the coupon can be used once or multiple times.
  • If the discount should be a monetary discount or a percentage of the subtotal.

The flexibility when creating coupons should allow you to create the ideal tool to help promote sales in the build up to Christmas!


Cart Viper 1.0.3 – New Feature: Email A Friend

  September 16, 2010 14:45
by Nigel

Here at Cart Viper we have been busy working on version 1.0.3 of our DotNetNuke shopping cart that is full of new features , over the next few days leading up to the release of version 1.0.3 Mark and myself are going to do a series of posts discussing the new features. This post will discuss “Email A Friend”.

Due to the flexibility of Cart Vipers template driven display simply by including the [EMAILAFRIEND] tag in your productDetail.htm template you output the necessary control onto your page that allows a user to send an email relating to a product on your site.

Example template:


Example page created from template:


When “Share With A Friend” is clicked upon the email a friend control is displayed via jQuery.

Email a friend control:


The email subject and message are pre-populated with the name of your store and a link to the page with the product on, if the user is logged in the email from is also pre-populated with their email address. All fields can be edited by the user before the message is sent.

Before the message can be sent all fields are checked for profanity if found the user is informed and the message is not sent, furthermore recaptcha has been added to avoid spam being sent.

It is worth noting for privacy reasons a copy of the users message is not stored in the system.

Viper Released Into The Wild

  August 18, 2010 14:48
by Nigel

cart viper on snowcovered

Here at Cart Viper Mark and myself are pleased to say that version 1.0.0 of Cart Viper DotNetNuke ecommerce module is now complete and available to purchase!

You can download Cart Viper for a free 14 day trial here, or you can purchase Cart Viper directly from our store or from the DotNetNuke market place  Snowcovered.

This is only the beginning though as we have a head full of ideas for future releases of Cart Viper that we will begin to implement – purchasing Cart Viper automatically enables you access to all future releases.

If you have any feature requests please let us know and we will do our best to include them in a future release.

Getting PortalSettings Instance outside HttpContext in DotNetNuke

  August 13, 2010 15:59
by Nigel

One of the ideas we had for this blog was to post the lessons we had learnt during the development of Cart Viper. Although we feel as a CMS DotNetNuke is really good, as a platform to develop on the documentation is somewhat lacking. So the aim of this and future posts is to try and save you some time and hours of pulling your hair out if you are developing modules for the DotNetNuke platform by recounting the issues with the framework we have encountered.

In Cart Viper we have made extensive use of jQuery Ajax calls to provide a rich user experience. In order to achieve this we call a HttpHandler which in turn delegated the request to the appropriate class that would then process the request and return the correctly formatted JSON result. It was whilst in this class we ran into an issue.

Whilst in the HttpContext whenever you required the current PortalSettings object you could simple call:

   1: PortalSettings portalSettings = Globals.GetPortalSettings();

However as we were not in the HttpContext, PortalSettings was always null. This left us with the problem of how to instantiate the PortalSettings object.

One solution would be to pass in the PortalID as a parameter into the jQuery Ajax request, however a user could easily see the JSON request using firebug and then attempt to pass in a different PortalID into your HttpHandler, which in turn could then lead to cross portal updates. We did not like the security risks in this method so we thought how could we securely pass the current PortalID to the required class?

The solution we devised involved creating a base class that all .ascx controls we use within Cart Viper would implement:

   1: public class StoreControlBase : PortalModuleBase
   2: {
   3:     public StoreControlBase()
   4:     {
   5:     }
   6: }

In this base class we inserted the following method:

   1: /// <summary>
   2: /// Writes the portalId to an encrypted cookie
   3: /// </summary>
   4: /// <remarks>this is the used by ajax to determine the correct portalId</remarks>
   5: protected void WritePortalIdCookie()
   6: {
   7:     HttpCookie cookie = HttpContext.Current.Request.Cookies["YOUR PORTAL COOKIE"];
   8:     if (cookie == null)
   9:     {
  10:         cookie = new HttpCookie("YOUR PORTAL COOKIE");
  11:     }
  13:     string cookieValue;
  15:     if (SymmetricHelper.CanSafelyEncrypt)
  16:         cookieValue = SymmetricHelper.Encrypt(this.PortalId.ToString());
  17:     else
  18:         cookieValue = PortalId.ToString();
  20:     cookie["PortalId"] = cookieValue;
  22:     HttpContext.Current.Response.Cookies.Add(cookie);
  23: }

Then in each of the .ascx controls that make a jQuery AJAX request we simple add the following line to the page load event:

   1: protected void Page_Load(object sender, System.EventArgs e)
   2: {
   3:    //write out the portal cookie so we have it for the ajax
   4:    base.WritePortalIdCookie();
   6:    //page load as normal
   7: }

Then in the class it is just a case of getting the PortalID that is stored securely in the cookie and populating the associated PortalSettings object:

   1: /// <summary>
   2: /// Readonly access to the PortalSettings object for the
   3: /// current portal context
   4: /// </summary>
   5: protected PortalSettings PortalSettings
   6: {
   7:     get
   8:     {
   9:         HttpCookie cartCookie = HttpContext.Current.Request.Cookies["YOUR COOKIE NAME"];
  10:         if (cartCookie != null)
  11:         {
  12:             string pid = cartCookie["PortalId"];
  13:             if (SymmetricHelper.CanSafelyEncrypt &&
  14:                 !string.IsNullOrEmpty(pid))
  15:             {
  16:                 try
  17:                 {
  18:                     pid = SymmetricHelper.Decrypt(pid);
  19:                     return new PortalSettings(Int32.Parse(pid));
  20:                 }
  21:                 catch (Exception ex)
  22:                 {
  23:                     //the portal cookie is correct, rethrow
  24:                     throw ex;
  25:                 }
  26:             }
  27:         }
  29:         throw new ApplicationException("Portal cookie is not valid");
  30:     }
  31: }

This property should then return a fully populated PortalSettings object.which you can then query to get specific information relating to the Portal the request has originated from.