-1

How would I used CURL to send a form of order information to PayPal (https://www.sandbox.paypal.com/cgi-bin/webscr), instead of the user doing so, but allowing the user to be sent to the URL that CURL would redirect to?

I can successfully code the manual form version of this code. This is where the user fills in a form that has unseen database data in hidden form fields, and when the user submits it, this form is POST to "https://www.sandbox.paypal.com/cgi-bin/webscr". They are then redirected to a page such as "https://www.sandbox.paypal.com/webapps/hermes?token=XXXXXXXX&useraction=commit&mfid=XXXXXXXXX_XXXXXXXX". It should be noted that this URL can then be accessed from anyone at any location to complete the process, if it is not completed by the user it was first given to.

In my attempt to recreate this with CURL, the following happens: The user submits a form of data, and that data is sent to a secondary page where it is combined with the unseen database data, and used as the CURLOPT_POSTFIELDS. The cURL is then executed, but for some reason it is redirected to the URL: "https://www.sandbox.paypal.com/home" instead of the expected URL that contains a unique token and mfid.

Here is a reduced version of the code I tried so far:

<?php

$post_data['business'] = PAYPAL_ID;
//other data also here

$i = 1;

foreach($_SESSION['basket'])
{
    //retrieve information from basket and insert into data

    $post_data["item_name_$i"] = $name;
    $post_data["amount_$i"] = $price;
    $post_data["quantity_$i"] = $qty;
    $post_data["item_number_$i"] = $id;

    $i++;
}

//other data also here
$post_data['notify_url'] = PAYPAL_NOTIFY_URL;

//create string with format "key1=value1&key2=value2&key3=value3" etc.
foreach ($post_data as $key => $value)
{
    $post_items[] = urlencode($key) . "=" . urlencode($value);

}

$post_string = implode('&', $post_items);

$curl_connection =
    curl_init(PAYPAL_URL);

    curl_setopt($curl_connection, CURLOPT_POST, 1);
    curl_setopt($curl_connection, CURLOPT_HEADER, 0);
    curl_setopt($curl_connection, CURLOPT_FRESH_CONNECT, 1);
    curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, 0);
    curl_setopt($curl_connection, CURLOPT_FORBID_REUSE, 1);
    curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT_MS, 30000);
    curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $post_string);

$result = curl_exec($curl_connection);

print_r(curl_getinfo($curl_connection));


echo ("<br> curl errors: <br>");

echo curl_errno($curl_connection) . '-' . 
    curl_error($curl_connection);

echo ("<br> end curl errors; <br>");


echo ("getinfo: <br>" . curl_getinfo($curl_connection));
echo ("<br> The post string is: $post_string");

echo ("<br> effective URL is: <br>");
echo curl_getinfo($curl_connection, CURLINFO_EFFECTIVE_URL);

echo ("<br> The result string is: $result <br>");

curl_close($curl_connection);

?>

In my "debugging", I am always greeted with cURL error "0", and an empty "curl_error($curl_connection);". The post string looks correct, in the format "key1=value1&key2=value2", with all the keys and values successfully having the special characters URL encoded. (e.g. "@" becomes "%40). Also, the [redirect_count] value from "print_r(curl_getinfo($curl_connection));" is "1", which I believe means only 1 redirect occurs, and is not the URL I expected. The result string is "1".

What am I doing wrong?

1 Answers1

-1

If you want to automate the user's form post you should be automating their browser with javascript, not attempting to do a curl form post from your server. That's not going to work.

Preston PHX
  • 27,642
  • 4
  • 24
  • 44
  • I don't want to automate the users form - I need the form to not exist in HTML. It's just that unfortunately PayPal requires a POST submission to work. Could you elaborate on why it would not work? I have seen several similar questions posted here that do something similar using curl but with slightly different means, e.g. send an email with information collected, or autocomplete the next page. One example: https://stackoverflow.com/questions/11746644/paypal-sandbox-ipn-always-returns-invalid – Denver Thomas Jun 10 '20 at 17:56
  • Verifying IPNs is a separate topic. You can use GET parameters in you redirection to PayPal if you want there to be no form, for some reason. – Preston PHX Jun 10 '20 at 20:51
  • Sorry I linked those examples as they do something similar to the same PayPal address with cURL successfully - I have already done the IPN section of PayPal. Unfortunately I need there to be a form, and have it submit information that is not in HTML whatsoever. Appending the GET parameters to the form "action=" still displays the hidden GET parameters in HTML format. – Denver Thomas Jun 11 '20 at 18:30
  • You can have your server redirect to a URL with get parameters. You can't have your server do things with curl and then redirect. You can automate a client-side HTML post with javascript. – Preston PHX Jun 11 '20 at 19:05
  • Correction, you can't have your server do non-IPN-verification things to 'webscr' via curl and then redirect. But if you want to set up a transaction via curl, there are various APIs for this. They do not use Payments Standard parameters, nor do they use webscr. The best would be v2/checkout/orders https://developer.paypal.com/docs/checkout/reference/server-integration/ – Preston PHX Jun 11 '20 at 19:07