# Monday, 18 October 2010

uCommerce comes with built-in support for PayPal using Website Payments Standard for authorizing new payments and Website Payments Pro for capturing, voiding, and refunding payments in the backend. This guide will walk you through getting uCommerce to work with PayPal for payment processing.

Authorization is available for all plans with PayPal. If you wish to acquire (capture), refund, or cancel payments PayPal requires you to upgrade your account to either Premier or Business.

Settings in uCommerce

Add a new payment method, under “uCommerce –> Settings –> Orders –> Payment Methods”. You can call it whatever you like, here I have used “Paypal”.

clip_image001[14]

Click the newly created node and selected “PayPal” in the Service drop down list. Fill out the rest of the required information, like where it’s available from under the “Access” tab, pricing and the language tabs. When you are done click “Save”.

clip_image003[14]

That’s everything in the uCommerce interface.

Settings in PayPal Administration Panel

Optional: Encrypted Website Payments

We recommend that “Encrypted Website Payments” is used, so the data sent to PayPal can’t be tampered with. This are some steps involved but again, it’s a security risk not to use this feature.

Getting OpenSSL for windows

OpenSSL is an open source tool for Windows, which is used to generate certificates. You will need to install it to generate the PayPal encryption certificates. Visit http://www.slproweb.com/products/Win32OpenSSL.html and download ”Win32 OpenSSL Light”.

Generating the keys

Open a command prompt and go to the bin directory under the installation directory.

clip_image004[14]

To create the private certificate type: “openssl genrsa –out private-key.pem 1024” and press [Enter].

clip_image005[14]

For the public certificate type: “openssl req –new –key private-key.pem –x509 –days 365 –out public-cert.pem”

Now it will ask you to enter some information, you can just skip them by pressing [Enter].

clip_image006[14]

Now we need to create the p12 file. Type the following in the prompt: “openssl pkcs12 –export –in public-cert.pem –inkey private-key.pem –out my_pkcs12.p12” followed by [Enter].

clip_image007[14]

Uploading the public key to PayPal

Log into PayPal and go to the profile settings.

clip_image009[14]

Click the “Encrypted Payment Settings”.

clip_image011[14]

Start by downloading the “PayPal Public Certificate” by clicking the download button marked with number 1. Next click the “Add” button marked number 2 on the page.

clip_image013[14]

Select the file and click “Add”.

clip_image015[14]

Copying the certificates

In the previously step you create 3 files and downloaded 1:

· paypal_cert_pem.txt – downloaded – PayPal public certificate

· private-key.pem – created – private key

· public-cert.pem – created – public key

· my_pkcs12.p12 – created – p12 exchange key

Copy the files to a directory where your uCommerce installation can get access to them. You will most likely have installed umbraco under: “C:\inetpub\umbraco”. A good place for them would be in the uCommerce configuration directory would be: “C:\inetpub\umbraco\umbraco\UCommerce\Configuration” together with the PayPal.config file.

Rejecting unencrypted messages

Log into the PayPal administration panel and click on “Profile”.

clip_image017[14]

On the profile page click the “Website Payment Preferences”.

clip_image019[14]

Scroll down to “Encrypted Website Payments” and make sure the radio button “Block Non-encrypted” are selected. Scroll down to the button and click “Save”.

clip_image021[14]

Editing the PayPal.config File

Now we need to edit the PayPal.config file.

You will find the PayPal.config file in the following location, where “rootdir” is the directory on the computer where you installed Umbraco: “rootdir\umbraco\UCommerce\Configuration\PayPal.config”. Usually “rootdir” is c:\inetpub.

clip_image022[14]

Some of the below information are found in the PayPal administration panel, so start by logging in if you haven’t done so already.

Optional: Finding privateCertificatePath, publicPayPalCertificatePath, privateCertificatePassword and useEncryption

If you earlier in this guide turned “Encrypted Website Payments” on, this step needs to be completed.

privateCertificatePath and publicPayPalCertificatePath

If you used the default names earlier in this guide, path of the two files should work out of the box. If you customized them, reflect the changes here.

privateCertificatePassword

Password entered when you created the p12 file. This can be an empty password, but recommended with a password if you are on a shared host.

useEncryption

Set this to “True” used you are using “Encrypted Website Payments”.

Optional: Finding apiUsername, apiPassword, and apiSignature

apiUsername, apiPassword, and apiSignature are all used to access the PayPal remote API to do Acquire, Refund, and Cancel.

Log into you PayPal account and make sure your account is verified.

clip_image024[14]

Click on “My Account”, then “Profile” and at last “API Access”

clip_image025[14]

On the “API Access” page, Click the “Request API credentials” link.

clip_image027[14]

Make sure “Request API signature” is selected, and then click the “Agree and Submit” button.

clip_image029[14]

Here you will find the “API Username”, “API Password” and “Signature”.

clip_image030[14]

Finding debug

If set to “True”, it will prompt you to click a button before posting the information to “PayPal” otherwise it will do an autosubmit. When running in production, you will have this set to “False”.

Finding sandbox

If testing the ingration with a developer account set this to “True” otherwise “False” at a production site.

Finding returnMethod

Leave it at default.

Finding business

Next we need to find your PayPal ID or an email address associated with your PayPal account. Again, click on “My Account”, then “Profile” and then “Email”.

clip_image031[14]

Here you can see your “Business” account name. Its usually your email address used, when you signed up for the PayPal account. I have only one, but you could have multiple.

clip_image032[14]

Finding notifyUrl

Leave this at “(auto)” if in doubt.

Finding paymentAction

What paymentaction to take.

· Sale - Finale sale, instant capture.

· Authorization - Authorization for a final sale, to be captured later.

· Order - Just place the order, but authorize & capture later. In most cases you you want “Authorization”.

Finding return

Url the user is returned to after successfully authorizing her credit card.

Finding cancelReturn

Url the user is returned to if she cancels a purchase.

Excecuting a pipeline on callback

Running a pipeline once payment is authorized can be helpful if you need to complete the order once the customer returns to your site.

To run a “pipeline” once the callback if received and processed, you need to modify the database. If you used the name “PayPal” for the payment method name, you can run this SQL query in the SQL Server Management Studio.

