Software that simplifies putting up an internet storefront

Microsoft Site Server 3.0 Commerce Edition (SSCE) simplifies creating an Internet storefront by providing e-commerce Web developers with an extensive set of tools and capabilities, such as sample stores that you can use as models for your storefront. SSCE's wizards can generate your storefront site from scratch with basic mechanisms for gathering shopper and order information, database storage, and skeletal order processing. SSCE includes integrated advertising and promotion tools and management tools for storefront maintenance. These tools, combined with third-party snap-ins that calculate tax, shipping costs, and payment, make it easy to put up a simple storefront and start doing business.

However, to understand SSCE and use it to create a more sophisticated solution that integrates with existing systems and databases, you must roll up your sleeves and look under the hood. Upon closer examination, you find that SSCE contains several key technologies and structures: Active Server Pages (ASP), component object model (COM) objects, and Order Processing Pipeline (OPP). Most pages in an SSCE Web site are ASP containing server-side script, which manipulates a set of COM objects Microsoft provides with SSCE. The software uses these COM objects to collect information from the shopper, retrieve data from and store data to the underlying database, and process the shopper's order through the OPP. In this article, I'll examine how the OPP works and how you can use the Scriptor tool to create your own OPP components that will customize the way SSCE processes orders.

OPP
Consider how you buy a product at a typical retail shop: You enter the store, find what you're looking for, and pay the checkout clerk for the item. In the same way, SSCE's OPP processes order information in a prescribed sequence. SSCE's Business to Consumer (B2C) OPPs go through steps similar to those of a sales clerk in a retail store. The B2C pipelines organize the order process into discrete stages, which the software executes in a well-defined sequence. At each stage in the order process, SSCE retrieves information from or adds information to the shopper's OrderForm. The OrderForm is a COM object SSCE provides to collect information about the shopper, about the items the shopper is purchasing, and about payment details. Table 1 outlines the standard B2C stages. SSCE also offers Business to Business (B2B) pipelines, which handle transactions in stages similar to B2C pipeline transaction stages.

SSCE stores OPP information in pipeline configuration files with .pcf extensions. You create these files with the Commerce Server Pipeline Editor. These .pcf files define which stages the software will carry out for a given pipeline transaction, and define which OPP COM objects SSCE will run within each stage. The OPP COM objects perform the work at each stage. SSCE offers three standard B2C templates you can use with the Pipeline Editor to create .pcf files (these templates have a .pct extension).

Product.pct. You use this template to create a .pcf file that runs OPP COM objects that compute price and discount information for individual products. This pipeline displays product and price information on the product.asp page. The resulting .pcf file defines the Product Info, Shopper Information, Item Price, Item Adjust Price, and Inventory stages.

Plan.pct. You use this template to create a .pcf file that runs OPP components that present the shopper with an order total. This order total includes all promotional discounts, taxes, shipping charges, and handling charges. SSCE uses this .pcf file to calculate an order total for the shopper to examine prior to payment processing. The resulting .pcf file defines the Product Info, Merchant Information, Shopper Information, Order Initialization, Order Check, Item Price, Item Adjust Price, Order Adjust Price, Order Subtotal, Shipping, Tax, Order Total, and Inventory stages.

Purchase.pct. This template creates a .pcf file that runs OPP components that validate the shopper's payment, perform the purchase transaction, and write an order to database storage. Optionally, you can customize this file to write the OrderForm contents to a receipt database. This .pcf file usually receives an OrderForm that the plan pipeline has processed for final payment and acceptance. This template creates a .pcf file that defines the Purchase Check, Payment, and Accept stages.

Screen 1 shows the plan pipeline template in the Commerce Server Pipeline Editor window. The software represents pipelines as plumbing pipes with each vertical section representing a stage and each horizontal section representing an OPP COM object that processes OrderForm information. You can use the Pipeline Editor to add, configure, or remove OPP COM objects in each stage. And, using expert mode, you can create new stages or remove existing ones.

You use the Pipeline Editor to configure each stage to carry out one or more OPP COM objects. If you don't designate an OPP COM object for a particular stage the software skips that stage. OPP COM objects interact with the OrderForm object to complete a transaction. SSCE provides simple prebuilt OPP COM objects you can use to process orders. For example, Table 2 shows prebuilt OPP COM objects for the Item Adjust Price stage. Also, you can purchase a variety of third-party COM objects that handle more complex operations. A third option is to create custom OPP COM objects for specialized processing on your site. You can use all of these OPP COM object types to provide the order processing your business requires.

How SSCE Runs a Pipeline
To run an OPP, you use ASP script to create a PipeContext object. Your SSCE ASP application initializes this object with information the OPP needs. You then create either the Commerce.MtsPipeline pipeline object or the Commerce.MtsTxPipeline pipeline object. Both of these pipeline objects perform the same function, but SSCE runs the Commerce.MtsTxPipeline object inside a Microsoft Transaction Server (MTS) transaction. You decide whether you need transactional integrity for the pipeline processing. Users typically run the purchase pipeline with the MtsTxPipeline object. After you've instantiated your pipeline object, you use your pipeline object's LoadPipe method to load the appropriate .pcf file. Finally, you use the pipeline objects' Execute method to run the pipeline. For more information about running the pipeline from your ASP, consult the SSCE documentation.

Creating a Custom Scriptor OPP Component
What makes a COM object an OPP COM object? The OPP COM object must support the COM interfaces necessary for the component to interact with the pipeline. If you're a COM developer, you can use your favorite COM object development tool (e.g., Visual C++ or Visual Basic--­VB) to implement these interfaces. The SSCE documentation specifies how to do this implementation. However, if you're not an experienced COM object developer, you can use SSCE's Scriptor component to construct custom OPP COM objects. With Scriptor, you can write VBScript or JScript (Microsoft's version of JavaScript) to create OPP COM objects that manipulate the OrderForm and perform calculations or back-end processing that the standard components don't provide. The Scriptor component supports the interfaces necessary for interacting with the OPP; you just need to create the script.

