From aea105c1abacc1cd4803a38c33467e11409b463b Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 3 Oct 2019 21:53:02 -0500 Subject: [PATCH] Revert "Merge pull request #9 from mattbk/7.x-3.1" This reverts commit 6324febf04905178d5b14e93da33dab0497b3a72, reversing changes made to fed9880872af77241f69f34d8054d3a502114079. --- js/uc_stripe.js | 312 +++++++++++++++----------------- js/uc_stripe_process_payment.js | 91 ---------- uc_stripe.mail.inc | 62 ------- uc_stripe.pages.inc | 149 --------------- 4 files changed, 145 insertions(+), 469 deletions(-) delete mode 100644 js/uc_stripe_process_payment.js delete mode 100644 uc_stripe.mail.inc delete mode 100644 uc_stripe.pages.inc diff --git a/js/uc_stripe.js b/js/uc_stripe.js index f787c41..d30b53a 100644 --- a/js/uc_stripe.js +++ b/js/uc_stripe.js @@ -8,186 +8,164 @@ Drupal.behaviors.uc_stripe = { attach: function (context) { - - // Once function prevents stripe from reloading. Any dom changes to stripe area will destroy element - // as a Stripe security feature - $('#uc-cart-checkout-form', context).once('uc_stripe', function(){ - - var stripe_card_element = '#stripe-card-element'; - - if (Drupal.settings && Drupal.settings.uc_stripe ) { - var apikey = Drupal.settings.uc_stripe.apikey; - - var stripe = Stripe(apikey); - var elements = stripe.elements(); - } - - + // Map stripe names to (partial) Ubercart field names; Ubercart names add "billing_" or "shipping_" on the front. - const address_field_mapping = { - "address_line1": "street1", - "address_line2": "street2", - "address_city": "city", - "address_state": "zone", - "address_zip": "postal_code", - "address_country": "country" - }; - var submitButton = $('.uc-cart-checkout-form #edit-continue'); + const address_field_mapping = { + "address_line1": "street1", + "address_line2": "street2", + "address_city": "city", + "address_state": "zone", + "address_zip": "postal_code", + "address_country": "country" + }; + var submitButton = $('.uc-cart-checkout-form #edit-continue'); - // Load the js reference to these fields so that on the review page - // we can input the last 4 and expiration date which is returned to us by stripe paymentMethod call - var cc_container = $('.payment-details-credit'); - var cc_num = cc_container.find(':input[id*="edit-panes-payment-details-cc-numbe"]'); - var cc_cvv = cc_container.find(':input[id*="edit-panes-payment-details-cc-cv"]'); - var cc_exp_month = cc_container.find('#edit-panes-payment-details-cc-exp-month'); - var cc_exp_year = cc_container.find('#edit-panes-payment-details-cc-exp-year'); - - // Make sure that when the page is being loaded the paymentMethod value is reset - // Browser or other caching might do otherwise. - $("[name='panes[payment-stripe][details][stripe_payment_method]']").val('default'); + var cc_container = $('.payment-details-credit'); + var cc_num = cc_container.find(':input[id*="edit-panes-payment-details-cc-numbe"]'); + var cc_cvv = cc_container.find(':input[id*="edit-panes-payment-details-cc-cv"]'); - // JS must enable the button; otherwise form might disclose cc info. It starts disabled - submitButton.attr('disabled', false); + // Make sure that when the page is being loaded the token value is reset + // Browser or other caching might do otherwise. + $("[name='panes[payment][details][stripe_token]']").val('default'); - // When this behavior fires, we can clean the form so it will behave properly, - // Remove 'name' from sensitive form elements so there's no way they can be submitted. - cc_num.removeAttr('name').removeAttr('disabled'); - $('div.form-item-panes-payment-details-cc-number').removeClass('form-disabled'); - cc_cvv.removeAttr('name').removeAttr('disabled'); - var cc_val_val = cc_num.val(); - if (cc_val_val && cc_val_val.indexOf('Last 4')) { - cc_num.val(''); + $('span#stripe-nojs-warning').parent().hide(); + + // JS must enable the button; otherwise form might disclose cc info. It starts disabled + submitButton.attr('disabled', false); + + // When this behavior fires, we can clean the form so it will behave properly, + // Remove 'name' from sensitive form elements so there's no way they can be submitted. + cc_num.removeAttr('name').removeAttr('disabled'); + $('div.form-item-panes-payment-details-cc-number').removeClass('form-disabled'); + cc_cvv.removeAttr('name').removeAttr('disabled'); + var cc_val_val = cc_num.val(); + if (cc_val_val && cc_val_val.indexOf('Last 4')) { + cc_num.val(''); + } + + submitButton.click(function (e) { + + // We must find the various fields again, because they may have been swapped + // in by ajax action of the form. + cc_container = $('.payment-details-credit'); + cc_num = cc_container.find(':input[id*="edit-panes-payment-details-cc-numbe"]'); + cc_cvv = cc_container.find(':input[id*="edit-panes-payment-details-cc-cv"]'); + + // If not credit card processing or no token field, just let the submit go on + // Also continue if we've received the tokenValue + var tokenField = $("[name='panes[payment][details][stripe_token]']"); + if (!$("div.payment-details-credit").length || !tokenField.length || tokenField.val().indexOf('tok_') == 0) { + return true; } - - - // Custom styling can be passed to options when creating an Element. - var style = { - base: { - // Add your base input styles here. For example: - fontSize: '24px', - color: "#000000", - iconColor: "blue", + + // If we've requested and are waiting for token, prevent any further submit + if (tokenField.val() == 'requested') { + return false; // Prevent any submit processing until token is received + } + + // Go ahead and request the token + tokenField.val('requested'); + + try { + var name = undefined; + + if ($(':input[name="panes[billing][billing_first_name]"]').length) { + name = $(':input[name="panes[billing][billing_first_name]"]').val() + " " + $(':input[name="panes[billing][billing_last_name]"]').val(); } - }; - - // Create an instance of the card Element. - var card = elements.create('card', {style: style}); - - // Add an instance of the card Element into the #stripe-card-element
. - card.mount(stripe_card_element); - - // Display errors from stripe - card.addEventListener('change', function(event) { - var displayError = document.getElementById('uc_stripe_messages'); - if (event.error) { - displayError.textContent = event.error.message; - console.log(event.error.message) - } else { - displayError.textContent = ''; - } - }); - - submitButton.click(function (e) { - - // We must find the various fields again, because they may have been swapped - // in by ajax action of the form. - cc_container = $('.payment-details-credit'); - cc_num = cc_container.find(':input[id*="edit-panes-payment-details-cc-numbe"]'); - cc_cvv = cc_container.find(':input[id*="edit-panes-payment-details-cc-cv"]'); - cc_exp_year = cc_container.find('#edit-panes-payment-details-cc-exp-month'); - cc_exp_month = cc_container.find('#edit-panes-payment-details-cc-exp-year'); - - // If not credit card processing or no payment method field, just let the submit go on - // Also continue if we've received the tokenValue - var paymentMethodField = $("[name='panes[payment-stripe][details][stripe_payment_method]']"); - if (!$("div.payment-details-credit").length || !paymentMethodField.length || paymentMethodField.val().indexOf('pm_') == 0) { - return true; + if (typeof name === "undefined" && $(':input[name="panes[delivery][delivery_first_name]"]').length) { + name = $(':input[name="panes[delivery][delivery_first_name]"]').val() + " " + $(':input[name="panes[delivery][delivery_last_name]"]').val(); } - // If we've requested and are waiting for token, prevent any further submit - if (paymentMethodField.val() == 'requested') { - return false; // Prevent any submit processing until token is received - } + var params = { + number: cc_num.val(), + cvc: cc_cvv.val(), + exp_month: $(':input[name="panes[payment][details][cc_exp_month]"]').val(), + exp_year: $(':input[name="panes[payment][details][cc_exp_year]"]').val(), + name: name + }; - // Go ahead and request the token - paymentMethodField.val('requested'); - - try { - - stripe.createPaymentMethod('card', card).then(function (response) { - - if (response.error) { - - // Show the errors on the form - $('#uc_stripe_messages') - .removeClass("hidden") - .text(response.error.message); - $('#edit-stripe-messages').val(response.error.message); - - // Make the fields visible again for retry - cc_num - .css('visibility', 'visible') - .val('') - .attr('name', 'panes[payment][details][cc_number]'); - cc_cvv - .css('visibility', 'visible') - .val('') - .attr('name', 'panes[payment][details][cc_cvv]'); - - - // Turn off the throbber - $('.ubercart-throbber').remove(); - // Remove the bogus copy of the submit button added in uc_cart.js ucSubmitOrderThrobber - submitButton.next().remove(); - // And show the hidden original button which has the behavior attached to it. - submitButton.show(); - - paymentMethodField.val('default'); // Make sure token field set back to default - - } else { - // token contains id, last4, and card type - var paymentMethodId = response.paymentMethod.id; - - - // Insert the token into the form so it gets submitted to the server - paymentMethodField.val(paymentMethodId); - - // set cc expiration date received from stripe so that it is available on checkout review - cc_exp_year.val(response.paymentMethod.card.exp_month); - cc_exp_month.val(response.paymentMethod.card.exp_year); - - // Since we're now submitting, make sure that uc_credit doesn't - // find values it objects to; after "fixing" set the name back on the - // form element. - // add dummy tweleve 5's and the last 4 of credit card so that last 4 show - cc_num - .css('visibility', 'hidden') - .val('555555555555' + response.paymentMethod.card.last4) - .attr('name', 'panes[payment][details][cc_number]'); - cc_cvv - .css('visibility', 'hidden') - .val('999') - .attr('name', 'panes[payment][details][cc_cvv]'); - - // now actually submit to Drupal. The only "real" things going - // are the token and the expiration date and last 4 of cc - submitButton.click(); + // Translate the Ubercart billing/shipping fields to Stripe values + for (var key in address_field_mapping) { + const prefixes = ['billing', 'delivery']; + for (var i = 0; i < prefixes.length; i++) { + var prefix = prefixes[i]; + var uc_field_name = prefix + '_' + address_field_mapping[key]; + var location = ':input[name="panes[' + prefix + '][' + uc_field_name + ']"]'; + if ($(location).length) { + params[key] = $(location).val(); + if ($(location).attr('type') == 'select-one') { + params[key] = $(location + " option:selected").text(); + } + break; // break out of billing/shipping loop because we got the info } - }); - } catch (e) { - $('#uc_stripe_messages') - .removeClass("hidden") - .text(e.message); - $('#edit-stripe-messages').val(e.message); + } } - // Prevent processing until we get the token back - return false; - }); - }); - - }, + Stripe.createToken(params, function (status, response) { + if (response.error) { + + // Show the errors on the form + $('#uc_stripe_messages') + .removeClass("hidden") + .text(response.error.message); + $('#edit-stripe-messages').val(response.error.message); + + // Make the fields visible again for retry + cc_num + .css('visibility', 'visible') + .val('') + .attr('name', 'panes[payment][details][cc_number]'); + cc_cvv + .css('visibility', 'visible') + .val('') + .attr('name', 'panes[payment][details][cc_cvv]'); + + + // Turn off the throbber + $('.ubercart-throbber').remove(); + // Remove the bogus copy of the submit button added in uc_cart.js ucSubmitOrderThrobber + submitButton.next().remove(); + // And show the hidden original button which has the behavior attached to it. + submitButton.show(); + + tokenField.val('default'); // Make sure token field set back to default + + } else { + // token contains id, last4, and card type + var token = response.id; + + // Insert the token into the form so it gets submitted to the server + tokenField.val(token); + + // Since we're now submitting, make sure that uc_credit doesn't + // find values it objects to; after "fixing" set the name back on the + // form element. + cc_num + .css('visibility', 'hidden') + .val('555555555555' + response.card.last4) + .attr('name', 'panes[payment][details][cc_number]'); + cc_cvv + .css('visibility', 'hidden') + .val('999') + .attr('name', 'panes[payment][details][cc_cvv]'); + + // now actually submit to Drupal. The only "real" things going + // are the token and the expiration date. + submitButton.click(); + } + }); + } catch (e) { + $('#uc_stripe_messages') + .removeClass("hidden") + .text(e.message); + $('#edit-stripe-messages').val(e.message); + } + + // Prevent processing until we get the token back + return false; + }); + } }; }(jQuery)); diff --git a/js/uc_stripe_process_payment.js b/js/uc_stripe_process_payment.js deleted file mode 100644 index 23f9384..0000000 --- a/js/uc_stripe_process_payment.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file - * uc_stripe.js - * - * Handles all interactions with Stripe on the client side for PCI-DSS compliance - */ -(function ($) { - - Drupal.behaviors.uc_stripe_process_payment = { - attach: function (context) { - - $('#uc-cart-checkout-review-form, #uc-stripe-authenticate-payment-form', context).once('uc_stripe', function(){ - - if (Drupal.settings && Drupal.settings.uc_stripe ) { - var apikey = Drupal.settings.uc_stripe.apikey; - var methodId = Drupal.settings.uc_stripe.methodId; - var orderId = Drupal.settings.uc_stripe.orderId - var stripe = Stripe(apikey); - } - - var submitButton = $('#edit-submit'); - var processed = false; - - submitButton.click(function (e) { - if(!processed){ - e.preventDefault(); - - $.ajax({ - url: '/uc_stripe/ajax/confirm_payment', - type: "POST", - data: JSON.stringify({ payment_method_id: methodId, order_id: orderId }), - contentType: 'application/json;', - dataType: 'json', - success: function(result){ - handleServerResponse(result); - }, - error: function(result){ - handleServerResponse(result); - } - }) - - } - - }); - - function handleServerResponse(response) { - if (response.error) { - processed = true; - submitButton.click(); - // Show error from server on payment form - } else if (response.requires_action) { - // Use Stripe.js to handle required card action - stripe.handleCardAction( - response.payment_intent_client_secret - ).then(function(result) { - if (result.error) { - // Show error in payment form - processed = true; - submitButton.click(); - } else { - // The card action has been handled - // The PaymentIntent can be confirmed again on the server - $.ajax({ - url: '/uc_stripe/ajax/confirm_payment', - type: 'POST', - data: JSON.stringify({ payment_intent_id: result.paymentIntent.id, order_id: orderId }), - contentType: 'application/json;', - dataType: 'json', - success: function(confirmResult){ - return handleServerResponse(confirmResult); - }, - error: function(confirmResult){ - return handleServerResponse(confirmResult); - }, - }) - } - }); - } else { - // Show success message - processed = true; - submitButton.click(); - } - } - - }); - - }, - - }; - -}(jQuery)); diff --git a/uc_stripe.mail.inc b/uc_stripe.mail.inc deleted file mode 100644 index bc9f875..0000000 --- a/uc_stripe.mail.inc +++ /dev/null @@ -1,62 +0,0 @@ - $params['user'], 'authentication_key' => $params['hash']); - - $message['body'][]= token_replace($params['body'], $variables, array('language' => language_default(), 'callback' => 'uc_stripe_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE)); - - break; - } - -} \ No newline at end of file diff --git a/uc_stripe.pages.inc b/uc_stripe.pages.inc deleted file mode 100644 index d80ce8d..0000000 --- a/uc_stripe.pages.inc +++ /dev/null @@ -1,149 +0,0 @@ -fields('u', array('order_id', 'completed', 'rfee_id')) - ->condition('hash', $hash) - ->execute() - ->fetchObject(); - - - if(!$pending_order){ - $form['error'] = array( - '#markup' => t('Sorry, we could not verify your payment details. Please verify the link and try again. Contact support if the problem persists.'), - ); - return $form; - } - - $order_id = $pending_order->order_id; - $completed = $pending_order->completed; - $rfee_id = $pending_order->rfee_id; - - if ($completed) { - $form['error'] = array( - '#markup' => t('This payment has already been verified.'), - ); - return $form; - }; - - $form['heading'] = array( - '#markup' => t('

Your financial institution has requested additional verification to process your scheduled payment.

'), - ); - - $form['order_id'] = array( - '#type' => 'hidden', - '#value' => $order_id, - ); - - $form['rfee_id'] = array( - '#type' => 'hidden', - '#value' => $rfee_id, - ); - - $form['hash'] = array( - '#type' => 'hidden', - '#value' => $hash, - ); - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Verify Payment') - ); - - $order = uc_order_load($order_id); - $user = user_load($order->uid); - $payment_method_id = _uc_stripe_get_payment_id($user->uid); - $stripe_customer_id = _uc_stripe_get_customer_id($user->uid); - - $order_id = $order_id; - $apikey = variable_get('uc_stripe_testmode', TRUE) ? check_plain(variable_get('uc_stripe_api_key_test_publishable', '')) : check_plain(variable_get('uc_stripe_api_key_live_publishable', '')); - $settings = array('apikey' => $apikey, 'methodId' => $payment_method_id, 'orderId' => $order_id); - - //Attach Stripe v3 JS library and JS for processing payment - $form['#attached']['js']['https://js.stripe.com/v3/'] = array('type' => 'external'); - $form['#attached']['js'][] = array('data' => array('uc_stripe' => $settings), 'type' => 'setting'); - $form['#attached']['js'][] = drupal_get_path('module', 'uc_stripe') . '/js/uc_stripe_process_payment.js'; - $form['#attached']['css'][] = drupal_get_path('module', 'uc_stripe') . '/css/uc_stripe.css'; - - return $form; -} - -function uc_stripe_authenticate_payment_form_submit($form, &$form_state){ - - $order_id = $form_state['values']['order_id']; - $rfee_id = $form_state['values']['rfee_id']; - $hash = $form_state['values']['hash']; - - $order = uc_order_load($order_id); - $intent_id = $order->data['payment_intent_id']; - - try{ - _uc_stripe_prepare_api(); - $payment_intent = \Stripe\PaymentIntent::retrieve($intent_id); - - if ($payment_intent->status != 'succeeded') { - throw new Exception('Payment intent failed'); - } - - $charge_id = $payment_intent->charges->data[0]['id']; - $amount = uc_currency_format($order->order_total, FALSE, FALSE, FALSE); - - $formatted_amount = $amount / 100; - $formatted_amount = number_format($formatted_amount, 2); - - $message = t('Payment of @amount processed successfully, Stripe transaction id @transaction_id.', array('@amount' => $formatted_amount, '@transaction_id' => $charge_id)); - $COMPLETED = 1; - - //Set all orders matching the order id and fee id to completed. This is incase - // there were multiple attempts to process the subscription. - db_update('uc_stripe_pending_auth') - ->fields(array( - 'completed' => $COMPLETED, - )) - ->condition('order_id', $order_id) - ->condition('rfee_id', $rfee_id) - ->execute(); - - $fee = uc_recurring_fee_user_load($rfee_id); - uc_payment_enter($order->order_id, $order->payment_method, $order->order_total, $fee->uid, $payment_intent, "Success"); - - // Since we have processed the payment here already, we'll temporarily change the fee - // handler to the the default uc_recurring fee handler that simply returns TRUE - // without any processing. - $fee->fee_handler = 'default'; - $id = uc_recurring_renew($fee); - - // We need to reset the fee handler for this order back to uc_stripe so that - // future subscriptions work. - $fee = uc_recurring_fee_user_load($fee->rfid); - $fee->fee_handler = 'uc_stripe'; - uc_recurring_fee_user_save($fee); - - uc_order_comment_save($order_id, $order->uid, $message, 'admin'); - uc_order_comment_save($order_id, $order->uid, $message, 'order', 'completed', FALSE); - - $form_state['redirect'] = '/'; - drupal_set_message('You have successfully completed your payment'); - - } catch (Exception $e) { - - $message = t("Stripe Charge Failed for order !order: !message", array( - "!order" => $order_id, - "!message" => $e->getMessage() - )); - - uc_order_comment_save($order_id, $order->uid, $message, 'admin'); - watchdog('uc_stripe', 'Stripe charge failed for order @order, message: @message', array('@order' => $order_id, '@message' => $message)); - $fail_message = variable_get('uc_credit_fail_message', t('We were unable to process your credit card payment. Please verify your details and try again. If the problem persists, contact us to complete your order.')); - drupal_set_message($fail_message, 'error'); - - } -}