NAB Transact Hosted Payments Implemented In ASP.NET


NAB Transact Hosted Payments Implemented In ASP.NET

This is a technical blog post for those wanting to implement the eCommerce product supplied by National Australia Bank (NAB) using their Hosted Payments Page (HPP) via ASP.NET. We created this blog post as it was clear that there were only solutions being sold and not made widely available for reference with NAB (the provider) only publishing a HTML based example / solution. Our website is based on ASP.NET with a Visual Basic (VB .NET) backend which is the basis for the code supplied, although those who are familiar with .NET know it can be converted in C# easily enough. The primary issue with ASP .NET being that if you use a Site.Master template that input names are pre-tagged with a Master Placeholder reference preventing a HTML submit from pairing parameters correctly. The solution provided in this blog post is not a direct copy of our implementation but rather a generic example to allow it to be adapted to other applications. We have also developed a plugin for the XML option in ASP.NET which can be found in the links at the bottom of the page. If you are considering alternatives you may also be interested in eWay's Hosted Payments Page which is a competing product and we would be happy to provide an example for the Rapid API for this product as well on request.

NAB makes available an integration manual for HPP which describes generically how to interface with it using HTML but if your business is anything like ours then you have a website that has progressed beyond basic HTML into formats such as ASP.NET, PHP, Node JS etc which are preferred for a range of reasons for which examples aren't provided. Given the range of functionality, scalability and maintenance concerns it was our preference to maintain our approach to interfacing with NAB Transact via server side VB .NET code. I will not pretend that I am a cutting edge coder and I will not preach pros and cons of interfacing with NAB Transact HPP in this way but rather wanted to demonstrate how you would achieve it knowing how much blood sweat and tears it took to find this information. Please be aware that the example provided only shows how to POST to NAB Transact HPP and not extract data on transaction completion / failure.

Note: This example assumes you are using Visual Studio 2010 or better. Generally square brackets have been used to denote where substitutions are required.

You'll start by creating ASP Labels and Textboxes for the data you will parse and replace [Data] with the description of the field contents such as:
<asp:label id="[Data]Label" Text="[Data]:&nbsp" vertical-align="bottom" runat="server"/> <asp:textbox id="[Data]Text" CssClass="asptextbox-table" runat="server"/></td>

This allows you to associate validators to the textboxes such as for required fields:
<asp:RequiredFieldValidator id="AmountReqFieldValidator" ControlToValidate="[Data]Text" Display="Static" ErrorMessage="*" runat="server"/>

E-mail Validator:
<asp:RegularExpressionValidator id="EmailRegExprValidator" ControlToValidate="[Data]Text" ValidationExpression="^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$" EnableClientScript="false" Display="Static" ErrorMessage="Invalid format for e-mail address." runat="server"/>

Amount Validator:
<asp:RegularExpressionValidator id="AmountRegExprValidator" ControlToValidate="[Data]Text" ValidationExpression="^(?:\d{1,6})?(?:\.\d{1,2})?$" EnableClientScript="false" Display="Static" ErrorMessage="Invalid format for a donation in dollars." runat="server"/>

Most payment systems these days also require acknowledgement of terms and conditions such as privacy, refund, delivery and transactional terms which can usually be achieved by using a checkbox:

<asp:CheckBox id="[Data]Check" runat="server" Checked="False" TextAlign="Left" /> <asp:label id="TCCheckLabel" Text="I have read and understand the Terms and Conditions including the Privacy Statement" vertical-align="bottom" runat="server"/> <asp:CustomValidator id="[Data]CheckCustVal" ClientValidationFunction="[Data]Check" ValidationGroup="AddMisc" ErrorMessage="*" runat="server"/>

Note: NAB Transact still requires a privacy, refund and return policy to be accessible from the HPP even if you use a checkbox.

You'll also need a submit button but unlike the HTML version this will link back to the VB.NET code for post execution:
<asp:button id="SubmitButton" Text="Submit" onclick="SubmitButton_OnClick" runat="server"/>

So that is the basic concept of the front end which you'll need to arrange and format as required, perhaps using a table or whatever takes your fancy. Keep in mind that all controls you will need to interface with on your server side using VB .NET will require a runat="server" attribute in order to be able to reference them in your code.

Your own research has probably led you to believe that you should be using WebRequest, HTTPWebRequest or WebClient as I did, unfortunately we were both wrong. The backend will use a custom function format and POST your data as if it was a HTML form post which NAB Transact HPP expects. In our VB .NET code it is recommended that we verify that validation has been met before processing any further allowing the website to respond more quickly. We should then preload, precondition and pack our data before posting it. In our case we created a test condition that allows us to direct individual requests to the demo site through modifying the parameters when navigating to our payment site. The majority of our code is irrelevant or specific to an implementation so I have included code for a scenario that I feel would be reasonable as an example using the demo URL:

I personally prefer storing credentials in my web.config file for retrieval through code rather than raw use and I'll use this in the example:

<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="NABTransact.merchantID" value="ABC0010"/>
<add key="NABTransact.DemoURL" value="https://demo.transact.nab.com.au/live/hpp/payment"/>
<add key="NABTransact.LiveURL" value="https://transact.nab.com.au/live/hpp/payment"/>
...
</configuration>

