You are here

protected function StripeGateway::chargeCard in Ubercart Stripe 8.3

Same name and namespace in other branches
  1. 8.2 src/Plugin/Ubercart/PaymentMethod/StripeGateway.php \Drupal\uc_stripe\Plugin\Ubercart\PaymentMethod\StripeGateway::chargeCard()

Called when a credit card should be processed.

@todo Replace the return array with a typed object.

Parameters

\Drupal\uc_order\OrderInterface $order: The order that is being processed. Credit card details supplied by the user are available in $order->payment_details[].

float $amount: The amount that should be charged.

string $txn_type: The transaction type, one of the UC_CREDIT_* constants.

string $reference: (optional) The payment reference, where needed for specific transaction types.

Return value

array Returns an associative array with the following members:

  • "success": TRUE if the transaction succeeded, FALSE otherwise.
  • "message": a human-readable message describing the result of the transaction.
  • "log_payment": TRUE if the transaction should be regarded as a successful payment.
  • "uid": The user ID of the person logging the payment, or 0 if the payment was processed automatically.
  • "comment": The comment string, markup allowed, to enter in the payment log.
  • "data": Any data that should be serialized and stored with the payment.

Overrides CreditCardPaymentMethodBase::chargeCard

File

src/Plugin/Ubercart/PaymentMethod/StripeGateway.php, line 195

Class

StripeGateway
Stripe Ubercart gateway payment method.

Namespace

Drupal\uc_stripe\Plugin\Ubercart\PaymentMethod

Code

protected function chargeCard(OrderInterface $order, $amount, $txn_type, $reference = NULL) {
  $user = \Drupal::currentUser();
  if (!$this
    ->prepareApi()) {
    $result = array(
      'success' => FALSE,
      'comment' => t('Stripe API not found.'),
      'message' => t('Stripe API not found. Contact the site administrator.'),
      'uid' => $user
        ->id(),
      'order_id' => $order
        ->id(),
    );
    return $result;
  }

  // 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
    ->id() != $order
    ->getOwnerId()) {
    $stripe_customer_id = $this
      ->getStripeCustomerID($order
      ->id());
  }

  // 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
      $stripe_token = \Drupal::service('user.private_tempstore')
        ->get('uc_stripe')
        ->get('uc_stripe_token');
      if (empty($stripe_token)) {
        throw new \Exception('Token not found');
      }

      //Create the customer in stripe
      $customer = \Stripe\Customer::create(array(
        "source" => $stripe_token,
        'description' => "OrderID: {$order->id()}",
        'email' => $order
          ->getEmail(),
      ));

      // Store the customer ID in temp storage,
      // We'll pick it up later to save it in the database since we might not have a $user object at this point anyway
      \Drupal::service('user.private_tempstore')
        ->get('uc_stripe')
        ->set('uc_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
          ->id(),
        'order_id' => $order
          ->id(),
      );
      uc_order_comment_save($order
        ->id(), $user
        ->id(), $result['message']);
      \Drupal::logger('uc_stripe')
        ->notice('Failed stripe customer creation: @message', array(
        '@message' => $result['message'],
      ));
      $message = $this
        ->t('Credit card charge failed.');
      uc_order_comment_save($order
        ->id(), $user
        ->id(), $message, 'admin');
      return $result;
    }

    // Charge the customer

    //--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
        ->id(), $result['message'], 'admin');
      return $result;
    }
    try {

      // charge the Customer the amount in the order
      $currency = \Drupal::config('uc_store.settings')
        ->get('currency')['code'];
      $charge = \Stripe\Charge::create(array(
        "amount" => $amount,
        "currency" => strtolower($currency),
        "customer" => $customer->id,
        "description" => t("Order #@order_id", array(
          "@order_id" => $order
            ->id(),
        )),
      ));
      $formatted_amount = $amount / 100;
      $formatted_amount = number_format($formatted_amount, 2);
      $message = $this
        ->t('Credit card charged: @amount', [
        '@amount' => $formatted_amount,
      ]);
      uc_order_comment_save($order
        ->id(), $user
        ->id(), $message, 'admin');
      $result = array(
        'success' => TRUE,
        'comment' => $this
          ->t('Card charged, resolution code: 0022548315'),
        'message' => $this
          ->t('Credit card payment processed successfully.'),
        'uid' => $user
          ->id(),
      );
      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;
  }
}