UPDATE uCommerce_PaymentMethod SET Pipeline = 'Checkout' WHERE Name = 'PayPal'

or just edit it manually in SQL Server Management Studio.

clip_image033[14]

Now the default piplline that comes with uCommerce will be run after each successful callback. This sets the Basket to an Order, gives it an OrderNumber, and other things.

Optional: Enable Acquire, Cancel, and Refund in uCommerce Back Office

To be able to acquire, cancel, and refund payments you need to enable two pipeline tasks in the ToCompletedOrder pipeline and ToCancelled pipeline.

The pipeline configuration is found in /umbraco/ucommerce/pipelines.

ToCancelled.config

clip_image035[14]

ToCompletedOrder.config

clip_image037[14]

FAQ

· Test mode – Make sure test mode if turned off when going live.

· Environment – Make sure this setting is set to “Live” when in production.

posted on Monday, 18 October 2010 13:04:02 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback

uCommerce comes with built-in support for DIBS payments. This guide will walk you through getting uCommerce to work with DIBS for payment processing.

Authorization is available for all plans with DIBS. If you wish to acquire (capture), refund, or cancel payments DIBS requires you to purchase the “Integration(API)” add-on.

Settings in uCommerce

Add a new payment method, under “uCommerce –> Settings –> Orders –> Payment Methods”. You can call it whatever you like, here I have used “DIBS”.

clip_image001

Click the newly created node and select “DIBS” in the Service drop down list. Fill out the rest of the required information, like where it’s available from under the “Access” tab, pricing and the language tabs. When you are done click “Save”.

clip_image002

That’s everything in the uCommerce interface.

Settings in DIBS Administration Panel

Changes needed in the DIBS administration panel, so it will work with uCommerce.

Configure MD5 Control Setting

On the Menu on the left side, click “Integration –> MD5 Keys”. Make sure that “Perform MD5 control” is checked. If not, check it and click “Update”.

clip_image004

Configure Return Values

uCommerce performs validation of the payment information when DIBS performs the callback. To verify that the payment wasn’t tampered with you’ll need to configure DIBS to include some additional information as part of the callback.

clip_image001[1]

Editing the DIBS.config File

Now we need to edit the DIBS.config file.

You will find the DIBS.config file in the following location, where “rootdir” is the directory on the computer where you installed Umbraco: “rootdir\umbraco\UCommerce\Configuration\DIBS.config”. Usually “rootdir” is c:\inetpub.

clip_image005

Some of the below information are found in the DIBS administration panel, so start by logging in you aren’t already.

Finding testMode

If set to “True”, test mode is enabled and you can that it works. Test credit card information from DIBS can be found here: 5. Your own test.

Finding debug

If set to “True” you will be prompted to click a button before posting the information to “DIBS” otherwise it will do an autosubmit using Javascript. When running in production, you will want this set to “False”.

Finding login

Used if you want to use the remote API to do authorization, capture and cancel. This is the same login used for the DIBS administration panel

Finding password

Only used when doing remote API. This is the password used when logging into the DIBS administration panel

Finding callbackUrl

Leave this at “(auto)” if in doubt.

Finding acceptUrl

Url the user is returned to after successfully authorizing her credit card.

Finding cancelUrl

Url the user is returned to if she cancels a purchase.

Finding merchant

On the Menu on the left, click “Setup –> Edit profile”, here you will find the Merchant ID.

clip_image006

Finding useMd5

True/False indicating weather to use Md5. Its recommended to use Md5 for security reasons.

Finding key1 and key2

The two keys found in the administration panel. On the Menu on the left, click “Integration –> MD5 Keys”, here you will find k1 and k2 which correspond to key1 and key2. Also make sure that “Perform MD5 control” are checked. If not, mark it and click “Update”.

Please note that the configuration files are subject to standard XML limitations. If your MD5 key contains the following characters they must be HTML encoded for .NET to be able to read the value:

For < write &lt;
For & write &amp;
For ' write &#39;
For " write &quot;

Given an MD5 key containing the & symbol you’d replace it to look like this: Before &P]ij|&4jNixCA%zZ è After &amp;P]ij|&4jNixCA%zZ
clip_image007

Excecuting a Pipeline on Callback

Running a pipeline once payment is authorized can be helpful if you need to complete the order once the customer returns to your site.

To run a “pipeline” once the callback if received and processed, you need to modify the database. If you used the name “DIBS” for the payment method name, you can run this SQL query in the SQL Server Management Studio.

UPDATE uCommerce_PaymentMethod SET Pipeline = 'Checkout' WHERE Name = 'DIBS'

or just edit it manually in SQL Server Management Studio.

clip_image008

Now the default pipeline that comes with uCommerce will be run after each successful callback. This sets the Basket to an Order, gives it an OrderNumber, and other things.

Optional: Enable Acquire, Cancel, and Refund in uCommerce Back Office

To be able to acquire, cancel, and refund payments you need to enable two pipeline tasks in the ToCompletedOrder pipeline and ToCancelled pipeline.

The pipeline configuration is found in /umbraco/ucommerce/pipelines.

ToCancelled.config

clip_image010

ToCompletedOrder.config

clip_image012

FAQ

· Test mode – Make sure test mode if turned off when going live.

posted on Monday, 18 October 2010 12:40:59 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback

uCommerce comes with built-in support for ePay payments. This guide will walk you through getting uCommerce to work with ePay for payment processing.

Authorization is available for all plans with ePay, i.e. Light, Pro, and Business. If you wish to acquire (capture), refund, or cancel payments ePay requires you to buy the Business plan.

Settings in uCommerce

Add a new payment method, under “uCommerce –> Settings –> Orders –> Payment Methods”. You can call it whatever you like, here I have used “ePay”.

clip_image002

Click the newly created node and select “ePay” in the Service drop down list. Fill out the rest of the required information, like where its available from under the “Access” tab, pricing and the language tabs. When you are done click “Save”.

clip_image003

That’s everything in the uCommerce interface.

Settings in ePay Administration Panel

Changes needed in the ePay administration panel, so it will work with uCommerce.

Unikt orderID, MD5 sikkerhedstjek & callback setting

