views:

382

answers:

5

I don't know whether this is possible, I can't seem to find any other help guides so this may not be possible...

I have a checkout page which POSTs a load of variables forwards to a 3rd party payment processor (WorldPay).

I want to know if it is possible to put a PHP script of some sort inbetween the two pages for validation purposes.

EG if an item in the basket has sold out while they were filling out the form, it could catch the customer before money is taken. Or useful if they tamper with form data.

If I do this on my own site I could use sessions to pass the POST data forward but as it's an external website, I don't know how to send the data without making another HTML page with a hidden form & refresh for instance.

Is it possible to do this 'invisibly' - not actually showing a HTML page inbetween?

A: 

I would suggest you to go like this:

Before directing a user to the form, you check (through sql quries) whether the item in the basket has sold out. If it has been sold, redirect the user to some other page saying that this item has been sold out otherwise let him go to the form for new purchase.

Sarfraz
Hi Sarfaz, sometimes an item can sell out while the customer is filling out the form, especially if it is a limited edition item that a lot of people are trying to purchase at the same time.I am interested in finding out if I can make an 'invisible' redirect and POST script.
Ashley
You will never solve this problem no matter how short the timeframe will get if you do not lock the items in the moment the visitor enters the checkout form. But then there are questions when items should be unlocked (eg when the user simply closes the window and does never complete checkout).
hurikhan77
A: 

Yes, you can. What you are looking for is the CURL function:

http://php.net/manual/en/book.curl.php

Also see:

http://php.dzone.com/news/execute-http-post-using-php-cu

tambler
+2  A: 

EDIT:

Ashley said:

Okay, i've taken a look at the cURL manual and written this very simple script to forward the POST values to the 3rd party checkout. This just displays the contents of the checkout page though. The URL address shows the script currently running rather than forwarding to the 3rd party site. Also all their relatively linked graphics will not work. Can 'true' forwarding be achieved using cURL?

The short answer - no.

With the way you described your payment process if you want to step in the middle of the offsite process to do things (customize html/messages, validate data, etc.) then you need to handle the entire process which cURL would allow you to do.

With cURL, you dont "forward" the request - you sort of "proxy" the request. So the fact that the browser URL never changes and that the relative graphics dont work is expected. With the use of cURL or something similar you would never let the user end user know that they are even touching an external page. you would be handling all the requests to that external server on your server and then simply displaying the response from the external server to your user OR parsing that response so that you can use the data from it in a customized way.

Essentially this means if secure.wp3.rbsworldpay.com/wcc/purchase is returning a form that requires futher interaction from the user you have to mimic this form on your server and display that instead. Then when the user submits your form you use cURL again to make a request to the external server - this time to post the next round of data submitted by the user. So for example lets say:

  • secure.wp3.rbsworldpay.com/wcc/purchase shows the cart
  • secure.wp3.rbsworldpay.com/wcc/confirm shows a final confirmation of the payment to be made
  • secure.wp3.rbsworldpay.com/wcc/success and secure.wp3.rbsworldpay.com/wcc/error show whether the transaction succeeded or failed respectively.

Then you are actuall going to need to make 2 requests externally as part of you transaction process which could be summarized like so:

  1. User shops at your site and adds items to cart
  2. User clicks on checkout and you validate the cart/user data
  3. If the data from #2 was valid you package up the data and post to secure.wp3.rbsworldpay.com/wcc/purchase via cURL
  4. If the cURL response from #3 was successful you build your own confirm page using data from the cURL response and display it to the user.
  5. The user submits the confirmation of the purchase to your server.
  6. You package up the data submitted to your server in #5 and post it to secure.wp3.rbsworldpay.com/wcc/confirm via cURL.
  7. If the cURL response from #6 was successful then you parse it for the expected "error" or "success" message returned from external server and display them or your own custom error messages.
  8. Rinse and repeat in case of error ;-)

Generally speaking most payment processors have an option of processing that supports this basic process often returning easy to parse data as XML, JSON, or Plain Text instead of HTML. You might want to look in to this. A lot of times they will often have libraries built for various programming languages to help ease the integration process.


Yep it sure is... i normally use the curl extension to do stuff like this, or an http client class that utilizes curl. You might want to make it a tad easier on yourself and use one of these class libraries - for example Zend_Http_Client. It supports not only curl but also sockets and proxies.

prodigitalson
Okay, i've taken a look at the cURL manual and written this very simple script to forward the POST values to the 3rd party checkout.This just displays the contents of the checkout page though. The URL address shows the script currently running rather than forwarding to the 3rd party site. Also all their relatively linked graphics will not work.Can 'true' forwarding be achieved using cURL?
Ashley
Here is the script:$query = "";foreach($_REQUEST as $k => $v) { $query=$query.$k."=".$v."}$query=substr($query, 0, -5);$url = "https://secure.wp3.rbsworldpay.com/wcc/purchase";$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);curl_setopt($ch, CURLOPT_POST, 1); // set POST methodcurl_setopt($ch, CURLOPT_POSTFIELDS, $query); // add POST fields $result = curl_exec($ch); curl_close($ch); echo $result;
Ashley
See my edit above. Also, if you have code that needs block formatting you should amend your question so its easier to decipher :-)
prodigitalson
Hi, thanks for the detailed answer, but it's not really the question I was asking. Although the short answer 'no' was exactly right! :)It's interesting to learn about cURL for in future, but I think that the ajax solution is pretty much what I was after.Sorry I couldn't figure out how to indent the code.
Ashley
A: 

I rather like the HTTP_Request2 package from PEAR, which basically wraps cURL and/or sockets in some simple objects. POSTing works great. You can use that to bounce the POST request to your validation-checker, then on to the payment processor.

Brian
+2  A: 

Yes you can do that by hooking into the onsubmit hook of the form and sending out an Ajax call like this (using jQuery):


$('#myform')[0].onsubmit = function() {
  if (form_check_elements(this.elements)) { /* ««« eg JS validator here */
    data = $('#myform').serialize();
    $.post('/ajax_validator.php', data, function(data, textStatus) {
      $('#myform')[0].submit();  /* ««« check the textStatus before here and
                                        eventually do not submit (wrap it in
                                        an if-clause) */
    });
    return false; /* make the form not post directly */
  } else {
    return false; /* do not post if JS validation fails */
  }
};

We use this snippet to store form data in a session before posting to a 3rd party so we have it available when the 3rd party returns to our page.

Edit: Keep in mind that this will only work with JS enabled, but it is fallback-safe: The form still submits without JS support.

hurikhan77
This looks like it will fit the bill exactly! I'm a little bit unsure of what this means though: ««« check the textStatus here and eventually do not submit */What are you checking for? Do you have an output from the php validator if it is invalid? At what point is the form submitted?Thanks!
Ashley
It contains the http return status of your php script (200, 302, 404) and data contains the body. While testing use an alert() to return the contents so you see exactly what comes back. http://api.jquery.com/jQuery.post/
hurikhan77