You are here

function uc_stripe_charge in Ubercart Stripe 7.2

Same name and namespace in other branches
  1. 6.2 uc_stripe.module \uc_stripe_charge()
  2. 6 uc_stripe.module \uc_stripe_charge()
  3. 7.3 uc_stripe.module \uc_stripe_charge()
  4. 7 uc_stripe.module \uc_stripe_charge()

Generic "charge" callback that runs on checkout and via the order's "card" terminal

Parameters

$order_id:

$amount:

$data:

Return value

array

1 string reference to 'uc_stripe_charge'
uc_stripe_uc_payment_gateway in ./uc_stripe.module
Implements hook_payment_gateway to register this payment gateway

File

./uc_stripe.module, line 413
A stripe.js PCI-compliant payment gateway Forked from Bitcookie's work (thanks!) which was posted at http://bitcookie.com/blog/pci-compliant-ubercart-and-stripe-js from discussion in the uc_stripe issue queue, https://www.drupal.org/node/1467886

Code

function uc_stripe_charge($order_id, $amount, $data) {
  global $user;

  //  Load the stripe PHP API
  if (!_uc_stripe_prepare_api()) {
    $result = array(
      'success' => FALSE,
      'comment' => t('Stripe API not found.'),
      'message' => t('Stripe API not found. Contact the site administrator.'),
      'uid' => $user->uid,
      'order_id' => $order_id,
    );
    return $result;
  }
  $order = uc_order_load($order_id);
  $context = array(
    'revision' => 'formatted-original',
    'type' => 'amount',
  );
  $options = array(
    'sign' => FALSE,
    'thou' => FALSE,
    'dec' => FALSE,
    'prec' => 2,
  );

  // Format the amount in cents, which is what Stripe wants
  $amount = uc_currency_format($amount, FALSE, FALSE, FALSE);
  $stripe_customer_id = FALSE;

  // If the user running the order is not the order's owner
  // (like if an admin is processing an order on someone's behalf)
  // then load the customer ID from the user object.
  // Otherwise, make a brand new customer each time a user checks out.
  if ($user->uid != $order->uid) {
    $stripe_customer_id = _uc_stripe_get_customer_id($order->uid);
  }

  // Always Create a new customer in stripe for new orders
  if (!$stripe_customer_id) {
    try {

      // If the token is not in the user's session, we can't set up a new customer
      if (empty($_SESSION['stripe']['token'])) {
        throw new Exception('Token not found');
      }
      $stripe_token = $_SESSION['stripe']['token'];
      $shipping_info = array();
      if (!empty($order->delivery_postal_code)) {
        $shipping_info = array(
          'name' => @"{$order->delivery_first_name} {$order->delivery_last_name}",
          'phone' => @$order->delivery_phone,
        );
        $delivery_country = uc_get_country_data(array(
          'country_id' => $order->delivery_country,
        ));
        if ($delivery_country === FALSE) {
          $delivery_country = array(
            0 => array(
              'country_iso_code_2' => 'US',
            ),
          );
        }
        $shipping_info['address'] = array(
          'city' => @$order->delivery_city,
          'country' => @$delivery_country[0]['country_iso_code_2'],
          'line1' => @$order->delivery_street1,
          'line2' => @$order->delivery_street2,
          'postal_code' => @$order->delivery_postal_code,
        );
      }
      $params = array(
        "source" => $stripe_token,
        'description' => "OrderID: {$order->order_id}",
        'email' => "{$order->primary_email}",
      );
      if (!empty($shipping_info)) {
        $params['shipping'] = $shipping_info;
      }

      //Create the customer in stripe
      $customer = \Stripe\Customer::create($params);

      // Store the customer ID in the session,
      // We'll pick it up later to save it in the database since we might not have a $user object at this point anyway
      $stripe_customer_id = $_SESSION['stripe']['customer_id'] = $customer->id;
    } catch (Exception $e) {
      $result = array(
        'success' => FALSE,
        'comment' => $e
          ->getCode(),
        'message' => t("Stripe Customer Creation Failed for order !order: !message", array(
          "!order" => $order_id,
          "!message" => $e
            ->getMessage(),
        )),
        'uid' => $user->uid,
        'order_id' => $order_id,
      );
      uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
      watchdog('uc_stripe', 'Failed stripe customer creation: @message', array(
        '@message' => $result['message'],
      ));
      return $result;
    }
  }

  //  Charge the stripe customer the amount in the order

  //--Handle transactions for $0

  // Stripe can't handle transactions < $0.50, but $0 is a common value
  // so we will just return a positive result when the amount is $0.
  if ($amount == 0) {
    $result = array(
      'success' => TRUE,
      'message' => t('Payment of $0 approved'),
      'uid' => $user->uid,
      'trans_id' => md5(uniqid(rand())),
    );
    uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
    return $result;
  }

  // Charge the customer
  try {

    //Bail if there's no customer ID
    if (empty($stripe_customer_id)) {
      throw new Exception('No customer ID found');
    }
    $params = array(
      "amount" => $amount,
      "currency" => strtolower($order->currency),
      "customer" => $stripe_customer_id,
      "description" => t("Order #@order_id", array(
        "@order_id" => $order_id,
      )),
    );
    if (!empty($shipping_info)) {
      $params['shipping'] = $shipping_info;
    }

    // charge the Customer the amount in the order
    $charge = \Stripe\Charge::create($params);
    $formatted_amount = $amount / 100;
    $formatted_amount = number_format($formatted_amount, 2);
    $result = array(
      'success' => TRUE,
      'message' => t('Payment of @amount processed successfully, Stripe transaction id @transaction_id.', array(
        '@amount' => $formatted_amount,
        '@transaction_id' => $charge->id,
      )),
      'comment' => t('Stripe transaction ID: @transaction_id', array(
        '@transaction_id' => $charge->id,
      )),
      'uid' => $user->uid,
    );
    uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
    uc_order_comment_save($order_id, $user->uid, $result['message'], 'order', 'completed', FALSE);
    return $result;
  } catch (Exception $e) {
    $result = array(
      'success' => FALSE,
      'comment' => $e
        ->getCode(),
      'message' => t("Stripe Charge Failed for order !order: !message", array(
        "!order" => $order_id,
        "!message" => $e
          ->getMessage(),
      )),
      'uid' => $user->uid,
      'order_id' => $order_id,
    );
    uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
    watchdog('uc_stripe', 'Stripe charge failed for order @order, message: @message', array(
      '@order' => $order_id,
      '@message' => $result['message'],
    ));
    return $result;
  }

  //  Default / Fallback procedure to fail if the above conditions aren't met
  $result = array(
    'success' => FALSE,
    'comment' => "Stripe Gateway Error",
    'message' => "Stripe Gateway Error",
    'uid' => $user->uid,
    'order_id' => $order_id,
  );
  uc_order_comment_save($order_id, $user->uid, $result['message'], 'admin');
  watchdog('uc_stripe', 'Stripe gateway error for order @order_id', array(
    'order_id' => $order_id,
  ));
  return $result;
}