You are here

payment_ubercart.module in Payment for Ubercart 7

Same filename and directory in other branches
  1. 7.2 payment_ubercart.module

Hook implementations and shared functions.

File

payment_ubercart.module
View source
<?php

/**
 * @file
 * Hook implementations and shared functions.
 */

/**
 * Implements hook_menu().
 */
function payment_ubercart_menu() {
  $item['admin/config/services/payment/payment_ubercart'] = array(
    'title' => 'Payment for Ubercart',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'payment_ubercart_form_configuration',
    ),
    'access arguments' => array(
      'payment_ubercart.administer',
    ),
  );
  return $item;
}

/**
 * Implements hook_permission().
 */
function payment_ubercart_permission() {
  $permissions = array(
    'payment_ubercart.administer' => array(
      'title' => t('Administer Payment for Ubercart'),
    ),
  );
  return $permissions;
}

/**
 * Implements hook_uc_order().
 */
function payment_ubercart_uc_order($op, $order, $arg2) {
  if (strpos($order->payment_method, 'payment_ubercart_') === 0) {
    switch ($op) {
      case 'delete':
        if (variable_get('payment_ubercart_uc_order_delete', FALSE)) {
          $pids = payment_ubercart_pids_load($order->order_id);
          if ($pids) {
            entity_delete_multiple('payment', $pids);
          }
        }
        break;
      case 'submit':
        $pids = payment_ubercart_pids_load($order->order_id);
        if ($pids) {
          $payment = entity_load_single('payment', end($pids));
          $payment
            ->execute();
        }
        break;
    }
  }
}

/**
 * Implements hook_uc_checkout_complete().
 */
function payment_ubercart_uc_checkout_complete($order, $account) {
  if (strpos($order->payment_method, 'payment_ubercart_') === 0) {
    $pids = payment_ubercart_pids_load($order->order_id);
    if ($pids) {
      $payment = entity_load_single('payment', end($pids));

      // For anonymous checkouts, set the payment UID to that of the order for
      // which a user account was created during checkout completion.
      if ($payment->uid != $order->uid) {
        $payment->uid = $order->uid;
        entity_save('payment', $payment);
      }
    }
  }
}

/**
 * Implements hook_form_alter().
 */
function payment_ubercart_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'uc_cart_checkout_form') {
    $form['#submit'] = array_unique(array(
      'payment_ubercart_checkout_form_submit',
      'uc_cart_checkout_form_submit',
    ));
  }
}

/**
 * Implements form submit callback.
 *
 * @see payment_ubercart_form_alter()
 */
function payment_ubercart_checkout_form_submit($form, &$form_state) {

  // Save all data required for payment execution, before we execute the
  // payment in payment_ubercart_uc_order().
  if (isset($form_state['storage']['order']) && strpos($form_state['storage']['order']->payment_method, 'payment_ubercart_') === 0) {
    $order = $form_state['storage']['order'];
    $payment = $form_state['payment'];
    entity_save('payment', $payment);
    $payment->payment_ubercart_uc_order_id = $order->order_id;
    payment_ubercart_order_id_save($payment);
  }
}

/**
 * Implements hook_uc_payment_method().
 */
function payment_ubercart_uc_payment_method() {
  $uc_payment_methods = array();
  foreach (entity_load('payment_method') as $payment_method) {
    if ($payment_method->enabled) {
      $uc_payment_methods['payment_ubercart_' . $payment_method->pmid] = array(
        'title' => $payment_method->title_generic,
        'name' => $payment_method->title_specific,
        'callback' => 'payment_ubercart_callback',
        'checkout' => TRUE,
        'weight' => 1,
      );
    }
  }
  return $uc_payment_methods;
}

/**
 * Implements hook_payment_line_item_info().
 */
function payment_ubercart_payment_line_item_info() {
  return array(
    new PaymentLineItemInfo(array(
      'callback' => 'payment_line_item_get_prefixed',
      'name' => 'payment_ubercart_product',
      'title' => t('Ubercart products'),
    )),
    new PaymentLineItemInfo(array(
      'callback' => 'payment_line_item_get_prefixed',
      'name' => 'payment_ubercart_order_balance',
      'title' => t('Ubercart order balance'),
    )),
    new PaymentLineItemInfo(array(
      'callback' => 'payment_line_item_get_prefixed',
      'name' => 'payment_ubercart_line_item',
      'title' => t('Ubercart order line items'),
    )),
    new PaymentLineItemInfo(array(
      'callback' => 'payment_line_item_get_prefixed',
      'name' => 'payment_ubercart_hook_uc_order_total',
      'title' => t('Ubercart hook_uc_order() total'),
    )),
  );
}

