diff --git a/payment/uc_payment/uc_payment.module b/payment/uc_payment/uc_payment.module index 2527560..adddc12 100644 --- a/payment/uc_payment/uc_payment.module +++ b/payment/uc_payment/uc_payment.module @@ -235,6 +235,50 @@ function uc_payment_uc_order_state() { } /** + * Implements hook_uc_payment_method(). + */ +function uc_payment_uc_payment_method() { + $methods['free_order'] = array( + 'name' => t('Free order'), + 'title' => t('No payment required'), + 'desc' => t('Allow customers with !zero order totals to checkout without paying.', array('!zero' => uc_currency_format(0))), + 'callback' => 'uc_payment_method_free_order', + 'checkout' => TRUE, + 'no_gateway' => TRUE, + 'weight' => 0, + ); + + return $methods; +} + +/** + * Payment method callback for free orders. + * + * @see uc_payment_uc_payment_method() + */ +function uc_payment_method_free_order($op, &$order) { + switch ($op) { + case 'cart-details': + return array( + '#markup' => t('Continue with checkout to complete your order.'), + ); + + case 'order-valid': + return $order->order_total < 0.01; + + case 'order-submit': + if ($order->order_total >= 0.01) { + return array(array( + 'pass' => FALSE, + 'message' => t('We cannot process your order without payment.'), + )); + } + + uc_payment_enter($order->order_id, 'free_order', 0, 0, NULL, t('Checkout completed for a free order.')); + } +} + +/** * Returns a formatted list of line items for an order total preview. * * @param $return diff --git a/payment/uc_payment/uc_payment_checkout_pane.inc b/payment/uc_payment/uc_payment_checkout_pane.inc index 35a280d..d123a19 100644 --- a/payment/uc_payment/uc_payment_checkout_pane.inc +++ b/payment/uc_payment/uc_payment_checkout_pane.inc @@ -31,6 +31,13 @@ function uc_checkout_pane_payment($op, &$order, $form = NULL, &$form_state = NUL $options = array(); foreach (_uc_payment_method_list() as $id => $method) { + // If the 'order-valid' callback returns FALSE, skip this method. + $func = $method['callback']; + if (function_exists($func) && $func('order-valid', $order) === FALSE) { + continue; + } + + // If Rules returns FALSE, skip this method. $set = rules_config_load('uc_payment_method_' . $method['id']); if ($set && !$set->execute($order)) { continue;