You are here

uc_2checkout.module in Ubercart 5

Integrates 2Checkout.com's redirected payment service.

File

payment/uc_2checkout/uc_2checkout.module
View source
<?php

/**
 * @file
 * Integrates 2Checkout.com's redirected payment service.
 */

/*******************************************************************************
 * Hook Functions (Drupal)
 ******************************************************************************/

/**
 * Implementation of hook_menu().
 */
function uc_2checkout_menu($may_cache) {
  if ($may_cache) {
    $items[] = array(
      'path' => 'cart/2checkout/complete',
      'title' => t('Order complete'),
      'callback' => 'uc_2checkout_complete',
      'access' => user_access('access content'),
      'type' => MENU_CALLBACK,
    );
  }
  return $items;
}

/**
 * Implementation of hook_ucga_display().
 */
function uc_2checkout_ucga_display() {

  // Tell UC Google Analytics to display the e-commerce JS on the custom
  // order completion page for this module.
  if (arg(0) == 'cart' && arg(1) == '2checkout' && arg(2) == 'complete') {
    return TRUE;
  }
}

/**
 * Implementation of hook_form_alter().
 */
function uc_2checkout_form_alter($form_id, &$form) {
  if ($form_id == 'uc_cart_checkout_review_form' && ($order_id = intval($_SESSION['cart_order'])) > 0) {
    $order = uc_order_load($order_id);
    if ($order->payment_method == '2checkout') {
      unset($form['submit']);
      $form['#prefix'] = '<table style="display: inline; padding-top: 1em;"><tr><td>';
      $form['#suffix'] = '</td><td>' . drupal_get_form('uc_2checkout_form', $order) . '</td></tr></table>';
    }
  }
}

/*******************************************************************************
 * Hook Functions (Ubercart)
 ******************************************************************************/

/**
 * Implementation of hook_payment_method().
 */
function uc_2checkout_payment_method() {
  $path = base_path() . drupal_get_path('module', 'uc_2checkout');
  $title = variable_get('uc_2checkout_method_title', t('Credit card on a secure server:'));
  $title .= '<br /><img src="' . $path . '/2cocc05.gif" style="position: relative; left: 2.5em;">';
  $methods[] = array(
    'id' => '2checkout',
    'name' => t('2Checkout'),
    'title' => $title,
    'review' => variable_get('uc_2checkout_check', FALSE) ? t('Credit card/eCheck') : t('Credit card'),
    'desc' => t('Redirect to 2Checkout to pay by credit card or eCheck.'),
    'callback' => 'uc_payment_method_2checkout',
    'weight' => 3,
    'checkout' => TRUE,
    'no_gateway' => TRUE,
  );
  return $methods;
}

/*******************************************************************************
 * Callback Functions, Forms, and Tables
 ******************************************************************************/

/**
 * Callback for 2Checkout payment method settings.
 */