On the Menu on the left, click “Indstillinger–> Betalingssystemet”, then you should get a view like the one below. These are the settings we recommend. Make a random key out of some digits/characters.

clip_image004

On the same page you need to enter the domain that the callbacks is made to. This include all subdomains.

clip_image005

Optional: Webservice setting if you need to Acquire, Cancel, and Refund

1. Now on the menu to the left, go to “API / Webservices –> Adgang”

2. Set a password if you are using a shared hosting environment

3. At the bottom type in the “IP address” of the webhost accessing the webservice. This needs to be the external ip address

4. Click “Opret IP-adresse” to save it

clip_image006

Editing the ePay.config File

Now we need to edit the ePay.config file.

You will find the ePay.config file in the following location, where “rootdir” is the directory on the computer where you installed Umbraco: “rootdir\umbraco\UCommerce\Configuration\ePay.config”. Usually “rootdir” is c:\inetpub.

clip_image007

Some of the below information are found in the ePay administration panel, so start by logging in you aren’t already.

Finding debug

If set to “True” you will be prompted to click a button before posting the information to “ePay” otherwise it will do an autosubmit using Javascript. When running in production, you will want this set to “False”.

Finding callback

Leave this at “(auto)” if in doubt.

Finding acceptUrl

Url the user is returned to after successfully authorizing her credit card.

Finding declineUrl

Url the user is returned to if she cancels a purchase.

Finding merchantNumber

The “Indløsningsnummer” is unique for your account. This can be found in the menu “Indstillinger -> Betalingssystemet”. Also make sure that “Test mode” is not active, like it is on the picture below, if you’re setting up a production environment.

clip_image008

Optional: Finding pwd if you need to Acquire, Cancel, or Refund

Password used for the webservice, if using a shared host. This can be found in the menu “API / Webservices -> Adgang”.

clip_image009

Finding useMd5

True/False indicating weather to use Md5. Its recommended to use Md5 for security reasons.

Finding key

The Md5 key set in the administration panel.

This can be found in the menu “Indstillinger–> Betalingssystemet”.

clip_image010


Executing a Pipeline on Callback

Running a pipeline once payment is authorized can be helpful if you need to complete the order once the customer returns to your site.

To run a “pipeline” once the callback if received and processed, you need to modify the database. If you used the name “ePay” for the payment method name, you can run this SQL query in the SQL Server Management Studio.

UPDATE uCommerce_PaymentMethod SET Pipeline = 'Checkout' WHERE Name = 'ePay'

or just edit it manually in SQL Server Management Studio.

clip_image011

Now the default piplline that comes with uCommerce will be run after each successful callback. This sets the Basket to an Order, gives it an OrderNumber, and other things.

Optional: Enable Acquire, Cancel, and Refund in uCommerce Back Office

To be able to acquire, cancel, and refund payments you need to enable two pipeline tasks in the ToCompletedOrder pipeline and ToCancelled pipeline.

The pipeline configuration is found in /umbraco/ucommerce/pipelines.

ToCancelled.config

clip_image013

ToCompletedOrder.config

clip_image015

FAQ

· Test mode – Make sure test mode if turned off when going live.

posted on Monday, 18 October 2010 11:43:44 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Wednesday, 13 October 2010

The uCommerce Catalog Foundation holds all the catalog information in your installation and as such serves as the most important foundation in uCommerce. This post will give you an idea of one of the most basic building blocks of the Catalog Foundation: Product Definitions… but first some basics.

Products, Product Families, and Variants. Oh My!

Before we get into the nitty gritty of things we need to get the terminology right so we agree on what’s what.

Products are pretty straight forward they represent a single product in the system with no variants associated.

Product Families are pretty much the same as a product but differ in that they’ve got variants associated with them, hence the product family.

Variants represents a single product much like a stand alone product, but they cannot stand by themselves. Variants are always associated with a product family.

uCommerce supports both products and product families and the good news is you don’t have to go with one over the other. You simply decide on a per product basis whether or not to support variants. So you might have some products be stand alone products and others be product families. Whatever works for your scenario.

Product Definitions

Product Definitions 2Before you can start using catalogs you need to perform some setup to determine the data you’ll be working with, i.e. the taxonomy of your site, the various types of products you’ll support in the site, and finally your pricing scheme.

Product definitions are the most fundamental building blocks of the uCommerce Catalog Foundation. If you’re familiar with Umbraco think of them as Document Types for products. Basically a product definition determines what data you’re working with in uCommerce, both via the UIs and the APIs.

Each product definition in uCommerce represents a different type of product available through your store. Say you’re selling Software and Shirts as in the screenshot below. Software requires a completely different set of data to sell from a Shirt. Notice that Software has different properties from the Shirt.

With product definitions you can tailor uCommerce to your client’s needs.

Adding a New Product Definition

uCommerce supports as many product definitions as you need. Simply right click the Product Definitions node and click create to add a new definition. Each of the product definitions must be named uniquely so you can find it later on.

Adding New Properties to Product Definitions

You can add new properties by right clicking the product definition and clicking Create. Just as you would do when creating a new content node in Umbraco. As you can see the product definition needs a name which will be your key for reference the product definition from code as well the identifier for the product type.

The product family check box indicates whether the product definition allows variants or not. A product family is basically a product with a bunch variants associated with it while a non-product family (product) represent just a single product.

uCommerce Product Definition Create New Property

Once created you’ll have the opportunity to change the meta data of the property to suit your needs.

uCommerce Product Definitions Property Details 

Multilingual Properties

If you need to maintain the data of the property in multiple languages you can tick off the multilingual check box. This will give you a field per language configured in Umbraco.

uCommerce Multilingual Property Definition

If you specify a property to be multilingual the property will show up under the multilingual tabs when you go and edit products.

uCommerce Product Editor Multilingual Properties

Display on Website

A true/false value which is set on the property when accessed via the API.

uCommerce Display on Site Property Definition

Variant Properties

Determines whether the property should be a variant property that you maintain under a product family. If one or more exist the product will turn into a product family automatically and enable you to create multiple variants associated with the product family.

uCommerce Variant Property Definition