In your web page (i.e. webpage.aspx, code goes in webpage.aspx.vb) that will request a transaction via the HPP include the following code which will link with your configured "Submit" button discussed earlier:

Imports System.IO
Imports System.Net
Partial Public Class [Webpage] Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub

' Submit Button Execution (Validation, Preconditioning & Data Packing
Protected Sub SubmitButton_OnClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles SubmitButton.Click
    ' Verify that all validation criteria is met
    If [Insert Validator IDs Here i.e. EmailReqFieldValidator.IsValid] Then
        Dim MerchantID As String
        Dim URL As String
        
        ' Define transaction credentials
        MerchantID = ConfigurationManager.AppSettings("NABTransact.merchantID").ToString()
        URL = ConfigurationManager.AppSettings("NABTransact.DemoURL").ToString()

        ' Create POST data as per HPP integration manual
        Dim PostData As NameValueCollection = New NameValueCollection
        PostData.Add("vendor_name", MerchantID)
        PostData.Add("payment_alert", "transactions@actsintuitively.com.au")
        PostData.Add("payment_reference", Session.SessionID)
        PostData.Add("privacy_policy", "http://www.actsintuitively.com.au/privacy.aspx")
        PostData.Add("refund_policy", "http://www.actsintuitively.com.au/refund.aspx")
        PostData.Add("return_link_text", "Return To Payment Page")
        PostData.Add("return_link_url", "http://www.actsintuitively.com.au/pay.aspx")
        ' PostData.Add("reply_link_url", "http://www.actsintuitively.com.au/complete.aspx")
        PostData.Add("gst_rate", 10)
        PostData.Add("gst_added", "false")
        PostData.Add("gst_exempt_fields", "")
        PostData.Add("receipt_address", CustomerEmail.Text)
        PostData.Add(ProductName.Text, ProductQuantity.Text & "," & ProductValue.Text) //you could use a loop for multiple products
        PostData.Add("Address", Address.Text)
        PostData.Add("State", State.Text)
        PostData.Add("Post Code", PostCode.Text)
        PostData.Add("E-Mail", CustomerEmail.Text)
        PostData.Add("information_fields", "Address,State,Post Code, E-Mail")
        PostData.Add("suppress_field_names", "State,Post Code")

        RedirectPOST(Me.Page, TransURL, PostData)
    End If
End Sub

Public Shared Sub RedirectPOST(ByVal Page As Page, ByVal DestinationURL As String, ByVal PostData As NameValueCollection)
    ' Prepare the form and post string 
    Dim sForm As String = PreparePOST(DestinationURL, PostData)

    ' Add a literal control to the specified page holding the form and 
    ' post javascript to submit with the request.
    Page.Controls.Add(New LiteralControl(sForm))
End Sub

Private Shared Function PreparePOST(ByVal URL As String, ByVal PostData As NameValueCollection) As String
    ' Set a name for the form to reference in Javascript
    Dim FormID As String = "PostForm"

    ' Build the form into a string using the specified data to be posted
    Dim sForm As StringBuilder = New StringBuilder()
    sForm.Append("<form id=""" & FormID & """ name=""" & FormID & """ action=""" & URL & """ method=""POST"">")
    For Each Key As String In PostData
        sForm.Append("<input type=""hidden"" name=""" & Key & """ value=""" & PostData(Key) & """>")
    Next
    sForm.Append("</form>")

    ' Build the JavaScript which will Post the form string
    Dim strScript As StringBuilder = New StringBuilder()
    strScript.Append("<script language='javascript'>")
    strScript.Append("var v" & FormID & " = document." & FormID & ";")
    strScript.Append("v" & FormID & ".submit();")
    strScript.Append("</script>")

    ' Return the form and the script concatenated.
    ' (The order is important, Form then JavaScript)
    Return sForm.ToString() + strScript.ToString()
End Function
End Class

The two functions PreparePOST and RedirectPOST can be moved into a public class if more than one page needs to execute a POST in this manner.

I would like to kindly thank Samer Abu Rabie who supplied the solution in C# I have repurposed and can be found in the outbound links section below. I hope that this post has helped you in some way, saved you from days of banging your head against a wall and made using NAB Transact a much easier experience when using ASP .NET. If you are interested in finding out more about what we can do for you then please feel free to visit our main website or contact us. Thank you for your time, for reading our blog post and it would be great if you feel the need to share or like our articles via one of our social media platforms with the @ActsIntuitively tag as applies.

Brent Webster
Technical Services Manager

ActsIntuitively
Bunbury, WA
info@actsintuitively.com.au

ActsIntuitively Website | Psychological Services Website | Shop | Digital Shop | Blog Home

Outbound links:

  1. Code Project - Redirect and POST in ASP.NET

  2. NAB Transact - Hosted Payment Page Integration Guide (29/12/2017)

  3. Drupal - PHP Module To Integrate NAB Transact Hosted Payment Gateway Page

  4. ActsIntuitively - NAB Transact XML API Implemented In ASP.NET