function uc_payment_method_2checkout($op, &$arg1) {
  switch ($op) {
    case 'cart-details':
      if (variable_get('uc_2checkout_check', FALSE)) {
        if ($_SESSION['pay_method'] == 'CK') {
          $sel[2] = ' selected="selected"';
        }
        else {
          $sel[1] = ' selected="selected"';
        }
        unset($_SESSION['pay_method']);
        $details = '<div class="form-item"><b>' . t('Select your payment type:') . '</b> <select name="pay_method" class="form-select" id="edit-pay-method">' . '<option value="CC"' . $sel[1] . '>' . t('Credit card') . '</option>' . '<option value="CK"' . $sel[2] . '>' . t('Online check') . '</option></select></div>';
      }
      return $details;
    case 'cart-process':
      $_SESSION['pay_method'] = $_POST['pay_method'];
      return;
    case 'settings':
      $form['uc_2checkout_sid'] = array(
        '#type' => 'textfield',
        '#title' => t('Vendor account number'),
        '#description' => t('Your 2Checkout vendor account number.'),
        '#default_value' => variable_get('uc_2checkout_sid', ''),
        '#size' => 16,
      );
      $form['uc_2checkout_secret_word'] = array(
        '#type' => 'textfield',
        '#title' => t('Secret word for order verification'),
        '#description' => t('The secret word entered in your 2Checkout account Look and Feel settings.'),
        '#default_value' => variable_get('uc_2checkout_secret_word', 'tango'),
        '#size' => 16,
      );
      $form['uc_2checkout_demo'] = array(
        '#type' => 'checkbox',
        '#title' => t('Enable demo mode, allowing you to process fake orders for testing purposes.'),
        '#default_value' => variable_get('uc_2checkout_demo', TRUE),
      );
      $form['uc_2checkout_language'] = array(
        '#type' => 'select',
        '#title' => t('Language preference'),
        '#description' => t('Adjust language on 2Checkout pages.'),
        '#options' => array(
          'en' => t('English'),
          'sp' => t('Spanish'),
        ),
        '#default_value' => variable_get('uc_2checkout_language', 'en'),
      );
      $form['uc_2checkout_check'] = array(
        '#type' => 'checkbox',
        '#title' => t('Allow customers to choose to pay by credit card or online check.'),
        '#default_value' => variable_get('uc_2checkout_check', FALSE),
      );
      $form['uc_2checkout_method_title'] = array(
        '#type' => 'textfield',
        '#title' => t('Payment method title'),
        '#default_value' => variable_get('uc_2checkout_method_title', t('Credit card on a secure server:')),
      );
      $form['uc_2checkout_method_title_icons'] = array(
        '#type' => 'checkbox',
        '#title' => t('Show credit card icons beside the payment method title.'),
        '#default_value' => variable_get('uc_2checkout_method_title_icons', TRUE),
      );
      $form['uc_2checkout_checkout_button'] = array(
        '#type' => 'textfield',
        '#title' => t('Order review submit button text'),
        '#description' => t('Provide 2Checkout specific text for the submit button on the order review page.'),
        '#default_value' => variable_get('uc_2checkout_checkout_button', t('Submit Order')),
      );
      $form['uc_2checkout_checkout_type'] = array(
        '#type' => 'select',
        '#title' => t('2Checkout.com checkout type'),
        '#description' => t('Single page checkout only works for stores selling intangible products using credit card payments.'),
        '#options' => array(
          'multi' => t('Multi-page checkout'),
          'single' => t('Single page checkout'),
        ),
        '#default_value' => variable_get('uc_2checkout_checkout_type', 'multi'),
      );
      return $form;
  }
}

