Author | Topic: Passing web page control | |
---|---|---|
Allen Lee | Passing web page control on Mon, 18 Dec 2006 12:07:51 -0800 Hi everyone; THE SITUATION: In Canada, our WAA app uses an real-time national credit card processor to provide authorization for our web transactions. Our DLL web page vaildates the data and sends to the third party credit card processor's site: oHtml:put('<form action="https://www3.creditcard.com/HPPDP/index.php" method=post>') oHtml:put('<input type="hidden" name="rvar1" value="'+cVAR1+'">') oHtml:put('<input type="hidden" name="rvar2" value="'+cVAR2+'">') oHtml:put('<input type="hidden" name="rvar3" value="'+cVAR3+'">') ... oHtml:put('<p><input type="submit" name="submit" value="Process the transaction">') oHtml:put('</form>') The credit card company sends a get string back to our standalone HTML page which includes their additional authorized/declined data. They require the standalone page. This page parses the string, creates the variable names/data and redirects to a page back into our DLL. THE PROBLEM: Sometimes their returned get string is not processed by our app. We think they don't send the string back. THE QUESTION: How can we create a real-time check to ensure that each tranaction sent is returned? | |
Phil Ide | Re: Passing web page control on Mon, 18 Dec 2006 22:18:24 +0000 Allen, > THE PROBLEM: > > Sometimes their returned get string is not processed by our app. > We think they don't send the string back. > > THE QUESTION: > > How can we create a real-time check to ensure that each tranaction sent is > returned? Well, that depends on exactly you mean by the question 1. If you want to find out whether they actualy performed a GET/POST on your page, you can always check your server logs. 2. If you want to find out whether they passed any data back, then put some error checking in the code. This is a static HTML page on your webserver correct? In that case, you could write the page in PHP, which will allow you to have the web page generate a log of it's own recording all transactions it processes, plus any data it receives. 3. If you are using Apache (you can probably do this with other servers) then you can put a rewrite rule that puts in a redirector and permanently moved flag, which then redirects to your WAA DLL. This might not work, because many scripts won't follow redirectors or follow alternate URL's. I had a similar problem here in the UK - eventually we got the return URL sorted to be a perl CGI script which a) created a log and b) posted the data into PostgreSQL. Regards, Phil Ide --------------------- www.xbhcl.com www.pbih.eu www.idep.org.uk/xbase --------------------- He does the work of three men: Larry, Moe and Curly. | |
Allen Lee | Re: Passing web page control on Tue, 19 Dec 2006 11:36:31 -0800 Hi Phil; You provided some good suggestions. Your #1. Since there will be a number GET/POSTs in the server log within the same time frame, wouldn't it be difficult to identify a specific transaction since there are no unique identifiers stored in the Apache log? Your #2. Where would the error checking go to find out if they passed any data back? Not on the static HTML page because it would not get called if no data was sent back and not on DLL page that send the data because it has terminated. It is a static HTML page on your webserver that receives the data back from the credit card processor. The redirected DLL page from the static HTML page already records all transactions it processes, plus any data it receives. I have written a user-activated sent/received data matching utility that will find unreturned transaction requests but the client wants to know at the time that a return string has not been received back so that the staff users of the application can re-submit the transaction request.. Your #3. Would the Apache rewrite rule (that puts in a redirector and permanently moved flag, which then redirects to the WAA DLL) suggestion work if no data was sent back from the credit card processor? The only solution I can think of is: a) write a small transaction ID named text file into a queue directory. b) delete the file when the return data is received. c) write a java program to run in the background that wakes up every 45 seconds to send an email if it finds orphaned files in the queue directory. Do you think that would work? | |
Phil Ide | Re: Passing web page control on Wed, 20 Dec 2006 03:07:08 +0000 Allen, > The only solution I can think of is: > a) write a small transaction ID named text file into a queue directory. > b) delete the file when the return data is received. > c) write a java program to run in the background that wakes up every 45 > seconds to send an email if it finds orphaned files in the queue directory. > > Do you think that would work? Possibly, but I wouldn't like to do it that way. What I don't understand, is when the cc processor calls your static web page, the web page seems to do two things: 1. receive data 2. record that data A static web page can't do either, unless it is running some script, which would then run on the client machine not the server. Theer are only two exceptions to this I can think of: a) The page is an SHTML page which calls a server script passing in the url used to invoke it, and the script then logs the transaction using the GET data appended to the url. b) The page is a pre-processed page, for example .php Can you enlighten me on how the mechanism works? Without understanding what is currently (supposed) to be happening, I'd only be guessing at a solution. Regards, Phil Ide --------------------- www.xbhcl.com www.pbih.eu www.idep.org.uk/xbase --------------------- I used to have a life, then I got a modem. | |
Allen Lee | Re: Passing web page control on Wed, 20 Dec 2006 11:43:23 -0800 Hi Phil; I have stripped out the non-essentials of the static HTML page that is called by the cc processor so you can see that it accepts the data and redirects the paired values to the WAA DLL. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Language" content="en-us"> <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <title>Credit Card Authorization</title> <script type="text/javascript"> /* Webmonkey GET Parsing Module Language: JavaScript 1.0 The parsing of GET queries is fundamental to the basic functionality of HTTP/1.0. This module parses GET with JavaScript 1.0. Source: Webmonkey Code Library (http://www.hotwired.com/webmonkey/javascript/code_library/) Author: Patrick Corcoran Email: patrick@taylor.org */ function createRequestObject() { FORM_DATA = new Object(); The Object ("Array") where our data will be stored. separator = ','; The token used to separate data from multi-select inputs query = '' + this.location; qu = query Get the current URL so we can parse out the data. Adding a null-string '' forces an implicit type cast from property to string, for NS2 compatibility. query = query.substring((query.indexOf('?')) + 1); Keep everything after the question mark '?'. if (query.length < 1) { return false; } Perhaps we got some bad data? keypairs = new Object(); numKP = 1; Local vars used to store and keep track of name/value pairs as we parse them back into a usable form. while (query.indexOf('&') > -1) { keypairs[numKP] = query.substring(0,query.indexOf('&')); query = query.substring((query.indexOf('&')) + 1); numKP++; Split the query string at each '&', storing the left-hand side of the split in a new keypairs[] holder, and chopping the query so that it gets the value of the right-hand string. } keypairs[numKP] = query; Store what's left in the query string as the final keypairs[] data.< for (i in keypairs) { keyName = keypairs[i].substring(0,keypairs[i].indexOf('=')); Left of '=' is name. keyValue = keypairs[i].substring((keypairs[i].indexOf('=')) + 1); Right of '=' is value. while (keyValue.indexOf('+') > -1) { keyValue = keyValue.substring(0,keyValue.indexOf('+')) + ' ' + keyValue.substring(keyValue.indexOf('+') + 1); Replace each '+' in data string with a space. } keyValue = unescape(keyValue); Unescape non-alphanumerics if (FORM_DATA[keyName]) { FORM_DATA[keyName] = FORM_DATA[keyName] + separator + keyValue; Object already exists, it is probably a multi-select input, and we need to generate a separator-delimited string by appending to what we already have stored. } else { FORM_DATA[keyName] = keyValue; Normal case: name gets value. } } return FORM_DATA; } FORM_DATA = createRequestObject(); This is the array/object containing the GET data. Retrieve information with 'FORM_DATA [ key ] = value'. </script> </head> <body onLoad="createRequestObject();"> <script type="text/javascript"> var rvar1=FORM_DATA['rvar1']; var rvar2=FORM_DATA['rvar2']; var rvar3=FORM_DATA['rvar3']; var cHEA,cBGC,cURL; if (rvar1=='1') {cHEA='approved',cBGC='7FFFD4';} else {cHEA='declined',cBGC='FFB6C1';} document.write('<table bgcolor="#C6D7DE" width="75%" cellpadding=6 border=1>'); document.write('<tr><td bgcolor="#'+cBGC+'" align="center" style="font-size:26px">Processing ...'); document.write('</table>'); cURL = "/cgi-bin/waa1gate.exe?WAA_PACKAGE=iReg6&WAA_FORM=RegNew&cVAR1="+rvar1+"&cVA R2="+rvar2+"&cVAR3="+rvar3; window.location = cURL; </script> </body> </html> What don't you like about the background java program? | |
Phil Ide | Re: Passing web page control on Wed, 20 Dec 2006 22:49:47 +0000 Allen, > What don't you like about the background java program? The Javascript is fine. I am just surprised that their automated system fetches the page and then runs the Javascript. In fact, it's a very weird way to do it - I would have expected them to call a CGI app and even supplied a sample one written in perl or something. Ok, so the problem you now have is how to record the data returned to the page. One way to do it is to call another dll function passing in the raw value of 'query'. A simple way to do that is using the XMLHTTPRequest object. This can send a synchronous request to your dll, which can then record the raw data, then the page will continue and call the usual function using the redirect it is using now. Does that sound ok to you? I can give you some help using the XMLHTTPRequest object - it's the same object used in Ajax and JSon calls. Regards, Phil Ide --------------------- www.xbhcl.com www.pbih.eu www.idep.org.uk/xbase --------------------- Taglines cause cancer. | |
Allen Lee | Passing web page control on Wed, 20 Dec 2006 21:41:20 -0800 Hi Phil; I don't quite understand. The problem is not how to record the data returned to the page. This line creates the paired values: cURL ="/cgi-bin/waa1gate.exe?WAA_PACKAGE=iReg6 &WAA_FORM=RegNew&cVAR1="+rvar1+"&cVAR2="+rvar2+"&cVAR3="+rvar3; And this line sends it back into the app for further processing: window.location = cURL; That works. The problem is how to handle transactions that are NOT returned to the page. That is why I suggested a java program to run in the background outside of the app. | |
Bruce Anderson | Re: Passing web page control on Tue, 19 Dec 2006 08:20:37 -0600 Perhaps you can use Phil's LoadFromURL( ) function to send this POST to your processor. The processor will return the Accepted/Declined response, a string which is LoadFromURL's return value in your DLL. Parse it and create the resultant page for your user. LoadFromURL, the magical function with a thousand and one uses. Thank you, Phil! | |
Allen Lee | Re: Passing web page control on Tue, 19 Dec 2006 11:40:22 -0800 Thanks Bruce; What happens if the credit card processor drops the transaction and doesn't send a return string back? Then there won't be anything to re-direct ... right? Have I misunderstood your point? | |
Bruce Anderson | Re: Passing web page control on Wed, 20 Dec 2006 16:02:31 -0600 Correct, you can wait a suitable length of time and then deal with the NIL. However, just because you received nothing from your processor does not mean that your customer has not been charged. You had better verify if your POST got through and was acted upon. But, if this is a frequent problem with your current service provider, then you need to change something. Failure to close the loop every time is a deal breaker. Card processor, your ISP, your equipment, whatever is dying at the awkward moment must go. | |
Allen Lee | Passing web page control on Wed, 20 Dec 2006 21:45:17 -0800 Hi Bruce; You have understood the problem. In this scenerio, how do you wait a suitable length of time and then deal with the NIL? Any suggestion? |