Blog

Categorised by 'General Development'.

  • I’ve been busy lately integrating a payment provider into a site I am working in. After looking at the best payment providers, it came down to either using PayPal or Google Checkout. In the end I decided to use Google’s payment provider (as you can probably tell from my post title).

    Before I start this post, I assume you have already created a sandbox Google Checkout account and know your way around setup and integration.

    For my own Google Checkout integration, I needed to be able to add new transaction item in my database only if a customer has ordered an item and if their payment is approved. This is where Google’s call-back notification service comes into play.

    I decided to use an synchronous notification process based on one the sample code that can be downloaded here: http://code.google.com/p/google-checkout-dotnet-sample-code/downloads/list.

    Just using the sample code provided by Google out-the-box caused issues. It seems that the code samples do not correctly reflect version changes to the payment provider. One of the repeating errors I got was: “Expected serial number was not contained in notification acknowledgement”.

    Google Checkout ErrorList

    You will only receive this error only if you are using API version 2.5 and have “Notification Filtering” enabled in account settings. Unfortunately, notification filtering is something I needed to ensure both Google Checkout and my database transactions were in sync.

    The Integration Issue error log showed me that the transaction serial number was not getting populated from my call-back notification page.

    Google Checkout Error XML Detail

    After a lot of debugging it became apparent that the notification page provided by Google Code sample was wrong! It was missing a key case statement: “authorization-amount-notification”. Once this was added no more errors occurred.

    If you are using the “notification_extended.aspx”, “notification.aspx” or “notification_handshake.aspx” code samples. Be sure to make the following change:

    <%@ Import Namespace="System.IO" %>
    <%@ Import Namespace="GCheckout" %>
    <%@ Import Namespace="GCheckout.AutoGen" %>
    <%@ Import Namespace="GCheckout.Util" %>
    <script runat="server" language="c#">
    
      public string SerialNumber = "";
    
      void Page_Load(Object sender, EventArgs e) {
        // Extract the XML from the request.
        Stream RequestStream = Request.InputStream;
        StreamReader RequestStreamReader = new StreamReader(RequestStream);
        string RequestXml = RequestStreamReader.ReadToEnd();
        RequestStream.Close();
        // Act on the XML.
        switch (EncodeHelper.GetTopElement(RequestXml)) {
          case "new-order-notification":
            NewOrderNotification N1 = (NewOrderNotification) EncodeHelper.Deserialize(RequestXml, typeof(NewOrderNotification));
            SerialNumber = N1.serialnumber;
            string OrderNumber1 = N1.googleordernumber;
            string ShipToName = N1.buyershippingaddress.contactname;
            string ShipToAddress1 = N1.buyershippingaddress.address1;
            string ShipToAddress2 = N1.buyershippingaddress.address2;
            string ShipToCity = N1.buyershippingaddress.city;
            string ShipToState = N1.buyershippingaddress.region;
            string ShipToZip = N1.buyershippingaddress.postalcode;
            foreach (Item ThisItem in N1.shoppingcart.items) {
              string Name = ThisItem.itemname;
              int Quantity = ThisItem.quantity;
              decimal Price = ThisItem.unitprice.Value;
            }
            break;
          case "risk-information-notification":
            RiskInformationNotification N2 = (RiskInformationNotification) EncodeHelper.Deserialize(RequestXml, typeof(RiskInformationNotification));
            // This notification tells us that Google has authorized the order and it has passed the fraud check.
            // Use the data below to determine if you want to accept the order, then start processing it.
            SerialNumber = N2.serialnumber;
            string OrderNumber2 = N2.googleordernumber;
            string AVS = N2.riskinformation.avsresponse;
            string CVN = N2.riskinformation.cvnresponse;
            bool SellerProtection = N2.riskinformation.eligibleforprotection;
            break;
          case "order-state-change-notification":
            OrderStateChangeNotification N3 = (OrderStateChangeNotification) EncodeHelper.Deserialize(RequestXml, typeof(OrderStateChangeNotification));
            // The order has changed either financial or fulfillment state in Google's system.
            SerialNumber = N3.serialnumber;
            string OrderNumber3 = N3.googleordernumber;
            string NewFinanceState = N3.newfinancialorderstate.ToString();
            string NewFulfillmentState = N3.newfulfillmentorderstate.ToString();
            string PrevFinanceState = N3.previousfinancialorderstate.ToString();
            string PrevFulfillmentState = N3.previousfulfillmentorderstate.ToString();
            break;
          case "charge-amount-notification":
            ChargeAmountNotification N4 = (ChargeAmountNotification) EncodeHelper.Deserialize(RequestXml, typeof(ChargeAmountNotification));
            // Google has successfully charged the customer's credit card.
            SerialNumber = N4.serialnumber;
            string OrderNumber4 = N4.googleordernumber;
            decimal ChargedAmount = N4.latestchargeamount.Value;
            break;
          case "refund-amount-notification":
            RefundAmountNotification N5 = (RefundAmountNotification) EncodeHelper.Deserialize(RequestXml, typeof(RefundAmountNotification));
            // Google has successfully refunded the customer's credit card.
            SerialNumber = N5.serialnumber;
            string OrderNumber5 = N5.googleordernumber;
            decimal RefundedAmount = N5.latestrefundamount.Value;
            break;
          case "chargeback-amount-notification":
            ChargebackAmountNotification N6 = (ChargebackAmountNotification) EncodeHelper.Deserialize(RequestXml, typeof(ChargebackAmountNotification));
            // A customer initiated a chargeback with his credit card company to get her money back.
            SerialNumber = N6.serialnumber;
            string OrderNumber6 = N6.googleordernumber;
            decimal ChargebackAmount = N6.latestchargebackamount.Value;
            break;
        // Edit: Additional case statement for "authorization-amount-notification"
          case "authorization-amount-notification":
            AuthorizationAmountNotification N7 = (AuthorizationAmountNotification)EncodeHelper.Deserialize(RequestXml, typeof(AuthorizationAmountNotification));
            // Information about a successful reauthorization for an order
            SerialNumber = N7.serialnumber;
            string OrderNumber7 = N7.googleordernumber;
            break;
          default:
            break;
        }
      }
    </script>
    <notification-acknowledgment xmlns="http://checkout.google.com/schema/2" serial-number="<%=SerialNumber %>" />
    

    Once I have got to grips on using Google Checkout I will add another blog post containing my full call-back solution.

  • The “Remove Format” button (Remove Formatting Button) within FCKEditor, only removes valid inline elements such as: strong, span, strike, font, em, etc.

    If you want to be able to make the Remove Formatting function more flexible so that it removes block elements, you can do so by modifying the “fckconfig.js” file found within the FCKeditor folder.

    Search for the “FCKConfig.RemoveFormatTags” line, which will look something like this:

    FCKConfig.RemoveFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var';
    

    All you need to do now is add any additional elements you wish to remove from your content. In my case, I wanted the Remove Formatting button to remove all header tags. So I carried out the following:

    FCKConfig.RemoveFormatTags = 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var,h1,h2,h3';
    
  • Web browsers have come a long way since the days of Internet Explorer 6 release back in 2001. You would think 9 years on we would have all dumped this piece of software in the garbage heap by now. Alas, we still have users to this very date who still use IE6 either due to personal preference or by force (company IT policies).

    As everyone knows, developing a site to be compliant with main stream browsers in addition to carrying out additional fixes to fit in with the slim 6.7% of global users can be a real pain. So instead of trying to fit your site around the small number of IE6 users, why not just knock some common sense into them and notify them to upgrade.

    Thankfully, there is a really easy and polite way to do this. Go to http://code.google.com/p/ie6-upgrade-warning/ and download the JavaScript file and embed the following code to your webpage…

    <!--[if lte IE 6]>
        <script src="js/ie6/warning.js"></script>
        <script>window.onload=function(){e("js/ie6/")}</script>
    <![endif]-->
    

    …which outputs the following result:

    IE6 Upgrade Warning

    As great as this idea is I don’t see many web developers or web agencies implementing this on the sites they create unless really needed. Nevertheless, its step in the right direction to hopefully put a final nail into that IE6 coffin!

  • I needed to create a custom web part using Visual Studio 2003 for a SharePoint 2003 client intranet, something I have never done before. As fellow SharePoint developers will know, you need to strongly name your project assembly whenever you need deploy a custom made web part.

    Visual Studio 2005 and onwards allows you to easily create a strongly named key through the graphical user interface. In Visual Studio 2003, you will need to use the Visual Studio 2003 Command Prompt. You can find the Visual Studio 2003 Command Prompt by going to: Start > Program Files > Visual Studio 2003 > Visual Studio.NET Tools > Visual Studio .NET 2003 Command Prompt.

    Visual Studio 2003 Command Prompt

    Once the command prompt window has opened all you need to do is enter the following to create a SNK:

    Setting environment for using Microsoft Visual Studio .NET 2003 tools.
    (If you have another version of Visual Studio or Visual C++ installed and wish
    to use its tools from the command line, run vcvars32.bat for that version.)
     
    C:\Documents and Settings\Administrator\Desktop>sn -k MyKey.snk
     
    Microsoft (R) .NET Framework Strong Name Utility  Version 1.1.4322.573
    Copyright (C) Microsoft Corporation 1998-2002. All rights reserved. 
     
    Key pair written to MyKey.snk
     
    C:\Documents and Settings\Administrator\Desktop>
    

    As you can see from my command prompt example above, I am creating a new SNK file called MyKey.snk. This SNK file will be generated on my Desktop.

  • I am sure all developers in the past have attempted to create their own bar or pie chart using .NET’s System.Drawing methods. However, I never been able to match a high quality finish similar to what you would expect from third party charting software. You can see my charting attempt in my post: Outputting Custom Made Charts.

    As much as I would like to use .NET charting solutions from the likes of DotNetCharting and FusionCharts, they are just too expensive to buy. I have downloaded trial versions and been thoroughly impressed with their range of charts and functionality.

    But it seems I have been quite late in noticing Microsoft have released their own range of chart controls to easily create rich professional looking visual data. Having had a play around in Microsoft Charts earlier this week, I have to say I am a big fan. Its a shame I hadn’t found it earlier.

    From looking around that net, there are many articles and blogs on how to use Microsoft Chart so I am not going to write another. Ha! But in the next day or two, I plan to blog on how I implemented Microsoft Chart as a web part within my Report Center in SharePoint 2007. So watch this space.

    In the meantime here are some useful links I have used to get started in Microsoft Chart:

  • BrowserRefresh Being a fellow Web Developer, you would probably agree with me when I say that the “Refresh” button is the most used button in your browser. I can’t even consider about counting the amount of times I hit the “Refresh” button while creating a web page.

    On the odd occasion when I am having a really bad day and nothing seems to be going my way. I am bound to be irritated even further because my browser is being really stupid and does not allow me to see the changes I have made to a web page I am working on. Its almost like the browser is trying to mock me and make my web developing life and living HELL!!!!!

    So I carry out the following methods to get my page to refresh.

    Force Refresh

    In many cases in order to see changes on your page you would press the “Refresh” button (or F5), which simply reloads the page without clearing the cache. So you will have to carry out a Force Refresh by pressing Ctrl + F5.

    Clearing Cache In Settings

    If the Force Refresh does not work. You will have to carry out some serious cleaning by going into the browser settings.

    • Mozilla FireFox – Tools > Options > Privacy > Private Data section > Settings
    • Microsoft Internet Explorer – Tools > Internet Options > Temporary Files > Delete Temporary Files

    Adding “?” To End of The WEB address

    This is probably my most favourite method of ensuring a page you are viewing is not cached. All you need to do is add a “?” to the end of the web address. For example:

    ?
    

    The browser thinks that you are requesting a new page. This works great if all else fails! You can even add another “?” to the end of the web address to carry out another non-cached refresh.

  • In 2005, the search engine Google launched the Sitemap 0.84 Protocol, which would be using the XML format. A sitemap is a way of organizing a website, identifying the URLs and the data under each section. Previously, the sitemaps were primarily geared for the users of the website. However, Google's XML format was designed for the search engines, allowing them to find the data faster and more efficiently.

    Even the most simple sitemap to a website is quite important in order to allow search engines such as Google and Microsoft Live Search to crawl your website for any changes. The following example shows what a basic XML sitemap contains:

    <?xml version="1.0" encoding="UTF-8" ?> 
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
    <url>
    <loc>/blog/</loc> 
    <priority>0.5</priority> 
    <changefreq>weekly</changefreq> 
    </url>
    </urlset>
    


    As you can see the sitemap contain the following:

    • <loc> = Location of the page
    • <priority> = The priority of a particular URL relative to other pages on the same site. The value for this tag is a number between 0.0 and 1.0, where 0.0 identifies the lowest priority page(s) on your site and 1.0 identifies the highest priority page(s) on your site.

    The default priority of a page is 0.5.

    • <changefreq> = This value indicates how frequently the content at a particular URL is likely to change.

    Thankfully, there is a site that will automatically generate an XML sitemap for you: http://www.sitemapspal.com/

    I have written a blog post a little while back on how to manually submit your sitemap to search engines which proves to be quite useful if you find that your site has not been crawled for a long time. You can find that blog post here.

  • After my last blog posting (Google Is Better Than I Thought!!!), one of my mates said that he was unable integrate the Google Sitemap facility to his Blogger.com blog since there we could not find a Sitemap file. You can create a Google Sitemap for your Blogger.com site by carrying out the following:

    1. Login to your Google Sitemap account.

    2. Soon as you login you will be able to add your blogger site. In my example, I am creating a fictitious blog called "someblog.blogsite.com".

    1. Once you have added your new site you will get a message saying that your new site was added successfully.

    2. Now you will need to verify that you are the owner of the blog you have submitted (you wouldn't want anybody to track your site would you? :-P). You have two options here. You can either use a HTML file (which cannot be used on Blogger blogs) or META tag. Select META tag.

    1. A unique META tag will be generated for you:

    1. Login to your Blogger.com account and edit your Blog Template. Insert your generated META tag straight after the <head> tag and Save your template.

    2. In the Google Sitemap account click on the "Verify" button and if everything goes to plan you will be able to create a Sitemap file.

    3. Click on the "Sitemap" link from the left navigation and then click "Add Sitemap".

    4. From the Drop Down List select "Add General Web Sitemap".


    10) The Blogger RSS feed will be used as your Sitemap. So enter the full web address of your RSS feed. For example: http://someblog.blogsite.com/feeds/posts/ and press "Add General Web Sitemap" button.

    That should be it. It may take up to 24 hours for Google to crawel through your blog depending on the amount of content on your site.

    UPDATE:

    It looks like  there are 4 possibilities for referencing your Blogger Sitemap:
    > someblog.blogsite.com/rss.xml
    > someblog.blogsite.com/feeds/posts/full
    > someblog.blogsite.com/feeds/posts/default?alt=rss
    > someblog.blogsite.com/atom.xml

  • Published on
    -
    1 min read

    Google Is Better Than I Thought!!!

    google-as-a-giant-robot I decide to test how well my site postings was being tracked on Google and I was quite surprised that my site had not been tracked for over a month, which meant that all my recent posts were not submitted to the search engine. However, I found that you can manually tell Google to update your website through XML sitemaps. Pretty much all well known blog formats have sitemaps functionality. For example, http://blogs.sampleblog.co.uk/sitemap.axd. As you can see the .axd page is the XML Sitemap file.

    Using Google's manual update is as simple as going to the following web address: http://www.google.com/ping?sitemap=[sitemap URL]. Once you have carried this out Google will display a link to check your tracking status and gives you additional information on when your site was last tracked. Amazing!

    From carrying out further research on the Internet, Microsoft Live Search has incorporated the Sitemap ping back service in the exact same way. Instead you will need to go to the following web address: http://webmaster.live.com/ping.aspx?siteMap=[sitemap URL].