Credit Payment

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.

Building the Active Server Pages

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>&nbsp;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>&nbsp;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.

© 1998 by Wrox Press. All rights reserved.