Setting the property as a variant property will add the Variants tabs to the editor to any product based on the product definition and will enable you to create variations of a product as part of a product family.

uCommerce Variant Editor

Render in Editor

Sometimes you need data that you don’t want the user to edit. Ticking this check box will tell uCommerce not to render this property as part of the editor UI essentially giving you meta data that you can use and maintain from the API without having to worry about the user tampering with it.

uCommerce Render in Editor Property Definition

Data Types

Each of the properties created in the previous paragraphs are based on data types, which you select when you create new ones. uCommerce comes with a number of built-in data types such as ShortText, LongText, Number, Boolean, Enum, and Image.

uCommerce DataType Property Definition 

Data types include string, number, bool, and enum which is a special type which enables you to predefine a list of values allowed for the user to select, e.g. colors, sizes, basically data with a finite number of options to choose from.

uCommerce Data Type Editor

Validation Expressions

Data types can have validation expressions associated with them to validate user input when editing in the product editor. A validation expression is a standard regular expression evaluated whenever a user clicks the save button.

uCommerce Data Type Validation Expression

In Conclusion

The Product Definition is the secret sauce which makes the uCommerce Catalog Foundation extremely powerful enabling you to model the reality you face be it as a developer creating an e-commerce solution for a client or for yourself.

An important aspect about a product definition is that you can change your mind whenever you please. If you start out without variants nothing is holding you back from moving your properties around even after you start creating products based on that product definition. uCommerce will simply reflect the changes you need without you having to create you products from scratch.

posted on Wednesday, 13 October 2010 21:17:46 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Thursday, 02 September 2010

When working in the uCommerce Admin tool it can be useful to be able to add your own custom nodes some in the trees, e.g. a new node under Product Catalog, Orders, Analytics, or Settings. This post describes how to achieve this.

The uCommerce tree handlers are using the standard Umbraco extension point for creating new trees. You can learn more about that in the excellent Umbraco.tv episode Adding a Custom tree.

uCommerce-UI-extension-1-New-Node

Finding the Extension Point

uCommerce comes with a bunch of tree handlers for managing all aspects of the uCommerce Foundations. Each tree handler deals with a separate root node in the uCommerce tree so depending on which tree you want to insert your custom node in you’ll need a different tree handler.

The tree handlers are called Load<whatever> where the whatever is the actual tree that it’s dealing with. All handlers are found in the assembly called UCommerce.Umbraco.dll which contains the integration pieces for Umbraco.

Handlers include:

Product Catalog tree – UCommerce.Umbraco.Menu.LoadCatalog
Orders tree– UCommerce.Umbraco.Menu.LoadOrders
Analytics tree– UCommerce.Umbraco.Menu.LoadAnalytics
Settingstree – UCommerce.Umbraco.Menu.LoadSettings

 

uCommerce-UI-extension-2-Tree-Handlers

Overriding the Default uCommerce Tree Handler

When you’ve found the handler you want to extend you need to  derive from the uCommerce class. In my case I’m extending the Product Catalog handler so I will derive from the LoadCatalog class.

To add your own node your need to override the method called Render(XmlTree tree) on the tree handler. This method is responsible for actually rendering the tree and will be triggered by Umbraco once configured to do so later on.

Please note that Umbraco isn’t exactly forthcoming with error messages which crop up during development of a tree handler so you’ll have to whip out the Sherlock Holmes thinking cap to find some of the issues which crop up. Especially Javascript for your Action will cause you grief.

public class MyCustomTreeHandler : LoadCatalog
{
    // Constructor is required by base type
    public MyCustomTreeHandler(string application) : base(application)
    {   
    }
 
    public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
    {
        base.Render(ref tree);
 
        XmlTreeNode node = XmlTreeNode.Create(this);
 
        string nodeId = "MyCustomNode";
        // Unique id of the node, can be used to store information about a data object being displayed on a particular node
        node.NodeID = nodeId;
 
        // Text to display on the node itself
        node.Text = "My Custom Node";
 
        // Action trigged by mouse click
        node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MyPage.htm';"); 
 
        node.Icon = "folder.png";
        node.OpenIcon = "folder.png";
 
        // The node type refers to a config file with Umbraco
        // which specifies additional config for a particular node
        // like dialogs and available right click actions
        // ~/umbraco/config/create/UI.xml
        node.NodeType = "my_custom_node_type";
 
        // Available right click actions as per UI.xml
        node.Menu = new List<IAction>(new IAction[] { ActionNew.Instance, ContextMenuSeperator.Instance, ActionDelete.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance });
 
        // Indicates whether the nodes is expandable
        node.HasChildren = false;
 
        // Source is used to perform async calls
        // uCommerce provides an abstraction which works for both Umbraco 4 and 4.5
        // Notice that the nodeId is reused for this call
        node.Source = GetVersionSafeTreeServiceUrl(nodeId);
 
        tree.Add(node);
    }
}

With the following code the node shows up in the tree. Interestingly the custom node turns up as a subnode to every single node in the catalog system, which isn’t what we’re after. We’d like to be able to insert a node anywhere in the tree, but just that one time.

Read on to find out what’s going in.

Determining Where You are in the uCommerce Tree

uCommerce trees are different from Umbraco trees in the sense that a single tree works with many different types of nodes. For example a catalog consists of product catalog groups (the store level), catalogs, and categories. To help you figure out where you are there are two properties you can ask: CurrentId and CatalogNodeType.

When uCommerce builds its tree ids are consistently built up in the format catalogNodeTypeName_ObjectId. This helps uCommerce determine which internal type we’re working with, e.g. a catalog group, a catalog, or a category, and which data object is currently in play.

To insert our node in a specific location we can ask CatalogNodeType what the type of the node currently being rendered is thus enabling us to only insert the custom node in a specific location in the tree.

For my example I’m inserting the node on the same level as the product catalog groups by inserting the following piece of code in the Render method of the tree handler:

public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
{
    base.Render(ref tree);
    
    if (CurrentNodeType != CatalogNodeType.Root) return;
    
    ...
}

Enabling Child Nodes for a Custom Node

Should you need child nodes for your new node that’s absolutely possible as well. Some additional plumbing is needed to determine which nodes to load for a particular super node.

