Submit form via cURL and redirect browser to PayPal

David Jones picture David Jones · Feb 12, 2013 · Viewed 16.9k times · Source

I'm developing a site where customers have several payment options, including PayPal Payments Standard. Since I'm collecting a fair amount of data about the customer, I'd like to process the form on my server before sending the user to PayPal's server. One option is to concatenate the data into a single string, assign the string to the custom field, and then process it in the IPN response, but I find this to be a very inelegant solution. Instead, after collecting the user data, I'm attempting to use cURL to submit a standard HTML PayPal form. How can I redirect the user to PayPal to complete the checkout process?

  // Process PayPal payment
  if ($method == 'PayPal') {

    // Prepare POST data
    $query = array();
    $query['notify_url'] = 'http://example.com/ipn';
    $query['cmd'] = '_cart';
    $query['upload'] = '1';
    $query['business'] = '[email protected]';
    $query['address_override'] = '1';
    $query['first_name'] = $first_name;
    $query['last_name'] = $last_name;
    $query['email'] = $email;
    $query['address1'] = $ship_to_address;
    $query['city'] = $ship_to_city;
    $query['state'] = $ship_to_state;
    $query['zip'] = $ship_to_zip;
    $query['item_name_'.$i] = $item['description'];
    $query['quantity_'.$i] = $item['quantity'];
    $query['amount_'.$i] = $item['info']['price'];

    // Prepare query string
    $query_string = '';
    foreach ($query as $key=>$value) {
      $query_string .= $key.'='.urlencode($value).'&';
    }
    $query_string = rtrim($query_string, '&');

    // Open connection
    $ch = curl_init();

    //set the url, number of POST vars, POST data
    curl_setopt($ch,CURLOPT_URL, 'https://www.paypal.com/cgi-bin/webscr');
    curl_setopt($ch,CURLOPT_POST, count($query));
    curl_setopt($ch,CURLOPT_POSTFIELDS, $query_string);

    // Execute post
    $result = curl_exec($ch);

    // Close connection
    curl_close($ch);
  }

Answer

Drahcir picture Drahcir · Feb 13, 2013

WARNING: this answer has a security deficit. Passing sensitive data (such as item and price) through the client allows the client to modify the transaction. ie. change the item, or change the price. See the PayPal documentation on how to implement IPN.

You should redirect the user with the php header function and send the vars as GET not POST.

// Process PayPal payment
if ($method == 'PayPal') {

    // Prepare GET data
    $query = array();
    $query['notify_url'] = 'http://jackeyes.com/ipn';
    $query['cmd'] = '_cart';
    $query['upload'] = '1';
    $query['business'] = '[email protected]';
    $query['address_override'] = '1';
    $query['first_name'] = $first_name;
    $query['last_name'] = $last_name;
    $query['email'] = $email;
    $query['address1'] = $ship_to_address;
    $query['city'] = $ship_to_city;
    $query['state'] = $ship_to_state;
    $query['zip'] = $ship_to_zip;
    $query['item_name_'.$i] = $item['description'];
    $query['quantity_'.$i] = $item['quantity'];
    $query['amount_'.$i] = $item['info']['price'];

    // Prepare query string
    $query_string = http_build_query($query);

    header('Location: https://www.paypal.com/cgi-bin/webscr?' . $query_string);
}