You are here

function uc_stripe_process in Ubercart Stripe 6

Same name and namespace in other branches
  1. 6.2 uc_stripe.module \uc_stripe_process()
  2. 7.3 uc_stripe.module \uc_stripe_process()
  3. 7.2 uc_stripe.module \uc_stripe_process()

Process the recurring fee transaction.

1 string reference to 'uc_stripe_process'
uc_stripe_recurring_info in ./uc_stripe.module
Implements hook_recurring_info().

File

./uc_stripe.module, line 386
A module used for Stripe. Developed by Victor Quinn for Health for Hackers (http://www.healthforhackers.com)

Code

function uc_stripe_process($order, &$fee) {
  global $user;
  $plan_id = str_replace('/', '_', $fee->data['model']);
  $customer_name = $order->billing_first_name . ' ' . $order->billing_last_name;

  // Load the Stripe API and set the API key.
  if (!_uc_stripe_load_api()) {
    return FALSE;
  }

  // First, check to see that a sku is tied to this recurring fee item.
  if (!isset($fee->data['model'])) {
    watchdog('uc_stripe', "You must set the applicable sku in the Recurring Fee setup. This must be the same as the Plan name in Stripe.");
    return FALSE;
  }
  try {

    // Then ensure it matches one of the plans in Stripe.
    $plans = Stripe_Plan::all();
  } catch (Exception $e) {
    watchdog('uc_stripe', "There was a problem loading the plans from Stripe: %error", array(
      '%error' => $e
        ->getMessage(),
    ), WATCHDOG_ERROR);
    return FALSE;
  }
  $match = FALSE;
  foreach ($plans['data'] as $plan) {
    if ($plan
      ->__get('id') == $plan_id) {
      $match = TRUE;
    }
  }

  // If no match, this recurring item doesn't correlate to any
  // Stripe subscription plan.
  if (!$match) {
    watchdog('uc_stripe', "The sku for the Recurring Fee object doesn't match any Stripe plans.");
    return FALSE;
  }

  // Tricky to find the nid of the recurring product from a cart of
  // other things. Note, this will only work with a single
  // subscription item in the cart. If more, it throws an error.
  foreach ($order->products as $product) {
    if (db_result(db_query("SELECT nid FROM {uc_product_features} WHERE fid = 'recurring' AND nid = %d", $product->nid))) {
      $nid[] = $product->nid;
    }
  }
  if (count($nid) > 1) {
    watchdog('uc_stripe', "Multiple subscriptions in cart. User %user warned.", array(
      '%user' => $user->name,
    ));
    drupal_set_message(t("Currently, only one subscription may be purchased at one time. Please purchase one subscription, then purchase another as a separate order. We apologize for the inconvenience."), 'error');
    return FALSE;
  }
  $nid = $nid[0];

  // Pad the expiration date with a 0 for single digit months.
  if (drupal_strlen($order->payment_details['cc_exp_month']) == 1) {
    $order->payment_details['cc_exp_month'] = '0' . $order->payment_details['cc_exp_month'];
  }

  // Pad the expiration date with a 0 for single digit months.
  if (drupal_strlen($order->payment_details['cc_exp_month']) == 1) {
    $order->payment_details['cc_exp_month'] = '0' . $order->payment_details['cc_exp_month'];
  }

  // Set up minimum fields.
  $data = array(
    'plan' => $plan_id,
    'card' => array(
      'number' => $order->payment_details['cc_number'],
      'exp_month' => $order->payment_details['cc_exp_month'],
      'exp_year' => $order->payment_details['cc_exp_year'],
      'name' => $order->billing_first_name . ' ' . $order->billing_last_name,
      'address_line1' => $order->billing_street1,
      'address_zip' => $order->billing_postal_code,
      'address_state' => uc_get_zone_code($order->billing_zone),
    ),
  );

  // CVV Number (if enabled).
  if (variable_get('uc_credit_cvv_enabled', TRUE)) {
    $data['card']['cvc'] = $order->payment_details['cc_cvv'];
  }

  // This user is not logged in, so create new subscription.
  $create_new = FALSE;
  if ($user->uid == 0) {
    $create_new = TRUE;
  }
  else {

    // Retrieve existing subscriptions.
    if (db_result(db_query("SELECT * FROM {uc_recurring_stripe} WHERE uid = %d", $user->uid))) {
      $result = db_query("SELECT * FROM {uc_recurring_stripe} WHERE uid = %d", $user->uid);
      while ($sub = db_fetch_object($result)) {
        if ($sub->plan_id == $plan_id) {
          $customer_id = $sub->customer_id;
        }
      }
      if ($customer_id) {
        try {
          $customer = Stripe_Customer::retrieve($customer_id);
        } catch (Exception $e) {
          drupal_set_message(t("Unable to retrieve customer subscription"), 'error');
          watchdog('uc_stripe', "Unable to retrieve customer subscription for %customer_id", array(
            '%customer_id' => $customer_id,
          ));
          return FALSE;
        }
      }
      else {
        $create_new = TRUE;
      }
    }
    else {
      $create_new = TRUE;
    }
  }

  // Create a new customer object if necessary.
  if ($create_new) {
    $data['email'] = $order->primary_email;
    $data['description'] = $customer_name;
    try {
      $customer = Stripe_Customer::create($data);

      // Write this customer record to our database.
      $cust_record->uid = $user->uid;
      $cust_record->order_id = $order->order_id;
      $cust_record->customer_id = $customer
        ->__get('id');
      $cust_record->plan_id = $plan_id;
      $cust_record->nid = $nid;
      $cust_record->active = 1;
      drupal_write_record('uc_recurring_stripe', $cust_record);
    } catch (Exception $e) {
      drupal_set_message(t("Unable to create new customer object: @message", array(
        "@message",
        $e
          ->getMessage(),
      )), 'error');
      watchdog('uc_stripe', "Unable to create new customer object for %customer_name", array(
        '%customer_name' => $customer_name,
      ));
      return FALSE;
    }
  }
  try {
    unset($data['email']);
    unset($data['description']);
    $customer
      ->updateSubscription($data);
    $customer->description = $customer_name;
    $customer
      ->save();
    $rfid = db_result(db_query("SELECT rfid FROM {uc_recurring_stripe} WHERE customer_id = '%s'", $customer
      ->__get('id')));
    $cust_record->uid = $user->uid;
    $cust_record->order_id = $order->order_id;
    $cust_record->customer_id = $customer
      ->__get('id');
    $cust_record->plan_id = $plan_id;
    $cust_record->nid = $nid;
    $cust_record->active = 1;
    drupal_write_record('uc_recurring_stripe', $cust_record);
    $result = array(
      'success' => TRUE,
      'message' => t('Recurring Payment set up for this transaction.'),
      'uid' => $user->uid,
    );
    watchdog('uc_stripe', "Recurring payment created for %customer_name for %plan.", array(
      '%customer_name' => $customer_name,
      '%plan' => $plan_id,
    ));
  } catch (Exception $e) {
    watchdog('uc_stripe', "There was a problem creating the subscription for %customer_name. \n\n%error", array(
      '%customer_name' => $customer_name,
      '%error' => $e
        ->getMessage(),
    ));
    $result = array(
      'success' => FALSE,
      'comment' => $e
        ->getCode(),
      'message' => t("Recurring payment failed. !message", array(
        "!message" => $e
          ->getMessage(),
      )),
      'uid' => $user->uid,
      'order_id' => $order_id,
    );
    uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
    return FALSE;
  }
  uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
  return TRUE;
}