You are here

function commerce_payflow_api_request in Commerce PayPal 7.2

Submits an API request to Payflow.

This function is currently used by PayPal Payments Advanced and Payflow Link.

This function may be used for any PayPal payment method that uses the same settings array structure as these other payment methods and whose API requests should be submitted to the same URLs as determined by the function commerce_payflow_api_server_url().

Parameters

$payment_method: The payment method instance array associated with this API request.

$api: Either 'pro' or 'link' indicating which API server the request should be sent to.

$nvp: The set of name-value pairs describing the transaction to submit.

$order: The order the payment request is being made for.

Return value

The response array from PayPal if successful or FALSE on error.

5 calls to commerce_payflow_api_request()
commerce_payflow_link_capture_form_submit in modules/payflow/includes/commerce_payflow.admin.inc
Submit handler: process a prior authorization capture via Payflow Pro.
commerce_payflow_link_create_secure_token in modules/payflow/commerce_payflow.module
Requests a Secure Token from Payflow for use in follow-up API requests.
commerce_payflow_link_reference_form_submit in modules/payflow/includes/commerce_payflow.admin.inc
Submit handler: process a reference transaction via Payflow Pro.
commerce_payflow_link_refund_form_submit in modules/payflow/includes/commerce_payflow.admin.inc
Submit handler: process a refund via Payflow Pro.
commerce_payflow_link_void_form_submit in modules/payflow/includes/commerce_payflow.admin.inc
Submit handler: process the void request.

File

modules/payflow/commerce_payflow.module, line 1234
Implements PayPal Payments Advanced (U.S. only) and Payflow Link Hosted Checkout pages and Transparent Redirect.

Code

function commerce_payflow_api_request($payment_method, $api, $nvp = array(), $order = NULL) {
  $mode = $payment_method['settings']['mode'];

  // Get the API endpoint URL for the payment method's transaction mode.
  if ($api == 'pro') {
    $url = commerce_payflow_pro_server_url($mode);
  }
  else {
    $url = commerce_payflow_link_server_url($mode);
  }

  // Add the default name-value pairs to the array.
  $nvp += array(
    // API credentials
    'PARTNER' => $payment_method['settings']['partner'],
    'VENDOR' => $payment_method['settings']['vendor'],
    'USER' => $payment_method['settings']['user'],
    'PWD' => $payment_method['settings']['password'],
    // Set the mode based on which server we're submitting to.
    'MODE' => $mode == 'test' ? 'TEST' : 'LIVE',
  );

  // Allow modules to alter parameters of the API request.
  drupal_alter('commerce_payflow_api_request', $nvp, $order, $payment_method);

  // Log the request if specified.
  if ($payment_method['settings']['log']['request'] == 'request') {

    // Mask sensitive request data.
    $log_nvp = $nvp;
    $log_nvp['PWD'] = str_repeat('X', strlen($log_nvp['PWD']));
    if (!empty($log_nvp['ACCT'])) {
      $log_nvp['ACCT'] = str_repeat('X', strlen($log_nvp['ACCT']) - 4) . substr($log_nvp['ACCT'], -4);
    }
    if (!empty($log_nvp['CVV2'])) {
      $log_nvp['CVV2'] = str_repeat('X', strlen($log_nvp['CVV2']));
    }
    watchdog('commerce_payflow', 'Payflow API request to @url: !param', array(
      '@url' => $url,
      '!param' => '<pre>' . check_plain(print_r($log_nvp, TRUE)) . '</pre>',
    ), WATCHDOG_DEBUG);
  }

  // Prepare the name-value pair array to be sent as a string.
  $pairs = array();
  foreach ($nvp as $key => $value) {

    // Since we aren't supposed to urlencode parameter values for PFL / PPA API
    // requests, we strip out ampersands and equals signs to
    $pairs[] = $key . '=' . str_replace(array(
      '&',
      '=',
      '#',
    ), array(
      '',
    ), $value);
  }

  // Setup the cURL request.
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_VERBOSE, 0);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $pairs));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
  curl_setopt($ch, CURLOPT_TIMEOUT, 45);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);

  // Commerce PayPal requires SSL peer verification, which may prevent out of
  // date servers from successfully processing API requests. If you get an error
  // related to peer verification, you may need to download the CA certificate
  // bundle file from http://curl.haxx.se/docs/caextract.html, place it in a
  // safe location on your web server, and update your settings.php to set the
  // commerce_paypal_cacert variable to contain the absolute path of the file.
  // Alternately, you may be able to update your php.ini to point to the file
  // with the curl.cainfo setting.
  if (variable_get('commerce_paypal_cacert', FALSE)) {
    curl_setopt($ch, CURLOPT_CAINFO, variable_get('commerce_paypal_cacert', ''));
  }
  $result = curl_exec($ch);

  // Log any errors to the watchdog.
  if ($error = curl_error($ch)) {
    watchdog('commerce_payflow', 'cURL error: @error', array(
      '@error' => $error,
    ), WATCHDOG_ERROR);
    return FALSE;
  }
  curl_close($ch);

  // Make the response an array.
  $response = array();
  foreach (explode('&', $result) as $nvp) {
    list($key, $value) = explode('=', $nvp);
    $response[urldecode($key)] = urldecode($value);
  }

  // Log the response if specified.
  if ($payment_method['settings']['log']['response'] == 'response') {
    watchdog('commerce_payflow', 'Payflow server response: !param', array(
      '!param' => '<pre>' . check_plain(print_r($response, TRUE)) . '</pre>',
    ), WATCHDOG_DEBUG);
  }
  return $response;
}