View source
<?php
define('COMMERCE_STRIPE_DEFAULT_INTEGRATION', 'elements');
define('COMMERCE_STRIPE_API_LATEST_TESTED', '2017-08-15');
define('COMMERCE_STRIPE_API_ACCOUNT_DEFAULT', 'Account Default');
define('COMMERCE_STRIPE_API_VERSION_CUSTOM', 'Custom');
function commerce_stripe_page_build(&$page) {
drupal_add_js('https://js.stripe.com/v3', 'external');
}
function commerce_stripe_menu() {
$items = array();
$items['admin/commerce/orders/%commerce_order/payment/%commerce_payment_transaction/commerce-stripe-refund'] = array(
'title' => 'Refund',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_stripe_refund_form',
3,
5,
),
'access callback' => 'commerce_stripe_return_access',
'access arguments' => array(
3,
5,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'context' => MENU_CONTEXT_INLINE,
'weight' => 1,
'file' => 'includes/commerce_stripe.admin.inc',
);
$items['admin/commerce/orders/%commerce_order/payment/%commerce_payment_transaction/stripe-capture'] = array(
'title' => 'Capture',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_stripe_capture_form',
3,
5,
),
'access callback' => 'commerce_stripe_capture_access',
'access arguments' => array(
3,
5,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'context' => MENU_CONTEXT_INLINE,
'weight' => 2,
'file' => 'includes/commerce_stripe.admin.inc',
);
$items['admin/commerce/orders/%commerce_order/payment/%commerce_payment_transaction/stripe-void'] = array(
'title' => 'Void',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'commerce_stripe_void_form',
3,
5,
),
'access callback' => 'commerce_stripe_void_access',
'access arguments' => array(
3,
5,
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'context' => MENU_CONTEXT_INLINE,
'weight' => 2,
'file' => 'includes/commerce_stripe.admin.inc',
);
return $items;
}
function commerce_stripe_libraries_info() {
return array(
'stripe-php' => array(
'name' => 'Stripe API Client Library for PHP',
'vendor url' => 'https://stripe.com/',
'download url' => 'https://github.com/stripe/stripe-php',
'dependencies' => array(),
'version arguments' => array(
'file' => 'VERSION',
'pattern' => '/((\\d+)\\.(\\d+)\\.(\\d+))/',
'lines' => 1,
'cols' => 12,
),
'files' => array(
'php' => array(
'init.php',
),
),
'callbacks' => array(
'post-load' => array(
'commerce_stripe_libraries_postload_callback',
),
),
),
);
}
function commerce_stripe_libraries_postload_callback($library, $version = NULL, $variant = NULL) {
if (!empty($library['loaded'])) {
$payment_method = commerce_payment_method_instance_load('commerce_stripe|commerce_payment_commerce_stripe');
$settings = $payment_method['settings'];
if (module_exists('commerce_stripe_connect') && !empty($settings['use_connected_account']) && $settings['use_connected_account'] == 'site account') {
$connect_settings = commerce_stripe_connect_get_settings();
$settings['secret_key'] = $connect_settings['connected_secret_key'];
$settings['public_key'] = $connect_settings['connected_public_key'];
}
if (!isset($settings['secret_key']) || empty($settings['secret_key'])) {
drupal_set_message(t('Stripe secret and public key are required in order to use Stripe payment method. See README.txt for instructions.'), 'warning');
$link = l(t('configured here'), 'admin/commerce/config/payment-methods');
drupal_set_message(t('Settings required for the Stripe payment method can be !link.', array(
'!link' => $link,
)), 'warning');
return;
}
\Stripe\Stripe::setApiKey(trim($settings['secret_key']));
if (!isset($settings['commerce_stripe_api_version'])) {
$api_version = COMMERCE_STRIPE_API_LATEST_TESTED;
}
else {
$api_version = $settings['commerce_stripe_api_version'];
}
if ($api_version != COMMERCE_STRIPE_API_ACCOUNT_DEFAULT) {
if ($api_version == COMMERCE_STRIPE_API_VERSION_CUSTOM) {
$api_version = check_plain($settings['commerce_stripe_api_version_custom']);
}
try {
\Stripe\Stripe::setApiVersion($api_version);
} catch (\Stripe\Error\InvalidRequest $e) {
watchdog('stripe', 'Stripe setApiVersion Exception: %error', array(
'%error' => $e
->getMessage(),
), WATCHDOG_ERROR);
drupal_set_message(t('Stripe API Error: :error', array(
':error' => $e
->getMessage(),
)), 'error');
}
}
}
}
function commerce_stripe_commerce_payment_method_info() {
$payment_methods = array();
$payment_methods['commerce_stripe'] = array(
'title' => t('Stripe'),
'short_title' => t('Stripe'),
'display_title' => t('Credit card'),
'description' => t('Stripe payment gateway'),
'active' => FALSE,
'terminal' => TRUE,
'offsite' => FALSE,
);
return $payment_methods;
}
function commerce_stripe_return_access($order, $transaction) {
if ($transaction->payment_method != 'commerce_stripe') {
return FALSE;
}
if (!empty($transaction->data['stripe']['amount_refunded'])) {
if ($transaction->data['stripe']['amount_refunded'] >= $transaction->amount) {
return FALSE;
}
}
if (!empty($transaction->data['stripe']['stripe_refund'])) {
return FALSE;
}
if (isset($transaction->remote_status) && $transaction->remote_status == 'AUTH_ONLY') {
return FALSE;
}
return commerce_payment_transaction_access('update', $transaction);
}
function commerce_stripe_settings_form($settings) {
$settings = (array) $settings + commerce_stripe_default_settings();
$form = array();
$currencies = commerce_currencies(TRUE);
$currency_list = array();
$supported_currencies = commerce_stripe_payment_currencies();
foreach ($currencies as $currency_code => $currency) {
if (in_array(strtolower($currency_code), $supported_currencies)) {
$currency_list[$currency_code] = $currency['name'];
}
}
$form['public_key'] = array(
'#type' => 'textfield',
'#title' => t('Publishable Key'),
'#description' => t('Publishable API Key. Get your key from https://stripe.com/'),
'#default_value' => $settings['public_key'],
'#required' => TRUE,
);
$form['secret_key'] = array(
'#type' => 'textfield',
'#title' => t('Secret Key'),
'#description' => t('Secret API Key. Get your key from https://stripe.com/'),
'#default_value' => $settings['secret_key'],
'#required' => TRUE,
);
if (module_exists('commerce_stripe_connect')) {
$connect_settings = commerce_stripe_connect_get_settings();
if (!empty($connect_settings['connected_account_id'])) {
$form['use_connected_account'] = array(
'#type' => 'radios',
'#title' => t('API Credentials'),
'#options' => array(
'none' => t('Input API credentials for this payment method.'),
'site account' => t('Use the site-wide account identified via Stripe Connect.'),
),
'#default_value' => $settings['use_connected_account'],
'#weight' => -10,
);
unset($form['secret_key']['#required']);
$form['secret_key']['#states'] = array(
'visible' => array(
':input[name="parameter[payment_method][settings][payment_method][settings][use_connected_account]"]' => array(
'value' => 'none',
),
),
'required' => array(
':input[name="parameter[payment_method][settings][payment_method][settings][use_connected_account]"]' => array(
'value' => 'none',
),
),
);
unset($form['public_key']['#required']);
$form['public_key']['#states'] = array(
'visible' => array(
':input[name="parameter[payment_method][settings][payment_method][settings][use_connected_account]"]' => array(
'value' => 'none',
),
),
'required' => array(
':input[name="parameter[payment_method][settings][payment_method][settings][use_connected_account]"]' => array(
'value' => 'none',
),
),
);
}
}
$form['stripe_currency'] = array(
'#type' => 'select',
'#title' => t('Currency'),
'#options' => $currency_list,
'#description' => t('Select the currency that you are using.'),
'#default_value' => !empty($settings['stripe_currency']) ? $settings['stripe_currency'] : 'USD',
);
$form['display_title'] = array(
'#type' => 'textfield',
'#title' => t('Payment method display title'),
'#description' => t('Payment method display title'),
'#default_value' => !empty($settings['display_title']) ? $settings['display_title'] : t('Stripe'),
);
$form['receipt_email'] = array(
'#type' => 'checkbox',
'#title' => t('Email receipts'),
'#description' => t('When selected, customers will receive email receipts from Stripe.'),
'#default_value' => isset($settings['receipt_email']) ? $settings['receipt_email'] : 0,
);
$form['integration_type'] = array(
'#type' => 'select',
'#title' => t('Integration type'),
'#description' => t('Choose Stripe integration method: Stripe.js makes it easy to collect credit card (and other similarly sensitive) details without having the information touch your server. Checkout is an embeddable iframe for desktop, tablet, and mobile devices.'),
'#options' => array(
'elements' => t('Elements'),
'stripejs' => t('stripe.js'),
'checkout' => t('checkout'),
),
'#default_value' => !empty($settings['integration_type']) ? $settings['integration_type'] : COMMERCE_STRIPE_DEFAULT_INTEGRATION,
);
$form['checkout_settings'] = array(
'#type' => 'fieldset',
'#title' => t('These settings are specific to "checkout" integration type.'),
'#states' => array(
'visible' => array(
':input[name$="[integration_type]"]' => array(
'value' => 'checkout',
),
),
),
);
$form['checkout_settings']['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('The name of your company or website.'),
'#default_value' => isset($settings['checkout_settings']['name']) ? $settings['checkout_settings']['name'] : variable_get('site_name', ''),
);
$form['checkout_settings']['description'] = array(
'#type' => 'textfield',
'#title' => t('Description'),
'#description' => t('A description of the product or service being purchased.'),
'#default_value' => isset($settings['checkout_settings']['description']) ? $settings['checkout_settings']['description'] : '',
);
$form['checkout_settings']['image'] = array(
'#type' => 'managed_file',
'#title' => t('Image'),
'#progress_message' => t('Please wait...'),
'#progress_indicator' => 'bar',
'#description' => t('Click "Browse..." to select an image to upload.'),
'#required' => FALSE,
'#upload_location' => 'public://commerce_stripe/checkout_images/',
'#default_value' => isset($settings['checkout_settings']['image']) ? $settings['checkout_settings']['image']['fid'] : '',
'#element_validate' => array(
'commerce_stripe_settings_form_image_validate',
),
);
$form['checkout_settings']['panelLabel'] = array(
'#type' => 'textfield',
'#title' => t('Payment button label'),
'#description' => t('The label of the payment button in the Checkout form (e.g. "Subscribe", "Pay {{amount}}", etc.). If you include {{amount}}, it will be replaced by the provided amount. Otherwise, the amount will be appended to the end of your label.'),
'#default_value' => isset($settings['checkout_settings']['panelLabel']) ? $settings['checkout_settings']['panelLabel'] : "Pay {{amount}}",
);
$form['checkout_settings']['zipCode'] = array(
'#type' => 'checkbox',
'#title' => t('ZIP code verification'),
'#description' => t('Specify whether Checkout should validate the billing ZIP code.'),
'#default_value' => isset($settings['checkout_settings']['zipCode']) ? $settings['checkout_settings']['zipCode'] : 0,
);
$form['checkout_settings']['allowRememberMe'] = array(
'#type' => 'checkbox',
'#title' => t('Show "Remember Me" option'),
'#description' => t('Specify whether Checkout should allow the user to store their credit card for faster checkout.'),
'#default_value' => isset($settings['checkout_settings']['allowRememberMe']) ? $settings['checkout_settings']['allowRememberMe'] : 0,
);
$form['checkout_settings']['bitcoin'] = array(
'#type' => 'checkbox',
'#title' => t('Accept Bitcoin'),
'#description' => t('When checked, Stripe Checkout will accept Bitcoin as payment.') . l(t('Must be enabled in your Stripe account.'), 'https://dashboard.stripe.com/account/bitcoin/enable'),
'#default_value' => isset($settings['checkout_settings']['bitcoin']) ? $settings['checkout_settings']['bitcoin'] : 0,
);
$form['checkout_settings']['billingAddress'] = array(
'#type' => 'checkbox',
'#title' => t('Billing address'),
'#description' => t('Specify whether to enable billing address collection in Checkout.'),
'#default_value' => isset($settings['checkout_settings']['billingAddress']) ? $settings['checkout_settings']['billingAddress'] : 0,
);
$form['checkout_settings']['shippingAddress'] = array(
'#type' => 'checkbox',
'#title' => t('Shipping address'),
'#description' => t('Specify whether to enable shipping address collection in Checkout.'),
'#default_value' => isset($settings['checkout_settings']['shippingAddress']) ? $settings['checkout_settings']['shippingAddress'] : 0,
);
if (module_exists('commerce_cardonfile')) {
$form['cardonfile'] = array(
'#type' => 'checkbox',
'#title' => t('Enable Card on File functionality.'),
'#default_value' => isset($settings['cardonfile']) ? $settings['cardonfile'] : 0,
);
}
else {
$form['cardonfile'] = array(
'#type' => 'markup',
'#markup' => t('To enable Card on File functionality, download and install the Commerce Card on File module.'),
);
}
$form['txn_type'] = array(
'#type' => 'radios',
'#title' => t('Default credit card transaction type'),
'#description' => t('The default will be used to process transactions during checkout.'),
'#options' => array(
COMMERCE_CREDIT_AUTH_CAPTURE => t('Authorization and capture'),
COMMERCE_CREDIT_AUTH_ONLY => t('Authorization only (requires manual capture after checkout)'),
),
'#default_value' => isset($settings['txn_type']) ? $settings['txn_type'] : COMMERCE_CREDIT_AUTH_CAPTURE,
);
$form['commerce_stripe_api_version'] = array(
'#type' => 'select',
'#title' => t('Stripe API Version'),
'#options' => array(
COMMERCE_STRIPE_API_LATEST_TESTED => 'Latest Tested (2017-08-15)',
COMMERCE_STRIPE_API_ACCOUNT_DEFAULT => 'Account Default',
COMMERCE_STRIPE_API_VERSION_CUSTOM => 'Custom',
),
'#empty_option' => COMMERCE_STRIPE_API_ACCOUNT_DEFAULT,
'#empty_value' => 'Account Default',
'#default_value' => $settings['commerce_stripe_api_version'],
'#description' => t('Specify the API version to use for requests.
Defaults to the version configured in your <a href="@dash">Stripe Account</a>.', array(
'@dash' => 'http://dashboard.stripe.com/account/apikeys',
)),
);
$form['commerce_stripe_api_version_custom'] = array(
'#type' => 'textfield',
'#title' => t('Specify an API Version'),
'#description' => t('Useful for testing API Versioning before committing to an upgrade. See the <a href="@docs">API Docs</a> and your <a href="@changelog">API Changelog</a>.', array(
'@docs' => 'https://stripe.com/docs/upgrades',
'@changelog' => 'https://stripe.com/docs/upgrades#api-changelog',
)),
'#default_value' => !empty($settings['commerce_stripe_api_version_custom']) ? $settings['commerce_stripe_api_version_custom'] : '',
'#size' => 12,
'#states' => array(
'visible' => array(
':input[name$="[commerce_stripe_api_version]"]' => array(
'value' => COMMERCE_STRIPE_API_VERSION_CUSTOM,
),
),
),
);
return $form;
}
function commerce_stripe_settings_form_image_validate($element, &$form_state, $form) {
if (isset($element['fid']['#value'])) {
$file = file_load($element['fid']['#value']);
if (is_object($file) && $file->status !== FILE_STATUS_PERMANENT) {
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
}
}
function _commerce_stripe_credit_card_form() {
module_load_include('inc', 'commerce_payment', 'includes/commerce_payment.credit_card');
$credit_card_fields = array(
'owner' => '',
'number' => '',
'exp_month' => '',
'exp_year' => '',
'code' => '',
);
$form = commerce_payment_credit_card_form($credit_card_fields);
foreach (array_keys($credit_card_fields) as $key) {
$credit_card_field =& $form['credit_card'][$key];
$credit_card_field['#attributes']['class'][] = 'stripe';
$credit_card_field['#required'] = FALSE;
$credit_card_field['#post_render'][] = '_commerce_stripe_credit_card_field_remove_name';
}
return $form;
}
function commerce_stripe_submit_form($payment_method, $pane_values, $checkout_pane, $order) {
$integration_type = !empty($payment_method['settings']['integration_type']) ? $payment_method['settings']['integration_type'] : COMMERCE_STRIPE_DEFAULT_INTEGRATION;
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$field = field_info_field('commerce_customer_address');
$instance = field_info_instance('commerce_customer_profile', 'commerce_customer_address', 'billing');
$available_countries = NULL;
if (isset($form_state['input']['country'])) {
$available_countries = array(
$form_state['input']['country'] => NULL,
);
}
$billing_address = addressfield_default_values($field, $instance, array(
$available_countries,
));
if (!empty($order->commerce_customer_billing)) {
if (!empty($order_wrapper->commerce_customer_billing->commerce_customer_address)) {
$billing_address = $order_wrapper->commerce_customer_billing->commerce_customer_address
->value();
}
}
$address = array(
'address_line1' => !empty($billing_address['thoroughfare']) ? $billing_address['thoroughfare'] : '',
'address_line2' => !empty($billing_address['premise']) ? $billing_address['premise'] : '',
'address_city' => !empty($billing_address['locality']) ? $billing_address['locality'] : '',
'address_state' => !empty($billing_address['administrative_area']) ? $billing_address['administrative_area'] : '',
'address_zip' => !empty($billing_address['postal_code']) ? $billing_address['postal_code'] : '',
'address_country' => !empty($billing_address['country']) ? $billing_address['country'] : '',
'name' => !empty($billing_address['name_line']) ? $billing_address['name_line'] : '',
);
drupal_add_js(array(
'commerce_stripe_address' => $address,
), array(
'type' => 'setting',
));
if ($integration_type === 'checkout' && isset($checkout_pane)) {
$form = array();
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$order_total = $order_wrapper->commerce_order_total
->value();
$checkout_settings = $payment_method['settings']['checkout_settings'];
$checkout_settings = array_map(function ($value) {
if ($value === 0 or $value === 1) {
$value = (bool) $value;
}
return $value;
}, $checkout_settings);
if (isset($checkout_settings['image']['fid'])) {
$image = file_load($checkout_settings['image']['fid']);
if (is_object($image)) {
$checkout_settings['image'] = file_create_url($image->uri);
}
else {
unset($checkout_settings['image']);
}
}
$checkout_settings += array(
'currency' => $payment_method['settings']['stripe_currency'],
'email' => $order->mail,
'amount' => $order_total['amount'],
);
drupal_add_js(array(
'stripe' => array(
'checkout' => $checkout_settings,
),
), 'setting');
}
elseif ($integration_type === 'elements' && (empty($pane_values) || empty($pane_values['payment_details']['cardonfile']) || !is_numeric($pane_values['payment_details']['cardonfile']))) {
$form = _commerce_stripe_elements_form();
}
elseif ($integration_type === 'stripejs' && (empty($pane_values) || empty($pane_values['payment_details']['cardonfile']) || !is_numeric($pane_values['payment_details']['cardonfile']))) {
$form = _commerce_stripe_credit_card_form();
}
$stripe_token = !empty($pane_values['stripe_token']) ? check_plain(trim($pane_values['stripe_token'])) : '';
_commerce_stripe_form_configure_stripe_common($form, $stripe_token, $integration_type);
$form['errors'] = array(
'#type' => 'markup',
'#markup' => '<div class="payment-errors"></div>',
);
return $form;
}
function _commerce_stripe_credit_card_field_remove_name($content, $element) {
$name_pattern = '/\\sname\\s*=\\s*[\'"]?' . preg_quote($element['#name']) . '[\'"]?/';
return preg_replace($name_pattern, '', $content);
}
function commerce_stripe_submit_form_submit($payment_method, $pane_form, $pane_values, $order, $charge) {
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);
}
if (!commerce_stripe_load_library()) {
drupal_set_message(t('Error making the payment. Please contact shop admin to proceed.'), 'error');
return FALSE;
}
$txn_capture_bool = _commerce_stripe_get_txn_capture_bool($payment_method, $pane_values);
$description = t('Order Number: @order_number', array(
'@order_number' => $order->order_number,
));
if (isset($charge['currency_code'])) {
$currency_code = $charge['currency_code'];
}
else {
$currency_code = $payment_method['settings']['stripe_currency'];
}
$c = array(
'amount' => $charge['amount'],
'currency' => $currency_code,
'card' => $pane_values['stripe_token'],
'capture' => $txn_capture_bool,
'description' => $description,
);
if (!empty($payment_method['settings']['receipt_email'])) {
$c['receipt_email'] = $order->mail;
}
$order->payment_method_settings = $payment_method['settings'];
commerce_stripe_add_metadata($c, $order);
drupal_alter('commerce_stripe_order_charge', $c, $order);
if (module_exists('commerce_cardonfile') && !empty($payment_method['settings']['cardonfile']) && !empty($pane_values['credit_card']['cardonfile_store'])) {
$user = user_load($order->uid);
$card = _commerce_stripe_create_card($pane_values['stripe_token'], $user, $payment_method);
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;
$transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
if (!_commerce_stripe_commerce_payment_transaction_save($transaction)) {
return FALSE;
}
try {
if ($charge['amount'] > 0) {
$response = Stripe\Charge::create($c);
$transaction->remote_id = $response->id;
$transaction->payload[REQUEST_TIME] = $response
->__toJSON();
$transaction->message = commerce_stripe_get_txn_message_success($txn_capture_bool);
$transaction->status = commerce_stripe_get_txn_status($txn_capture_bool);
$transaction->remote_status = commerce_stripe_get_remote_status($txn_capture_bool);
_commerce_stripe_commerce_payment_transaction_save($transaction);
}
} catch (Exception $e) {
drupal_set_message(t('We received the following error processing your card: :error
Please enter your information again or try a different card.', array(
':error' => $e
->getMessage(),
)), 'error');
watchdog('commerce_stripe', 'Following error received when processing card @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
), WATCHDOG_NOTICE);
if (is_a($e, 'Stripe\\Error\\Base')) {
$transaction->remote_id = $e
->getHttpStatus();
$transaction->payload[REQUEST_TIME] = $e->jsonBody;
}
else {
$transaction->remote_id = $e
->getCode();
$transaction->payload = $e
->getTraceAsString();
}
$transaction->message = t('Card processing error: @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
));
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
$transaction->remote_status = 'FAILED';
_commerce_stripe_commerce_payment_transaction_save($transaction);
return FALSE;
}
if (!empty($save_card)) {
$profile = NULL;
if (!empty($order->commerce_customer_billing)) {
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$profile = $order_wrapper->commerce_customer_billing
->value();
}
_commerce_stripe_save_cardonfile($response->source, $order->uid, $payment_method, $pane_values['cardonfile_instance_default'], $profile);
}
}
function _commerce_stripe_commerce_payment_transaction_save($transaction) {
if (!commerce_payment_transaction_save($transaction)) {
drupal_set_message(t('Our site is currently unable to process your card. Please contact the site administrator to complete your transaction'), 'error');
watchdog('commerce_stripe', 'commerce_payment_transaction_save returned false in saving a stripe transaction for order_id @order_id.', array(
'@order_id' => $transaction->order_id,
), WATCHDOG_ERROR);
return FALSE;
}
else {
return TRUE;
}
}
function _commerce_stripe_create_card($stripe_token, $account, $payment_method, $throw_exceptions = FALSE) {
if (!commerce_stripe_load_library()) {
return FALSE;
}
$stripe_customer_id = commerce_stripe_customer_id($account->uid, $payment_method['instance_id']);
if (!$stripe_customer_id) {
try {
$customer = Stripe\Customer::create(array(
'email' => $account->mail,
'description' => t('Customer for !mail', array(
'!mail' => $account->mail,
)),
'source' => $stripe_token,
));
$cards = Stripe\Customer::retrieve($customer->id)->sources
->all(array(
'object' => 'card',
));
$cards_array = Stripe\Util\Util::convertStripeObjectToArray(array(
$cards,
));
foreach ($cards_array[0]['data'] as $card) {
return (object) $card;
}
} catch (Exception $e) {
drupal_set_message(t('We received the following error processing your card: %error Please enter your information again or try a different card.', array(
'%error' => $e
->getMessage(),
)), 'error');
watchdog('commerce_stripe', 'Following error received when creating Stripe customer: @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
), WATCHDOG_NOTICE);
if ($throw_exceptions) {
throw $e;
}
return FALSE;
}
}
else {
try {
$customer = Stripe\Customer::retrieve($stripe_customer_id);
$card = $customer->sources
->create(array(
'source' => $stripe_token,
));
return $card;
} catch (Exception $e) {
drupal_set_message(t('We received the following error processing your card: %error Please enter your information again or try a different card.', array(
'%error' => $e
->getMessage(),
)), 'error');
watchdog('commerce_stripe', 'Following error received when adding a card to customer: @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
), WATCHDOG_NOTICE);
if ($throw_exceptions) {
throw $e;
}
return FALSE;
}
}
}
function _commerce_stripe_save_cardonfile($card, $uid, $payment_method, $set_default, $billing_profile = NULL) {
$remote_id = (string) $card->customer . '|' . (string) $card->id;
$card_data = commerce_cardonfile_new();
$card_data->uid = $uid;
$card_data->payment_method = $payment_method['method_id'];
$card_data->instance_id = $payment_method['instance_id'];
$card_data->remote_id = $remote_id;
$card_data->card_type = $card->brand;
$card_data->card_name = $card->name;
$card_data->card_number = $card->last4;
$card_data->card_exp_month = $card->exp_month;
$card_data->card_exp_year = $card->exp_year;
$card_data->status = 1;
$card_data->instance_default = $set_default;
$saved = commerce_cardonfile_save($card_data);
if (!empty($billing_profile)) {
$card_wrapper = entity_metadata_wrapper('commerce_cardonfile', $card_data);
$card_wrapper->commerce_cardonfile_profile
->set($billing_profile);
$card_wrapper
->save();
}
if (!empty($set_default)) {
commerce_stripe_load_library();
try {
$customer = Stripe\Customer::retrieve($card->customer);
$customer->default_source = $card->id;
$customer
->save();
} catch (Exception $e) {
drupal_set_message('Could not set the card as default on Stripe.');
return FALSE;
}
}
watchdog('commerce_stripe', 'Stripe Customer Profile @profile_id created and saved to user @uid.', array(
'@profile_id' => (string) $card->customer,
'@uid' => $uid,
));
}
function commerce_stripe_commerce_payment_method_info_alter(&$payment_methods) {
if (isset($payment_methods['commerce_stripe'])) {
$stripe_integration = COMMERCE_STRIPE_DEFAULT_INTEGRATION;
$cardonfile = FALSE;
$payment_method_rule = rules_config_load('commerce_payment_commerce_stripe');
if ($payment_method_rule && $payment_method_rule->active) {
foreach ($payment_method_rule
->actions() as $action) {
if (!$action instanceof RulesAction) {
continue;
}
if (!empty($action->settings['payment_method']['method_id']) && $action->settings['payment_method']['method_id'] == 'commerce_stripe') {
if (!empty($action->settings['payment_method']['settings']['integration_type'])) {
$stripe_integration = $action->settings['payment_method']['settings']['integration_type'];
}
$cardonfile = !empty($action->settings['payment_method']['settings']['cardonfile']) ? TRUE : FALSE;
break;
}
}
}
if (!empty($cardonfile)) {
$payment_methods['commerce_stripe']['cardonfile'] = array(
'charge callback' => 'commerce_stripe_cardonfile_charge',
'delete callback' => 'commerce_stripe_cardonfile_delete',
'create form callback' => 'commerce_stripe_cardonfile_create_form',
'create callback' => 'commerce_stripe_cardonfile_create',
'update form callback' => 'commerce_stripe_cardonfile_update_form',
'update callback' => 'commerce_stripe_cardonfile_update',
);
}
}
}
function _commerce_stripe_load_settings($name = NULL) {
static $settings = array();
if (!empty($settings)) {
return $settings;
}
if (commerce_payment_method_load('commerce_stripe') && rules_config_load('commerce_payment_commerce_stripe')) {
$commerce_stripe_payment_method = commerce_payment_method_instance_load('commerce_stripe|commerce_payment_commerce_stripe');
}
if (isset($name) && rules_config_load('commerce_payment_commerce_stripe')) {
$commerce_stripe_payment_method = commerce_payment_method_instance_load('commerce_stripe|commerce_payment_commerce_stripe');
}
if (isset($commerce_stripe_payment_method)) {
$settings = $commerce_stripe_payment_method['settings'];
if (module_exists('commerce_stripe_connect') && !empty($settings['use_connected_account']) && $settings['use_connected_account'] == 'site account') {
$connect_settings = commerce_stripe_connect_get_settings();
$settings['public_key'] = $connect_settings['connected_public_key'];
$settings['secret_key'] = $connect_settings['connected_secret_key'];
}
}
return $settings;
}
function _commerce_stripe_load_setting($name, $default_value = NULL) {
$settings = _commerce_stripe_load_settings($name);
return isset($settings[$name]) ? $settings[$name] : $default_value;
}
function commerce_stripe_cardonfile_charge($payment_method, $card_data, $order, $charge = NULL) {
if (!commerce_stripe_load_library()) {
return FALSE;
}
list($customer_id, $card_id) = explode('|', $card_data->remote_id);
$txn_capture_bool = _commerce_stripe_get_txn_capture_bool($payment_method, $payment_method['settings']);
$description = t('Order Number: @order_number', array(
'@order_number' => $order->order_number,
));
if (isset($charge['currency_code'])) {
$currency_code = $charge['currency_code'];
}
else {
$currency_code = $payment_method['settings']['stripe_currency'];
}
$c = array(
'amount' => $charge['amount'],
'currency' => $currency_code,
'customer' => $customer_id,
'card' => $card_id,
'capture' => $txn_capture_bool,
'description' => $description,
);
$order->payment_method_settings = $payment_method['settings'];
commerce_stripe_add_metadata($c, $order);
drupal_alter('commerce_stripe_order_charge', $c, $order);
$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;
$transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
if (!_commerce_stripe_commerce_payment_transaction_save($transaction)) {
return FALSE;
}
$lock = __FUNCTION__ . '_' . $order->order_id;
try {
if (lock_acquire($lock) && $charge['amount'] > 0) {
$response = Stripe\Charge::create($c);
$transaction->remote_id = $response->id;
$transaction->payload[REQUEST_TIME] = $response
->__toJSON();
$transaction->message = commerce_stripe_get_txn_message_success($txn_capture_bool);
$transaction->status = commerce_stripe_get_txn_status($txn_capture_bool);
$transaction->remote_status = commerce_stripe_get_remote_status($txn_capture_bool);
_commerce_stripe_commerce_payment_transaction_save($transaction);
lock_release($lock);
return TRUE;
}
} 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);
if (is_a($e, 'Stripe\\Error\\Base')) {
$transaction->remote_id = $e
->getHttpStatus();
$transaction->payload[REQUEST_TIME] = $e->jsonBody;
}
else {
$transaction->remote_id = $e
->getCode();
$transaction->payload = $e
->getTraceAsString();
}
$transaction->message = t('Card processing error: @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
));
$transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
$transaction->remote_status = 'FAILED';
_commerce_stripe_commerce_payment_transaction_save($transaction);
lock_release($lock);
return FALSE;
}
}
function commerce_stripe_cardonfile_create_form($form, &$form_state, $op, $card_data) {
$account = user_load($form_state['build_info']['args'][1]->uid);
$form['card_data'] = array(
'#type' => 'value',
'#value' => $card_data,
);
$form['op'] = array(
'#type' => 'value',
'#value' => $op,
);
$form['user'] = array(
'#type' => 'value',
'#value' => $account,
);
$stripe_integration = _commerce_stripe_load_setting('integration_type', COMMERCE_STRIPE_DEFAULT_INTEGRATION);
if ($stripe_integration === 'stripejs') {
_commerce_stripe_form_add_credit_card_form($form);
drupal_add_js('https://js.stripe.com/v2/', 'external');
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add card'),
);
}
elseif ($stripe_integration === 'elements') {
$form += _commerce_stripe_elements_form();
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Add card'),
);
}
elseif ($stripe_integration === 'checkout') {
$form['credit_card'] = array(
'#tree' => TRUE,
);
$order_total = array(
'amount' => 0,
'currency_code' => commerce_default_currency(),
);
$checkout_currency = _commerce_stripe_load_setting('stripe_currency');
$email = $account->mail;
$checkout_settings = _commerce_stripe_load_setting('checkout_settings');
$checkout_settings['panelLabel'] = t('Save card');
_commerce_stripe_form_configure_stripe_checkout($checkout_settings, $checkout_currency, $email, $order_total);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Enter card details'),
'#description' => t('Please enter your details in the pop-up that opens. They are sent directly to the payment processor and do not pass through this website.'),
);
}
$public_key = _commerce_stripe_load_setting('public_key');
$stripe_token = !empty($form_state['values']['stripe_token']) ? $form_state['values']['stripe_token'] : '';
_commerce_stripe_form_configure_stripe_common($form, $stripe_token, $stripe_integration);
$payment_method = commerce_payment_method_instance_load($card_data->instance_id);
$stored_cards = commerce_cardonfile_load_multiple_by_uid($account->uid, $payment_method['instance_id']);
$set_new_card_default = variable_get('commerce_cardonfile_set_new_card_default', 0);
$valid_cards = array();
if (!empty($stored_cards)) {
$valid_cards = array_filter($stored_cards, 'commerce_cardonfile_validate_card_expiration');
}
$form['credit_card']['cardonfile_instance_default'] = array(
'#type' => 'checkbox',
'#title' => t('Use as default card for payments with %method', array(
'%method' => $payment_method['display_title'],
)),
'#default_value' => empty($valid_cards) || $set_new_card_default ? TRUE : FALSE,
'#disabled' => empty($valid_cards) || $set_new_card_default ? TRUE : FALSE,
);
$profile = commerce_customer_profile_new('billing', $account->uid);
$profile->entity_context = array(
'entity_type' => 'commerce_cardonfile',
'entity_id' => $card_data->card_id,
);
$form['commerce_customer_profile'] = array(
'#type' => 'value',
'#value' => $profile,
);
field_attach_form('commerce_customer_profile', $profile, $form, $form_state);
$form['#validate'][] = 'commerce_stripe_cardonfile_create_validate';
$addressfields = array();
foreach (commerce_info_fields('addressfield', 'commerce_customer_profile') as $field_name => $field) {
if (!empty($form['address'][$field_name]['#language'])) {
$langcode = $form['address'][$field_name]['#language'];
if (!empty($form['address'][$field_name][$langcode])) {
$addressfields[] = array(
$field_name,
$langcode,
);
}
}
}
if (count($addressfields) == 1) {
list($field_name, $langcode) = array_shift($addressfields);
foreach (element_children($form['address'][$field_name][$langcode]) as $delta) {
if ($form['address'][$field_name][$langcode][$delta]['#type'] != 'submit') {
$form['address'][$field_name][$langcode][$delta]['#type'] = 'container';
}
}
}
commerce_stripe_set_addressfield_class_names($form['address']);
$form['errors'] = array(
'#markup' => '<div id="card-errors"></div>',
);
return $form;
}
function _commerce_stripe_form_configure_stripe_checkout($checkout_settings, $checkout_currency, $email, $amount) {
$checkout_settings = array_filter(array_map(function ($value) {
if ($value === 0 or $value === 1) {
$value = (bool) $value;
}
return $value;
}, $checkout_settings));
if (isset($checkout_settings['image']['fid'])) {
$image = file_load($checkout_settings['image']['fid']);
if (is_object($image)) {
$checkout_settings['image'] = file_create_url($image->uri);
}
else {
unset($checkout_settings['image']);
}
}
$checkout_settings += array(
'currency' => $checkout_currency,
'email' => $email,
'amount' => $amount['amount'],
);
drupal_add_js(array(
'stripe' => array(
'checkout' => $checkout_settings,
),
), 'setting');
drupal_add_js('https://checkout.stripe.com/checkout.js', 'external');
}
function _commerce_stripe_form_configure_stripe_common(&$form, $stripe_token, $integration_type = COMMERCE_STRIPE_DEFAULT_INTEGRATION) {
$public_key = _commerce_stripe_load_setting('public_key');
$form['stripe_token'] = array(
'#type' => 'hidden',
'#attributes' => array(
'id' => 'stripe_token',
),
'#default_value' => !empty($stripe_token) ? $stripe_token : '',
);
if ($integration_type === 'elements') {
$form['#attached']['js'] = array(
drupal_get_path('module', 'commerce_stripe') . '/commerce_stripe.elements.js' => array(
'preprocess' => FALSE,
'cache' => FALSE,
),
);
}
elseif ($integration_type === 'checkout') {
drupal_add_js('https://checkout.stripe.com/checkout.js', 'external');
}
if ($integration_type == 'stripejs') {
$form['#attached']['js'] = array(
'https://js.stripe.com/v2/' => array(
'type' => 'external',
),
drupal_get_path('module', 'commerce_stripe') . '/commerce_stripe.js' => array(
'preprocess' => FALSE,
'cache' => FALSE,
),
);
}
$form['#attached']['js'][] = array(
'data' => array(
'stripe' => array(
'publicKey' => trim($public_key),
'integration_type' => $integration_type,
),
),
'type' => 'setting',
);
}
function _commerce_stripe_form_add_credit_card_form(&$form) {
$form += _commerce_stripe_credit_card_form();
drupal_add_js('https://js.stripe.com/v2/', 'external');
}
function commerce_stripe_cardonfile_create_validate($form, &$form_state) {
$profile = $form_state['values']['commerce_customer_profile'];
field_attach_form_validate('commerce_customer_profile', $profile, $form, $form_state);
}
function commerce_stripe_cardonfile_create_form_submit($form, &$form_state) {
$card_data = $form_state['values']['card_data'];
$payment_method = commerce_payment_method_instance_load($card_data->instance_id);
commerce_stripe_cardonfile_create($form, $form_state, $payment_method, $card_data);
$form_state['redirect'] = 'user/' . $card_data->uid . '/cards';
}
function commerce_stripe_cardonfile_update_form($form, &$form_state, $op, $card_data) {
$account = user_load($form_state['build_info']['args'][1]->uid);
$form['card_data'] = array(
'#type' => 'value',
'#value' => $card_data,
);
$form['op'] = array(
'#type' => 'value',
'#value' => $op,
);
$form['user'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['errors'] = array(
'#markup' => '<div id="card-errors"></div>',
);
$card['number'] = t('xxxxxx ' . $card_data->card_number);
$card['owner'] = t($card_data->card_name);
$card['exp_month'] = strlen($card_data->card_exp_month) == 1 ? '0' . $card_data->card_exp_month : $card_data->card_exp_month;
$card['exp_year'] = $card_data->card_exp_year;
$fields = array(
'owner' => $card['owner'],
'code' => '',
'exp_month' => $card['exp_month'],
'exp_year' => $card['exp_year'],
);
module_load_include('inc', 'commerce_payment', 'includes/commerce_payment.credit_card');
$form += commerce_payment_credit_card_form($fields, $card);
$form['credit_card']['number']['#disabled'] = TRUE;
$payment_method = commerce_payment_method_instance_load($card_data->instance_id);
$stored_cards = commerce_cardonfile_load_multiple_by_uid($account->uid, $payment_method['instance_id']);
$valid_cards = array();
if (!empty($stored_cards)) {
$valid_cards = array_filter($stored_cards, 'commerce_cardonfile_validate_card_expiration');
}
$card_count = count($valid_cards);
$form['credit_card']['cardonfile_instance_default'] = array(
'#type' => 'checkbox',
'#title' => t('Use as default card for payments with %method', array(
'%method' => $payment_method['display_title'],
)),
'#default_value' => empty($valid_cards) && $card_count == 1 ? TRUE : $card_data->instance_default,
'#disabled' => empty($valid_cards) && $card_count == 1 ? TRUE : $card_data->instance_default,
);
$wrapper = entity_metadata_wrapper('commerce_cardonfile', $card_data);
$addressfields = array();
$langcode = LANGUAGE_NONE;
foreach (commerce_info_fields('addressfield', 'commerce_customer_profile') as $field_name => $field) {
if (!empty($form[$field_name]['#language'])) {
$langcode = $form[$field_name]['#language'];
if (!empty($form[$field_name][$langcode])) {
$addressfields[] = array(
$field_name,
$langcode,
);
}
}
}
if ($wrapper
->__isset('commerce_cardonfile_profile') && $wrapper->commerce_cardonfile_profile
->value()) {
$profile = $wrapper->commerce_cardonfile_profile
->value();
}
if (empty($profile)) {
$profile = commerce_customer_profile_new('billing', $account->uid);
$field = field_info_field('commerce_customer_address');
$instance = field_info_instance('commerce_customer_profile', 'commerce_customer_address', 'billing');
$address = addressfield_default_values($field, $instance);
$profile->commerce_customer_address[$langcode][] = $address;
}
$profile->entity_context = array(
'entity_type' => 'commerce_cardonfile',
'entity_id' => $card_data->card_id,
);
$form['commerce_customer_profile'] = array(
'#type' => 'value',
'#value' => $profile,
);
field_attach_form('commerce_customer_profile', $profile, $form, $form_state);
$form['#validate'][] = 'commerce_stripe_cardonfile_update_validate';
if (count($addressfields) == 1) {
list($field_name, $langcode) = array_shift($addressfields);
foreach (element_children($form['address'][$field_name][$langcode]) as $delta) {
if ($form[$field_name][$langcode][$delta]['#type'] != 'submit') {
$form[$field_name][$langcode][$delta]['#type'] = 'container';
}
}
}
commerce_stripe_set_addressfield_class_names($form[$field_name][$langcode][0]);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Update card'),
);
return $form;
}
function commerce_stripe_cardonfile_update_validate($form, &$form_state) {
$profile = NULL;
if (!empty($form_state['values']['commerce_customer_profile'])) {
$profile = $form_state['values']['commerce_customer_profile'];
}
field_attach_form_validate('commerce_customer_profile', $profile, $form, $form_state);
}
function commerce_stripe_cardonfile_update_form_submit($form, &$form_state) {
$card_data = $form_state['values']['card_data'];
$payment_method = commerce_payment_method_instance_load($card_data->instance_id);
commerce_stripe_cardonfile_update($form, $form_state, $payment_method, $card_data);
$form_state['redirect'] = 'user/' . $card_data->uid . '/cards';
}
function commerce_stripe_cardonfile_create($form, &$form_state, $payment_method, $card_data) {
$account = $form_state['values']['user'];
$card = _commerce_stripe_create_card($form_state['values']['stripe_token'], $account, $payment_method);
if (!$card) {
return;
}
$profile = NULL;
if (isset($form_state['values']['commerce_customer_profile'])) {
$profile = $form_state['values']['commerce_customer_profile'];
$profile->status = TRUE;
if (empty($profile->profile_id)) {
$profile->uid = $account->uid;
}
field_attach_submit('commerce_customer_profile', $profile, $form, $form_state);
commerce_customer_profile_save($profile);
}
$saved = _commerce_stripe_save_cardonfile($card, $card_data->uid, $payment_method, $form_state['values']['credit_card']['cardonfile_instance_default'], $profile);
}
function commerce_stripe_cardonfile_update($form, &$form_state, $payment_method, $card_data) {
if (!commerce_stripe_load_library()) {
return FALSE;
}
$account = $form_state['values']['user'];
list($customer_id, $card_id) = explode('|', $card_data->remote_id);
try {
$customer = Stripe\Customer::retrieve($customer_id);
$card = $customer->sources
->retrieve($card_id);
if ($card_data->instance_default != $form_state['values']['credit_card']['cardonfile_instance_default']) {
$customer->default_source = $card->id;
}
$card_data->card_name = check_plain($form_state['values']['credit_card']['owner']);
$card_data->card_exp_month = $form_state['values']['credit_card']['exp_month'];
$card_data->card_exp_year = $form_state['values']['credit_card']['exp_year'];
$card_data->instance_default = $form_state['values']['credit_card']['cardonfile_instance_default'];
$card_data->status = 1;
$langcode = $form['commerce_customer_address']['#language'];
if ($payment_method['settings']['integration_type'] == 'checkout' && valid_email_address($form_state['values']['credit_card']['owner']) && !empty($form_state['values']['commerce_customer_address'][$langcode][0]['name_line'])) {
$card_data->card_name = check_plain($form_state['values']['commerce_customer_address'][$langcode][0]['name_line']);
}
$card->exp_month = $card_data->card_exp_month;
$card->exp_year = $card_data->card_exp_year;
$card->name = $card_data->card_name;
$card
->save();
$billing_profile = NULL;
if (isset($form_state['values']['commerce_customer_profile'])) {
$billing_profile = $form_state['values']['commerce_customer_profile'];
$billing_profile->status = TRUE;
if (empty($billing_profile->profile_id)) {
$billing_profile->uid = $account->uid;
}
field_attach_submit('commerce_customer_profile', $billing_profile, $form, $form_state);
commerce_customer_profile_save($billing_profile);
}
$card_wrapper = entity_metadata_wrapper('commerce_cardonfile', $card_data);
if (!empty($billing_profile)) {
$card_wrapper->commerce_cardonfile_profile
->set($billing_profile);
}
$card_wrapper
->save();
if (!empty($card_data->instance_default)) {
$customer->default_source = $card->id;
$customer
->save();
}
return TRUE;
} catch (Exception $e) {
drupal_set_message(t('We received the following error processing your card: %error Please enter your information again or try a different card.', array(
'%error' => $e
->getMessage(),
)), 'error');
watchdog('commerce_stripe', 'Following error received when updating card @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
), WATCHDOG_NOTICE);
return FALSE;
}
}
function commerce_stripe_cardonfile_delete($form, &$form_state, $payment_method, $card_data) {
if (!commerce_stripe_load_library()) {
return FALSE;
}
list($customer_id, $card_id) = explode('|', $card_data->remote_id);
try {
$customer = Stripe\Customer::retrieve($customer_id);
$customer->sources
->retrieve($card_id)
->delete();
return TRUE;
} catch (Exception $e) {
drupal_set_message(t('We received the following error processing your card: %error Please enter your information again or try a different card.', array(
'%error' => $e
->getMessage(),
)), 'error');
watchdog('commerce_stripe', 'Following error received when deleting card @stripe_error', array(
'@stripe_error' => $e
->getMessage(),
), WATCHDOG_NOTICE);
return FALSE;
}
}
function commerce_stripe_load_library() {
$library = libraries_load('stripe-php');
if (!$library || empty($library['loaded'])) {
watchdog('commerce_stripe', 'Failure to load Stripe API PHP Client Library. Please see the Status Report for more.', array(), WATCHDOG_CRITICAL);
return FALSE;
}
return TRUE;
}
function commerce_stripe_customer_id($uid, $instance_id = NULL) {
$stored_cards = commerce_cardonfile_load_multiple_by_uid($uid, $instance_id);
if (!empty($stored_cards)) {
$card_data = reset($stored_cards);
list($customer_id, $card_id) = explode('|', $card_data->remote_id);
}
return !empty($customer_id) ? $customer_id : FALSE;
}
function commerce_stripe_field_widget_addressfield_standard_form_alter(&$element, &$form_state, $context) {
if ($context['field']['field_name'] === 'commerce_customer_address' && $context['instance']['bundle'] === 'billing') {
commerce_stripe_set_addressfield_class_names($element);
}
}
function commerce_stripe_set_addressfield_class_names(&$element) {
if (isset($element['street_block']['thoroughfare'])) {
$element['street_block']['thoroughfare']['#attributes']['class'][] = 'commerce-stripe-thoroughfare';
}
if (isset($element['street_block']['premise'])) {
$element['street_block']['premise']['#attributes']['class'][] = 'commerce-stripe-premise';
}
if (isset($element['locality_block']['locality'])) {
$element['locality_block']['locality']['#attributes']['class'][] = 'commerce-stripe-locality';
}
if (isset($element['locality_block']['administrative_area'])) {
$element['locality_block']['administrative_area']['#attributes']['class'][] = 'commerce-stripe-administrative-area';
}
if (isset($element['locality_block']['postal_code'])) {
$element['locality_block']['postal_code']['#attributes']['class'][] = 'commerce-stripe-postal-code';
}
if (isset($element['country'])) {
$element['country']['#attributes']['class'][] = 'commerce-stripe-country';
}
}
function commerce_stripe_add_metadata(&$c, $order) {
$metadata = module_invoke_all('commerce_stripe_metadata', $order);
if (count($metadata)) {
$c['metadata'] = $metadata;
}
}
function commerce_stripe_commerce_stripe_metadata($order) {
return array(
'order_id' => $order->order_id,
'order_number' => $order->order_number,
'uid' => $order->uid,
'email' => $order->mail,
);
}
function _commerce_stripe_set_api_key($payment_method) {
if (!empty($payment_method['settings']['secret_key'])) {
Stripe\Stripe::setApiKey(trim($payment_method['settings']['secret_key']));
}
elseif (!empty($payment_method['settings']['use_connected_account']) && $payment_method['settings']['use_connected_account'] == 'site account') {
if (module_exists('commerce_stripe_connect')) {
$connect_settings = commerce_stripe_connect_get_settings();
Stripe\Stripe::setApiKey(trim($connect_settings['connected_secret_key']));
}
}
}
function commerce_stripe_payment_currencies() {
commerce_stripe_load_library();
$supported_currencies = array();
$payment_method = commerce_payment_method_instance_load('commerce_stripe|commerce_payment_commerce_stripe');
if (!empty($payment_method['settings']['secret_key']) || !empty($payment_method['settings']['use_connected_account']) && $payment_method['settings']['use_connected_account'] == 'site account') {
_commerce_stripe_set_api_key($payment_method);
try {
$info = \Stripe\Account::retrieve();
$country_spec = \Stripe\CountrySpec::retrieve($info->country);
$supported_currencies = $country_spec->supported_payment_currencies;
} catch (Exception $e) {
drupal_set_message(check_plain($e
->getMessage()), 'error');
}
}
return $supported_currencies;
}
function commerce_stripe_form_commerce_payment_order_transaction_add_form_alter(&$form, &$form_state, $form_id) {
if (!empty($form['payment_terminal']) && isset($form_state['payment_method']['method_id']) && $form_state['payment_method']['method_id'] == 'commerce_stripe') {
if (isset($form['payment_terminal']['payment_details']['credit_card']['#access']) && $form['payment_terminal']['payment_details']['credit_card']['#access'] === FALSE) {
return;
}
$form['payment_terminal']['payment_details']['txn_type'] = array(
'#type' => 'select',
'#title' => t('Transaction type'),
'#options' => array(
COMMERCE_CREDIT_AUTH_ONLY => t('Authorization only'),
COMMERCE_CREDIT_AUTH_CAPTURE => t('Authorization and capture'),
),
'#default_value' => $form_state['payment_method']['settings']['txn_type'],
);
$form['payment_terminal']['commerce_stripe_terminal'] = array(
'#value' => 1,
'#type' => 'hidden',
);
}
}
function _commerce_stripe_elements_form() {
$form = array();
$form['credit_card'] = array(
'#tree' => TRUE,
'#attached' => array(
'css' => array(
drupal_get_path('module', 'commerce_payment') . '/theme/commerce_payment.theme.css',
),
),
);
if (isset($fields['owner'])) {
$form['credit_card']['owner'] = array(
'#type' => 'textfield',
'#title' => t('Card owner'),
'#attributes' => array(
'autocomplete' => 'off',
'placeholder' => variable_get('commerce_stripe_owner_placeholder', 'John Q. Smith'),
),
'#required' => TRUE,
'#maxlength' => 64,
'#size' => 32,
);
}
$form['credit_card']['number'] = array(
'#type' => 'item',
'#markup' => '<label for="card-element">Card number</label><div data-stripe="number" id="card-element"></div>',
);
$form['card_errors'] = array(
'#type' => 'item',
'#markup' => '<div data-stripe-errors="number" class="stripe-errors form-text" id="card-errors"></div>',
'#weight' => 0,
);
return $form;
}
function commerce_stripe_capture_access($order, $transaction) {
if ($transaction->payment_method != 'commerce_stripe' || empty($transaction->remote_id) || strtoupper($transaction->remote_status) != 'AUTH_ONLY') {
return FALSE;
}
if (time() - $transaction->created > 86400 * 7) {
return FALSE;
}
return commerce_payment_transaction_access('update', $transaction);
}
function commerce_stripe_void_access($order, $transaction) {
if ($transaction->payment_method != 'commerce_stripe' || empty($transaction->remote_id) || strtoupper($transaction->remote_status) != 'AUTH_ONLY') {
return FALSE;
}
return commerce_payment_transaction_access('update', $transaction);
}
function _commerce_stripe_get_txn_capture_bool($payment_method, $pane_values) {
$txn_type = !empty($payment_method['settings']['txn_type']) ? $payment_method['settings']['txn_type'] : COMMERCE_CREDIT_AUTH_CAPTURE;
if (!empty($pane_values['txn_type'])) {
$txn_type = $pane_values['txn_type'];
}
if ($txn_type == COMMERCE_CREDIT_AUTH_CAPTURE) {
return TRUE;
}
else {
if ($txn_type == COMMERCE_CREDIT_AUTH_ONLY) {
return FALSE;
}
}
return TRUE;
}
function commerce_stripe_get_remote_status($txn_capture_bool, $prev_transaction = NULL, $action = NULL) {
if (!$prev_transaction) {
if ($txn_capture_bool === FALSE) {
return 'AUTH_ONLY';
}
else {
if ($txn_capture_bool === TRUE) {
return 'AUTH_CAPTURE';
}
}
}
else {
switch ($action) {
case 'capture':
if ($prev_transaction->remote_status == 'AUTH_ONLY') {
return 'PRIOR_AUTH_CAPTURE';
}
else {
throw new Exception(t('Remote Status capture improperly used internally.'));
}
break;
case 'void':
if ($prev_transaction->remote_status == 'AUTH_ONLY') {
return 'VOID';
}
else {
throw new Exception(t('Remote Status void improperly used internally.'));
}
break;
}
}
return 'FAILED';
}
function commerce_stripe_get_txn_message_success($txn_capture_bool) {
return $txn_capture_bool ? t('Payment completed successfully.') : t('Payment information authorized successfully.');
}
function commerce_stripe_get_txn_status($txn_capture_bool) {
return $txn_capture_bool ? COMMERCE_PAYMENT_STATUS_SUCCESS : COMMERCE_PAYMENT_STATUS_PENDING;
}
function commerce_stripe_default_settings() {
return array(
'secret_key' => '',
'public_key' => '',
'use_connected_account' => 'none',
'commerce_stripe_api_version' => COMMERCE_STRIPE_API_LATEST_TESTED,
'commerce_stripe_api_version_custom' => '',
);
}