-1

I would like to cancel a cURL request. The request should be cancelled when the user is leaving the page.

Explanation of the situation: we're sending a cURL request to a mobile payment terminal to start a new payment. The request is still pending since we're waiting for the customer to enter the pin code. When the pin code is entered, the request will be answered with success / failure. We would like to cancel the request from the server to the payment terminal when, for example, the customer would like to pay in cash.

We've tried different approaches, e.g. connection_aborted & ignore_user_abort but nothing will fix the job.

$dataString = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
  'Content-Type: application/json',                                                        
  'Content-Length: ' . strlen($dataString)                                                                       
));
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_SSLCERT, certificateRoot.'/test.crt.pem');
curl_setopt($ch, CURLOPT_SSLKEY, certificateRoot.'/test.key.pem');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
Stefan
  • 249
  • 5
  • 17
  • eh? You initiate a HTTP request (via cURL) despite knowing the customer hasn't entered all the data? Are you sure that's what the structure really is? Also HTTP requests don't just hang indefinitely, they time out eventually, and there's no way to provide further info to the _same_ request. A more likely scenario is that the request is made, the remote payment service response saying it doesn't have the PIN, then you wait for user input, and then you send the request again but with the PIN. What you're describing sounds very odd or even impossible. – ADyson Apr 30 '18 at 15:56
  • 1
    Please provide an some sample code with your question. As it stands, your question is too open ended to obtain an answer of a reasonable quality. – Alex Mulchinock Apr 30 '18 at 15:56
  • @ADyson, actually, the requests are indeed a bit more complex. I've simplified the approach. Still, the fact is that we'll send a request and have to wait up to 30 sec. for a result. – Stefan Apr 30 '18 at 16:03
  • @AlexMulchinock, I'll add the cURL request in the original message. – Stefan Apr 30 '18 at 16:03
  • What is triggering the cURL request? Is it upon page request (i.e when a user wants to load the page in their browser), or via Ajax call? – Alex Mulchinock Apr 30 '18 at 16:11
  • @AlexMulchinock, the trigger is indeed an Ajax call. We'll abort the Ajax call when we would like to cancel the request, but the cURL request will not be cancelled when we abort the Ajax call. – Stefan Apr 30 '18 at 16:15
  • 1
    Why are you initiating the request if the customer hasn't yet decided whether to pay card or cash, and/or entered all relevant info such as a PIN? I don't get it. What causes the Ajax request to start? – ADyson Apr 30 '18 at 16:18
  • Also on most commerce sites I've used, if the user initiates a payment, the site then warns them not to leave the page, or refresh etc etc until a confirmation is received, on pain of the transaction failing or it's status being uncertain – ADyson Apr 30 '18 at 16:21
  • In theory that will indeed not occur, practically it will. But, however this will be the case: it is a mandatory development that we can cancel the request. – Stefan Apr 30 '18 at 16:21
  • I don't quite get the problem... So you issue an HTTP request, which then stalls till the user has made some kind of confirmation? How does that even work, wouldn't the page load stall for the user as well untill the request is completed? I think we need to know more about this. – EJTH Apr 30 '18 at 16:33
  • 1
    Ok, so its ajax. still seems wierd to me as you would need to have really high timeouts configured on your server. You shouldn't let PHP requests hang on purpose not even for polling. Its insanely resource demanding to do with a classical PHP+apache setup. – EJTH Apr 30 '18 at 16:38
  • Indeed, we issue a HTTP request, which stalls till the user made a confirmation. How this exactly works is unknown for us, since the API is developed by the supplier of the payment terminals – Stefan Apr 30 '18 at 16:49
  • Can't you just wait until after the confirmation to start this request? Then the remote service would respond immediately, I guess? I don't understand how you currently tell the remote server that the user has confirmed? Once you've started a HTTP request and sent the data, you're just waiting for a response. It doesn't make any sense why you'd start the request before the confirmation. to my knowledge you can't send any extra data without making a new request, but maybe I'm wrong in this case. – ADyson Apr 30 '18 at 17:18

1 Answers1

1

Here is my suggestion IF you really need to do this. Im sure that you are approaching this integration in the wrong way though and I will sincerely recommend that you re-read the documentation provided to you.

What you COULD do:

Instead of using cURL bindings in PHP you could use an exec call to call the curl binary instead, grab the pid and store it in the session.

$json_body = escapeshellarg(json_encode($data));
$pid = shell_exec("(curl https://dodgy-payment-vendor.com/api/foobar -XPOST -d $json_body > /dev/null 2>/dev/null) & echo \$!");

Then when the user cancels, you simply kill the process.

posix_kill($pid, 9) (If you don't have posix extension then maybe just use another shell_exec with the appropriate kill command under your particular OS... Oh and echo $! won't work for getting the PID under windows)

But I really recommend that you rethink what you are doing. A lot of bad things can come out of using system calls when not really appropriate so make damn sure that you serialize, sanitize and escape whatever data you will be sending properly if you go down this path!

EJTH
  • 2,178
  • 1
  • 20
  • 25