Posting Payments

In this part of the application, the user's payment information will be packaged and forwarded to the credit card processor for payment. The user will enter the information into the system. A feature that could be added would be for the credit card information to be instantly validated. There are a number of 3rd party tools and code examples that show how to perform card validation. This is not shown in the case study, but the source code indicates where this type of feature could be easily added. The validation action is different from the processing action. In validation, a third party is merely verifying that this is a valid credit card for this particular customer. The validation could either check against a list of stolen cards, or do an online check against the account, to see if there is sufficient credit available. The customer's credit card account is actually charged for the amount of the order during the processing of a payment.

We will be looking at the method to transmitting this information to the credit card processor. In reality, there are many systems in place on the Internet that will handle credit card processing for on-line transactions. In this example, we will create our own system for processing payments. In the first part, we will create the system that will transmit the payment information to the credit card processor. This will be done using a message queuing system. The information will be packaged into a message and sent a queue. In the second part, we will create a method for the credit processor to retrieve the message from the queue, examine its contents, and then proceed using their own internal methods for payment.

This may not be a realistic system in the way that actual on-line transactions are handled. But, it is a good example of how message queuing can be used to reliably transmit information between two applications, even when the applications are not running simultaneously. Whenever money is changing hands, a reliable system is absolutely critical to the business. In this case, our two applications are the book purchasing application, and the credit payment verification application.

We will be showing two methods for integrating Active Server Pages with Microsoft Message Queues Server. The first part of the application will show an ASP script interacting with a server component written in Visual Basic. This server component will interact with MSMQ using the ActiveX interface that we covered earlier in this chapter. The second part of the application will use the MSMQ ActiveX API directly from an ASP script.

Post Payment Component

This active server component will be used to post the order payment information to the credit card processor. The payment information will be transmitted in a MSMQ message. This message will contain the following information:

This message will be sent to a queue on an MSMQ server. The message will also contain a request for response, and include the queue that the response should be sent to. This method will be called from an Active Server Page script that will supply the method with the information that it needs from the current session-level variables.

Public Function PostPayment(vOrderID As Variant, vCardNumber As Variant, vCardName As Variant, vCardAmount As Variant, vCardExpireDate As Variant) As Variant

The parameters that will compose the message are passed as variants. This makes the use of this method more flexible. If, for example, the CardExpireDate had been declared as a date type, then we would need to ensure that the value passed from the ASP script was a valid Visual Basic date. Since the information is not being processed by this method, rather it is just being packaged and sent on, the validation of the data in the method itself is not critical.

On Error GoTo PostPaymentErr
  
Dim strBody
  strBody = "OrderID=" & vOrderID & "&"
  strBody = strBody & "CardNumber=" & vCardNumber & "&"
  strBody = strBody & "CardName=" & vCardName & "&"
  strBody = strBody & "CardAmount=" & vCardAmount & "&"
  strBody = strBody & "CardExpireDate=" & vCardExpireDate

We will be using an encoded string to package the information that will be passed in the message. The format of the string will be similar to the way that parameters are passed in an HTTP GET method, with name/value pairs separated by the ampersand (&) character. Since the body of a message can contain only one binary object, this encoding method will package up distinct pieces of information for later retrieval. You will see in the next section how easy this makes it to retrieve the information.

Next, we need to define some variables that we will use to locate and manipulate the message queues that this method will send the message to. The first step is to locate the queue to send the message queue. We will use the LookupQueue method to attempt to locate a queue with a specific label. This label identifies the queue as one that will accept pending credit processing messages.

The LookupQueue method returns a collection of queues that match the search criteria. Since this list of queues maintains its own internal pointer, we need to reset the pointer to the beginning of the list. Then, we can ask the list to give us its first element.

Dim query As New MSMQQuery, respQuery As New MSMQQuery
  Dim qinfos As MSMQQueueInfos, qRespInfos As MSMQQueueInfos
  Dim qinfo As MSMQQueueInfo
  Dim q As MSMQQueue
  Dim msg As New MSMQMessage
  

'Find the queue to send the credit request to and open it
  Set qinfos = query.LookupQueue(Label:="Credit Processing Pending")
  qinfos.Reset
  Set qinfo = qinfos.Next

If the object that this element refers to is undefined, we know that the search was unsuccessful. This could mean that this was the first time the application was run. It could also mean that the destination queue was inadvertently deleted. To give our message a destination, we will create a queue to send the message to.

If qinfo Is Nothing Then
      Set qinfo = New MSMQQueueInfo
    qinfo.PathName = "BOFFIN\CreditProcessingPending"
    qinfo.Label = "Credit Processing Pending"
    qinfo.Create False, True
  End If
  

The queue will be created on a machine named BOFFIN. This machine should have MSMQ running on it, and should be accessible from our web server.

In your installation, you will need to change the name of the server to match the name of the MSMQ server that you wish to create the queue on.

The Label of the new queue will be set to "Credit Processing Pending". This is the same value that we searched for earlier and were unable to find. Creating the queue using this label will allow it to be found in the future.

The next step is open the queue. We will be setting the parameters to allow send access to the queue. We set the share flag to DENY_NONE, which means that other application will be able to write messages to this queue and retrieve messages from it. This is the only valid option when opening a queue for sending.

Set q = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  Dim qResponse As MSMQQueueInfo
'Create a queue to send the response to
  Dim strLabel
  strLabel = CStr(vOrderID)
  Set qResponse = New MSMQQueueInfo
  qResponse.PathName = "BOFFIN\CreditResult" & strLabel
  qResponse.Label = "CreditResult" & strLabel
  qResponse.Create False, True