To configure a pipeline, you use the Pipeline Editor. (Microsoft offers a Win32 and an HTML version of this tool. I'll use the Win32 application for this discussion, but the same features are available in both versions.) Using SSCE's Site Foundation Wizard and Store Builder Wizard, I constructed a simple mock site I called Eddins Product Catalog. Using the Pipeline Editor, I added a custom OPP Scriptor component to the purchase pipeline (purchase.pcf) the Store Builder Wizard created. I used the Scriptor component to make a final inventory adjustment at the beginning of the Accept stage that reduced the inventory count for specific items in an OrderForm. The simple database table that Screen 2, page 71, shows represents my inventory system, which the Scriptor component will update with the appropriate SKU counts.

To create the Scriptor component, I open purchase.pcf for Eddins Product Catalog in the Pipeline Editor. Next, I select and right-click the first OPP COM object in the Accept Stage. From the resulting context menu, I select Insert Component, Before. From the resulting Choose a component dialog box, I select the Scriptor entry from the Components list and click OK. The system then adds the Scriptor object to the pipeline above the SQLItemAdo horizontal section.

To set the new object's properties, right-click the new Scriptor object and select Properties. The system then displays the Component Properties dialog box, which Screen 3 shows. The Scriptor tab in this dialog box includes three fields: In the Scripting Engine drop-down list, you choose an available ActiveX scripting engine (JScript and VBScript are the default options). In the Source field, you specify where the system stores the script. Selecting Internal tells the system to store your script within the .pcf file, and this selection lets you edit the script by clicking Edit. If you select External, you can create a separate script file. In this case, you provide the system a full path to the file location in the Filename text box. If you select External, you can use the Config text box to pass runtime parameters, in the form of named value pairs, to the script for processing. For example, you can use the Config text box to pass an Open Database Connectivity (ODBC) string to the Scriptor component, which your script uses to dynamically choose the database to use at runtime. The script determines which named value pairs are appropriate or needed. In my example, I used Internal VBScript to program the Scriptor component that will update my inventory table, so the Config text box is not available.

Selecting Edit on the Scriptor tab takes you to a window with three predefined entry point functions that the Scriptor component will use to call your script. These functions are MSCSExecute, MSCSOpen, and MSCSClose. Screen 4 shows the initial Source Code Edit window with the skeletal entries for these three functions. MSCSExecute is the primary function that does the component's work; this function is where you put the bulk of your code. This function acts as the main module for the program, and it must be present in your script. MSCSOpen and MSCSClose are optional entry points for initialization or clean-up code for your object. The software runs the MSCSOpen subroutine immediately after you create the Scriptor component. The software carries out the MSCSClose subroutine when you destroy the Scriptor component. The Scriptor component strictly defines these three functions, so you shouldn't change their declarations. However, you can add functions to organize and develop your program. The script calls these additional helper functions from the MSCSExecute function.

Listing 1 shows the complete script for my inventory update. The MSCSExecute function directly hosts most of this code. I created a helper function that I called GetItemQuantity. It returns the item quantity for a particular SKU the shopper is ordering. The MSCSOpen and MSCSClose functions are not present in Listing 1 because I didn't include initialization or termination code.

At callout A in Listing 1, the script creates an ADO connection object and sets ConnectionString for the database hosting my inventory table (i.e., DSN=Commerce). At callout B, the script creates a Recordset object to hold the inventory records I need to update, and builds a SQL statement that retrieves all the inventory records for SKUs the shopper has ordered. The ASP store these inventory records in the OrderForm. Next, the code walks through the OrderForm items, picks the SKUs, and adds them to the list of criteria. This code leaves an extra comma at the end of the list, so I used the VB Left function to drop the last character. I appended the closing parenthesis, which resulted in a SQL statement similar to

"SELECT * FROM eddinswear_inventory where sku in ('001-001','001-002')"

At callout C, this SQL statement populates my Recordset object. The Recordset object will contain only those inventory records the shopper has actually purchased. Finally, at callout D, the script loops through the Recordset object and reduces inventory by the item quantity the shopper purchased.

At callout E, the job is finished, so the script closes the ADO connection and Recordset and destroys the objects by setting them to Nothing. At callout F, the script returns 1, which signifies that the table is updated.

The GetItemQuantity function, at the end of Listing 1, simply walks through the OrderForm items until it finds the SKU that matches the inventory record the script is in the process of updating. When GetItemQuantity finds a match, it returns the item quantity the shopper purchased, and that number is the amount by which the script reduces the inventory.

Reality Check
We've just used the Scriptor component to create a custom OPP COM object. You might have noticed that my code doesn't have any error handling. Definitely add good error checking to any code you develop, especially if you're accessing a database. SSCE provides a well-documented structure for managing errors, and the OrderForm includes list objects for recording any Basket_Errors and Purchase_Errors the software discovers during OPP processing. Microsoft also provides a special MessageManager object that stores error messages in multiple languages, which OPP components can use to describe error conditions the software generates during OrderForm processing in a location-specific manner.

The work performed in the example is, of course, an example. To simply update one table, you would just use the standard SQLItemAdo object and a SQL stored procedure. However, with the Scriptor component and a custom script, you can add logging, more complex calculations, and more sophisticated integration with other systems.

A Word of Caution
If your script becomes very involved (over a hundred lines of code), consider creating a compiled OPP COM object using VB, Visual C++, or a tool other than the Scriptor component. Because the system interprets script, your Scriptor component script will perform slower than a compiled object.