This is where the Node.Source property comes into play. You’ll have seen it configured on our custom node already like so node.Source = GetVersionSafeTreeServiceUrl(nodeId);.

Basically Umbraco loads child nodes on the fly by requesting a back end URL which is called TreeDataService.ashx. Among the parameters passed to this handler is the nodeKey which tells you the sub tree being requested.

uCommerce-UI-extension-5-Tree-Data-Service

To make sure that we only generate child nodes for our MyCustomNode a check to determine which node is being requested is required as a single handler does all the work for the entire tree. For that to work we have to refactor our code a bit to support the sub nodes.

The Render method is still our main entry point from Umbraco so it has to act as an check point which will determine what needs to be rendered.

public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
{
    // Make sure to only render the default nodes at the root
    // and not under our custom node
    if (NodeKey != "MyCustomNode")
        base.Render(ref tree);
 
    XmlTreeNode node = null;
 
    // If the NodeKey passed by Umbraco is our custom id
    // we know that we need to render subnodes for our
    // custom node
    if (NodeKey == "MyCustomNode")
    {
        node = XmlTreeNode.Create(this);
        node.NodeID = "MyCustomSubnode";
        node.Text = "My Custom Subnode";
        node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MySubPage.htm';");
        node.Icon = "folder.png";
        node.OpenIcon = "folder.png";
        node.NodeType = "my_custom_node_type";
        node.HasChildren = false;
    }
    // If we're at the root of the catalog
    // we render the custom node
    else if (CurrentNodeType == CatalogNodeType.Root)
    {
        node = RenderMyCustomNode();
    }
    else return;
 
    // Add the rendered content to the tree
    tree.Add(node);
}

Final Code

Final code with support for a custom node under Product Catalog and child nodes for that looks like this:

using System;
using System.Collections.Generic;
using UCommerce.Umbraco.Menu;
using umbraco.cms.presentation.Trees;
using umbraco.interfaces;
using umbraco.BusinessLogic.Actions;
 
namespace MyUCommerceApp.Umbraco
{
    public class MyCustomTreeHandler : LoadCatalog
    {
        // Constructor is required by base type
        public MyCustomTreeHandler(string application)
            : base(application)
        {
        }
 
        public override void Render(ref umbraco.cms.presentation.Trees.XmlTree tree)
        {
            // Make sure to only render the default nodes at the root
            // and not under our custom node
            if (NodeKey != "MyCustomNode")
                base.Render(ref tree);
 
            XmlTreeNode node = null;
 
            // If the NodeKey passed by Umbraco is our custom id
            // we know that we need to render subnodes for our
            // custom node
            if (NodeKey == "MyCustomNode")
            {
                node = XmlTreeNode.Create(this);
                node.NodeID = "MyCustomSubnode";
                node.Text = "My Custom Subnode";
                node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MySubPage.htm';");
                node.Icon = "folder.png";
                node.OpenIcon = "folder.png";
                node.NodeType = "my_custom_node_type";
                node.HasChildren = false;
            }
            // If we're at the root of the catalog
            // we render the custom node
            else if (CurrentNodeType == CatalogNodeType.Root)
            {
                node = RenderMyCustomNode();
            }
 
            else return;
 
            tree.Add(node);
        }
 
        public XmlTreeNode RenderMyCustomNode()
        {
            XmlTreeNode node = XmlTreeNode.Create(this);
 
            string nodeId = "MyCustomNode";
 
            // Unique id of the node, can be used to store information about a data object being displayed on a particular node
            node.NodeID = nodeId;
 
            // Text to display on the node itself
            node.Text = "My Custom Node";
 
            // Action trigged by mouse click
            node.Action = string.Format("javascript:{0}", "parent.right.document.location.href = '~/MyPage.htm';");
 
            // Images are picked up from ~/umbraco/images/umbraco
            node.Icon = "folder.png";
            node.OpenIcon = "folder.png";
 
            // The node type refers to a config file with Umbraco
            // which specifies additional config for a particular node
            // like dialogs and available right click actions
            // ~/umbraco/config/create/UI.xml
            node.NodeType = "my_custom_node_type";
 
            // Available right click actions as per UI.xml
            node.Menu = new List<IAction>(new IAction[] { ActionNew.Instance, ContextMenuSeperator.Instance, ActionDelete.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance });
 
            // Indicates whether the nodes is expandable
            node.HasChildren = true;
 
            // Source is used to perform async calls to load children of the node
            // uCommerce provides an abstraction which works for both Umbraco 4 and 4.5
            // Notice that the nodeId is reused for this call
            node.Source = GetVersionSafeTreeServiceUrl(nodeId);
            return node;
        }
    }
}

Configuring Your Custom Tree Handler with Umbraco

To replace the uCommerce tree handler with your own you need to open up the Umbraco database and look for the table called umbracoAppTree.

This table specifies the piece of code which builds a given tree and which app it’s associated with. The default uCommerce config will some like this:

uCommerce-UI-extension-3-Configure-Tree-Handler-with-Umbraco

The fields in question are called treeHandlerAssembly and treeHandlerType, which contains the name of the DLL which contains your new class and the name of the class which will handle the tree.

With the custom tree handler in place the configuration will now look like this:

uCommerce-UI-extension-4-Configure-Tree-Handler-with-Umbraco

In Summary

You can hook into almost any aspect of the uCommerce Admin to replace or extended the existing UIs thanks to the flexibility of Umbraco and the custom extensions built on top.

Working with the uCommerce trees is much the same process as the default Umbraco approach although you will have to deal with different types of nodes in a single tree.

With this extension in place you’re free to load your own webform and do whatever you want with it.

posted on Thursday, 02 September 2010 12:29:45 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Friday, 27 August 2010

uCommerce holds rich information about each product in the system with the ability to customize the product schema to customer needs. This flexibility comes at a cost though as the database schema to hold both the product information and the meta information can be quite difficult to grok.

This posts highlights the tables used for both the products and variants themselves.

Product schema

Product table
Product and the variants for a given product. Variants are associated with the product family by using the ParentProductId found in the table. Products (without variants) and product families (with variants) will have a null values in the ParentProductId column, which can be useful for querying the system.