Next, we need to create a response queue. The message that we are sending to the credit processor will contain a pointer to a response queue. It is the responsibility of the receiving application to recognize this in the message, and send a response to this queue. This is different from an acknowledgment. In an acknowledgment, MSMQ is responsible for sending the message automatically, depending on what conditions are met. A response message needs to be explicitly sent by the receiving application. The format of this response message is mutually determined by the two applications.

The response queue will be created with the value of the OrderID appended to it. Since this OrderID is a unique value, this means that every order will have its own response queue. It will be created and will wait to accept the response message from the credit processor. While we will not show it here, when the message is retrieved from the queue, the queue should be deleted to free up resources in the MSMQ server.

  msg.Label = "Credit Processing - Order Num:" & strLabel
  
  msg.Body = strBody
  
  Set msg.ResponseQueueInfo = qResponse
  
  msg.Send q

Finally, we will create the message and then send it. The message is given a label that both describes what the message is, "Credit Processing", it also identifies the order. Even though the orderID is stored in the body of the message, by including it in the label it allows administrators to see which orders are pending by using the MSMQ management tools. The body of the message is set to the encoded string that contains all of the order information. To indicate that the receiver should respond to the message, and to show where to respond to, the ResponseQueueInfo property is set to the response queue that we created earlier. Finally, the message is sent to the queue that was located and then opened. Notice that we do not need to open the response queue, as we are merely passing a reference to it. It will be the responsibility of the credit processing application to open this queue and send the response to it.

  Dim vResponse As New Collection
  vResponse.Add False, Key:="error"
 
  oObjectContext.SetComplete
  Set PostPayment = vResponse

  Exit Function
PostPaymentErr:
  oObjectContext.SetAbort
  Set PostPayment = RaiseError("PostPayment")
End Function

This method has basically the same ending code as all of the other application and data components that we have created in the case study. For this method to participate in transactions, we allow it to add its vote to the success or failure of the transaction it is participating in.

Next, we will take a look at the ASP script code that will call this method to generate the message to the credit processor.

Building the Active Server Pages

In this script file, we will take an order that has been validated by the user, along with the payment information supplied by the user, and transmit that information to the credit processor. At this point, the user has already entered their credit card number and expiration date. While we did not show this, it is a relatively straightforward HTML FORM and ASP script to put the values into session-level variables.

This script file will take the information stored in the session-level variables and call the PostPayment method that was defined above. Based on the response from the PostPayment method, this script file will either display an error message for the user, or will indicate successful transmission of the payment information.

<%@ LANGUAGE="VBSCRIPT" %>
<% Option Explicit %>
<% Response.Expires = 0 %>
<% if not Session("Auth") = true then %>
<%  Response.Redirect "checkreg.asp"%>
<% End If %>
<% if Session("CardValidated") <> true then %>
<%  Response.Redirect "GetCreditInfo.asp" %>
<% End If %>

Before this script begins its application processing, it needs to ensure two things about the user accessing this page. First, the user has to be properly logged into the application. If they are not, then the client is redirected to the login page. Second, the user must have submitted valid credit card information. This is indicated by a session-level variable that is called CardValidated. If this variable is not set to true, then we know that the user has not submitted valid credit card information. The script will then redirect the browser to the page where the credit card information can be submitted.

<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;Processing Payment
</th>
</tr>
</table>

The next part of the script file is the standard header information that appears in all of the script files in this application. We will also need some local variables to interact with the application object. A message is presented to the user that the data is being transmitted to the credit card processor. Since we have not set the Buffer property of the Response object to true, the client will output this text before the application object is called. This will give the user some indication that the server is processing the request.

<%    dim objOrder %>
<%    dim objResponse %>
   <p>Transmitting data to Credit Card Processor…
   
<%    set objOrder = Server.CreateObject("BpkgOrderProcessing.Payment") %>
<%      dim strCardName %>
<%      strCardName = Session("firstname") & " " & Session("surname") %>
<%    set objResponse = objOrder.PostPayment(Session("OrderID"), Session("cardnumber"), strCardName, Session("totalprice"), Session("expirydate")) %>

The five parameters that the PostPayment method requires are extracted from the current session. Concatenating the first name and the surname creates the credit card holder's name. Since all of the parameters that the PostPayment method expects are variants, we do not need to worry about explicitly setting the datatypes of the parameters.

<%    if objResponse("error") then %>
<!--#include file=error.inc-->
<%    else %>
<p>Information Sent Successfully...
<p>Your order has been completed. Thanks for shopping at WROX.
<% End If %>
</body>
</html>

All of the work of the payment transmission is done in the application object. All that the client needs to do is show the user the results. If the method was not able to complete successfully, the standard error handling code will be used to output an error message to the client. If there were no errors, then the client will indicate a successful completion of the order.

The browser would display this page as:

Since there are more steps to actually fulfilling an order than we have shown in this case study, there would probably be more information displayed to the user at this point. Some of these additional pieces of information could be:

We'll leave the creation of these other pieces of information up to you. This case study has shown you the basics of how to perform electronic commerce. You should be able to build on these pieces to create the rest of the application.

One of the pieces that we will create is the application used by the credit card processor to check for the pending credit card orders that need to be processed. This is the example that will be covered in the next section.

© 1998 by Wrox Press. All rights reserved.