The credit payment application will be used by the credit card processor to obtain the information about the credit card payment and pass a response back to the customer that the payment has been processed. As we have stated before, this is probably not an exact representation of how a credit card processor operates in real life. What it does show is an example of how information can be read from message queues and messages can be sent just using Active Server Pages.
The credit payment processing application will consist of two Active Server Pages scripts. The first one will retrieve a message from the queue, display the information contained in the message, and then allow the user to either accept or reject the charge. The second script will process the acceptance or rejection of the charge by sending a response message to the customer. It will then inform the user if there are additional payments pending, in which case it will give them an option to retrieve them.
The first Active Server Page will locate the message queue. If it is found, it will see if there are any messages there. If there is a message, it will retrieve the first one. The information contained in the message will be displayed for the user and the user will be given the options to approve or deny this payment.
Let's start with the standard header stuff that is at the top of each of our ASP script files.
<%@ LANGUAGE="VBSCRIPT" %>
<% Option Explicit %>
<% Response.Expires = 0 %>
<html>
<head>
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
<title></title>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<table width=100% cellspacing=0 cellpadding=0 border=0>
<tr class="pageheader">
<th align=left> Verify Credit Payment
</th>
</tr>
</table>
<%
Dim objquery
Dim objqinfos
Dim objqinfo
Dim objq
Dim objMsg
set objquery = Server.CreateObject("MSMQ.MSMQQuery")
The first step we need to take is to create an instance of the MSMQQuery
object. This object will be used to look for a queue that matches a set of criteria. The LookupQueue
method of this object will look for all queues that have a label set to "Credit Processing Pending." The LookupQueue
method consists of all optional parameters. Since there is no way in VBScript to use named parameters as we did in Visual Basic, we must place the parameter that we are supplying at the correct position in the parameter list. The Label
parameter is the third parameter; therefore we have to preface it with two commas, to indicate the optional parameters.
If a queue with this label cannot be found, then we know that there are no messages pending. We will then output a message to the user indicating that there is nothing to process.
Set objqinfos = objquery.LookupQueue (,,"Credit Processing Pending")
objqinfos.Reset
Set objqinfo = objqinfos.Next
If objqinfo Is Nothing Then
%>
<P>No pending payments could be located</P>
<%
else
If a valid queue matching the criteria can be found, then we will open that queue. Since we will be reading messages out of it, we will open it with RECEIVE
access, by setting the first parameter of the Open
method to 1. To allow other applications to deposit messages into the queue, we will set the share flag to DENY_NONE
, which is indicated by a 0 for the second parameter. This will also allow multiple users of the credit processing application to retrieve messages at the same time. Since the LookupQueue
method only checks for the existence of a queue, we do not know if there are actually any messages in the queue. The Receive
method also consists of optional parameters. We will be supplying the timeout value, which is the fourth parameter. This makes it necessary for us to precede the parameter with 3 commas, to indicate the three leading optional parameters.
Set objq = objqinfo.Open(1, 0)
Set objMsg = objq.Receive(,,,10)
objq.Close
if objMsg is Nothing then
If the Receive
method times out, or is unable to retrieve a message from the queue, then the objMsg
variable will not have a value. If this is the case, then we will need to output a message to the user that no messages could be found. If we do find a valid message, then we will need to read the encoded string that was used to send the order information to the message queue. The encoded string will look like this:
OrderID=884537142&CardNumber=4444333322221111&CardName=Nigel Reader&CardAmount=$379.07&CardExpireDate=09/99
We will be using a simple parsing routine that will look for each name/value pair. Once the routine has located the next name/value pair, it will break it into separate variables for name and value. A Scripting.Dictionary
object will be used to store the names and values. The key will be set to the parameter name, and the item value will be set to the value of the parameter.
%>
<P>No pending payments could be located</P>
<%
else
dim strBody
dim objqResponse
strBody = objMsg.Body
Dim dBody
Set dBody = CreateObject("Scripting.Dictionary")
dim iAmpersand, iPos, strItem, iEquals
dim strVar, strVal
iAmpersand = -1
iPos = 1
do while not iAmpersand = 0
dim iEnd
iAmpersand = InStr (iPos, strBody, "&")
if iAmpersand = 0 then
iEnd = len(strBody)
else
iEnd = iAmpersand - 1
end if
strItem = Mid(strBody, iPos, iEnd-iPos+1)
iEquals = Instr(strItem, "=")
strVar = Left(strItem, iEquals-1)
strVal = Mid(strItem, iEquals+1, len(strItem))
dBody.Add strVar, strVal
iPos = iAmpersand + 1
loop
The Dictionary
object that contains the Body
of the message and the pointer to the Response queue will be saved into local and session-level variables. The pointer to the incoming message queue is also saved. This will be used in the other script of this application. We could have used the same method in that script to locate the queue, but since we have the reference, we might as well save it. The information that was contained in the body of the message is then displayed for the user.
set objqResponse = objMsg.ResponseQueueInfo
set Session("objResponseQ") = objqResponse
set Session("dMsgBody") = dBody
dim keys, items, i
keys = dBody.Keys
items = dBody.Items
for i = 0 to dBody.count - 1
Response.Write "<P>" & keys(i) & ": " & items(i) & "</P>" & vbcrlf
next
%>
Finally, we present the user with two choices. They can choose to approve the payment of this order, or they can choose to decline the payment. They make their selection by choosing from one of the two links that are displayed. These two links will launch the second ASP script. The parameter named approve
is used to indicate to this second script if the payment has been approved or not.
<HR>
<P><A HREF="CreditResponse.asp?approve=true">Approve this transaction</a>
<P><A HREF="CreditResponse.asp?approve=false">Deny this transaction</a>
<% end if
end if
%>
</body>
</html>
When this server page is viewed in a browser, it will look like:
The second part of this application will be to process the approval or denial of this payment. This script file will be responsible for creating the response message and sending it to the response queue. After sending the message, the script will then check to see if there are any more messages in the queue. If there are, it will ask the user if they wish to process the remaining messages.
<%@ LANGUAGE="VBSCRIPT" %>
<% Option Explicit %>
<% Response.Expires = 0 %>
<html>
<head>
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
<title></title>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<table width=100% cellspacing=0 cellpadding=0 border=0>
<tr class="pageheader">
<th align=left> Verify Credit Payment
</th>
</tr>
</table>
<%
Dim objquery
Dim objqinfos
Dim objqinfo
Dim objq
Dim objMsg
set objMsg = Server.CreateObject("MSMQ.MSMQMessage")
set objqinfo = Session("objResponseQ")
Set objq = objqinfo.Open(2, 0)
Since we will be generating a new message to send, we will need to create an instance of a MSMQMessage
object. This message object can then be sent to the response queue that was determined by the incoming message. The reference to the response queue is stored in a session-level variable, and we will store it in a local variable for use in the script. This queue will be opened with SEND
permissions, which is indicated by the value of 2 for the first parameter of the Open
method.
The next step is to create the contents of the message that will be sent as the response. All that this message needs to do is indicate to the client whether or not the payment was approved or denied. Since the response queue was created solely to receive this one message, we do not need to pass a great deal of data in it.
dim strLabel
if Request.QueryString("approve") = "true" then
objMsg.Body = "APPROVED"
strLabel = "Credit Card Approved for Order #"
else
objMsg.Body = "DENIED"
strLabel = "Credit Card Denied for Order #"
end if
strLabel = strLabel & Session("dMsgBody").Item("OrderID")
objMsg.Label = strLabel
If the payment has been approved, then we will send "APPROVED
" in the body of the message. The label for the message will state that the payment for the specified order number was approved.
If the payment is denied, then the body of the response message will contain "DENIED
." The label for the denial message will state that the payment was denied, and again state the order number.
This message is then sent to the response queue. After the message is sent, the user is notified that the response message has been processed. The next step is to determine if there are any messages remaining in the incoming queue. We stored the reference to this queue in the previous script. We can use this reference to open the incoming queue. This time, we will be opening for peek access. Peek access allows us to look at the messages in the queue, but not retrieve them. If we peek at the queue and find a message, then we will ask the user if they wish to process this next payment.
objMsg.Send objq
%>
<P>Response Processed.....
<%
Set objqinfo = Session("objIncomingQ")
Set objq = objqinfo.Open(32, 0)
Set objMsg = objq.Peek(100)
objq.Close
if not objMsg is Nothing then
%>
<P>No further payments to process</P>
<%
else
%>
<P><A HREF="CreditAuthorization.asp">Click here to process the next payment</A>
<% End If %>
</body>
</html>
When this page is displayed in the browser, it will look like this:
We now have an application that can be used to retrieve messages from a queue, processes the body of the message, and then respond to that message with another message. While this was a simple example, this is pretty much all there is to using message queuing systems. The information can be much more complex, and the routing of messages much more involved, but the simple elements of messages and queues stay the same.