ProductProperty table
Invariant product properties are stored in this table meaning any property not configured as Multi lingual in the uCommerce backend.

Invariant product properties

 

ProductDescription and ProductDescriptionProperty tables

Whenever multi lingual properties come into play this table stores the header for each language. Say you configure Umbraco to support English and German two rows will be inserted per product to store display name, short- and long description, but more importantly this table acts as the main hub for additional multilingual properties on a product.

Each multilingual property value stored for a product is stored in the ProductDescriptionProperty table as such is very similar to the ProductProperty table described above.

Multilingual product properties


PriceGroupPrice table

Each product in uCommerce may hold multiple prices which are stored in PriceGroupPrice. The convoluted name is an indication of the link to a price group. Prices are stored the same way regardless of product and variants due to the fact that essentially a product and variant is the same thing, ParentProductId notwithstanding.

PriceGroup table

Usually you’ll configure the price groups you need in uCommerce Admin, but you still have to link up new prices with a price group to be able to add a new price for a product, either via .NET or SQL.

uCommerce price groups UI

In conclusion the uCommerce product schema holds all your custom data and can be populated from external sources either via .NET code or SQL directly to the tables. Regardless of the approach you select the schema is important to know even from a .NET perspective because the uCommerce entities reflect the data schema closely to make the disconnect between the data models as tiny as possible.

posted on Friday, 27 August 2010 07:44:13 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Friday, 28 May 2010

One of the questions I’ve come across a couple of times with uCommerce is using the LINQ API to query products by custom properties added to a product definition.

Here’s how:

var q = from product in Product.All()
  where product.ProductProperties.Where(property => 
    (property.ProductDefinitionField.Name == "MyProperty" && property.Value == "MyPropertyValue") 
    || (property.ProductDefinitionField.Name == "MyOtherProperty" && property.Value == "MyotherPropertyValue")).Count() == 2
    && product.ParentProductId == null
  select product;
posted on Friday, 28 May 2010 15:07:28 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Tuesday, 25 May 2010

One thing you might want to do before putting a new uCommerce solution into a production environment is remove any test baskets and orders you might have placed during development. The schema gets a little complicated with the rich functionality found in the uCommerce Transaction Foundation requiring the objects to be removed in a certain order.

image

Here’s how you go about deleting them.

*** WARNING! HERE BE DRAGONS! ***

Please be aware that running the following script will remove any baskets and orders found in the system with no way to get them back unless you have a database backup handy.

--DELETE PURCHASEORDERS AND ASSOCIATED DATA
BEGIN TRAN
 
-- Delete reviews
DELETE FROM uCommerce_ProductReviewComment
DELETE FROM uCommerce_ProductReview
 
-- Delete discounts
DELETE FROM uCommerce_OrderLineDiscountRelation
DELETE FROM uCommerce_Discount
 
-- Remove shipment <-> order line link
UPDATE uCommerce_OrderLine SET ShipmentId = NULL
 
UPDATE uCommerce_PurchaseOrder SET BillingAddressId = NULL
DELETE FROM uCommerce_Shipment
DELETE FROM uCommerce_OrderAddress
DELETE FROM uCommerce_OrderProperty
DELETE FROM uCommerce_OrderLine
DELETE FROM uCommerce_PaymentProperty
DELETE FROM uCommerce_Payment
DELETE FROM uCommerce_OrderStatusAudit
DELETE FROM uCommerce_PurchaseOrder
DELETE FROM uCommerce_Address
DELETE FROM uCommerce_Customer
--COMMIT

As an added precaution I uncommented the commit statement in case you were wondering why the data isn’t being deleted :)

This post was written for uCommerce 2.0.0.0 (schema version 50).

posted on Tuesday, 25 May 2010 22:55:00 (Romance Daylight Time, UTC+02:00)  #    Comments [2] Trackback
# Wednesday, 19 May 2010

You will learn how to create a Payment Method Service, which integrates uCommerce with an online payment processer such as Sage, DIBS, PayPal, Cyber Source, or another processor used during checkout. This information is based onuCommerce 1.0.3.x and 1.0.3.2.

Create Visual Studio Project

Create a new Visual Studio solution and choose Class Library for your project type.

 Project structure - File Explorer

 

Add References to Your Project

uCommerce.dll

uCommerce.Infrastructure.dll

Subsonic.Core.dll

VS add reference select UC assemblies

Import Namespaces

Import the UCommerce.Transactions.Payment and UCommerce.Entities namespaces in you class file

Import namespaces

Implement interface IPaymentMethodService on your class

The IPaymentMethodService interface gives you full control over the behavior of the service. Alternatively you can inherit from AbstractPaymentService, which gives a default implementation for ProcessPaymentRequest, which will give you a properly initialized Payment.

Implement interface 

Implement interface 2

Implement Name property

The name property is used to uniquely identify your Payment Method Service. It is read from configuration and set on your service at runtime.

public class MyPaymentService : IPaymentMethodService
{
    public string Name { get; set; }    
}

Implement RequestPayment(PaymentRequest)

RequestPayment can be used in one of two ways: 1) Either to redirect the customer to the remote server handling payment information there, e.g. credit card information, or 2) to simply send payment information received on your server directly to the provider.

1)

public Payment RequestPayment(PaymentRequest request) 
{ 
    // Package up information for the backend service, 
    // in the form of a http request 
    // Redirect customer to backend service with 
    // the needed information 
    // Payment would be set pending authorization status (the status will have to be added to the uCommerce_PaymentStatus table) 
}

2)

public Payment RequestPayment(PaymentRequest request)
{
    // Processing is happening synchronously so we just
    // call the backend service with ProcessPaymentRequest
    return ProcessPaymentRequest(request);
}

Implement ProcessPaymentRequest(PaymentRequest)

ProcessPaymentRequest is used to handle any processing before or callbacks from the remote server in the case of a payment processing being handled exclusively by a remote party.

1) In the case of a callback scenario you use ProcessPaymentRequest to handle the callback and do any needed processing like updating order status. To receive the callback an endpoint needs to be exposed to the remote party such an http handler or a module. The handler or module will call ProcessPaymentRequest to complete the payment.

