You are here

function _uc_authorizenet_charge in Ubercart 6.2

Same name and namespace in other branches
  1. 5 payment/uc_authorizenet/uc_authorizenet.module \_uc_authorizenet_charge()
  2. 7.3 payment/uc_authorizenet/uc_authorizenet.module \_uc_authorizenet_charge()

Handles authorizations and captures through AIM at Authorize.Net

1 call to _uc_authorizenet_charge()
uc_authorizenet_charge in payment/uc_authorizenet/uc_authorizenet.module

File

payment/uc_authorizenet/uc_authorizenet.module, line 448
Process payments using Authorize.net. Supports AIM and ARB.

Code

function _uc_authorizenet_charge($order, $amount, $data) {
  global $user;

  // Build a description of the order for logging in Auth.Net.
  $description = array();
  foreach ((array) $order->products as $product) {
    $description[] = $product->qty . 'x ' . $product->model;
  }
  $billing_address = $order->billing_street1;
  if ($order->billing_street2) {
    $billing_address .= ', ' . $order->billing_street2;
  }
  $delivery_address = $order->delivery_street1;
  if ($order->delivery_street2) {
    $delivery_address .= ', ' . $order->delivery_street2;
  }
  $billing_country = uc_get_country_data(array(
    'country_id' => $order->billing_country,
  ));
  $delivery_country = uc_get_country_data(array(
    'country_id' => $order->delivery_country,
  ));

  // Build the POST data for the transaction.
  $submit_data = array(
    // Merchant Information
    'x_login' => variable_get('uc_authnet_api_login_id', ''),
    'x_tran_key' => variable_get('uc_authnet_api_transaction_key', ''),
    // Transaction Information
    'x_version' => '3.1',
    'x_type' => _uc_authorizenet_txn_map($data['txn_type']),
    // 'x_method' => $order->payment_method == 'credit' ? 'CC' : 'ECHECK',
    'x_method' => 'CC',
    // 'x_recurring_billing' => 'FALSE',
    'x_amount' => _uc_authorizenet_format_amount($amount),
    'x_card_num' => $order->payment_details['cc_number'],
    'x_exp_date' => $order->payment_details['cc_exp_month'] . '/' . $order->payment_details['cc_exp_year'],
    'x_card_code' => $order->payment_details['cc_cvv'],
    // 'x_trans_id' => '',
    // 'x_auth_code' => '',
    'x_test_request' => variable_get('uc_authnet_aim_txn_mode', 'live_test') == 'live_test' ? 'TRUE' : 'FALSE',
    'x_duplicate_window' => variable_get('uc_authnet_duplicate_window', 120),
    // Order Information
    'x_invoice_num' => $order->order_id,
    'x_description' => substr(implode(', ', $description), 0, 255),
    // Customer Information
    'x_first_name' => substr($order->billing_first_name, 0, 50),
    'x_last_name' => substr($order->billing_last_name, 0, 50),
    'x_company' => substr($order->billing_company, 0, 50),
    'x_address' => substr($billing_address, 0, 60),
    'x_city' => substr($order->billing_city, 0, 40),
    'x_state' => substr(uc_get_zone_code($order->billing_zone), 0, 40),
    'x_zip' => substr($order->billing_postal_code, 0, 20),
    'x_country' => !$billing_country ? '' : $billing_country[0]['country_iso_code_2'],
    'x_phone' => substr($order->billing_phone, 0, 25),
    // 'x_fax' => substr('', 0, 25),
    'x_email' => substr($order->primary_email, 0, 255),
    'x_cust_id' => substr($order->uid, 0, 20),
    'x_customer_ip' => substr(ip_address(), 0, 15),
    // Shipping Information
    'x_ship_to_first_name' => substr($order->delivery_first_name, 0, 50),
    'x_ship_to_last_name' => substr($order->delivery_last_name, 0, 50),
    'x_ship_to_company' => substr($order->delivery_company, 0, 50),
    'x_ship_to_address' => substr($delivery_address, 0, 60),
    'x_ship_to_city' => substr($order->delivery_city, 0, 40),
    'x_ship_to_state' => substr(uc_get_zone_code($order->delivery_zone), 0, 40),
    'x_ship_to_zip' => substr($order->delivery_postal_code, 0, 20),
    'x_ship_to_country' => !$delivery_country ? '' : $delivery_country[0]['country_iso_code_2'],
    // Extra Information
    'x_delim_data' => 'TRUE',
    'x_delim_char' => '|',
    'x_encap_char' => '"',
    'x_relay_response' => 'FALSE',
    'x_email_customer' => variable_get('uc_authnet_aim_email_customer', FALSE) ? 'TRUE' : 'FALSE',
  );
  if ($data['txn_type'] == UC_CREDIT_PRIOR_AUTH_CAPTURE) {
    $submit_data['x_trans_id'] = $data['auth_id'];
  }

  // Determine the correct URL based on the transaction mode.
  if (variable_get('uc_authnet_aim_txn_mode', 'live_test') == 'developer_test') {
    $post_url = variable_get('uc_authnet_api_test_gateway_url', UC_AUTHORIZENET_TEST_GATEWAY_URL);
  }
  else {
    $post_url = variable_get('uc_authnet_api_live_gateway_url', UC_AUTHORIZENET_LIVE_GATEWAY_URL);
  }

  // Translate the data array into a string we can POST.
  $post_fields = array();
  foreach ($submit_data as $key => $value) {
    $post_fields[] = $key . '=' . urlencode($value);
  }

  // Setup the cURL request.
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $post_url);
  curl_setopt($ch, CURLOPT_VERBOSE, 0);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $post_fields));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
  curl_setopt($ch, CURLOPT_NOPROGRESS, 1);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
  $result = curl_exec($ch);

  // Log any errors to the watchdog.
  if ($error = curl_error($ch)) {
    watchdog('uc_authorizenet', 'cURL error: @error', array(
      '@error' => $error,
    ), WATCHDOG_ERROR);
    return array(
      'success' => FALSE,
    );
  }
  curl_close($ch);
  $response = explode('|', $result);
  if (variable_get('uc_authnet_response_debug', FALSE)) {
    watchdog('uc_authorizenet', 'Debug response: !data', array(
      '!data' => '<pre>' . check_plain(print_r($response, TRUE)) . '</pre>',
    ));
  }

  // Trim off the encapsulating character from the results.
  for ($i = 0; $i < count($response); $i++) {
    $response[$i] = substr($response[$i], 1, strlen($response[$i]) - 2);
  }

  /**
   * Response key index:
   * 0 = Response Code
   * 2 = Response Reason Code
   * 3 = Response Reason Text
   * 4 = Authorization Code
   * 5 = Address Verification Service (AVS) Response
   * 6 = Transaction ID; needed for CREDIT, PRIOR_AUTH_CAPTURE, and VOID transactions.
   * 9 = Amount
   * 11 = Transaction Type
   * 32 = Tax Amount Charged
   * 37 = Transaction Response MD5 Hash
   * 38 = Card Code (CVV) Response
   */

  // If we didn't get an approval response code...
  if ($response[0] != '1') {

    // Fail the charge with the reason text in the decline message.
    $result = array(
      'success' => FALSE,
      'message' => t('Credit card payment declined: @message', array(
        '@message' => $response[3],
      )),
      'uid' => $user->uid,
    );
  }
  else {

    // Build a message for display and comments in the payments table.
    $message = t('Type: @type<br />ID: @id', array(
      '@type' => _uc_authorizenet_txn_type($response[11]),
      '@id' => $response[6],
    ));
    $result = array(
      'success' => TRUE,
      'comment' => $message,
      'message' => $message,
      'data' => array(
        'module' => 'uc_authorizenet',
        'txn_type' => $response[11],
        'txn_id' => $response[6],
        'txn_authcode' => $response[4],
      ),
      'uid' => $user->uid,
    );

    // If this was an authorization only transaction...
    if ($data['txn_type'] == UC_CREDIT_AUTH_ONLY) {

      // Log the authorization to the order.
      uc_credit_log_authorization($order->order_id, $response[6], $amount);
    }
    elseif ($data['txn_type'] == UC_CREDIT_PRIOR_AUTH_CAPTURE) {
      uc_credit_log_prior_auth_capture($order->order_id, $data['auth_id']);
    }

    // Create a transaction reference if specified in the payment gateway
    // settings and this is an appropriate transaction type.
    if (variable_get('uc_authnet_cim_profile', FALSE) && in_array($data['txn_type'], array(
      UC_CREDIT_AUTH_ONLY,
      UC_CREDIT_AUTH_CAPTURE,
    ))) {

      // Ignore the returned message for now; that will appear in the comments.
      _uc_authorizenet_cim_profile_create($order);
    }
  }

  // Don't log this as a payment money wasn't actually captured.
  if (in_array($data['txn_type'], array(
    UC_CREDIT_AUTH_ONLY,
  ))) {
    $result['log_payment'] = FALSE;
  }

  // Build an admin order comment.
  $context = array(
    'revision' => 'formatted-original',
    'type' => 'amount',
  );
  $comment = t('<b>@type</b><br /><b>@status:</b> @message<br />Amount: @amount<br />AVS response: @avs', array(
    '@type' => _uc_authorizenet_txn_type($response[11]),
    '@status' => $result['success'] ? t('ACCEPTED') : t('REJECTED'),
    '@message' => $response[3],
    '@amount' => uc_price($response[9], $context),
    '@avs' => _uc_authorizenet_avs($response[5]),
  ));

  // Add the CVV response if enabled.
  if (variable_get('uc_credit_cvv_enabled', TRUE)) {
    $comment .= '<br />' . t('CVV match: @cvv', array(
      '@cvv' => _uc_authorizenet_cvv($response[38]),
    ));
  }

  // Save the comment to the order.
  uc_order_comment_save($order->order_id, $user->uid, $comment, 'admin');
  return $result;
}