/**
 * Implements hook_payment_status_change().
 */
function payment_ubercart_payment_status_change(Payment $payment, PaymentStatusItem $previous_status_item) {
  if ($payment->context == 'payment_ubercart') {
    if (payment_ubercart_order_id_load($payment)) {
      if (!payment_status_is_or_has_ancestor($previous_status_item->status, PAYMENT_STATUS_SUCCESS) && payment_status_is_or_has_ancestor($payment
        ->getStatus()->status, PAYMENT_STATUS_SUCCESS)) {
        $order = uc_order_load($payment->payment_ubercart_uc_order_id);
        uc_payment_enter($order->order_id, 'payment_ubercart_' . $payment->method->pmid, $payment
          ->totalAmount(TRUE), $payment->uid, NULL, '', $payment
          ->getStatus()->created);
        uc_cart_complete_sale($order, FALSE);
      }
    }
  }
}

/**
 * Implements hook_views_api().
 */
function payment_ubercart_views_api() {
  return array(
    'api' => '2',
    'path' => drupal_get_path('module', 'payment_ubercart'),
  );
}

/**
 * Implements Ubercart payment method callback.
 *
 * @see payment_ubercart_uc_payment_method()
 */
function payment_ubercart_callback($op, &$order, array $form = NULL, array &$form_state = NULL) {
  if ($op == 'cart-details') {
    $payment = payment_ubercart_payment_create($order);

    // Build the form.
    $form_state['payment'] = $payment;
    $form = payment_form_embedded($form_state, $payment, array(
      $payment->method->pmid,
    ));
    unset($form['elements']['payment_method']['#title']);
    unset($form['elements']['payment_line_items']);
    unset($form['elements']['payment_status']);
    return $form['elements'];
  }
}

/**
 * Implements Payment::finish_callback.
 */
function payment_ubercart_finish(Payment $payment) {

  // Set messages for the user.
  if (payment_status_is_or_has_ancestor($payment
    ->getStatus()->status, PAYMENT_STATUS_SUCCESS)) {
    drupal_set_message(t('Your payment was successfully completed.'));
    $complete = TRUE;
  }
  elseif (payment_status_is_or_has_ancestor($payment
    ->getStatus()->status, PAYMENT_STATUS_PENDING)) {
    drupal_set_message(t('Your payment is still being processed.'));
    $complete = TRUE;
  }
  else {
    drupal_set_message(t('Your payment was not completed.'), 'error');
    $complete = FALSE;
  }

  // Redirect the user.
  if (empty($_SESSION['cart_order'])) {
    drupal_goto('<front>');
  }
  elseif ($complete) {

    // Tell Ubercart's uc_cart_checkout_complete() to complete the sale.
    $_SESSION['uc_checkout'][$_SESSION['cart_order']]['do_complete'] = TRUE;
    unset($_SESSION['uc_checkout'][$_SESSION['cart_order']]['do_review']);
    drupal_goto('cart/checkout/complete');
  }
  else {
    drupal_goto('cart/checkout');
  }
}

/**
 * Load the ID of the Ubercart order a Payment belongs to.
 *
 * @param Payment $payment
 *
 * @return integer
 */
function payment_ubercart_order_id_load(Payment $payment) {
  if (!isset($payment->payment_ubercart_uc_order_id)) {
    $payment->payment_ubercart_uc_order_id = db_query("SELECT uc_order_id FROM {payment_ubercart} WHERE pid = :pid", array(
      ':pid' => $payment->pid,
    ))
      ->fetchField();
  }
  return (bool) $payment->payment_ubercart_uc_order_id;
}

/**
 * Save the ID of the Ubercart order a Payment belongs to.
 *
 * @param Payment $payment
 *
 * @return integer
 *   Either MergeQuery::STATUS_INSERT or MergeQuery::STATUS_UPDATE.
 */
function payment_ubercart_order_id_save(Payment $payment) {
  return db_merge('payment_ubercart')
    ->key(array(
    'pid' => $payment->pid,
  ))
    ->fields(array(
    'pid' => $payment->pid,
    'uc_order_id' => $payment->payment_ubercart_uc_order_id,
  ))
    ->execute();
}

/**
 * Load the PIDs of the Payments that belong to an Ubercart order.
 *
 * @param integer $order_id
 *
 * @return array
 */
function payment_ubercart_pids_load($order_id) {
  return db_query("SELECT pid FROM {payment_ubercart} WHERE uc_order_id = :uc_order_id ORDER BY pid ASC", array(
    ':uc_order_id' => $order_id,
  ))
    ->fetchCol();
}