public Payment ProcessPaymentRequest(PaymentRequest request)
{
// Update payment according to received status from remote 
// party, e.g. Accepted, Declined
 
// Grab any transaction ids and put them on the payment before 
// returning the Payment
}

2) For a synchronous scenario ProcessPaymentRequest would be used to perform the query to the backing system and create a new Payment according to the result received.

public Payment RequestPayment(PaymentRequest request) 
{ 
    // Package up information for the backend service, 
    // in the form of a http request 
    // Redirect customer to backend service with 
    // the needed information 
    // Payment would be set pending authorization status 
}

Implement AcquirePayment(Payment)

For legal reason you sually can’t withdraw money from the customer until you actually ship their order. AcquirePayment is ment for this very scenario where you first authorize the payment and later withdraw from their account.

AcquirePayment(Payment) is used for capturing the payment from the customer.

public Payment ProcessPaymentRequest(PaymentRequest request)
{
    // Send request to remote party
 
    // Update payment according to received status from remote 
    // party, e.g. Accepted, Declined
 
    // Grab any transaction ids and put them on the payment before 
    // returning the Payment
}

Implement CancelPayment(Payment)

If you wish to cancel af payment with your payment method service you need to implement CancelPayment, and have it reach out the remote payment processor. Typical scenarios for cancelling a payment includes a customer return, cancelled order and typically requires you to handle two scenarios: Payment authorized but not capture and payment authorized and captured.

public Payment CancelPayment(Payment payment)
{
    // Update payment according to received status from remote 
    // party, e.g. Cancelled
 
    // Grab any transaction ids and put them on the payment before 
    // returning the Payment
}

Implement CalculatePaymentFee(PaymentRequest)

If applicable, used for calculating the fee associated with the payment method.

public virtual Money CalculatePaymentFee(PaymentRequest request)
{
    var order = request.PurchaseOrder;
    var paymentMethod = request.PaymentMethod;
 
    var fee = paymentMethod.GetFeeForCurrency(order.BillingCurrency);
 
    if (!order.SubTotal.HasValue)
        return new Money(0, 
new CultureInfo(Globalization.CultureCode), order.BillingCurrency);
 
    return new Money(order.SubTotal.Value 
        * (paymentMethod.FeePercent / 100) 
        + fee.Fee, 
new CultureInfo(Globalization.CultureCode), order.BillingCurrency);
}

Optionally Implement IPaymentFactory Interface on Your Provider

With uCommerce 1.0.3.2 the option for deferred payment requests was introduced meaning that you can create a payment placeholder for the choices made by a user and then later perform the actual payment request to the backend service.

If you need this functionality your PaymentMethodService should implement the interface IPaymentFactory (new for version 1.0.3.2), which will be used for creating the new Payment.

/// <summary>
/// Creates a new payment fully initialized
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Payment CreatePayment(PaymentRequest request)
{
    PurchaseOrder order = request.PurchaseOrder;
 
    var payment = new Payment
    {
        TransactionId = Guid.NewGuid().ToString(),
        OrderId = order.OrderId,
        PaymentMethodName = GetPaymentName(request.PaymentMethod),
        Created = DateTime.Now,
        PaymentMethodId = request.PaymentMethod.PaymentMethodId,
        Fee = CalculatePaymentFee(request).Value,
        FeePercentage = request.PaymentMethod.FeePercent,
        PaymentStatusId = 1, // Status new
        Amount = request.Amount.Value
    };
 
    return payment;
}

Copy Your Assembly to Your Umbraco Site

Copy MyUCommerceApp.Library.dll to the /bin folder of your Umbraco site.

Add Your Payment Method Service to web.config

Configure your new Payment Method Service in web.config of your Umbraco site. In the <paymentMethodServices> element of you web.config add the following xml:

<add name="MyPaymentMethodService" type="MyUCommerceApp.Library.MyPaymentMethodService, MyUCommerceApp.Library" />

image 

Configure Payment Method to Use Your Service

Configure Payment Method to use your new service in uCommerce Backoffice.

Configure Payment Method to use PaymentMethodService - 2 

Execute Your Payment Method Service from Commerce XSLT Library

You have two options when you need to carry out your payment request: Either create and request a payment in one go by or do a two step request whereby you create a payment, but defer the actual request of the payment to backend service to a later time.

Please note that the two-step request is only available with uCommerce 1.0.3.2 or newer.

Typically the two step approach is used when you’re dealing with a redirect scenario in which part of the payment authorization happens on a remote server.

For a single step request, you'll use this XSLT extension:

<xsl:variable name="result" select="CommerceLibrary:CreatePayment($paymentMethodId, -1, true(), true())"></xsl:variable>

or the version with no amount argument, which will default to the SubTotal of the PurchaseOrder, i.e. use this if you only accept one payment per purchase order.

If you need the two step version you’ll use a couple of extensions. First the one which creates a payment for you and second an extension, which performs the request. Please note that your PaymentMethodService must implemention IPaymentFactory for this to work.

// -1 is a convenience which will tell uCommerce to grab the total of the order for the payment
// The first bool parameter indicates whether to perform the payment request
// The second bool parameter will overwrite existing payments if set to true (a way to avoid duplicates)
<xsl:variable name="result" select="CommerceLibrary:CreatePayment($paymentMethodId, -1, false(), true())"/>

The uCommerce Store executes CreatePayment in the macro called UpdatePayment[XSLT].

To perform the payment request you’ll execute:

// Perform request payment for all payments associated with the basket
<xsl:variable name="paymentResult" select="CommerceLibrary:RequestPayments()"/>
 
- or -
 
// Perform request payment for a single payment
<xsl:variable name="paymentResult" select="CommerceLibrary:RequestPayment(paymentId)"/>

Execute Your Payment Method Service from .NET

To execute your Payment Service directly from .NET code you use the following snippet:

