Coldfusion Protx VSP Form Integration Kit
Do you have a Coldfusion site and wish to integrate it with the Protx payment system? If so then this is the best script for you, by using the VSP Form you do not require SSL encryption because all sensitive details are collected on a Protx secure server.
In this script you will need 6 pages.
- functions.cfm
- submit1.cfm
- submit2.cfm
- submit3.cfm
- completed.cfm
- notcompleted.cfm
I will start with the page functions.cfm this page will contain variables such as your VendorName, EncryptionPassword and your server name.
VendorName="CFProject";
EncryptionPassword="Passwordhere";
MyServer="http://cfproject.co.uk/payment/";
vspsite="https://ukvps.protx.com/vps2form/submit.asp";
function base64Encode(plain) {
output = "";
output = ToBase64(plain);
return output;
}
function base64Decode(scrambled) {
output = "";
output = toString(toBinary(scrambled));
return output;
}
function simpleXor(InString, Key) {
KeyList = ArrayNew(1);
output = "";
for(i = 1; i LTE Len(Key); i=i+1){
KeyList[i] = Asc(Mid(Key, i, 1));
}
for(i = 0; i LTE Len(InString)-1; i=i+1){
result = (bitXor((Asc(Mid(InString, i+1, 1))), (KeyList[(i MOD Len(Key))+1])));
if (result eq 0){
output = output & urldecode("%00");
} else {
output = output & Chr(result);
}
}
return output;
}
function getTokens(thisString, thisToken) {
Tokens = arrayNew(1);
subString = "";
Tokens = ListToArray ("Status,StatusDetail,VendorTxCode,VPSTxId,TxAuthNo,AVSCV2,Amount,AddressResult,PostCodeResult,CV2Result,GiftAid,3DSecureStatus,CAVV");
if (REFindNoCase(thisToken&"=", thisString) eq 0) {
output="";
} else{
subString=mid(thisString,REFindNoCase(thisToken, thisString)+len(thisToken)+1,len(thisString));
i = 1;
while (i LTE ArrayLen(Tokens)){
if (Tokens[i] neq thisToken) {
if (REFindNoCase("&" & Tokens[i], subString) gt 1) {
substring=left(substring,REFindNoCase("&"&tokens[i], subString)-1);
}
if (REFindNoCase("&" & Tokens[i], subString) eq 1) {
substring="";
}
}
i = i +1;
}
output=subString;
}
return output;
}
</CFSCRIPT>
The vspSite variable should be changed depending on which stage of th development you are at, all you have to do is uncomment the appropriate line. For example the extract below is set the send the data to the live site.
//** Simulator site **
//vspSite="https://ukvpstest.protx.com/VSPSimulator/VSPFormGateway.asp";
//** Test site **
//vspSite="https://ukvpstest.protx.com/vps2form/submit.asp";
//** Live site - ONLY uncomment when going live **
vspsite="https://ukvps.protx.com/vps2form/submit.asp";
The VendorName and EncryptionPassword will be provided to you when you signup with Protx.
Now we more on to the 3 submit pages. these pages will be used to collect appropriate information about the products being sold so they can be saved to your database and sent onto Protx.
Submit1.cfm
<CFSET NewID = CreateUUID()>
<CFSET Session.VendorTXCode = "#NewID#">
<FORM ACTION="submit2.cfm" METHOD="POST" ID="form1" NAME="Example">
<TABLE BORDER="1" WIDTH="100%">
<TR>
<TD WIDTH="36%" ALIGN="right"><B>Your Unique Transaction Code</B> </TD>
<TD WIDTH="64%"><CFOUTPUT>#Session.VendorTXCode#
<INPUT type="hidden" NAME="VendorTxCode" VALUE="#Session.VendorTXCode#">
</CFOUTPUT> </TD>
</TR>
<TR>
<TD WIDTH="36%" ALIGN="right"><B>Transaction Value</B> </TD>
<TD WIDTH="64%"><CFOUTPUT>#Form.FinalCost#
<INPUT type="hidden" NAME="Amount" VALUE="#Form.FinalCost#">
</CFOUTPUT> </TD>
</TR>
<TR>
<TD WIDTH="36%" ALIGN="right"><B>Currency</B> </TD>
<TD WIDTH="64%"> GBP <CFOUTPUT>
<INPUT type="hidden" NAME="Currency" VALUE="GBP">
</CFOUTPUT> </TD>
</TR>
<TR>
<TD WIDTH="36%" ALIGN="right"><B>Description of Goods<BR>
</B></TD>
<TD WIDTH="64%"> Items Bought From CFProject
<INPUT type="hidden" NAME="Description" VALUE="Items Bought From CFProject"></TD>
</TR>
</TABLE>
<BR>
<TABLE BORDER="0" WIDTH="100%">
<TR>
<TD WIDTH="50%"><table width="100" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="1" nowrap="nowrap" bgcolor="#BFBFBF"></td>
<td><a href="../checkout.cfm"><img src="../images/back.gif" border="0" /></a></td>
<td width="1" nowrap="nowrap" bgcolor="#BEBEBE"></td>
</tr>
</table></TD>
<TD WIDTH="50%"><cfoutput>
<input type="hidden" value="#Form.CustomerID#" name="CustomerID">
<cfif IsDefined ("Form.Delivery")>
<INPUT TYPE="HIDDEN" NAME="Delivery" VALUE="#FORM.Delivery#">
</cfif>
<INPUT TYPE="HIDDEN" NAME="CartID" VALUE="#FORM.CartID#">
</cfoutput>
<table width="100" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="1" bgcolor="#BFBFBF"></td>
<td><input name="image" type="image" value="Submit the Order details" src="../images/proceed.gif" /></td>
<td width="1" bgcolor="#BEBEBE"></td>
</tr>
</table></TD>
</TR>
</TABLE>
</FORM>
In this script you will notice a few Form cariables which need to be collected fromt he previous page. These are:
- Form.FinalCost
- Form.CustomerID
- Form.Delivery
- Form.CartID
This step is the start of the Payment process. More experienced developers may be able to integrate this step with submit2.cfm.
submit2.cfm
For this page we need to get the information sent from the page before and save it into a database.
<cfquery name="cust" datasource="#Application.datasource#">
SELECT *
FROM tblStoreCustomers
WHERE CustomerID = '#FORM.CustomerID#'
</cfquery>
<CFSCRIPT>
ThisVendorTxCode = form.VendorTxcode;
ThisAmount = form.Amount;
ThisCurrency = form.Currency;
ThisDescription = form.Description;
</CFSCRIPT>
We now need to create a form collecting the rest of the information about the billing and delivery address.
<TR>
<TD ALIGN="left"><FORM ACTION="submit3.cfm" METHOD="post" ID="form1" NAME="Example"><CFOUTPUT>
<cfif IsDefined ("Form.Delivery")>
<INPUT TYPE="HIDDEN" NAME="Delivery" VALUE="#FORM.Delivery#">
</cfif>
<INPUT TYPE="HIDDEN" NAME="CartID" VALUE="#FORM.CartID#">
<INPUT TYPE="hidden" NAME="VendorTxCode" VALUE="#ThisVendorTxCode#">
<INPUT TYPE="hidden" NAME="Amount" VALUE="#ThisAmount#">
<INPUT TYPE="hidden" NAME="Currency" VALUE="#ThisCurrency#">
<INPUT TYPE="hidden" NAME="Description" VALUE="#ThisDescription#">
<INPUT type="hidden" NAME="VendorEmail" VALUE="Sales@cfproject.co.uk">
<input type="hidden" name="AllowGiftAid" value="">
<input type="hidden" name="ApplyAVSCV2" value="">
<input type="hidden" name="Apply3DSecure" value="">
<INPUT type="hidden" NAME="CustomerEmail" VALUE="#cust.Email#">
<INPUT type="hidden" NAME="BillingAddress" value="#cust.Address1# #cust.Address2# #cust.City#">
<INPUT type="hidden" name="BillingPostCode" value="#cust.PostCode#">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="3">If Your Delivery Address Is Different From Your Billing Address Please Enter It Here</td>
</tr>
<tr>
<td width="28%"> </td>
<td> </td>
<td width="38%"> </td>
</tr>
<tr>
<td valign="top">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td><strong>Billing Address </strong></td>
</tr>
<tr>
<td>#cust.FirstName# #cust.LastName#</td>
</tr>
<tr>
<td>#cust.CompanyName#</td>
</tr>
<tr>
<td>#cust.Address1#</td>
</tr>
<tr>
<td>#cust.Address2#</td>
</tr>
<tr>
<td>#cust.City#</td>
</tr>
<tr>
<td>#cust.PostCode#</td>
</tr>
</table></td>
<td> </td>
<td valign="top"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td colspan="2"><strong>Delivery Address</strong></td>
</tr>
<tr>
<td>Name:</td>
<td><input maxlength="30" name="CustomerName" size="30" value=""></td>
</tr>
<tr>
<td>Address:</td>
<td><textarea rows="3" name="DeliveryAddress" cols="20"></textarea></td>
</tr>
<tr>
<td>PostCode:</td>
<td><input maxlength="10" name="DeliveryPostCode" size="10" value=""></td>
</tr>
<tr>
<td>Contact Number: </td>
<td><input type="text" name="ContactNumber" size="20" maxlength="20"></td>
</tr>
<tr>
<td>Contact Fax: </td>
<td><INPUT TYPE="text" NAME="ContactFax" SIZE="20" MAXLENGTH="20"></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</table></td>
</tr>
</table>
</CFOUTPUT>
<TABLE BORDER="0" WIDTH="100%">
<TR>
<TD WIDTH="50%">
<table width="100" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="1" nowrap="nowrap" bgcolor="#BFBFBF"></td>
<td>
<a href="../checkout.cfm"><img src="../images/back.gif" border="0" /></a></td>
<td width="1" nowrap="nowrap" bgcolor="#BEBEBE"></td>
</tr>
</table>
</TD>
<TD WIDTH="50%">
<table width="100" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="1" bgcolor="#BFBFBF"></td>
<td><input name="image" type="image" value="Submit the Order details" src="../images/proceed.gif" /></td>
<td width="1" bgcolor="#BEBEBE"></td>
</tr>
</table>
</TD>
</TR>
</TABLE>
</FORM>
</TD>
</TR>
</TABLE>
submit3.cfm
Ok this is where it starts to get difficult. This is where we bring it all together and send it off to Protx for payment. what happends here is we gt all of the information and build them together into a crypt string to they cannot be read when being send to Protx you encrypt the data with the Encryption key that protx assign you. we will then save the rest of the data into our database to await conformation of payment.
<cfquery name="Customer" datasource="#Application.datasource#">
SELECT *
FROM tblStoreCustomers
WHERE CustomerID = '#SESSION.CustomerID#'
</cfquery>
<CFINCLUDE template = "functions.cfm">
<CFSCRIPT>
ThisVendorTxCode = form.VendorTxCode;
ThisAmount = form.Amount;
ThisCurrency = form.Currency;
ThisDescription = form.Description;
if (IsDefined('form.ShoppingBasket')) {
ThisShoppingBasket= form.ShoppingBasket;
} else {
ThisShoppingBasket="OFF";
}
ThisContactNumber = form.ContactNumber;
ThisContactFax = form.ContactFax;
ThisAllowGiftAid = form.AllowGiftAid;
ThisApplyAVSCV2 = form.ApplyAVSCV2;
ThisApply3DSecure = form.Apply3DSecure;
stuff = "VendorTxCode=" & ThisVendorTxCode & "&";
stuff = stuff & "Amount=" & ThisAmount & "&";
stuff = stuff & "Currency=" & ThisCurrency & "&";
stuff = stuff & "Description=" & ThisDescription & "&";
stuff = stuff & "SuccessURL=" & MyServer & "completed.cfm&";
stuff = stuff & "FailureURL=" & MyServer & "notcompleted.cfm&";
if (form.CustomerEmail NEQ "") {
stuff = stuff & "CustomerEmail=" & form.CustomerEmail & "&";
}
if (form.VendorEmail NEQ "") {
stuff = stuff & "VendorEmail=" & form.VendorEmail & "&";
}
if (form.CustomerName NEQ "") {
stuff = stuff & "CustomerName=" & form.CustomerName & "&";
}
if (form.DeliveryAddress NEQ "") {
stuff = stuff & "DeliveryAddress=" & form.DeliveryAddress & "&";
}
if (form.DeliveryPostCode NEQ "") {
stuff = stuff & "DeliveryPostCode=" & form.DeliveryPostCode & "&";
}
if (form.BillingAddress NEQ "") {
stuff = stuff & "BillingAddress=" & form.BillingAddress & "&";
}
if (form.BillingPostCode NEQ "") {
stuff = stuff & "BillingPostCode=" & form.BillingPostCode & "&";
}
if (ThisShoppingBasket eq "ON") {
stuff = stuff & "Basket=3:Sony SV-234 DVD Player:1:GBP170.20:GBP29.79:GBP199.99:GBP199.99:The Fast and The Furious Region 2 DVD:2:GBP17.01:GBP2.98:GBP19.99:GBP39.98:Delivery:1:GBP4.99:----:GBP4.99:GBP4.99&";
}
stuff = stuff & "Your goods will be dispatched within 7 days.
If you have any problems with your order please do not hesitate to contact us.
We look foreward to dealing with you in the future.";
stuff = stuff & "ContactNumber=" & ThisContactNumber & "&";
stuff = stuff & "ContactFax=" & ThisContactFax & "&";
stuff = stuff & "AllowGiftAid=" & ThisAllowGiftAid & "&";
stuff = stuff & "ApplyAVSCV2=" & ThisApplyAVSCV2 & "&";
stuff = stuff & "Apply3DSecure=" & ThisApply3DSecure;
crypt = base64Encode(SimpleXor(stuff,EncryptionPassword));
</CFSCRIPT>
<CFTRANSACTION action="begin">
<cfoutput>
<CFSET NewID = CreateUUID()>
<CFQUERY datasource="#Application.datasource#" Name="CreateOrderHeader">
INSERT INTO tblOrders
(CustomerIDFK, OrderID, OrderDate, OrderTime, TotalCost, Delivery, VendorTxCode, Status, StatusDetail, VPSTxID, TxAuthNo, Curr, ContactNumber, ContactFax, AllowGiftAid, ApplyAVSCV2, Apply3DSecure, CustomerEmail, CustomerName, DeliveryAddress, DeliveryPostCode, BillingAddress, BillingPostCode)
VALUES (
'#Session.CustomerID#',
'#NewID#',
'#DateFormat(Now(),"mmmm, dd, yyyy")#',
'#TimeFormat(Now(), "HH:mm:ss")#',
'#ThisAmount#',
<cfif IsDefined("Form.Delivery") AND #Form.Delivery# NEQ "">
'#FORM.Delivery#'
<cfelse>
NULL
</cfif>,
'#Session.VendorTXCode#',
'New',
'Sent to user for sumbission',
'null',
'null',
'#Form.Currency#',
<cfif IsDefined("Form.ContactNumber") AND #Form.ContactNumber# NEQ "">
'#Form.ContactNumber#'
<cfelse>
NULL
</cfif>
,
<cfif IsDefined("Form.ContactFax") AND #Form.ContactFax# NEQ "">
'#Form.ContactFax#'
<cfelse>
NULL
</cfif>
,
<cfif IsDefined("Form.AllowGiftAid") AND #Form.AllowGiftAid# NEQ "">
'#Form.AllowGiftAid#'
<cfelse>
NULL
</cfif>
,
<cfif IsDefined("Form.ApplyAVSCV2") AND #Form.ApplyAVSCV2# NEQ "">
'#Form.ApplyAVSCV2#'
<cfelse>
NULL
</cfif>
,
<cfif IsDefined("Form.Apply3DSecure") AND #Form.Apply3DSecure# NEQ "">
'#Form.Apply3DSecure#'
<cfelse>
NULL
</cfif>
,
'#Customer.Email#'
,
'#Customer.FirstName# #Customer.LastName#'
,
<cfif IsDefined("Form.DeliveryAddress") AND #Form.DeliveryAddress# NEQ "">
'#Form.DeliveryAddress#'
<cfelse>
'#Customer.Address1#, #Customer.Address2#, #Customer.City#'
</cfif>
,
<cfif IsDefined("Form.DeliveryPostCode") AND #Form.DeliveryPostCode# NEQ "">
'#Form.DeliveryPostCode#'
<cfelse>
'#Customer.PostCode#'
</cfif>
,
<cfif IsDefined("Form.BillingAddress") AND #Form.BillingAddress# NEQ "">
'#Form.BillingAddress#'
<cfelse>
NULL
</cfif>
,
<cfif IsDefined("Form.BillingPostCode") AND #Form.BillingPostCode# NEQ "">
'#Form.BillingPostCode#'
<cfelse>
NULL
</cfif>
)
</cfquery>
</cfoutput>
</cftransaction>
<CFSET OrderID = NewID>
<CFQUERY datasource="#Application.datasource#" Name="CreateOrderHeader">
INSERT INTO tblOrderDetails (OrderIDPK, ItemIDPK, Quantity, Colour, ItemSize, IDtandn, tandncost)
SELECT '#OrderID#', ItemIDPK, Quantity, Colour, ItemSize, ID, tandncost
FROM tblCartItems,tblItems
WHERE ItemIDPK = ItemID
AND CartIDPK='#Form.CartID#'
AND Colour = Colour
And ItemSize = ItemSize
</cfquery>
Ok now we have saved all the data now we just need to show some terms and conditions and send the details off to Protx.
<FORM ACTION="#vspSite#" METHOD="post" ID="form1" NAME="Test">
<INPUT TYPE="hidden" NAME="VPSProtocol" VALUE="2.22">
<INPUT TYPE="hidden" NAME="TxType" VALUE="DEFERRED">
<INPUT TYPE="hidden" NAME="Vendor" VALUE="#VendorName#">
<INPUT TYPE="hidden" NAME="Crypt" VALUE="#crypt#">
<TABLE ALIGN="right" WIDTH="100%" BORDER="0" CELLPADDING="4" CELLSPACING="0">
<tr>
<td colspan="2"><div align="center">
<textarea name="Terms And Conditions" readonly="readonly" cols="65" rows="10" id="Terms And Conditions">#Termsandcon.Body#</textarea>
</div></td>
</tr>
<tr>
<td colspan="2"><div align="center">By Clicking on 'Proceed' below you are agreeing to the Terms And Conditions. </div></td>
</tr>
<TR>
<TD WIDTH="50%"><table width="100" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="1" nowrap="nowrap" bgcolor="##BFBFBF"></td>
<td><a href="../checkout.cfm"><img src="../images/back.gif" border="0" /></a></td>
<td width="1" nowrap="nowrap" bgcolor="##BEBEBE"></td>
</tr>
</table></TD>
<TD WIDTH="50%"><table width="100" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="1" bgcolor="##BFBFBF"></td>
<td><input name="image" type="image" value="Submit the Order details" src="../images/proceed.gif" /></td>
<td width="1" bgcolor="##BEBEBE"></td>
</tr>
</table></TD>
</TR>
</TABLE>
</FORM>
</CFOUTPUT>
There we have it, the payment can now be sent to Protx.
completed.cfm
On this page we need to decrypt the information sent back to us from Protx and update the database to tell us the payment has been completed.
<CFSCRIPT>
Decoded=(SimpleXor(base64decode(crypt),EncryptionPassword));
VendorTxCode = getTokens(Decoded, "VendorTxCode");
Status = getTokens(Decoded, "Status");
VPSTxID = getTokens(Decoded, "VPSTxID");
TxAuthNo = getTokens(Decoded, "TxAuthNo");
AVSCV2 = getTokens(Decoded, "AVSCV2");
Amount = getTokens(Decoded, "Amount");
AddressResult = getTokens(Decoded, "AddressResult");
PostCodeResult = getTokens(Decoded, "PostCodeResult");
CV2Result = getTokens(Decoded, "CV2Result");
GiftAid = getTokens(Decoded, "GiftAid");
VBVSecureStatus = getTokens(Decoded, "3DSecureStatus");
CAVV = getTokens(Decoded,"CAVV");
</CFSCRIPT>
<CFQUERY
NAME="updateOrder"
DATASOURCE="#Application.datasource#">
UPDATE tblOrders
SET
Status='Authorised',
TxAuthNo='#TxAuthNo#',
VPSTxID='#VPSTxID#'
WHERE VendorTxCode= '#VendorTxCode#'
</CFQUERY>
<cfquery name="order" datasource="#Application.datasource#">
SELECT *
FROM tblOrders
WHERE VendorTxCode= '#VendorTxCode#'
</cfquery>
Now you can just display some details to the user such as the order number and contact details.
<TABLE BORDER="1" WIDTH="100%">
<TR>
<TD ALIGN="right" HEIGHT="18"><B><FONT SIZE="2">Order ID :</FONT></B></TD>
<TD ALIGN="left" HEIGHT="18">#order.OrderID#</TD>
</TR>
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">Vendor Tx ID:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#VendorTxCode#</TD>
</TR>
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">Amount:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#Amount#</TD>
</TR>
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">VPS Transaction ID:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#VPSTxID#</TD>
</TR>
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">Status:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#Status#</TD>
</TR>
</TABLE>
<BR>
<P>
<FONT COLOR="##006699">If you have any queries about your transaction, please email us on "<strong><a href="mailto:sales@cfproject.co.uk">sales@cfproject.co.uk</a></strong>" quoting reference "<strong>#order.OrderID#</strong>"</FONT></P>
</TD>
</TR>
</TABLE>
</CFOUTPUT>
On this page you could also send an email to the customer using my Coldfusion Mail Script
notcompleted.cfm
As with the completed page we will need to Decrypt the data sent back to us from Protx, and we will need to update the order with the status of why the order did not complete.
<CFSCRIPT>
Decoded=(SimpleXor(base64decode(crypt),EncryptionPassword));
VendorTxCode = getTokens(Decoded, "VendorTxCode");
Status = getTokens(Decoded, "Status");
StatusDetail = getTokens(Decoded, "StatusDetail");
VPSTxID = getTokens(Decoded, "VPSTxID");
AVSCV2 = getTokens(Decoded, "AVSCV2");
AddressResult = getTokens(Decoded, "AddressResult");
PostCodeResult = getTokens(Decoded, "PostCodeResult");
CV2Result = getTokens(Decoded, "CV2Result");
GiftAid = getTokens(Decoded, "GiftAid");
VBVSecureStatus = getTokens(Decoded, "3DSecureStatus");
CAVV = getTokens(Decoded,"CAVV");
</CFSCRIPT>
<cfquery name="updateOrder" datasource="#Application.datasource#">
UPDATE tblOrders
SET Status='#Status#',
StatusDetail='#StatusDetail#',
VPSTxID='#VPSTxID#'
WHERE VendorTxCode= '#VendorTxCode#'
</cfquery>
Again we should also show the customer some information about the transaction
<TABLE BORDER="1" WIDTH="100%">
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">Vendor Tx ID:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#VendorTxCode#</TD>
</TR>
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">VPS Transaction ID:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#VPSTxID#</TD>
</TR>
<TR>
<TD ALIGN="right" WIDTH="25%" HEIGHT="18"><B><FONT SIZE="2">Status:</FONT></B></TD>
<TD ALIGN="left" WIDTH="75%" HEIGHT="18">#Status#</TD>
</TR>
</TABLE>
<BR>
<P> <FONT COLOR="#006699">If you have any queries about your transaction, please email us on "<strong><a href="mailto:sales@cfproject.co.uk">sales@cfproject.co.uk</a></strong>" quoting reference "<strong>#VendorTxCode#</strong>"</FONT></P> </CFOUTPUT>
And that is the script. There is a lot of room for improvement and extra functionality to be added.
Enjoy