// Form to build the submission to 2Checkout.com.
function uc_2checkout_form($order) {
  $country = uc_get_country_data(array(
    'country_id' => $order->billing_country,
  ));
  if ($country === FALSE) {
    $country = array(
      0 => array(
        'country_iso_code_3' => 'USA',
      ),
    );
  }
  $data = array(
    'sid' => variable_get('uc_2checkout_sid', ''),
    'total' => uc_currency_format($order->order_total, FALSE, FALSE, '.'),
    'cart_order_id' => $order->order_id,
    'demo' => variable_get('uc_2checkout_demo', TRUE) ? 'Y' : 'N',
    'fixed' => 'Y',
    'lang' => variable_get('uc_2checkout_language', 'en'),
    'x_receipt_link_url' => url('cart/2checkout/complete/' . uc_cart_get_id(), NULL, NULL, TRUE),
    'merchant_order_id' => $order->order_id,
    'pay_method' => isset($_SESSION['pay_method']) ? $_SESSION['pay_method'] : 'CC',
    'card_holder_name' => substr($order->billing_first_name . ' ' . $order->billing_last_name, 0, 128),
    'street_address' => substr($order->billing_street1, 0, 64),
    'street_address2' => substr($order->billing_street2, 0, 64),
    'city' => substr($order->billing_city, 0, 64),
    'state' => uc_get_zone_code($order->billing_zone),
    'zip' => substr($order->billing_postal_code, 0, 16),
    'country' => $country[0]['country_iso_code_3'],
    'email' => substr($order->primary_email, 0, 64),
    'phone' => substr($order->billing_phone, 0, 16),
    'id_type' => 1,
  );
  $i = 0;
  foreach ($order->products as $product) {
    $i++;
    $data['c_prod_' . $i] = $product->model . ',' . $product->qty;
    $data['c_name_' . $i] = $product->title;
    $data['c_description_' . $i] = $desc;
    $data['c_price_' . $i] = uc_currency_format($product->price, FALSE, FALSE, '.');
  }
  $form['#action'] = _2checkout_post_url(variable_get('uc_2checkout_checkout_type', 'multi'));
  foreach ($data as $name => $value) {
    $form[$name] = array(
      '#type' => 'hidden',
      '#value' => $value,
    );
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => variable_get('uc_2checkout_checkout_button', t('Submit Order')),
  );
  return $form;
}
function uc_2checkout_complete($cart_id = 0) {
  watchdog('2Checkout', t('Receiving new order notification for order !order_id.', array(
    '!order_id' => check_plain($_POST['merchant_order_id']),
  )));
  $order = uc_order_load($_POST['merchant_order_id']);
  if ($order === FALSE || uc_order_status_data($order->order_status, 'state') != 'in_checkout') {
    return t('An error has occurred during payment.  Please contact us to ensure your order has submitted.');
  }
  $key = $_POST['key'];
  $valid = md5(variable_get('uc_2checkout_secret_word', 'tango') . $_POST['sid'] . $_POST['merchant_order_id'] . $_POST['total']);
  if (strtolower($key) != strtolower($valid)) {
    uc_order_comment_save($order->order_id, 0, t('Attempted unverified 2Checkout completion for this order.'), 'admin');
    return MENU_ACCESS_DENIED;
  }
  if ($_POST['demo'] == 'Y' xor variable_get('uc_2checkout_demo', TRUE)) {
    watchdog('uc_2checkout', 'The 2checkout payment for order <a href="!order_url">@order_id</a> demo flag was set to %flag, but the module is set to %mode mode.', array(
      '!order_url' => url('admin/store/orders/' . $order->order_id),
      '@order_id' => $order->order_id,
      '%flag' => $_POST['demo'] == 'Y' ? 'Y' : 'N',
      '%mode' => variable_get('uc_2checkout_demo', TRUE) ? 'Y' : 'N',
    ), WATCHDOG_ERROR);
    if (!variable_get('uc_2checkout_demo', TRUE)) {
      return MENU_ACCESS_DENIED;
    }
  }
  $order->billing_street1 = $_POST['street_address'];
  $order->billing_street2 = $_POST['street_address2'];
  $order->city = $_POST['city'];
  $order->billing_postal_code = $_POST['zip'];
  $order->billing_phone = $_POST['phone'];
  $zone_id = db_result(db_query("SELECT zone_id FROM {uc_zones} WHERE zone_code LIKE '%s'", $_POST['state']));
  if (!empty($zone_id)) {
    $order->billing_zone = $zone_id;
  }
  $country_id = db_result(db_query("SELECT country_id FROM {uc_countries} WHERE country_name LIKE '%s'", $_POST['country']));
  if (!empty($zone_id)) {
    $order->billing_country = $country_id;
  }
  if (strtolower($_POST['email']) !== strtolower($order->primary_email)) {
    uc_order_comment_save($order->order_id, 0, t('Customer used a different e-mail address during payment: !email', array(
      '!email' => check_plain($_POST['email']),
    )), 'admin');
  }
  if ($_POST['credit_card_processed'] == 'Y' && is_numeric($_POST['total'])) {
    $comment = t('Paid by !type, 2Checkout.com order #!order.', array(
      '!type' => $_POST['pay_method'] == 'CC' ? t('credit card') : t('echeck'),
      '!order' => check_plain($_POST['order_number']),
    ));
    uc_payment_enter($order->order_id, '2checkout', $_POST['total'], 0, NULL, $comment);
  }
  else {
    drupal_set_message(t('Your order will be processed as soon as your payment clears at 2Checkout.com.'));
    uc_order_comment_save($order_id, 0, t('!type payment is pending approval at 2Checkout.com.', array(
      '!type' => $_POST['pay_method'] == 'CC' ? t('Credit card') : t('eCheck'),
    )), 'admin');
  }

  // Empty that cart...
  uc_cart_empty($cart_id);

  // Save changes to order without it's completion.
  uc_order_save($order);

  // Add a comment to let sales team know this came in through the site.
  uc_order_comment_save($order->order_id, 0, t('Order created through website.'), 'admin');
  $output = uc_cart_complete_sale($order, variable_get('uc_new_customer_login', FALSE));
  $page = variable_get('uc_cart_checkout_complete_page', '');
  if (!empty($page)) {
    drupal_goto($page);
  }
  return $output;
}
function _2checkout_post_url($type) {
  switch ($type) {
    case 'single':
      return 'https://www.2checkout.com/checkout/spurchase';
    case 'multi':
    default:
      return 'https://www.2checkout.com/2co/buyer/purchase';
  }
}

Functions

Namesort descending Description
uc_2checkout_complete
uc_2checkout_form
uc_2checkout_form_alter Implementation of hook_form_alter().
uc_2checkout_menu Implementation of hook_menu().
uc_2checkout_payment_method Implementation of hook_payment_method().
uc_2checkout_ucga_display Implementation of hook_ucga_display().
uc_payment_method_2checkout Callback for 2Checkout payment method settings.
_2checkout_post_url