public void ExecutePaymentMethodService(PaymentMethod paymentMethod, 
    PurchaseOrder purchaseOrder, decimal amount)
{
 
    var cultureInfo = new CultureInfo(Globalization.CultureCode);
 
    // Create a new payment request to 
    var paymentRequest = new PaymentRequest(
                purchaseOrder,
                paymentMethod,
                new Money(
                    amount,
                    cultureInfo,
                    purchaseOrder.BillingCurrency)
                             );
 
    Payment payment = paymentMethod
                    .GetPaymentMethodService()
                    .RequestPayment(paymentRequest);
}
posted on Wednesday, 19 May 2010 12:52:18 (Romance Daylight Time, UTC+02:00)  #    Comments [0] Trackback
# Wednesday, 03 June 2009

Microsoft-Commerce-Server-LogoBack in 2007 I was faced with designing a multi-currency catalog solution for Commerce Server. I knew from previous experience that we would need a general purpose solution, which we could employ for many clients.

Back then Commerce Server 2007 was new thus performance characteristics were new territory as well. I ended up designing a solution based solely on virtual catalogs. Basically one catalog for each price group/currency. You can read the details on multi-currency/price groups, which we’ve employed successfully numerous times since then.

Since 2007 we’ve gotten a new version of Commerce Server though no significant new features were added in the catalog system, and we’ve gained valuable new knowledge on both the pricing scenarios and limitation of the Commerce Server catalog system. With that information in hand I’m going to try my hand at redesigning the original multi-currency catalog structure from 2007 to both address performance issues and increased flexibility.

Virtual Catalogs are Slow

Virtual catalogs are slow and so they make a poor choice to expressing essentially a single piece of data. You might say that virtual catalogs perform perfectly well if you materialize them and you would be right. You gain in the order of 10x performance by materializing a virtual catalog but lose the ability to make any changes in them in the process.

Basing my original multi-currency solution on virtual catalogs seemed to make perfect sense, but with the added requirement of changing the category hierarchy two levels of modifiable virtual catalogs were needed, thus the ability to materialize was lost.

To make matters worse we rarely deal with clients who are inclined to go with an Enterprise license for their Commerce Server solution, so we don’t see very many full fledged staged solutions, which would take care of the challenge handily.

Virtual Catalogs Two Levels Deep

Virtual catalogs are by nature limited to two levels, i.e. you can have a total of three levels of catalogs, one with base catalogs and two with virtual catalogs. Are we to use one of these levels of virtual catalogs for pricing we lose it for other purposes, and gain very little other than the ability to store another price group per catalog.

Pricing is a Separate Issue

What I’ve come to realize over the years is that product pricing is a completely separate issue from the product itself. While the two might seem like one and the same; in reality they aren’t. Sure the customer needs to be told a certain price, but more often than not the price is determined by context surrounding the product, rather than the product itself.

An example would be a seasonal business, which is highly dependant on calendar time, the product would probably sell for a higher rate at specific times of the year and lower rates the rest of the year, e.g. ChristmasTreesOnline.com. The context in this particular instance is time.

Now for business to business scenarios the context might be especially convoluted as you might go for pricing granularity, which allow organizations, groups within the organization, even individual people in the organization to have specific prices, e.g. memberships to the gym provided by your company or framework agreements made between supplier and customer. The context deciding the price is who you are in this case, not the product itself.

Pricing is a Service

To handle the separate issue of pricing we need something akin to a service in domain driven design parlance. The service is responsible for looking up the right price based on whichever context is present for a given customer request.

Of course we need some sort of structure to maintain the pricing for individual price groups, and catalogs come in handy to solve this as I’ll show you next.

The Product Catalog

Our product catalog would in the new scheme continue to exist as we know and love it with one minor exception. The list price of the product is either to be ignored or used only to get an idea of what the pricing is like. The list price will not be picked up from the product catalog, which contains the marketing data for a product. Please note that I define marketing data in this instance as data used to display to potential customers, but other than that serve no purpose to the system.

The Pricing Catalog

In Commerce Server we have the notion of different types of catalogs, i.e. the product catalog and the inventory catalog. I’m going to introduce a third kind called the Pricing Catalog. As you might imagine a pricing catalog concerns itself only with price and as such contains only the bare minimum of data to identify a product.

The pricing catalog will have metadata to indicate that it is in fact a pricing catalog. Each pricing catalog reflects a single price group such as “Internet Users”, “Gold Customers”, whatever makes sense for the particular scenario.

Having pricing split out like this means that we can price products based on the calendar time context as a standard Commerce Server catalog has dates associated with it to allow us to display it within only a given period of time.

For a pricing catalog these fields are used to determine whether a price is valid or not, so you could have the seasonal pricing expressed as two different pricing catalogs for our ChristmasTreesOnline.com, one for holiday pricing and one for the rest of the year. The pricing service would then grab the pricing from the proper Pricing Catalog and display it to the customer.

Pricing Definitions

Finally I propose a new kind of definition called the Pricing Definition. What this is is a specialized Product Definition used for creating Pricing in the Pricing Catalogs for advanced scenarios, e.g. complex pricing matrices defined in external systems such as an ERP.

Products, i.e. Prices, created based on a Pricing Definition would contain at least the SKU, name, description, and of course the list price. These specialized products go into a Pricing Catalog as we discussed in the previous paragraph.

Tying it All Together

Another context we discussed in a previous section is the organizational context, which might also influence product pricing. Fortunately Commerce Server comes with CatalogSets as a neat way of bundling catalog together. CatalogSets leveraged with our Product Catalogs and Pricing Catalogs would allow us to do multi-currency and, incidentally, a bunch of even more interesting scenarios.

Imagine if you will a scenario where our online retail outlet would like to give Internet customers access to only currencies, which make sense for their particular region, e.g. here in Denmark Euro and our national currency Kroner would make sense, while UK customers should be enabled to shop in either Pounds or Euro.

Simple! Create two catalog sets one called Denmark and one called UK. For the Denmark catalog set select our one product catalog containing all products or the one which reflects the range available in Denmark and select the two Pricing Catalogs Kroner and Euro. For the UK catalog set select Euro and Pounds Pricing Catalogs.

By way of the metadata on the catalogs we’re now able to display the same range for both UK and Danish customers, but in three different currencies with Pound being available to the British and Kroner available only to the Danish customers.

posted on Wednesday, 03 June 2009 14:21:57 (Romance Daylight Time, UTC+02:00)  #    Comments [2] Trackback