Paul's profilePaul Sterling's blogPhotosBlogLists Tools Help
    October 31

    Process Credit Cards Offline with dashCommerce

    A not uncommon requirement is to capture and store CC numbers for processing at some point in the future.  While this is NOT RECOMMENDED by me or Visa / Mastercard, there may be occasions when this is the appropriate solution.  Following is my implementation of this feature - provided AS-IS:

    Create a new class in App_Code\OfflineCC.cs:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Configuration;
    using System.Security.Cryptography;
    using System.Data.SqlClient;
    using Commerce.Common;
    
    namespace Commerce.OfflineCC
    {
        /// <summary>
        /// OfflineCC
        /// - store cc information locally for offline processing
        /// - store only, no retrieval function built in
        /// </summary>
        public static class OfflineCC
        {
            /// <summary>
            /// Inserts a record to CskOrderCc table
            /// </summary>
            public static void Insert(Order order)
            {
                //set values and then call SP to do insert
                int varorderid = order.OrderID;
                string varcc = order.CreditCardNumber;
                string varccv = order.CreditCardSecurityNumber;
                int varexpmonth = order.CreditCardExpireMonth;
                int varexpyear = order.CreditCardExpireYear;
                string varccsalt = "<your salt string here>";
                DateTime varcreatedon = DateTime.UtcNow.Date;
                DateTime varmodifiedon = DateTime.UtcNow.Date;
    
                SqlConnection conn = new SqlConnection();
                conn.ConnectionString = 
    ConfigurationManager.ConnectionStrings["CommerceTemplate"].ConnectionString.ToString(); SqlCommand cmd = new SqlCommand(); cmd.CommandType = CommandType.StoredProcedure; cmd.Connection = conn; cmd.CommandText = ("INSERT_CSK_Store_OfflineCC"); cmd.Parameters.Add("@orderID",SqlDbType.Int); // encrypt the cc number first // your encrypt routine here cmd.Parameters.Add("@cc",SqlDbType.VarChar); cmd.Parameters.Add("@ccv",SqlDbType.VarChar); cmd.Parameters.Add("@expMonth",SqlDbType.Int); cmd.Parameters.Add("@expYear",SqlDbType.Int); cmd.Parameters.Add("@ccSalt",SqlDbType.NVarChar); cmd.Parameters["@orderID"].Value = varorderid; cmd.Parameters["@cc"].Value = varcc; cmd.Parameters["@ccv"].Value = varccv; cmd.Parameters["@expMonth"].Value = varexpmonth; cmd.Parameters["@expYear"].Value = varexpyear; cmd.Parameters["@ccSalt"].Value = varccsalt; conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); } }

    Add a TransactionType Enum in App_Code\DataAccess\Enums.cs:

        public enum TransactionType : int
        {
            CreditCardPayment = 1,
            PayPalPayment = 2,
            Refund = 3,
            PurchaseOrder = 4,
            OfflineCreditCardPayment = 5,
            GoogleCheckout = 6
        }
    Add the call to Commerce.OfflineCC.OfflineCC.Insert in App_Code\BusinessLogic\OrderController.cs:
        public static Transaction TransactOrder(Order order, TransactionType transType)
        {
          ...
            switch (transType)
            {
                case TransactionType.PayPalPayment:
                    order.OrderNumber = companyOrderIdentifier + "-PP-" + Utility.GetRandomString();
                    break;
                case TransactionType.PurchaseOrder:
                    order.OrderNumber = companyOrderIdentifier + "-PO-" + Utility.GetRandomString();
                    break;
                case TransactionType.CreditCardPayment:
    case TransactionType.OfflineCreditCardPayment: order.OrderNumber = companyOrderIdentifier + "-CC-" + Utility.GetRandomString(); Commerce.OfflineCC.OfflineCC.Insert(order); break; }
    ...
    Add the call to the above method in Checkout.aspx.cs:
        string RunCharge()
        {
    ... Transaction trans = OrderController.TransactOrder(currentOrder, TransactionType.OfflineCreditCardPayment);
    ...

    }

    Set the provider in web.config:

     <PaymentService acceptCreditCards="true" defaultProvider="CCPaymentProvider">
      <providers>
       <clear />
       <add 
         currencyCode="USD" 
         name="CCPaymentProvider" 
         type="Commerce.Providers.CCPaymentProvider" />
      </providers>
     </PaymentService>

    Now for some SQL - this may be a bit different if you're set up with SubSonic.  Create a table to store the cc information:

    CREATE TABLE [dbo].[CSK_Order_CC](
        [ccID] [int] IDENTITY(1,1) NOT NULL,
        [orderID] [int] NOT NULL,
        [cc] [nvarchar](250) NOT NULL,
        [ccv] [varchar](50) NULL,
        [expMonth] [int] NOT NULL,
        [expYear] [int] NOT NULL,
        [ccSalt] [nvarchar](50) NULL,
        [createdOn] [datetime] NULL 
            CONSTRAINT [DF_CSK_Order_CC_createdOn]  DEFAULT (getdate()),
        [modifiedOn] [datetime] NULL 
            CONSTRAINT [DF_CSK_Order_CC_modifiedOn]  DEFAULT (getdate()),
     CONSTRAINT [PK_CSK_Order_CC] PRIMARY KEY CLUSTERED 
    (
        [ccID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
        IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, 
        ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

    Create the stored procedure to do the insert to the table:

    CREATE PROCEDURE [dbo].[INSERT_CSK_Store_OfflineCC]
        (
                @orderID int
               ,@cc varchar(200)
               ,@ccv varchar(50)
               ,@expMonth int
               ,@expYear int
               ,@ccSalt nvarchar(50)
        )
    AS    
            BEGIN
    
                INSERT INTO [].[dbo].[CSK_Order_CC]
               ([orderID]
               ,[cc]
               ,[ccv]
               ,[expMonth]
               ,[expYear]
               ,[ccSalt]
               ,[createdOn]
               ,[modifiedOn])
         VALUES
               (@orderID
               ,@cc
               ,@ccv
               ,@expMonth
               ,@expYear
               ,@ccSalt
               ,GetDate()
               ,GetDate())
        
            END
        
        RETURN
    

    There you go!

    Please use this responsibly if you do use it and be sure to salt + encrypt the credit card numbers.  As always, feedback is welcome.

    -Paul

    October 23

    Umbraco 3 - Looks even better than before!

    I spent this afternoon setting up some samples on a new Umbraco v3 installation.  I had looked at this open-source CMS a few months back but had abandoned it due to sketchy documentation and the lack of a production ready commerce module.  Looks like 'most' of the documentation has been addressed - still missing a comprehensive guide, but so are most open source projects.  The missing commerce module is a moot-point now since I've settled on dashCommerce (a standalone project) there is a commerce module for Umbraco, but I don't think it's production ready.

    Honestly, the simplicity and focus of Umbraco is more appealing than DNN - at least to me.  At this point I'm back a few steps as I thought I was settled on DNN and am off to OpenForce in two weeks.  Umbraco seems much more approachable from the authoring perspective than DNN.

    If anyone has some input here I'd be thrilled to consider your views.

    Thanks,

    -Paul

    October 19

    Using dashCommerce (2.2) With DotNetNuke (4.5.5)

    We are using dashCommerce as our web commerce solution and DotNetNuke as our content solution.  I would, of course, prefer to use an integrated DNN store module, there are several available, but none can approach the feature set and usability of dC.  Perhaps one day dC will be ported to a DNN module (Chris?).  The rest of this post details the steps I've taken to use these two implementations together as an integrated site.

    My approach:
    With each site I create I first logically separate out the product information from the other site content.  Having done this I'm ready to begin - okay, a little bit simplified but on to the details.  I install DNN and dC in different physical directories at the same level and run through the installer for each project.

    Create the IIS Virtual Directories
    Create a 'parent' VD to contain the VD's for both the DNN and dC projects.  Then create a VD for DNN and a VD for dC under this 'parent' VD.  dCWithDNN.com is the parent VD, store is the VD for dC, and home is the VD for DNN.

    IIS 
    In the root of the parent VD create a default.aspx page with the following in the Page_Load event:

        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Redirect("home/default.aspx");  
        }

    This will simply forward the request to the DNN site for processing. Yes, this results in an extra request for every domain request - suggestions for cleaning this up?

    In DNN make sure you create an alias for your site (portal) that will resolve to the correct site.  In the DNN Host > Portals list set the alias of your site to be as follows (NB:  this is for a VD under the Default Web Site in IIS, as shown above):

    Portal Alias = <default web site name>/dCWithDNN.com/home

    For a domain web site the portal alias will be:

    Portal Alias = www.<yourdomain>.com/home

    At this point you should be able to browse the default DNN and dC sites - for the dC site the address will be:

    <default web site name>/dCWithDNN.com/store

    Configure ASP.NET Authorization, Membership, and Profile

    In each site's web.config you need to make the entries for Authorization, Membership, and Profile sections the same.  I realize this is very straightforward, but it gave me some grief while I was first getting this together, so take the time to get it right. 

    It's worth a note here that I've ended up with a sort of hybrid in regard to these items.  I'm using the ASP.Net Profile provider so the DNN Profile bits aren't used - this could be changed I'm sure.  Also, the Roles and Users are administered via DNN and not dC, although the Role for the dC admin user needs to be set correctly.  Either create a 'storeadmin' role and assign the dC admin user to this role (make sure to update the web.config in .../store/admin/... with the role to allow access to the store administration section).

    Following are the sections that need to be identical in both web.config files:

          <connectionStrings>
        <add name="SiteSqlServer" 
             connectionString="Data Source=<db server>\SQLExpress;Initial Catalog=dCDNN;
                              User=;password=;" 
             providerName="System.Data.SqlClient" />
    ...

    <machineKey validationKey="<key here>" decryptionKey="<key here>" decryption="3DES" validation="SHA1" /> <authentication mode="Forms"> <forms name=".HGIWEB" protection="All" timeout="60" cookieless="UseCookies" enableCrossAppRedirects="true" /> </authentication> <!-- ASP.NET 2 Membership/Profile/Role and AnonymousAuthentication Providers --> <anonymousIdentification enabled="true" cookieName=".ASPXANONYMOUS" cookieTimeout="100000" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="None" domain="" /> <roleManager enabled="true"> <providers> <clear /> <add name="AspNetSqlRoleProvider" connectionStringName="SiteSqlServer" applicationName="DotNetNuke" type="System.Web.Security.SqlRoleProvider" /> </providers> </roleManager> <membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15"> <providers> <clear /> <add connectionStringName="SiteSqlServer" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="DotNetNuke" requiresUniqueEmail="false" passwordFormat="Encrypted" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" passwordStrengthRegularExpression="" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider,
    System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
    " /> </providers> </membership> <profile enabled="true" defaultProvider="AspNetSqlProvider"> <providers> <clear /> <add name="AspNetSqlProvider" type="System.Web.Profile.SqlProfileProvider,
    System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
    " connectionStringName="SiteSqlServer" applicationName="DotNetNuke" /> </providers> <properties> <add name="LastShippingAddress" type="Commerce.Common.Address"
    allowAnonymous="true"/> <add name="LastBillingAddress" type="Commerce.Common.Address"
    allowAnonymous="true"/> <add name="FullName" type="System.String"
    allowAnonymous="true"/> <add name="Email" type="System.String"
    allowAnonymous="true"/> <add name="CurrentOrderTax" type="System.Decimal"
    allowAnonymous="true"/> <add name="CurrentOrderShipping" type="System.Decimal"
    allowAnonymous="true"/> <add name="CurrentOrderShippingMethod" type="System.String"
    allowAnonymous="true"/> </properties> </profile>

    The key in <machine key> and the applicationName in <membership>, <role>, and <profile> are the items to pay particular attention to.

    Configuring Login Redirection from dashCommerce

    Now that we've set the authentication to be the same we need to tell dC where to go to authenticate users - to the DNN login controls.  I created appSettings keys to hold these values per dC site instance - set in the dC web.config only.

      <appSettings>
        <add key="AppLoginUrl"
         value="<VD>/home/Home/tabid/102/ctl/Login/Default.aspx"/>
        <add key="AppRegisterUrl"
         value="<VD>/home/Home/tabid/102/ctl/Register/Default.aspx"/>

    From this point I altered the site.master page in dC replacing the existing login and register links with the following:

                  <li><asp:LinkButton runat="server" ID="lnkLogin" 
                  OnClick="lnkLogin_Click">Log In</asp:LinkButton>
                  </li>
                  <li><asp:LinkButton runat="server" ID="lnkRegister" 
                  OnClick="lnkRegister_Click">Register</asp:LinkButton>
                  </li>

    and in site.master.cs I added the event handlers:

        protected void lnkLogin_Click(object sender, EventArgs e)
        {
            string returnURL = ConfigurationSettings.AppSettings.Get("AppLoginUrl");
            returnURL += "?returnurl=";
            returnURL += HttpUtility.HtmlEncode(Request.Url.PathAndQuery.ToString());
                
            Response.Redirect(returnURL);
        }
        protected void lnkRegister_Click(object sender, EventArgs e)
        {
            string returnURL = ConfigurationSettings.AppSettings.Get("AppRegisterUrl");
            returnURL += "?returnurl=";
            returnURL += HttpUtility.HtmlEncode(Request.Url.PathAndQuery.ToString());
    
            Response.Redirect(returnURL);
        }

    Navigation Considerations

    Other than the fact that DNN uses skins and dC uses master pages the navigation component is the part of the integration that has the most (in my opinion) potential for pain.  So far I've used the DNN URL rewriter and URLRewriter.Net with dC (see post here) to allow the navigation to be integrated more easily - though it does require some careful planning to get this right.  I use DNN's link module (which allows author edits for changes) and create a user control to handle the navigation on the dC side.  There's certainly room for improvement in this area.

    Other Considerations

    As I've mentioned several times, the part of this integration scenario that leaves the most to be desired is the fact that DNN uses it's own skinning engine while dC uses ASP.Net's master pages.  By the careful use of plain-html and CSS I've been able to keep the visual presentation of the sites identical so the user is unaware of the DNN / dC difference.  I've spent more time on this single item than the rest of the above items combined.  Please let me know if you have a better solution to this issue.

    Any input on what I've outlined here is appreciated.  Please let me know if it also works, or not, for you.

    -Paul

    October 17

    How To Use UrlRewriter.NET with dashCommerce 2.2

    I've grown accustomed to the flexibility of the UrlRewrtiter.Net that Seth Yates has put together and have used it with CSK in the past.  With dashCommerce 2.2 I recently went through the process of replacing the default Utility.GetRewriterUrl() method with UrlRewriter.Net - and added a new method Utility.GetAppPath().  It is a straightforward integration although there are few decisions to make along the way that should be considered. 

    My goal was to be able to rewrite any Url to any page on the site and to have human-readable pages for the categories and products (i.e., pet.aspx, petwipes.aspx, etc...) regardless of the related GUID's or product names.

    There was an excellent document available for using UrlRewriter.NET with CSK - here.  If if disappears let me know and I'll ask the author permission to repost.  Here's the process I followed:

    1 - Set up UrlRewriter.Net per the instructions in the above document.

    2 - Create the new method in Utility:

        public static string GetAppPath()
        {
            string appPath = System.Web.HttpContext.Current.Request.ApplicationPath;
            return appPath;
        }

    3 - Added the following rules in web.config:

      <rewriter>
        <!-- <rewrite url="~/catlog/Pet.aspx" to="~/catalog.aspx?n=Pet" />-->
        <rewrite url="~/catalog/(.+).aspx" to="~/catalog.aspx?n=$1" 
    processing="stop" /> <!-- < check for GUID, 36 characters including dashes better to use regex like:
    ^\{?[a-fA-F\d]{8}-([a-fA-F\d]{4}-){3}[a-fA-F\d]{12}\}?$ >--> <if url="^~/product/(.{36}).aspx$" > <rewrite to="~/product.aspx?guid=$1" processing="stop" /> </if> <!-- <rewrite url="~/product/StainRemover.aspx"
    to="~/product.aspx?n=StainRemover" />--> <rewrite url="~/product/(.+).aspx" to="~/product.aspx?n=$1"
    processing="stop" /> </rewriter>

    4 - Alter the appropriate sections in catalog.aspx, product.aspx, and the controls contained in these pages - RecentProductsViewed.ascx shown here - this uses the product GUID:

        <a class="smalltext" 
        href="<%#Utility.GetAppPath() %>/product/
    <%#Eval("productGUID").ToString() %>.aspx"> <%#Eval("ProductName") %></a>
    5 - Here's ProductSummaryDisplay.ascx - this uses product SKU 
    (which is the human-readable name for us):
            <a href="<%=Utility.GetAppPath()%>/product/
    <%#Eval("SKU").ToString()%>.aspx" > <%#Eval("productName")%></a>

    6 - Finally, here's catalog.aspx - this uses the category name:

        <a href="<%#Utility.GetAppPath() %>/catalog/<%=categoryName%>.aspx"
            class="subcategory">
            <%#Eval("categoryName") %>
        </a>

    I'm sure you get the idea.  There are a number of lines to change in a similar fashion.  I made the decision to use product SKU as the human-readable value, and the page-name to display.  You could just as easily use GUID, product name, or another value that's returned with the data.

    As far as using UrlRewriter.NET to aid in alternate landing pages (for SEO campaigns, etc...) this is a matter of adding a rule to web.config.  To log visits to these particular pages I plan to use the provider logging capabilities along with Google Analytics.

    As always, I welcome input and alternate views on different/better ways to get this done.

    -Paul

    October 16

    Update to dashCommerce UpsShippingProvider

    The default dashCommerce UpsShippingProvider, while very good out of the box, needed to offer a couple of customization features for our sites.

    1. The ability to set a threshold for an order to receive free shipping - either number of items or order subtotal amount (before tax and shipping)
    2. The ability to specify which UPS services are offered.

    These needed to be set per site (we have 9 with more coming) so I decided to set the configuration values in web.config.  The dashCommerce v2.2 files I altered are:

    • web.config
    • Fullfillmentprovider.cs
    • FullfillmentService.cs
    • SimpleShippingProvider.cs
    • UpsShippingProvider.cs
    • USPostalServicesShippingProvider.cs
    • Checkout.aspx.cs

    The bulk of the changes were made to UpsShippingProvider.cs and the added code follows:

    add the class variables -

            string _upsflateRate = "";
            string _upsflatRateService = "";
            string _upsfreeServiceType = "";
            string _upsfreeServiceThreshold = "";
            string _upsExcludeService = "";

    create a new override method:

            public override DeliveryOptionCollection GetDeliveryOptions(
                PackageInfo package,
                decimal orderAmount, 
                int orderQuantity)
            {
                HttpRequestHandler http = new HttpRequestHandler(_connectionUrl);
                string rateXml = http.POST(rateRequest(package));
                DeliveryOptionCollection collection = UpsParseRates(rateXml);
    
                // PVS - 10/15/2007 - add fixed and free options, if set in web.config
                if (_upsflatRateService.Length > 0)
                    collection.Add(addFixedRateService());
    
                if (_upsfreeServiceType.Length > 0)
                    if (addFreeService(orderAmount, orderQuantity) != null)
                        collection.Add(addFreeService(orderAmount, orderQuantity));
    
                return collection;
            }

    also, three methods to handle the new config settings:

     

            DeliveryOption addFixedRateService()
            {
                // create a new DeliveryOption
                DeliveryOption flatRate = new DeliveryOption();
                flatRate.Rate = decimal.Parse(_upsflateRate);
                flatRate.Service = _upsflatRateService;
    
                return flatRate;
            }
    
            // PVS 10/15/2007 - add a free option for specified threshold
            private DeliveryOption addFreeService(decimal orderAmount, int orderQuantity)
            {
               // create a new DeliveryOption
               DeliveryOption freeRate = new DeliveryOption();
               // the 'M' is used to set the literal 0.00 to a decimal
                freeRate.Rate = 0.00M;
    
                switch (_upsfreeServiceType)
                {
                    case "Unit":
                        if (orderQuantity >= int.Parse(_upsfreeServiceThreshold))
                        {
                            freeRate.Service = "Free shipping - " + _upsfreeServiceThreshold.ToString() + " or more";
                            return freeRate;
                        }
                        else
                        {
                            return null;
                        }
                    case "Amount":
                        if (orderAmount >= decimal.Parse(_upsfreeServiceThreshold))
                        {
                            freeRate.Service = "Free shipping - $" + _upsfreeServiceThreshold.ToString() + " or more";
                            return freeRate;
                        }
                        else
                        {
                            return null;
                        }
                    default:
                        freeRate.Service = "";
                        return null;
                }
                    
            }
    
            private bool includedService(string serviceCode)
            {
                if (_upsExcludeService.IndexOf(serviceCode) > 0)
                    return false;
                else
                    return true;
            }

    and added these to the UPS <provider> section of web.config:

        upsflateRate="4.99"
        upsflatRateService="Flat Rate Ground"
        upsfreeServiceType="Amount"
        upsfreeServiceThreshold="50.00"
        upsExcludeService="07,08,12,13,14,54,59"
    Then, updates to the related Provider files - FullfillmentProvider.cs shown here:
            public abstract DeliveryOptionCollection GetDeliveryOptions(
                PackageInfo package, decimal orderAmount, int orderQuantity);

    Finally, update the call to the provider from Checkout.aspx.cs:

      void BindShipping(PackageInfo package) {
       
        // PVS - 10/15/2007 - add fixed and free options, if set in web.config
        Commerce.Providers.DeliveryOptionCollection options = 
            Commerce.Providers.FulfillmentService.GetOptions(
            package,
            (currentOrder.OrderTotal - currentOrder.ShippingAmount),
            currentOrder.Items.Count);

    That's it. If this isn't clear or you suggest a different approach, please let me know.

    -Paul

    Joined Technorati - finally!

    View my Technorati profile here:
     
     
    (or don't)
     
    -Paul
    October 11

    Amazon Elastic Compute Cloud (EC2) and Storage (S3) Services

    I've had my eye on these for a bit and finally got around to reading up on these offerings and installing some utilities.  On first impression these are very, very good.  I've already begun using the S3 service as a de facto offsite backup location for Moldware's 11GB backups - at a cost of about $30 per month. 

    I'll spare the details (check them out here for EC2 and here for S3) and offer my take on a summary:

    • EC2 - a virtualized grid computing environment where you can define your Linux-based OS as an image (AMI) and start and stop any number of instances of the image using some utilities.
    • S3 - a cloud based storage network with a variety of interfaces for access - essentially an unlimited size hard drive in the cloud

    There are loads of solutions offered around these services - see the Solutions Catalog on the AWS site.  I hope to be able to utilize both of these services to aid in scaling out in the future without requiring the capital investment that's vexed us in the past.

    There were no tutus

    I took my almost-5 year old to see STREB last night at the Mt Baker Theatre...she was a bit disappointed that the ballet dancers weren't wearing tutus.  Not a bad show, but more like watching seven people get high-energy exercise than an actual show...fun though.

    This on the heels of the Dream Science Circus show last weekend which was thoroughly enjoyed by all.  I highly recommend you see see these folks if you can.  It was a very Bellingham scene:  several hundred people sitting on mismatched chairs and old church pews in an unheated (and leaky-roofed) warehouse watching the performance with audience interaction de rigueur.

    October 02

    OpenForce 2007

    I'm planning on attending OpenForce in Las Vegas this November.  It's a conference focusing on DotNetNuke and related technologies.

    LVFALL07OpenFrceCELL

    Looks great and I'm excited to get more backgrounding in the underlying technologies - particularly the SubSonic DAL and using DNN for community sites.

    -Paul

    Gonzo

    A bit of shuffling with priorities here.  We'll back-burner the StoneCareforDummies.com commerce site for a few weeks (waiting for product to be produced and located at the DC) and fast-track the rework of the Gonzo commerce site.  http://www.gonzocorp.com/


    The Gonzo! Genie

    If you'll have a look at the http://www.gonzocorp.com/ site I think you'll agree it's a bit, um, dated.  In addition to a revised layout we'll also port the site forward to the Web Framework in order to take advantage of the CMS, Commerce, Security and scalability built in.  Also, along with Yelena Shapiro we'll initiate several SEO campaigns and begin the keyword marketing that http://www.gonzocorp.com/ desperately needs.

    Finally, we'll get away from manual order entry to our back end and use the existing integration maps we have for the https://www.leadtesttoys.com/ commerce site.

    -Paul