Archive for the ‘Tea Commerce’ Category


Making a payment provider for Tea Commerce

Making a payment provider for Tea Commerce

When making an e-commerce system one of the key points, is often the ability for customers to pay online with credit card or others online payment services. Tea Commerce comes with a couple of pre-installed payment providers, but one of the great things is if you need to use a payment provider that isn’t given to you out of the box – it’s really simple to make you own. It’s as simple as inherit from a single .Net class and implement some metods and that’s it!


APaymentProvider is an abstract class, in the TeaCommerce.Payment.dll, all payment providers in Tea Commerce needs to inherit from, to be able to process payments through the Tea Commerce API and admin interface. When your payment provider inherits from APaymentProvider you will have to implement 6 different methods and a property – each explained below
All methods that returns a valid PaymentCallbackInfo will change the order’s transaction information.


You need to implement this property as it tells Tea Commerce what url to post the payment request to when the customer makes it to the payment step.

string FormPostUrl { get { return ""; } }


When webshop customers is ready to go to the payment step – and the front-end developer call TeaCommerce.goToPayment() in our javascript API – Tea Commerce will see what payment method the customer selected, and based on the related payment provider, Tea Commerce generates a form and post it to the FromPostUrl. Return a dictionary containing the name/value pairs that builds up the form

Dictionary<string, string> GenerateForm( string orderName, string currencyISOCode, decimal amount, string defaultContinueUrl, string defaultCancelUrl, string defaultCallBackUrl, Dictionary<string, string> settings );


