View source  
  <?php
define('STRIPE_API_LATEST_TESTED', '2017-08-15');
define('STRIPE_API_ACCOUNT_DEFAULT', 'Account Default');
define('STRIPE_API_VERSION_CUSTOM', 'Custom');
function stripe_help($path, $arg) {
  if ($path == 'admin/config/stripe/admin/keys') {
    $output = '<ol>';
    $output .= '<li>' . t('Enter the API keys you get from your <a href="@url">Stripe account page</a>.', array(
      '@url' => 'https://manage.stripe.com/account',
    )) . '</li>';
    $output .= '<li>' . t('Use the radio buttons to choose which API Key should be used with this site.') . '</li>';
    $output .= '<li>' . t('After designating an API Key, you might want to try out <a href="@url">the test form</a>.', array(
      '@url' => '/admin/config/stripe/test',
    )) . '</li>';
    $output .= '</ol>';
    return $output;
  }
  if ($path == 'admin/config/stripe/admin/test') {
    return '<p>' . t('This form is to test responses from Stripe. The default values are accepted by Stripe for testing purposes. Before you can use this form, you should <a href="@url">designate an active API Key</a>.', array(
      '@url' => '/admin/config/stripe/keys',
    )) . '</p>';
  }
}
function stripe_permission() {
  return array(
    'administer stripe' => array(
      'title' => t('Administer the Stripe module'),
      'description' => t('Allows access to configure API Keys and to the test form.'),
    ),
  );
}
function stripe_menu() {
  $items['admin/config/stripe'] = array(
    'title' => 'Stripe Payment Gateway',
    'description' => 'Configuration, and testing',
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array(
      'administer stripe',
    ),
    'position' => 'right',
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );
  $items['admin/config/stripe/settings'] = array(
    'title' => 'Stripe Settings',
    'description' => 'API keys and other general Stripe settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'stripe_admin_keys',
    ),
    'access arguments' => array(
      'administer stripe',
    ),
    'file' => 'stripe.admin.inc',
  );
  $items['admin/config/stripe/test'] = array(
    'title' => 'Test form',
    'description' => 'A form for testing Stripe responses.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'stripe_admin_test',
    ),
    'access arguments' => array(
      'administer stripe',
    ),
    'file' => 'stripe.test.inc',
  );
  $items['stripe/webhooks'] = array(
    'title' => 'Stripe Webhooks',
    'description' => 'Handler for incoming Stripe Webhook requests.',
    'page callback' => 'stripe_webhooks_callback',
    'delivery callback' => 'stripe_webhook_response_output',
    'access callback' => TRUE,
    'file' => 'stripe.pages.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}
function stripe_element_info() {
  return array(
    'stripe_payment' => array(
      '#process' => array(
        'stripe_element_process',
      ),
      '#cardholder_name' => TRUE,
      '#address' => FALSE,
      '#cvc' => TRUE,
      '#publishable_key' => NULL,
    ),
  );
}
function stripe_element_process($element, $form_state, $complete_form) {
  $live = variable_get('stripe_key_status', 'test') === 'live';
  $element['#type'] = 'fieldset';
  $element += element_info('fieldset');
  $element['#tree'] = TRUE;
  $element['stripe_token'] = array(
    '#type' => 'hidden',
    '#element_validate' => array(
      'stripe_token_element_validate',
    ),
    '#attributes' => array(
      'data-stripe' => 'token',
    ),
  );
  if ($element['#cardholder_name']) {
    if (is_bool($element['#cardholder_name']) && $element['#cardholder_name'] == TRUE) {
      
      $element['name'] = array(
        '#type' => 'textfield',
        '#title' => t('Name on card'),
        '#description' => t('Name of the cardholder as displayed on the card.'),
        '#attributes' => array(
          'data-stripe' => 'name',
          'autocomplete' => 'cc-name',
          'placeholder' => variable_get('stripe_subscription_placeholder_name', 'John Doe'),
        ),
        '#element_validate' => array(
          'stripe_element_validate_empty',
        ),
        '#pre_render' => array(
          'stripe_element_remove_name',
        ),
      );
    }
    elseif (is_array($element['#cardholder_name'])) {
      
      $cardholder_name_element =& drupal_array_get_nested_value($form, $element['#cardholder_name']);
      if ($cardholder_name_element) {
        $cardholder_name_element['#attributes']['data-stripe'] = 'name';
        $cardholder_name_element['#pre_render'][] = 'stripe_element_remove_name';
      }
    }
  }
  if (!empty($element['#address'])) {
    require_once 'includes/locale.inc';
    if (is_numeric($element['#address']) && $element['#address'] == TRUE) {
      if ($element['#address_option'] == 1) {
        $element['address'] = array(
          '#type' => 'textfield',
          '#title' => t('Billing Street Address'),
          '#attributes' => array(
            'data-stripe' => 'address_line1',
          ),
          
          '#pre_render' => array(
            'stripe_element_remove_name',
          ),
          '#description' => t('Street address associated with the credit card.'),
        );
      }
      else {
        
        $element['address'] = array(
          '#type' => 'fieldset',
          'thoroughfare' => array(
            '#type' => 'textfield',
            '#title' => t('Street Address Line 1'),
            '#attributes' => array(
              'data-stripe' => 'address_line1',
            ),
            
            '#pre_render' => array(
              'stripe_element_remove_name',
            ),
          ),
          'premise' => array(
            '#type' => 'textfield',
            '#title' => t('Street Address Line 2'),
            '#attributes' => array(
              'data-stripe' => 'address_line2',
            ),
            '#pre_render' => array(
              'stripe_element_remove_name',
            ),
          ),
          'locality' => array(
            '#type' => 'textfield',
            '#title' => t('City'),
            '#attributes' => array(
              'data-stripe' => 'address_city',
            ),
            '#pre_render' => array(
              'stripe_element_remove_name',
            ),
          ),
          'administrative_area' => array(
            '#type' => 'textfield',
            '#title' => t('State/Province'),
            '#attributes' => array(
              'data-stripe' => 'address_state',
            ),
            '#pre_render' => array(
              'stripe_element_remove_name',
            ),
          ),
          'postal_code' => array(
            '#type' => 'textfield',
            '#title' => t('Postal code'),
            '#attributes' => array(
              'data-stripe' => 'address_zip',
            ),
            '#pre_render' => array(
              'stripe_element_remove_name',
            ),
          ),
          'country' => array(
            '#type' => 'select',
            '#title' => t('Country'),
            '#attributes' => array(
              'data-stripe' => 'address_country',
            ),
            '#options' => country_get_list(),
            '#default_value' => variable_get('stripe_default_country', 'US'),
            '#pre_render' => array(
              'stripe_element_remove_name',
            ),
          ),
        );
      }
    }
    elseif (is_array($element['#address'])) {
      
    }
  }
  
  $element['card'] = array(
    '#type' => 'item',
    '#markup' => '<label for="card-element">Card number</label><div autocomplete="cc-number" data-stripe="number" id="card-element"></div>',
  );
  $element['card_errors'] = array(
    '#type' => 'item',
    '#markup' => '<div data-stripe-errors="number" class="stripe-errors form-text" id="card-errors"></div>',
  );
  
  $element['#attached']['js'][] = drupal_get_path('module', 'stripe') . '/stripe.js';
  
  $element['#attributes']['data-stripe-key'] = !empty($element['#publishable_key']) ? $element['#publishable_key'] : variable_get('stripe_publishable', '');
  
  drupal_add_js(array(
    'stripe' => array(
      'publicKey' => variable_get('stripe_publishable', ''),
    ),
  ), 'setting');
  return $element;
}
function stripe_token_element_validate($element, $form_state, $form) {
  if (empty($element['#value']) && isset($element['#access']) && $element['#access']) {
    form_error($element, t('There was a problem processing your payment.'));
  }
}
function stripe_element_validate_empty($element, $form_state, $form) {
  static $logged = FALSE;
  
  if (!empty($element['#value']) && !$logged) {
    
    form_error($element, t('There was a problem processing your payment.
      For your own protection, it is recommended you do NOT attempt to re-enter
      your payment information.'));
    
    $message = 'Credit Card information is being posted to your server. ' . 'Please disable Stripe module immediately and submit a bug ' . 'report at http://drupal.org/node/add/project-issue/stripe.';
    watchdog('stripe', $message, NULL, WATCHDOG_ALERT);
    $logged = TRUE;
  }
}
function stripe_element_remove_name($element) {
  $name_pattern = '/\\sname\\s*=\\s*[\'"]?' . preg_quote($element['#name']) . '[\'"]?/';
  return preg_replace($name_pattern, '', $content);
}
function tg_stripe_live() {
  
  $secret = variable_get('stripe_secret');
  if (substr($secret, 0, 7) == 'sk_live') {
    return TRUE;
  }
  return FALSE;
}
function stripe_get_publishable_key() {
  $status = variable_get('stripe_key_status', 'test');
  $pub_key_name = 'stripe_' . $status . '_publishable';
  $pub_key = variable_get($pub_key_name, '');
  return $pub_key;
}
function stripe_libraries_info() {
  $libraries['stripe-php'] = array(
    'name' => 'Stripe Payment API PHP Library',
    'vendor url' => 'https://stripe.com/docs/libraries',
    'download url' => 'https://stripe.com/docs/libraries#php-library',
    'version arguments' => array(
      'file' => 'VERSION',
      'pattern' => '/((\\d+)\\.(\\d+)\\.(\\d+))/',
      'lines' => 1,
    ),
    'files' => array(
      'php' => array(
        'init.php',
      ),
    ),
    'callbacks' => array(
      'post-load' => array(
        'stripe_libraries_postload_callback',
      ),
    ),
  );
  return $libraries;
}
function stripe_load_library() {
  $secret_key = variable_get('stripe_secret', '');
  
  if (substr($secret_key, 0, 2) == 'pk') {
    _stripe_error('A publishable key was entered instead of a secret key');
    $library['loaded'] = FALSE;
    return FALSE;
  }
  if (empty($secret_key)) {
    _stripe_error('You must enter a secret key to connect to Stripe.');
    $library['loaded'] = FALSE;
    return FALSE;
  }
  $library = libraries_load('stripe-php');
  if (!$library || empty($library['loaded'])) {
    watchdog('stripe', 'Could not load Stripe PHP Library', WATCHDOG_CRITICAL);
    drupal_set_message('There was a problem loading the Stripe Library.', 'error');
    return FALSE;
  }
  return $library;
}
function stripe_libraries_postload_callback($library, $version = NULL, $variant = NULL) {
  $secret_key = variable_get('stripe_secret', '');
  
  try {
    \Stripe\Stripe::setApiKey($secret_key);
  } catch (\Stripe\Error\RateLimit $e) {
    
    _stripe_error('Stripe', 'Stripe RateLimit was hit.');
  } catch (\Stripe\Error\InvalidRequest $e) {
    
    _stripe_error(t('Invalid Stripe request: %msg', array(
      '%msg' => $e
        ->getMessage(),
    )));
  } catch (\Stripe\Error\Authentication $e) {
    
    _stripe_error(t('Could not authenticate to Stripe. Reason: %msg', array(
      '%msg' => $e
        ->getMessage(),
    )));
  } catch (\Stripe\Error\ApiConnection $e) {
    
    _stripe_error(t('Could not connect to Stripe. Reason: %msg', array(
      '%msg' => $e
        ->getMessage(),
    )));
  } catch (\Stripe\Error\Base $e) {
    
    _stripe_error(t('Stripe error: %msg', array(
      '%msg' => $e
        ->getMessage(),
    )));
  } catch (Exception $e) {
    
    _stripe_error(t('Could not load Stripe library. Reason: %msg', array(
      '%msg' => $e
        ->getMessage(),
    )));
  }
  if (!empty($library['loaded'])) {
    
    $api_version = variable_get('stripe_api_version', STRIPE_API_ACCOUNT_DEFAULT);
    if ($api_version != STRIPE_API_ACCOUNT_DEFAULT) {
      if ($api_version == STRIPE_API_VERSION_CUSTOM) {
        $api_version = check_plain(variable_get('stripe_api_version_custom'));
      }
      try {
        \Stripe\Stripe::setApiVersion($api_version);
      } catch (\Stripe\Error\InvalidRequest $e) {
        _stripe_error(t('Stripe InvalidRequest Exception: %error', array(
          '%error' => $e
            ->getMessage(),
        )));
      } catch (\Stripe\Error\Authentication $e) {
        _stripe_error(t('Stripe setApiVersion Exception: %error', array(
          '%error' => $e
            ->getMessage(),
        )));
      }
    }
  }
  return $library;
}
function stripe_get_key($type = NULL, $set = NULL) {
  $keys = drupal_static(__FUNCTION__, array());
  if ($set === NULL) {
    $set = variable_get('stripe_key_status', 'test');
  }
  if (empty($keys[$set])) {
    $keys[$set] = array(
      'secret' => variable_get("stripe_{$set}_secret", ''),
      'publishable' => variable_get("stripe_{$set}_publishable", ''),
    );
  }
  return $type === NULL ? $keys[$set] : (isset($keys[$set][$type]) ? $keys[$set][$type] : NULL);
}
function stripe_cron() {
  $expiration_day = variable_get('stripe_log_webhooks_expire_days', 30) + 1;
  
  db_query("DELETE FROM {stripe_webhook_events} WHERE processed >= :time", array(
    ':time' => strtotime($expiration_day . ' days'),
  ));
}
function stripe_webhook_response_output($var = NULL) {
  drupal_add_http_header('Content-Type', 'text/plain');
}
function stripe_stripe_params($object = NULL) {
  $params = array();
  return $params;
}
function stripe_page_build() {
  drupal_add_js('https://js.stripe.com/v2', 'external');
  drupal_add_js('https://js.stripe.com/v3', 'external');
}
function stripe_payment_currencies() {
  if (stripe_load_library()) {
    try {
      $info = \Stripe\Account::retrieve();
      $country_spec = \Stripe\CountrySpec::retrieve($info->country);
      $supported_currencies = $country_spec->supported_payment_currencies;
      return $supported_currencies;
    } catch (Exception $e) {
      return array();
    }
  }
}
function _stripe_error($message) {
  if (user_access('administer stripe')) {
    drupal_set_message($message, 'error');
  }
  watchdog('Stripe', $message, WATCHDOG_ERROR);
}