You are here

public function StripePaymentMethodController::execute in Stripe 7

Execute a payment.

Parameters

Payment $payment: The executed payment.

Return value

boolean Whether the payment was successfully executed or not.

Overrides PaymentMethodController::execute

File

stripe_payment/includes/StripePaymentMethodController.inc, line 137
Stripe Payment controller class and helper code (classes and function).

Class

StripePaymentMethodController

Code

public function execute(Payment $payment) {
  $api_key = !empty($payment->method->controller_data['keys']['mode']) ? $payment->method->controller_data['keys']['secret'] : stripe_get_key('secret');
  try {
    if (empty($payment->method_data['charge'])) {

      // Create the Stripe Charge for the payment.
      $data = array(
        'amount' => $payment
          ->totalAmount(TRUE) * 100,
        'currency' => $this->currencies[$payment->currency_code],
        'description' => t($payment->description, $payment->description_arguments),
      );

      // Charge a token...
      if (isset($payment->method_data['token'])) {
        $data['card'] = $payment->method_data['token'];
      }
      elseif (isset($payment->method_data['customer'])) {
        $data['customer'] = $payment->method_data['customer'];
      }
      elseif (isset($payment->method_data['card'])) {
        $data['card'] = $payment->method_data['card'];
      }

      // Support execution of Payment with a non-captured charge. Currently
      // not provided in the UI. Probably not usable without more work.
      if (isset($payment->method_data['capture'])) {
        $data['capture'] = $payment->method_data['capture'];
      }

      // Support for application fee. Currently not provided in the UI.
      // Probably not usable without more work.
      if (isset($payment->method_data['application_fee'])) {
        $data['capture'] = $payment->method_data['application_fee'];
      }
      $charge = \Stripe\Charge::create($data, $api_key);
      $payment
        ->setStatus($this
        ->statusFromCharge($charge));
      $payment->method_data['charge'] = $charge->id;
      watchdog('stripe_payment', 'Stripe Charge [id=@charge_id] created for Payment [pid=@pid].', array(
        '@charge_id' => $payment->method_data['charge'],
        '@pid' => $payment->pid,
      ), WATCHDOG_DEBUG, l(t('view'), "payment/{$payment->pid}", array(
        'absolute' => TRUE,
      )));
    }
    else {

      // The Payment is already linked to a Stripe Charge. This should not
      // happen. Let's update the payment status and pretend everything went
      // fine.
      watchdog('stripe_payment', 'Executing a payment already linked to a Stripe Charge [id=@charge_id].', array(
        '@charge_id' => $payment->method_data['charge'],
      ), WATCHDOG_WARNING, url("payment/{$payment->pid}"));

      // Do not use the StripePaymentMethodController::retrieveCharge() method
      // since we want to catch Stripe exception.
      $charge = \Stripe\Charge::retrieve($payment->method_data['charge'], $api_key);
      $payment
        ->setStatus($this
        ->statusFromCharge($charge));
    }

    // If we get to this LoC, then the payment execution has succeeded.
    return TRUE;
  } catch (\Stripe\Error\Card $e) {
    $payment
      ->setStatus($this
      ->statusFromCardErrorCode($e
      ->getCode()));

    // Display human-readable message.
    if ($e
      ->getMessage()) {
      drupal_set_message($e
        ->getMessage(), 'error');
    }

    // Log error.
    watchdog('stripe_payment', 'Stripe Card Error for Payment [pid=@pid]: @message.', array(
      '@pid' => $payment->pid,
      '@message' => $e
        ->getMessage(),
    ), WATCHDOG_ERROR, l(t('view'), "payment/{$payment->pid}"));
  } catch (\Stripe\Error\InvalidRequest $e) {
    $payment
      ->setStatus(new PaymentStatusItem(STRIPE_PAYMENT_STATUS_INVALID_REQUEST));
    watchdog('stripe_payment', 'Invalid Stripe Request for Payment [pid=@pid]: @message.<br/>!json_body', array(
      '@pid' => $payment->pid,
      '@message' => $e
        ->getMessage(),
      '!json_body' => '<?php ' . highlight_string(var_export($e
        ->getJsonBody(), TRUE), TRUE),
    ), WATCHDOG_ERROR, l(t('view'), "payment/{$payment->pid}"));
  } catch (\Stripe\Error\Authentication $e) {
    $payment
      ->setStatus(new PaymentStatusItem(STRIPE_PAYMENT_STATUS_AUTHENTICATION_ERROR));
    if (payment_method_access('update', $payment->method)) {
      drupal_set_message(t("Stripe Authentication Error for Payment [pid=@pid]: @message.", array(
        '@pid' => $payment->pid,
        '@message' => $e
          ->getMessage(),
      )) . t("Please review <a href='@url'>configuration</a>.", array(
        '@url' => url("admin/config/services/payment/method/{$payment->method->pmid}"),
      )), 'error');
    }
    watchdog('stripe_payment', "Stripe Authentication Error for Payment [pid=@pid]: @message.", array(
      '@pid' => $payment->pid,
      '@message' => $e
        ->getMessage(),
    ), WATCHDOG_ERROR, l(t('edit'), "admin/config/services/payment/method/{$payment->method->pmid}"));
  } catch (\Stripe\Error\Api $e) {
    $payment
      ->setStatus(new PaymentStatusItem(STRIPE_PAYMENT_STATUS_API_ERROR));
    watchdog('stripe_payment', 'Stripe API Error for Payment [pid=@pid]: @message.<br/>!json_body', array(
      '@pid' => $payment->pid,
      '@message' => $e
        ->getMessage(),
      '!json_body' => '<?php ' . highlight_string(var_export($e
        ->getJsonBody(), TRUE), TRUE),
    ), WATCHDOG_ERROR, l(t('view'), "payment/{$payment->pid}"));
  } catch (Exception $e) {
    $payment
      ->setStatus(new PaymentStatusItem(STRIPE_PAYMENT_STATUS_UNKNOWN_ERROR));
    watchdog('stripe_payment', 'Unknown Exception for Payment [pid=@pid]: @message.<br/><pre>!trace</pre>', array(
      '@pid' => $payment->pid,
      '@message' => $e
        ->getMessage(),
      '!trace' => $e
        ->getTraceAsString(),
    ), WATCHDOG_ERROR, l(t('view'), "payment/{$payment->pid}"));
  }

  // The only way to reach this LoC is to exit the try block with an
  // exception. Thus, the payment execution has failed.
  return FALSE;
}