/**
 * Implements form build callback for the configuration form.
 */
function payment_ubercart_form_configuration(array $form, array &$form_state) {
  $form['payment_ubercart_uc_order_delete'] = array(
    '#type' => 'checkbox',
    '#title' => t('When deleting an Ubercart order, delete its payments as well.'),
    '#default_value' => variable_get('payment_ubercart_uc_order_delete', FALSE),
  );
  return system_settings_form($form);
}

/**
 * Creates a payment for an order.
 *
 * @param object $order
 *
 * @return Payment
 */
function payment_ubercart_payment_create($order) {

  // Check for an existing payment;
  $pids = payment_ubercart_pids_load($order->order_id);
  $payment = $pids ? entity_load_single('payment', end($pids)) : NULL;
  $pid = $payment && payment_status_is_or_has_ancestor($payment
    ->getStatus()->status, PAYMENT_STATUS_NEW) ? $payment->pid : 0;
  $pmid = (int) str_replace('payment_ubercart_', '', $order->payment_method);
  $payment = new Payment(array(
    'context' => 'payment_ubercart',
    'currency_code' => $order->currency,
    'description' => t('Order #!order_id', array(
      '!order_id' => $order->order_id,
    )),
    'finish_callback' => 'payment_ubercart_finish',
    'method' => entity_load_single('payment_method', $pmid),
    'payment_ubercart_uc_order_id' => $order->order_id,
    'pid' => $pid,
  ));

  // Add orders, line items, and hook_uc_order() totals to the payment as line items.
  $order->order_total = uc_order_get_total($order);
  $balance = uc_payment_balance($order);
  if ($order->order_total == $balance) {
    foreach ($order->products as $product) {
      $payment
        ->setLineItem(new PaymentLineItem(array(
        'amount' => $product->price,
        'description' => $product->title,
        'quantity' => $product->qty,
        'name' => 'payment_ubercart_product_' . $product->nid,
      )));
    }
    if (is_array($order->line_items)) {
      foreach ($order->line_items as $line_item) {
        if (_uc_line_item_data($line_item['type'], 'calculated') == TRUE) {
          $payment
            ->setLineItem(new PaymentLineItem(array(
            'amount' => $line_item['amount'],
            'description' => $line_item['title'],
            'quantity' => 1,
            'name' => 'payment_ubercart_line_item_' . $line_item['line_item_id'],
          )));
        }
      }
    }
    $hook_order_total = 0;
    foreach (module_implements('uc_order') as $module) {
      $function = $module . '_uc_order';

      // $order must be passed by reference.
      if ($value = $function('total', $order, NULL) && is_numeric($value)) {
        $hook_order_total += $value;
      }
    }
    if ($hook_order_total) {
      $payment
        ->setLineItem(new PaymentLineItem(array(
        'amount' => $hook_order_total,
        'description' => 'Other',
        'quantity' => 1,
        'name' => 'payment_ubercart_hook_uc_order_total_',
        $order->order_id,
      )));
    }
  }
  else {
    $payment
      ->setLineItem(new PaymentLineItem(array(
      'amount' => $balance,
      'description' => 'Order !order_id',
      'description_arguments' => array(
        '!order_id' => $order->order_id,
      ),
      'quantity' => 1,
      'name' => 'payment_ubercart_order_balance_',
      $order->order_id,
    )));
  }
  return $payment;
}

Functions

Namesort descending Description
payment_ubercart_callback Implements Ubercart payment method callback.
payment_ubercart_checkout_form_submit Implements form submit callback.
payment_ubercart_finish Implements Payment::finish_callback.
payment_ubercart_form_alter Implements hook_form_alter().
payment_ubercart_form_configuration Implements form build callback for the configuration form.
payment_ubercart_menu Implements hook_menu().
payment_ubercart_order_id_load Load the ID of the Ubercart order a Payment belongs to.
payment_ubercart_order_id_save Save the ID of the Ubercart order a Payment belongs to.
payment_ubercart_payment_create Creates a payment for an order.
payment_ubercart_payment_line_item_info Implements hook_payment_line_item_info().
payment_ubercart_payment_status_change Implements hook_payment_status_change().
payment_ubercart_permission Implements hook_permission().
payment_ubercart_pids_load Load the PIDs of the Payments that belong to an Ubercart order.
payment_ubercart_uc_checkout_complete Implements hook_uc_checkout_complete().
payment_ubercart_uc_order Implements hook_uc_order().
payment_ubercart_uc_payment_method Implements hook_uc_payment_method().
payment_ubercart_views_api Implements hook_views_api().