Dictionary<string, string> GenerateForm( string orderName, string currencyISOCode, decimal amount, string defaultContinueUrl, string defaultCancelUrl, string defaultCallBackUrl, Dictionary<string, string> settings ){
  Dictionary<string, string> nameValues = new Dictionary<string, string>();
  nameValues.Add( "provider", "TeaCommerce" );
  nameValues.Add( "secretKey", "Expect simplicity" );
  return nameValues;


This method is called when Tea Commerce recieves a callback from the payment gateway. You need to process the request and tell Tea Commerce if the callback is valid

PaymentCallbackInfo ProcessCallback( HttpRequest request, Dictionary<string, string> settings );


For Tea Commerce to show the newest information about a transaction, this method is called when the webshop owner views an order in the admin.

PaymentCallbackInfo GetStatus( string transactionId, Dictionary<string, string> settings );


Called when capturing the transaction from the Tea Commerce admin

PaymentCallbackInfo CapturePayment( string transactionId, string currencyISOCode, decimal amount, Dictionary<string, string> settings );


Called when refunding the transaction from the Tea Commerce admin

PaymentCallbackInfo RefundPayment( string transactionId, string currencyISOCode, decimal amount, Dictionary<string, string> settings );


Called when cancelling the transaction from the Tea Commerce admin

PaymentCallbackInfo CancelPayment( string transactionId, Dictionary<string, string> settings );

Helper methods

To make it much easier for your to make a payment provider for Tea Commerce, we have implemented some generic used methods in the APaymentProvider base class for you to use


These methods makes a post request for you and returns the response as a string.

string MakePostRequest( string url, Dictionary<string, string> inputFields );
string MakePostRequest( string url, string request );


For Tea Commerce to work correctly, you need to use this method when generating a continue url. This methods makes a wrapper for your url, which force the continue url to be returned to Tea Commerce and process the request from the payment gateway before returning to your specified continue url.

string GenerateContinueUrl( string finalContinueUrl );


This one works just like the GenerateContinueUrl method, just for the cancel url.

string GenerateCancelUrl( string finalCancelUrl );


Some payment gateways use a MD5 hash as a security mechanism and this method makes it easy to generate one.

string GetMD5Hash( string input );

Extra properties

There is some extra properties for you to control in the APaymentProvider

//Return true to finalize the order as soon as the customer accepts the payment terms
bool AutoFinalize { get { return false; } }

//Add extra attributes to the genereated form element in GenerateForm()
string FormAttributes { get { return @"name=\""ePay\"" target=\""ePay_window\"" id=\""ePay\"""; } }

//If a method is specified - Tea Commerce will call it instead of posting the form when goToPayment is called
string SubmitJavascriptFunction { get { return @"open_ePay_window();"; } }

//These properties tells Tea Commerce if the specific action is possible with your payment provider
bool AllowsGetStatus { get { return true; } }
bool AllowsCapturePayment { get { return true; } }
bool AllowsRefundPayment { get { return true; } }
bool AllowsCancelPayment { get { return true; } }


This is the object almost every APaymentProvider method returns. The object should contain information about the response from the payment provider. When returning this object, if it’s valid, it will be used to change the order’s current transaction information

/// <summary>
/// Payment callback info
/// </summary>
///<param name="orderName">Name of the order</param>
///<param name="amount">Amount of the order</param>
///<param name="state">State of the order</param>
///<param name="transactionId">Id of the transaction</param>
///<param name="paymentStatus">The new payment status for the order to have</param>
PaymentCallbackInfo( string orderName, decimal amount, string state, string transactionId, PaymentStatus paymentStatus );

/// <summary>
/// Used to tell Tea Commerce an error occured in the payment provider
/// </summary>
///<param name="errorMessage">Message to show in Tea Commerce</param> 
PaymentCallbackInfo( string errorMessage );

Tea Commerce – XSLT extensions

Tea Commerce – XSLT extensions

Tea Commerce offers a lot of nice XSLT extension to be used in Umbraco. In this post i will walk you through the different extension, but because the xml output can be quite large for some of the methods i won’t go into details about the output. You can just do a simple <xsl:copy-of select=”teacommerce:method” /> to see the xml output


Returns the current order – if no order is present in the cart the order output is empty

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>
<xsl:if test="$order/@id != ''">
  <xsl:value-of select="$order/@name" />
  <xsl:for-each select="$order/orderLine">
    <xsl:value-of select="properties/productName" />

Output example

Apple Speakers
Podspeaker MicroPod


Returns the finalized order – is to be used in the shopping cart’s last step after the order is finalized

<xsl:variable name="order" select="teacommerce:GetFinalizedOrderXml()/@totalQuantity"/>

Output example



Returns the order with the specified id – is made to be used for testing and is also used in the default implementation of Tea Commerce – TeaCommerce/teaCommerceAdminOrder.xslt

<xsl:variable name="order" select="teacommerce:GetSpecificOrderXml( '11' )/@name"/>

Output example



Returns all finalized orders – can be used in many different cases, its just your imagination that is the limit

<xsl:for-each select="teacommerce:GetFinalizedOrdersXml()/order">
  <xsl:value-of select="@name" />

Output example



Returns all finalized orders for a specific member

<xsl:for-each select="teacommerce:GetFinalizedOrdersXmlForMember( umbraco.library:GetCurrentMember()/@id )/order">
  <xsl:value-of select="@name" /> - <xsl:value-of select="@totalPriceFormatted" />

Output example

WEB-7 - $250.00
WEB-9 - $349.00


Returns all countries

<xsl:for-each select="teacommerce:GetCountries()/country">
  <xsl:value-of select="@name" />

Output example

United States


Returns all currencies

<xsl:for-each select="teacommerce:GetCurrencies()/currency">
  <xsl:value-of select="@ISOCode" />

Output example



Returns possible shipping methods for the current selected country

<xsl:for-each select="teacommerce:GetShippingMethods()/shipping">
  <xsl:value-of select="@name" /> - <xsl:value-of select="@feeFormatted" />

Output example

Pick up - kr. 0,00
FedEx - kr. 100,00


Returns possible payment methods for the current selected country

<xsl:for-each select="teacommerce:GetPaymentMethods()/payment">
  <xsl:value-of select="@name" /> - <xsl:value-of select="@fee" />

Output example

VISA - 10,00
Account Transfer - 0,00


Returns the currently selected country. I no specific country has been selected through the javascript API, the default country is returned

<xsl:variable name="currentCountry" select="teacommerce:GetCurrentCountry()" />
<xsl:if test="$currentCountry/@id ='2'">
  <xsl:value-of select="@name" />

Output example

United States


Returns the currently selected currency. I no specific currency has been selected through the javascript API, current currency fallback to the default country’s currency

<xsl:variable name="currentCurrency" select="teacommerce:GetCurrentCurrency()" />
<xsl:value-of select="@cultureName" />

Output example



Formats a price with a currency symbol, based on current currency’s culture

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>
<xsl:value-of select="teacommerce:FormatPrice( $order/@totalPrice )" />

Output example

kr. 1395,00


Formats a price without a currency symbol, based on current currency’s culture

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>
<xsl:value-of select="teacommerce:FormatPriceNoSymbol( $order/@totalPrice )" />

Output example



Formats a decimal price with a currency symbol, based on the specified culture

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>
<xsl:value-of select="teacommerce:FormatPriceWithSpecificCulture( $order/@totalPrice, 'en-US' )" />

Output example



Formats a decimal price without a currency symbol, based on the specified culture

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>
<xsl:value-of select="teacommerce:FormatPriceNoSymbolWithSpecificCulture( $order/@totalPrice, 'en-US' )" />

Output example


I installed Tea Commerce – what’s next

I installed Tea Commerce – what’s next


Since we launched Tea Commerce back in November 2010 much has happened. We have launched a starter kits that you can install – its a complete Umbraco/Tea Commerce site so you can quickly and easily get started with an Umbraco ecommerce solution.

Getting started

So you downloaded the latest version of Tea Commerce and installed it – now what to do? In this blog post i will walk you though a very simple setup of a web shop on top of a umbraco runway install. The web shop will sell four products and the shop will be an american shop with USD as the currency. So lets start.

The initial setup of Tea Commerce


Lets start by setting up the “United States” as a country. Make it the default country – as this is the country we “expect” customers to shop from and based on that we can calculate the prices from the country VAT. ( The selected VAT group in my example is 0% as we doesn’t need to calculate VAT in this simple setup )


With Tea Commerce comes 3 standard currencies – DKK, EUR and USD. Let me explain the different properties of a Currency.
- ISO code – used to passed along to payment providers and can be used in the UI
- Price field – this is the property alias for where to find the USD price on a product node from Umbraco
- Culture name – is used to format the currency

E-mail template

For the shop to send a confirmation e-mail to the customer and the shop owner we have to setup the e-mail settings. These properties should be pretty basic to setup
Remember – if you want to send email you will have to specify the smtp in your web.config


Defining the product document type

One of the great thing about Umbraco is the possibility to create almost anything with document types and it’s properties. Of course Tea Commerce is build with this in mind, so all you products/product categories etc. you will create as your familiar Umbraco document types. For my demo i have only made a product document type as it’s enough to show how to do it.

Let me walk you though the properties:
- Product name – is used in the standard teaCommerceAdminOrder.xslt and teaCommerceEmailTemplate.xslt to output the product name ( this is for setups with product variants – for simple setups you could use nodeName in the XSLT files instead of productName )
- Product number – again used in the standard XSLT files
- Image – What to say :)
- Product price USD – this is the USD price field that we specified earlier for the USD currency

Display the products

Now we need to create some products and display them. Lets create a XSLT file and matching macro to output the products. To display the products i have created a text page “Products” and 4 products below it. Below is the XSLT and screenshots of the products in Umbraco and when displayed at the website.

<xsl:for-each select="$currentPage/Product [@isDoc]">
    <h3><xsl:value-of select="@nodeName"/></h3>
    <xsl:if test="./image != ''">
      <img src="{umbraco.library:GetMedia(./image, false)/umbracoFile}" style="float: none; padding: 0;" />
    <span><xsl:value-of select="productPriceUSD"/></span>
    <a href="#" class="productAddToCart" nodeid="{./@id}">Add to cart</a>

Adding order lines the cart

Configure order line properties to copy

Next step is to have the different products added to a cart. Before we make the javascript to do this, we have to go back to the “General settings” for Tea Commerce. When we add order lines to the cart, Tea Commerce need to know which properties to copy from the product node – as these properties can we used in the email template and the admin interface. These properties is configured in the “Order line property aliases” field. In the standard admin and email XSLT i know that “productName” and “productNumber” is used so I specify these two.

Adding order lines with javascript

Tea Commerce has an extensive javascript API to do a lot of the shop functionality through /base calls – but in this post i will only touch about three of the API methods – to read more about the javascript API, please read my colleague Rune’s blog.
Before we can do anything through javascript we need to have some script references in the head section – i have created a script file “default.js” where i will implement the javascript necessary to run my specific web shop.

<script type="text/javascript" src="/scripts/TeaCommerce/teaCommerce.js"></script>
<script type="text/javascript" src="/scripts/default.js"></script>


/* When we add product to cart */
jQuery(".productAddToCart").live("click", function () {
  var nodeId = jQuery(this).attr('nodeid');

  /* Add orderline is called using the Tea Commerce javascript API */
  TeaCommerce.addOrderLine(nodeId, 1, false);
  return false;

Now when i click the “Add to cart” the product is added as an order line to my cart – BUT at the moment the content of the cart isn’t displayed – lets do that as the next thing

Building a mini cart

Before making my mini cart XSLT macro, I will make my checkout pages as i need to link to them in my minicart, so i created a “Cart” page with two subpages – “Personal information – Step 01″ and “Order confirmation – Step 02″.
Next step is to create the mini cart XSLT and insert the macro in my text page template so the customer can see what is in his cart. In my demo setup i haven’t used a lot of nifty javascript so the customer has to refresh with F5 to get the mini cart to display the newly items added to the cart :)

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>

<xsl:if test="$order/@id != ''">
    <h2>Mini cart</h2>
    <xsl:for-each select="$order/orderLine">
      <div><xsl:value-of select="./properties/nodeName"/> - <xsl:value-of select="./@totalPriceFormattedNoSymbol"/></div>
    Total: <xsl:value-of select="$order/@totalPriceFormattedNoSymbol"/>
    <a href="/cart/personal-information-step-01.aspx">Checkout</a>

Building the checkout – step 1

Now that the customer has order lines in his cart – he want to go through the checkout flow. In the mini cart there is a “Checkout” link that will take the customer to step 1 of the checkout flow.

Personal information form

For step 1 i have created an XSLT macro and inserted it on the step 01 page. This step will let the customer fill in some information needed to ship the products to him.

<xsl:variable name="order" select="teacommerce:GetOrderXml()"/>

<xsl:if test="$order/@id != ''">
  <div id="personalInformation">
    <span>Company:</span><input type="text" id="company" /><br/><br/>
    <span>First name:</span><input type="text" id="firstName" /><br/><br/>
    <span>Last name:</span><input type="text" id="lastName" /><br/><br/>
    <span>Email:</span><input type="text" id="email" /><br/><br/>
    <span>Street address:</span><input type="text" id="streetAddress" /><br/><br/>
    <span>Zip code:</span><input type="text" id="zipCode" /><br/><br/>
    <span>City</span><input type="text" id="city" /><br/>
    <a id="confirmOrder" href="#">Confirm order</a>

Order properties

Order properties is a property bag in the Tea Commerce API, which means that there is no limit to what you can add as order properties.
Important To give the ability to search orders by customer name and to send email to the customer, Tea Commerce needs to know the order property names of these three. This can be configured in “General settings” in the Tea Commerce custom section. Please specify the order property names – as default values the system uses “firstName”, “lastName” and “email”.

Confirm order

Before we can click the “Confirm order” in this demo setup and go to the next step we need to specify the “Default continue URL” in “General settings”. Tea Commerce will redirect to this URL when a payment provider ( a payment method uses a payment provider ) makes a positive feedback about a payment. In my demo shop i will use the “Account” payment method that uses the default Tea Commerce payment provider.

Now that we have specified these things we are ready to create the javascript that will do the magic. The javascript is hooked up to the “Confirm order” click event, and when its clicked these things happens:
- Build a an array with the information to save as order properties and send it to the server
- Set the payment method to “Account” ( id = 2 )
- Go to payment – the default payment provider in Tea Commerce – will finalize the order, send a confirmation email and redirect to the “Default continue URL” ( this is the step 2 page in my demo )

/* The confirm order step of the cart */
jQuery('a#confirmOrder').live("click", function () {
  var personalInformation = jQuery("#personalInformation");

  /* We fetch the information from the form and creates
    an object that can be sent to the server as a form
    POST submit */
  var formObj = {
    "company": personalInformation.find("#company").val(),
    "firstName": personalInformation.find("#firstName").val(),
    "lastName": personalInformation.find("#lastName").val(),
    "email": personalInformation.find("#email").val(),
    "streetAddress": personalInformation.find("#streetAddress").val(),
    "zipCode": personalInformation.find("#zipCode").val(),
    "city": personalInformation.find("#city").val()

  /* The properties is sent to the server with a syncronous call
    This way we lock the UI and can redirect the user.*/
  TeaCommerce.updateOrderProperties(formObj, false);
  TeaCommerce.setPaymentMethod(2, false);
  return false;

Building the checkout – step 2

Now that the customer has recieved his email, the order will be finalized and his cart is empty again. But to show exactly what the customer bought, I have a confirmation page that will display the personal information entered in the previous step and his order lines.

<xsl:variable name="order" select="teacommerce:GetFinalizedOrderXml()"/>
<xsl:if test="$order/@id != ''">
    <span>First name:</span><xsl:value-of select="$order/properties/firstName"/><br/>
    <span>Last name:</span><xsl:value-of select="$order/properties/lastName"/><br/>
    <span>Email:</span><xsl:value-of select="$order/properties/email"/><br/>
    <span>Street address:</span><xsl:value-of select="$order/properties/streetAddress"/><br/>
    <span>Zip code:</span><xsl:value-of select="$order/properties/zipCode"/><br/>
    <span>City:</span><xsl:value-of select="$order/properties/city"/><br/>
    <xsl:for-each select="$order/orderLine">
      <div><xsl:value-of select="./properties/nodeName"/> - <xsl:value-of select="./@totalPriceFormattedNoSymbol"/></div>
    Total: <xsl:value-of select="$order/@totalPriceFormattedNoSymbol"/>

The end

Thats it – I have created a simply web shop and hope that you got the basic knowledge to begin setup your own web shop in Umbraco, using Tea Commerce. Please ask any questions regarding this basic demo shop or tell me what you would like to see in my next blog post – where I will dive deeper into what is possible with Tea Commerce


Tea Commerce – the new eCommerce for umbraco

Tea Commerce – the new eCommerce for umbraco

The birth of Tea Commerce

It all started on Sept. 23, 2010 to umbraco meetup in Copenhagen with my colleague Rune Grønkjær and four others from the great danish Umbraco community. The evening’s most discussed topic was ecommerce systems – what systems exist today, advantages / disadvantages, which situations fits the various systems and are there alternatives to the systems we use today.

There were both talking about uCommerce, super simple webshop, simplecartjs and simple ecommerce solutions developed for specific cases. As the conversation went on, it soon became clear that among the participants we would agreed the lack of a low budget ecommerce system for Umbraco, but still flexible and having the functionality necessary to operate an online store.

On the way home from Copenhagen, we could not help but think of how such a system should work and how to be developed, and during the trip we laid the first bricks for the new ecommerce system for Umbraco – Tea Commerce

Focus points

Tea Commerce has been developed with two main focus points, compared to the people who ultimately use the system to implement webshops – low cost and simple implementation. The price has been a really great focus point throughout the entire development, which has meant that we thought out the system more simple than other ecommerce systems – but without losing the essential functionalities.

The implementation process of Tea Commerce is incredibly simple, because the whole system is integrated into Umbraco and when you know Umbraco you quick get the touch of Tea Commerce. Many ecommerce systems offer a whole lot of different options so the system can be used in all possible situations, but often ends confusing the developers and end users with all the different options and possibilities. To avoid this in Tea Commerce, we have cut away some functionalities which are often not used or are incredibly complex to use. This of course means that Tea Commerce can not be used in all situations, but by having focus on the primary functions I think most webshops can be build untop of Tea Commerce and as the big prize the system is incredibly easy to implement and use.

Price Structure

Now for one of the very important points – the price. As promised, we have placed great emphasis on price and this means that a site license for will cost: 249 USD ex. VAT – Introduction price rest of 2010

With such a low price, it is possible to implement Tea Commerce in even very small projects with a limited budget, while the system is so flexible that it can easily be used for large ecommerce solutions that require a more custom setup.

Integration scenarios

To give an idea of how flexible Tea Commerce is, I will give two fictitious examples of customers who want a webshop and how these could be implemented in Tea Commerce.

Scenario 1 – simple ecommerce solution

In the first senarie we have a customer who has just started his business up and want to try the online market – but have a low budget. Its products consist of 10 different posters, and they want a new website to sell these through where there is a shopping cart and online payment. These functions are the core of every ecommerce system and of course Tea Commerce have these features out of the box. With the included JavaScript API and integrated payment providers its super simple to implement and the price makes Tea Commerce the perfect choice for a shop with a low budget.

Scenario 2 – advanced ecommerce solution

The second senarie could be a larger company that has hundreds of products, product variants and want the possibility for customers to choose gift wrapping for their purchase. As products and product variants is controlled by Umbraco document types it makes Tea Commerce incredibly flexible and allows almost anything is possible – just as you know it from Umbraco. Gift wrapping options could be created as nodes in Umbraco and be outputted in the basket process via XSLT, and through the javascript API it’s really easy to add custom fields to an order or to add gift wrapping as an order line.

A more technical point of view

If you want a more technical approach to Tea Commerce, I would recommend you to read my colleague Rune’s blog post that goes more into technical details about how Tea Commerce work – from the frontend, through the server and into the data layer.

The next few weeks

Over the next week, my colleague Rune and I will blog about the development of Tea Commerce, all the possibilities in the system and how you can use Tea Commerce to build your next ecommerce solution. If you want a live review of the system and look at some of the technical possibilities of it, you’re more than welcome to come to Umbraco UK Festival – Copenhagen where we’ve got 30 minutes to present the product and to take on questions.

We hope to have a version ready of Tea Commerce we can share with developers in the next couple of weeks so you can try it out. Follow our blogs/twitter the next few weeks for more information and as always you’re more than welcome to ask questions or make a comment.