You are here

function commerce_stripe_submit_form_submit in Commerce Stripe 7

Same name and namespace in other branches
  1. 7.3 commerce_stripe.module \commerce_stripe_submit_form_submit()
  2. 7.2 commerce_stripe.module \commerce_stripe_submit_form_submit()

Payment method callback: checkout form submission.

File

./commerce_stripe.module, line 478
This module provides Stripe (http://stripe.com/) payment gateway integration to Commerce. Commerce Stripe offers a PCI-compliant way to process payments straight from you Commerce shop.

Code

function commerce_stripe_submit_form_submit($payment_method, $pane_form, $pane_values, $order, $charge) {

  // If instructed to do so, try using the specified card on file.
  if (module_exists('commerce_cardonfile') && !empty($payment_method['settings']['cardonfile']) && !empty($pane_values['cardonfile']) && $pane_values['cardonfile'] !== 'new') {
    $card_data = commerce_cardonfile_load($pane_values['cardonfile']);
    if (empty($card_data) || $card_data->status == 0) {
      drupal_set_message(t('The requested card on file is no longer valid.'), 'error');
      return FALSE;
    }
    return commerce_stripe_cardonfile_charge($payment_method, $card_data, $order, $charge);
  }

  // The card is new.  Either charge and forget, or charge and save.
  if (!commerce_stripe_load_library()) {
    drupal_set_message(t('Error making the payment. Please contact shop admin to proceed.'), 'error');
    return FALSE;
  }

  // Begin assembling charge parameters.
  Stripe::setApiKey($payment_method['settings']['secret_key']);

  // Build a default description and offer modules the possibility to alter it.
  $description = t('Order Number: @order_number', array(
    '@order_number' => $order->order_number,
  ));
  $currency_code = $payment_method['settings']['stripe_currency'];
  if (isset($charge['currency_code'])) {
    $currency_code = $charge['currency_code'];
  }
  $c = array(
    'amount' => $charge['amount'],
    'currency' => $currency_code,
    'card' => $pane_values['stripe_token'],
    'description' => $description,
  );

  // Specify that we want to send a receipt email if we are configured to do so.
  if (!empty($payment_method['settings']['receipt_email'])) {
    $c['receipt_email'] = $order->mail;
  }

  // The metadata could be added via the alter below but for compatibility
  // reasons it may stay.
  commerce_stripe_add_metadata($c, $order);

  // Let modules alter the charge object to add attributes.
  drupal_alter('commerce_stripe_order_charge', $c, $order);

  // To later store the card with all required fields, carry out necessary steps before making the charge request.
  if (module_exists('commerce_cardonfile') && !empty($payment_method['settings']['cardonfile']) && !empty($pane_values['credit_card']['cardonfile_store']) && $pane_values['credit_card']['cardonfile_store']) {
    $card = _commerce_stripe_create_card($pane_values['stripe_token'], $order->uid, $payment_method);

    // If the card is not declined or otherwise is error-free, we can save it.
    if ($card && !empty($card->id)) {
      $stripe_card_id = $card->id;
      $stripe_customer_id = $card->customer;
      $c['card'] = $stripe_card_id;
      $c['customer'] = $stripe_customer_id;
      $save_card = TRUE;
    }
  }
  $transaction = commerce_payment_transaction_new('commerce_stripe', $order->order_id);
  $transaction->instance_id = $payment_method['instance_id'];
  $transaction->amount = $charge['amount'];
  $transaction->currency_code = $currency_code;

  /*
   * save the transaction as pending. this will cause an exception to be thrown
   * if the transaction cannot be saved. this prevents the scenario where it
   * can go all the way through the try/catch below with success in stripe but
   * failing to ever save the transaction. saving the transaction here also acts as
   * an early catch to prevent the stripe charge from going through if the Drupal
   * side will be unable to save it for some reason.
   */
  $transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
  if (!_commerce_stripe_commerce_payment_transaction_save($transaction)) {
    return FALSE;
  }
  try {

    // Stripe does not appreciate $0 transfers.
    if ($charge['amount'] > 0) {
      $response = Stripe_Charge::create($c);
      $transaction->remote_id = $response->id;
      $transaction->payload[REQUEST_TIME] = $response
        ->__toJSON();
      $transaction->message = t('Payment completed successfully.');
      $transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
      _commerce_stripe_commerce_payment_transaction_save($transaction);
      if (property_exists($response, 'card')) {
        $card_response = $response->card;
      }
      else {
        $card_response = $response->source;
      }
    }
    else {
      $card_response = $card;
    }
  } catch (Exception $e) {
    drupal_set_message(t('We received the following error processing your card. Please enter your information again or try a different card.'), 'error');
    drupal_set_message(check_plain($e
      ->getMessage()), 'error');
    watchdog('commerce_stripe', 'Following error received when processing card @stripe_error.', array(
      '@stripe_error' => $e
        ->getMessage(),
    ), WATCHDOG_NOTICE);
    $transaction->remote_id = $e
      ->getHttpStatus();
    $transaction->payload[REQUEST_TIME] = $e->jsonBody;
    $transaction->message = t('Card processing error: @stripe_error', array(
      '@stripe_error' => $e
        ->getMessage(),
    ));
    $transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
    _commerce_stripe_commerce_payment_transaction_save($transaction);
    return FALSE;
  }

  // If so instructed by the customer, save the card.
  if (!empty($save_card)) {
    _commerce_stripe_save_cardonfile($card_response, $order->uid, $payment_method, $pane_values['cardonfile_instance_default']);
  }
}