From b8ef6a1c0c072c50ada1f749b28eb513d4dd099f Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Mon, 31 May 2021 09:52:04 +1000 Subject: [PATCH 01/18] Added braintree.js onload callback to prevent braintree not defined error --- .../spree/braintree_vzero/_paypal_checkout.html.erb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/spree/braintree_vzero/_paypal_checkout.html.erb b/app/views/spree/braintree_vzero/_paypal_checkout.html.erb index 780e8fd..0a7e79f 100644 --- a/app/views/spree/braintree_vzero/_paypal_checkout.html.erb +++ b/app/views/spree/braintree_vzero/_paypal_checkout.html.erb @@ -4,7 +4,7 @@ - + - - + + + <% end %> From c91b50a6eb61f997aa0de9265276120114e6bfbf Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Wed, 14 Jul 2021 15:33:07 +1000 Subject: [PATCH 03/18] Add currency preference to backend: --- .../spree/admin/payment_methods_helper.rb | 2 +- .../braintree_vzero/_WIP_paypal.html.erb | 11 +++++ .../_non_three_d_secure.html.erb | 42 +++++++++++++++---- .../payment/braintree_vzero/_payment.html.erb | 11 +++-- 4 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb diff --git a/app/helpers/spree/admin/payment_methods_helper.rb b/app/helpers/spree/admin/payment_methods_helper.rb index 69d7b25..b7ed325 100644 --- a/app/helpers/spree/admin/payment_methods_helper.rb +++ b/app/helpers/spree/admin/payment_methods_helper.rb @@ -81,7 +81,7 @@ def braintree_advanced_preference_fields(object, form) end def get_preference_fields(object, keys, form) - keys.reject { |k| k == :currency_merchant_accounts }.map do |key| + keys.map do |key| next unless object.has_preference?(key) if object.preference_type(key) == :boolean diff --git a/app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb new file mode 100644 index 0000000..a26eb43 --- /dev/null +++ b/app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb @@ -0,0 +1,11 @@ +return setupPaypal(clientToken).then(function(paypalInstance) { + paypalInstance.loadPayPalSDK({ + vault: false + }, function() { + paypal.Buttons({ + fundingSource: paypal.FUNDING.PAYPAL, + createBillingAgreement: function () { + return paypalInstance.createPayment({ + flow: 'vault' // Required + }); + }, diff --git a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb index 4b158e6..79f30cf 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb @@ -74,7 +74,26 @@ function setupDropin (clientToken) { return braintree.dropin.create({ authorization: clientToken, - container: '#drop-in' + container: '#drop-in', + paypal: { + flow: 'vault', + buttonStyle: { + label: 'paypal', + tagline: false, + size: 'medium' + } + } + }) + } + + function setupPaypal (clientToken) { + return braintree.dropin.create({ + authorization: clientToken, + container: '#paypal-container', + card: false, + paypal: { + flow: 'vault' + } }) } @@ -86,8 +105,10 @@ <% elsif dropin %> return setupDropin(clientToken).then(function(instance) { dropin = instance; - <% end %> - + <% elsif paypal %> + return setupPaypal(clientToken).then(function(instance) { + paypal = instance; + <% end %> setupForm(); }).catch(function (err) { console.log('component error:', err); @@ -143,7 +164,7 @@ <% if hosted %> hf.tokenize().then(function (payload) { - <% elsif dropin %> + <% elsif dropin || paypal %> dropin.requestPaymentMethod( function(err, payload) { if (err) { @@ -156,10 +177,15 @@ } <% end %> - $(formId).append(""); - $(formId).append(""); - $(formId).append(""); - $(formId).append(""); + if (payload.type == "CreditCard") { + $(formId).append(""); + $(formId).append(""); + $(formId).append(""); + $(formId).append(""); + } else if (payload.type == "PayPalAccount") { + $(formId).append(""); + $(formId).append(""); + } setTimeout(function () { $(payBtn).attr("disabled", false) $('#checkout form').submit() diff --git a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb index e5e77f4..c069081 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb @@ -17,7 +17,6 @@ <% end %> <% end %> -
<% if paypal %>
@@ -89,15 +88,19 @@ <% elsif dropin %> - + +<% elsif paypal %> + + + <% end %> <% if payment_method.try(:preferred_3dsecure) == "true" %> <%= render partial: 'spree/checkout/payment/braintree_vzero/three_d_secure', - locals: { payment_method: payment_method, hosted: hosted, dropin: dropin } + locals: { payment_method: payment_method, hosted: hosted, dropin: dropin, paypal: paypal } %> <% else %> <%= render partial: 'spree/checkout/payment/braintree_vzero/non_three_d_secure', - locals: { payment_method: payment_method, hosted: hosted, dropin: dropin } + locals: { payment_method: payment_method, hosted: hosted, dropin: dropin, paypal: paypal } %> <% end %> From 5dec32e46de1887fb4ed7a9cda6489917c0f3b52 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Thu, 5 Aug 2021 16:48:08 +1000 Subject: [PATCH 04/18] Added device data to non-3D secure for advanced fraud prevention --- .../payment/braintree_vzero/_non_three_d_secure.html.erb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb index 79f30cf..62ef8f8 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb @@ -75,6 +75,7 @@ return braintree.dropin.create({ authorization: clientToken, container: '#drop-in', + dataCollector: true, paypal: { flow: 'vault', buttonStyle: { @@ -177,13 +178,14 @@ } <% end %> + $(formId).append(""); + $(formId).append(""); + if (payload.type == "CreditCard") { $(formId).append(""); $(formId).append(""); - $(formId).append(""); $(formId).append(""); } else if (payload.type == "PayPalAccount") { - $(formId).append(""); $(formId).append(""); } setTimeout(function () { From f86937649350edabfd96e08d1ba3b9ec72917741 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Sat, 7 Aug 2021 23:21:02 +1000 Subject: [PATCH 05/18] Added recaptcha v2 to prevent fraud --- .../spree/checkout/payment/braintree_vzero/_payment.html.erb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb index c069081..9ddb83a 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb @@ -61,7 +61,10 @@ <% end %> <% elsif dropin %> + +
+
<% end %> From 52741773bbe7886743ca63be14c8fd960d70343e Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Mon, 9 Aug 2021 11:58:09 +1000 Subject: [PATCH 06/18] Added recaptcha_tags for recaptcha gem --- .../spree/checkout/payment/braintree_vzero/_payment.html.erb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb index 9ddb83a..e1c65d5 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb @@ -34,6 +34,8 @@
<% end %> + <%= recaptcha_tags %> + <% if hosted || dropin %> <% if hosted %>
@@ -61,10 +63,7 @@ <% end %> <% elsif dropin %> - -
-
<% end %> From 0c877b0c7419bf10864ed930bffb6610329b7cb2 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Tue, 10 Aug 2021 15:06:26 +1000 Subject: [PATCH 07/18] Implement braintree-submit button to allow use of gift certificate --- app/overrides/spree/checkout/_payment.rb | 2 +- .../payment/braintree_vzero/_buttons.html.erb | 2 +- .../braintree_vzero/_non_three_d_secure.html.erb | 14 +++++++++----- .../payment/braintree_vzero/_payment.html.erb | 2 -- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/overrides/spree/checkout/_payment.rb b/app/overrides/spree/checkout/_payment.rb index f6c1e68..bea3d94 100644 --- a/app/overrides/spree/checkout/_payment.rb +++ b/app/overrides/spree/checkout/_payment.rb @@ -13,7 +13,7 @@ ) Deface::Override.new( - virtual_path: 'spree/checkout/_payment', + virtual_path: 'spree/checkout/edit', name: 'Adds necessary buttons for Braintree payment methods', insert_after: 'erb[loud]:contains("submit_tag")', partial: 'spree/checkout/payment/braintree_vzero/buttons' diff --git a/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb index ac441e7..d2efaa2 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb @@ -6,6 +6,6 @@ <%= Spree.t(:save_and_continue) %> <% else %> - <%= submit_tag Spree.t(:save_and_continue), class: 'btn btn-lg btn-success primary braintree-submit', style: 'display: none;', method_id: method.id %> + <%= submit_tag Spree.t(submit_label_key), class: 'btn btn-primary text-uppercase font-weight-bold w-100 checkout-content-save-continue-button braintree-submit', style: 'display: none;', method_id: method.id %> <% end %> <% end %> diff --git a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb index 62ef8f8..bfc8ca9 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb @@ -7,11 +7,15 @@ function setupPayment() { $('#order_payments_attributes__payment_method_id_<%= payment_method.id %>').click(function (e) { - var threeDSecure; - var checkoutFormId = "<%= payment_method.preferred_checkout_form_id %>" - var formId = "#" + checkoutFormId; + var checkoutFormId = "<%= payment_method.preferred_checkout_form_id %>" + SpreeBraintreeVzero.advancedFraudTools = <%= payment_method.preferred_advanced_fraud_tools %>; + SpreeBraintreeVzero.paymentMethodID = "<%= payment_method.id %>"; + SpreeBraintreeVzero.checkoutFormId = "#" + checkoutFormId; + SpreeBraintreeVzero.threeDSecure = <%= payment_method.try(:preferred_3dsecure) || false %>; - var clientToken = "<%= payment_method.client_token(@order) %>"; + var formId = "#" + checkoutFormId; + + var clientToken = "<%= payment_method.client_token(@order) %>"; <% if hosted %> var hf, threeDS; @@ -20,7 +24,7 @@ var dropin; <% end %> - var payBtn = document.getElementsByName('commit')[0]; + var payBtn = document.getElementsByClassName('braintree-submit')[0]; var payGroup = $('.pay-group'); $('.credit-card-pay-success').css('display', 'none'); diff --git a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb index e1c65d5..c069081 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb @@ -34,8 +34,6 @@
<% end %> - <%= recaptcha_tags %> - <% if hosted || dropin %> <% if hosted %>
From 8065e69862f8fa70da138ca54d3c54ce1349f8ee Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Sun, 15 Aug 2021 21:35:45 +1000 Subject: [PATCH 08/18] Move update_source_data to be called inside update action --- app/controllers/spree/checkout_controller_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/spree/checkout_controller_decorator.rb b/app/controllers/spree/checkout_controller_decorator.rb index e6a6d59..5193a54 100644 --- a/app/controllers/spree/checkout_controller_decorator.rb +++ b/app/controllers/spree/checkout_controller_decorator.rb @@ -4,7 +4,7 @@ def self.prepended(base) base.include Spree::BraintreeHelper base.helper_method [:asset_available?, :options_from_braintree_payments] base.after_action :allow_braintree_iframe - base.after_action :update_source_data, only: :update, if: proc { params[:state].eql?('payment') } + #base.after_action :update_source_data, only: :update, if: proc { params[:state].eql?('payment') } end private From 84c5bf6c78bf1c95cd8f24730d68bf9a7013db8d Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Fri, 20 Aug 2021 17:31:52 +1000 Subject: [PATCH 09/18] Fix issue with provider method --- app/models/spree/payment_processing_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/spree/payment_processing_decorator.rb b/app/models/spree/payment_processing_decorator.rb index 12200a3..d5ab811 100644 --- a/app/models/spree/payment_processing_decorator.rb +++ b/app/models/spree/payment_processing_decorator.rb @@ -65,7 +65,7 @@ def handle_payment_preconditions end def braintree_payment_method? - payment_method.provider == Braintree + payment_method.try(:provider) == Braintree end end end From 4d3801dbd31472fe03c132e48db328b583c902d9 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Tue, 24 Aug 2021 12:09:38 +1000 Subject: [PATCH 10/18] Update backend dropin --- .../braintree_vzero/_payments.html.erb | 27 +-- .../shared/braintree_vzero/_dropin.js.erb | 161 +++++++++++------- 2 files changed, 115 insertions(+), 73 deletions(-) diff --git a/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb b/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb index 24f6a22..b6189f4 100644 --- a/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb +++ b/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb @@ -44,9 +44,7 @@


<% elsif dropin %> -
-
<% end %>
@@ -55,8 +53,17 @@ <% end %>
- - +<% if hosted %> + + + +<% elsif dropin %> + +<% elsif paypal %> + + + +<% end %> diff --git a/app/views/spree/shared/braintree_vzero/_dropin.js.erb b/app/views/spree/shared/braintree_vzero/_dropin.js.erb index af2ab79..9c97c5f 100644 --- a/app/views/spree/shared/braintree_vzero/_dropin.js.erb +++ b/app/views/spree/shared/braintree_vzero/_dropin.js.erb @@ -1,70 +1,109 @@ -container: container, -paypal: { - singleUse: <%= payment_method.preferred_store_payments_in_vault.eql?('do_not_store') %>, - amount: <%= @order.order_total_after_store_credit %>, - currency: "<%= current_currency %>", - enableShippingAddress: true, - shippingAddressOverride: { - recipientName: '<%= "#{shipping_address.firstname} #{shipping_address.lastname}" %>', - streetAddress: '<%= shipping_address.address1 %>', - extendedAddress: '<%= shipping_address.address2 %>', - locality: '<%= shipping_address.city %>', - countryCodeAlpha2: '<%= shipping_address.country.try(:iso) %>', - postalCode: '<%= shipping_address.zipcode %>', - region: '<%= shipping_address.state.try(:abbr) %>', - phone: '<%= shipping_address.phone %>', - editable: false +if(document.readyState !== 'loading') { + setupPayment() +} else { + window.addEventListener('DOMContentLoaded', setupPayment); +} + +function setupPayment() { + var formId = "#" + checkoutFormId; + var dropin; + var payBtn = document.getElementsByClassName('braintree-submit')[0]; + var payGroup = $('.pay-group'); + + function start() { + getClientToken(); } -}, - -onPaymentMethodReceived: function (result) { - var formId = "#" + checkoutFormId; - - function submitWithAttributes(data) { - switch (data.type) { - case "CreditCard": - $(formId).append(""); - $(formId).append(""); - break; - case "PayPalAccount": - $(formId).append(""); - break; - } - if(SpreeBraintreeVzero.admin) - $(formId).append(""); - else - $(formId).append(""); - $(formId)[0].submit(); + + function getClientToken() { + onFetchClientToken(clientToken); + } + + function setupDropin (clientToken) { + return braintree.dropin.create({ + authorization: clientToken, + container: '#' + container + }) } - if (SpreeBraintreeVzero.threeDSecure && result.type == "CreditCard") { - var client = new braintree.api.Client({ - clientToken: clientToken + function onFetchClientToken(clientToken) { + return setupDropin(clientToken).then(function(instance) { + dropin = instance; + setupForm(); + }).catch(function (err) { + console.log('component error:', err); }); + } + + function setupForm() { + enablePayNow(); + } + + function enablePayNow() { + payBtn.value = "<%= Spree.t(:save_and_continue) %>"; + payBtn.removeAttribute('disabled'); + } - client.verify3DS({ - amount: <%= @order.order_total_after_store_credit %>, - creditCard: result.nonce - }, function (error, response) { - if (!error) { - submitWithAttributes(response); - } else { - $(errorMessagesContainer).prepend("
<%= I18n.t(:gateway_error, scope: 'braintree.error') %>
") + function showErrors(err) { + if (err) { + if (err.details && err.details.invalidFields) { + const invalidFields = [] + Object.keys(err.details.invalidFields).forEach(function (key) { + if (key === "expirationDate") { + invalidFields.push("expiration") + } else { + invalidFields.push(key) + } + }) + const errorString = invalidFields.join(", ") + const linkingVerb = invalidFields.length > 1 ? "are" : "is" + + $('.credit-card-pay-errors').text("Card " + errorString + " " + linkingVerb + " incorrect.") + } } - }); - } else { - submitWithAttributes(result); - } -}, + payGroup.addClass('hidden'); + payGroup.css('display', 'none'); + $('.credit-card-pay-success').css('display', 'none'); + $('.credit-card-pay-errors').css('display', 'block'); + } -onReady: function (integration) { - if(!SpreeBraintreeVzero.admin) - SpreeBraintreeVzero.deviceData = integration.deviceData; - <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_ready_callback', formats: [:js] %> -}, + function showSuccess() { + payGroup.addClass('hidden'); + payGroup.css('display', 'none'); + $('.credit-card-pay-success').css('display', 'block'); + $('.credit-card-pay-errors').css('display', 'none'); + } -onError: function (error) { - SpreeBraintreeVzero.enableSubmitButton(); - <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_error_callback', formats: [:js] %> -} + payBtn.addEventListener('click', function(event) { + event.preventDefault() + payBtn.setAttribute('disabled', 'disabled'); + payBtn.value = "<%= Spree.t(:processing_credit_card) %>"; + dropin.requestPaymentMethod( + function(err, payload) { + if (err) { + console.log('tokenization error:'); + console.log(err); + dropin.clearSelectedPaymentMethod(); + enablePayNow(); + + return; + } + + $(formId).append(""); + + if (payload.type == "CreditCard") { + $(formId).append(""); + $(formId).append(""); + $(formId).append(""); + } else if (payload.type == "PayPalAccount") { + $(formId).append(""); + } + setTimeout(function () { + $(payBtn).attr("disabled", false) + $(formId).submit() + }, 200); + }); + }); + + start(); + } From ebf622c62c3b9450075a3ff2b2ed270438b3a250 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Tue, 24 Aug 2021 12:33:38 +1000 Subject: [PATCH 11/18] Remove redundant JS functions --- .../shared/braintree_vzero/_dropin.js.erb | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/app/views/spree/shared/braintree_vzero/_dropin.js.erb b/app/views/spree/shared/braintree_vzero/_dropin.js.erb index 9c97c5f..9517826 100644 --- a/app/views/spree/shared/braintree_vzero/_dropin.js.erb +++ b/app/views/spree/shared/braintree_vzero/_dropin.js.erb @@ -42,37 +42,7 @@ function setupPayment() { payBtn.value = "<%= Spree.t(:save_and_continue) %>"; payBtn.removeAttribute('disabled'); } - - function showErrors(err) { - if (err) { - if (err.details && err.details.invalidFields) { - const invalidFields = [] - Object.keys(err.details.invalidFields).forEach(function (key) { - if (key === "expirationDate") { - invalidFields.push("expiration") - } else { - invalidFields.push(key) - } - }) - const errorString = invalidFields.join(", ") - const linkingVerb = invalidFields.length > 1 ? "are" : "is" - - $('.credit-card-pay-errors').text("Card " + errorString + " " + linkingVerb + " incorrect.") - } - } - payGroup.addClass('hidden'); - payGroup.css('display', 'none'); - $('.credit-card-pay-success').css('display', 'none'); - $('.credit-card-pay-errors').css('display', 'block'); - } - - function showSuccess() { - payGroup.addClass('hidden'); - payGroup.css('display', 'none'); - $('.credit-card-pay-success').css('display', 'block'); - $('.credit-card-pay-errors').css('display', 'none'); - } - + payBtn.addEventListener('click', function(event) { event.preventDefault() payBtn.setAttribute('disabled', 'disabled'); From 2222966526321b0392abca969b21600c8f34142d Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Tue, 24 May 2022 14:12:30 +1000 Subject: [PATCH 12/18] Remove logos from payment partial --- app/overrides/spree/shared/_payment.rb | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/app/overrides/spree/shared/_payment.rb b/app/overrides/spree/shared/_payment.rb index 15b452e..4f33545 100644 --- a/app/overrides/spree/shared/_payment.rb +++ b/app/overrides/spree/shared/_payment.rb @@ -5,24 +5,14 @@ text: %{ <% elsif payment.payment_method.kind_of?(Spree::Gateway::BraintreeVzeroBase) %> <% if (last_digits = payment.source.braintree_last_digits) %> - <% - cc_type = payment.source.braintree_card_type - img = "credit_cards/icons/" + cc_type.downcase + ".png" - %> - <% if asset_available?(img) %> - <%= image_tag img %> - <% else %> -

<%= Spree.t(:cc_type) + ": " + cc_type %>

-
- <% end %> + <% cc_type = payment.source.braintree_card_type %> +

<%= cc_type %>

<%= Spree.t(:ending_in) + " " + last_digits %>

<% end %> - <% if (paypal_email = payment.source.paypal_email) %> - PayPal Logo - <%= paypal_email %> +

Paypal

+

<%= paypal_email %>

<% end %> - <% else %> } ) From 72179b6acf1186daa921c149f24c1e713ce6b9ad Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Tue, 24 May 2022 14:47:06 +1000 Subject: [PATCH 13/18] Update formatting of payment partial --- app/overrides/spree/shared/_payment.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/overrides/spree/shared/_payment.rb b/app/overrides/spree/shared/_payment.rb index 4f33545..5873670 100644 --- a/app/overrides/spree/shared/_payment.rb +++ b/app/overrides/spree/shared/_payment.rb @@ -5,13 +5,16 @@ text: %{ <% elsif payment.payment_method.kind_of?(Spree::Gateway::BraintreeVzeroBase) %> <% if (last_digits = payment.source.braintree_last_digits) %> - <% cc_type = payment.source.braintree_card_type %> -

<%= cc_type %>

-

<%= Spree.t(:ending_in) + " " + last_digits %>

+

+ <%= payment.source.braintree_card_type.capitalize %>
+ <%= Spree.t(:ending_in) + " " + last_digits %> +

<% end %> <% if (paypal_email = payment.source.paypal_email) %> -

Paypal

-

<%= paypal_email %>

+

+ Paypal
+ <%= paypal_email %> +

<% end %> <% else %> } From 95363bee65ea0218e7fc7d0e9f52fe2022bd9a1e Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Thu, 1 Sep 2022 16:04:11 +1000 Subject: [PATCH 14/18] Add v2 API endpoint for Vue Spree support --- .../v2/braintree_client_token_controller.rb | 24 +++++++++++++++++++ ...end_spree_permitted_checkout_attributes.rb | 7 ++++++ config/routes.rb | 3 +++ 3 files changed, 34 insertions(+) create mode 100644 app/controllers/spree/api/v2/braintree_client_token_controller.rb diff --git a/app/controllers/spree/api/v2/braintree_client_token_controller.rb b/app/controllers/spree/api/v2/braintree_client_token_controller.rb new file mode 100644 index 0000000..1fdfa8b --- /dev/null +++ b/app/controllers/spree/api/v2/braintree_client_token_controller.rb @@ -0,0 +1,24 @@ +module Spree + module Api + module V2 + class BraintreeClientTokenController < ::Spree::Api::V2::BaseController + include Spree::Api::V2::Storefront::OrderConcern + before_action :ensure_order + + def create + gateway = if params[:payment_method_id] + Spree::Gateway::BraintreeVzeroBase.find(params[:payment_method_id]) + else + Spree::Gateway::BraintreeVzeroBase.active.first + end + + render json: { + client_token: gateway.client_token(spree_current_order, @current_api_user), + payment_method_id: gateway.id + } + end + + end + end + end +end diff --git a/config/initializers/extend_spree_permitted_checkout_attributes.rb b/config/initializers/extend_spree_permitted_checkout_attributes.rb index 2a610cb..75201d3 100644 --- a/config/initializers/extend_spree_permitted_checkout_attributes.rb +++ b/config/initializers/extend_spree_permitted_checkout_attributes.rb @@ -1,5 +1,12 @@ module Spree module PermittedAttributes @@payment_attributes = [:amount, :payment_method_id, :payment_method, :braintree_token, :braintree_nonce] + @@source_attributes = [ + :number, :month, :year, :expiry, :verification_value, + :first_name, :last_name, :cc_type, :gateway_customer_profile_id, + :gateway_payment_profile_id, :last_digits, :name, :encrypted_data, + # Add Braintree params to allow source to be created + :braintree_last_two, :braintree_card_type, :braintree_nonce + ] end end diff --git a/config/routes.rb b/config/routes.rb index 72ccda8..41339b2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,5 +3,8 @@ namespace :v1 do resource :braintree_client_token, only: :create, controller: 'braintree_client_token' end + namespace :v2 do + resource :braintree_client_token, only: :create, controller: 'braintree_client_token' + end end end From 5e27b00773f7a376e758eecdc2536fd5f0ec9627 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Thu, 1 Sep 2022 20:56:21 +1000 Subject: [PATCH 15/18] Revert to master --- .../spree/checkout_controller_decorator.rb | 2 +- .../spree/admin/payment_methods_helper.rb | 2 +- .../spree/braintree_vzero/order_decorator.rb | 4 +- app/overrides/spree/shared/_payment.rb | 23 ++-- .../_braintree_vzero_form.html.erb | 5 - .../braintree_vzero/_payments.html.erb | 28 ++-- .../braintree_vzero/_paypal_checkout.html.erb | 3 - .../braintree_vzero/_WIP_paypal.html.erb | 11 -- .../payment/braintree_vzero/_buttons.html.erb | 2 +- .../_non_three_d_secure.html.erb | 56 ++------ .../payment/braintree_vzero/_payment.html.erb | 11 +- .../shared/braintree_vzero/_dropin.js.erb | 130 ++++++++---------- 12 files changed, 108 insertions(+), 169 deletions(-) delete mode 100644 app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb diff --git a/app/controllers/spree/checkout_controller_decorator.rb b/app/controllers/spree/checkout_controller_decorator.rb index 5193a54..e6a6d59 100644 --- a/app/controllers/spree/checkout_controller_decorator.rb +++ b/app/controllers/spree/checkout_controller_decorator.rb @@ -4,7 +4,7 @@ def self.prepended(base) base.include Spree::BraintreeHelper base.helper_method [:asset_available?, :options_from_braintree_payments] base.after_action :allow_braintree_iframe - #base.after_action :update_source_data, only: :update, if: proc { params[:state].eql?('payment') } + base.after_action :update_source_data, only: :update, if: proc { params[:state].eql?('payment') } end private diff --git a/app/helpers/spree/admin/payment_methods_helper.rb b/app/helpers/spree/admin/payment_methods_helper.rb index b7ed325..69d7b25 100644 --- a/app/helpers/spree/admin/payment_methods_helper.rb +++ b/app/helpers/spree/admin/payment_methods_helper.rb @@ -81,7 +81,7 @@ def braintree_advanced_preference_fields(object, form) end def get_preference_fields(object, keys, form) - keys.map do |key| + keys.reject { |k| k == :currency_merchant_accounts }.map do |key| next unless object.has_preference?(key) if object.preference_type(key) == :boolean diff --git a/app/models/spree/braintree_vzero/order_decorator.rb b/app/models/spree/braintree_vzero/order_decorator.rb index 3ef5d20..49a3c01 100644 --- a/app/models/spree/braintree_vzero/order_decorator.rb +++ b/app/models/spree/braintree_vzero/order_decorator.rb @@ -116,9 +116,7 @@ def remove_phone_number_placeholder def braintree_confirmation_required? - # Updated so only Paypal Express payments require confirmation - #paid_with_braintree? && state.eql?('payment') - paid_with_paypal_express? + paid_with_braintree? && state.eql?('payment') end def prepare_address_hash(hash) diff --git a/app/overrides/spree/shared/_payment.rb b/app/overrides/spree/shared/_payment.rb index 5873670..3836ee2 100644 --- a/app/overrides/spree/shared/_payment.rb +++ b/app/overrides/spree/shared/_payment.rb @@ -5,17 +5,24 @@ text: %{ <% elsif payment.payment_method.kind_of?(Spree::Gateway::BraintreeVzeroBase) %> <% if (last_digits = payment.source.braintree_last_digits) %> -

- <%= payment.source.braintree_card_type.capitalize %>
- <%= Spree.t(:ending_in) + " " + last_digits %> -

+ <% + cc_type = payment.source.braintree_card_type + img = "credit_cards/icons/" + cc_type.downcase + ".png" + %> + <% if asset_available?(img) %> + <%= image_tag img %> + <% else %> +

<%= Spree.t(:cc_type) + ": " + cc_type %>

+
+ <% end %> +

<%= Spree.t(:ending_in) + " " + last_digits %>

<% end %> + <% if (paypal_email = payment.source.paypal_email) %> -

- Paypal
- <%= paypal_email %> -

+ PayPal Logo + <%= paypal_email %> <% end %> + <% else %> } ) diff --git a/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb b/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb index bc34b50..c5183e9 100644 --- a/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb +++ b/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb @@ -25,11 +25,6 @@ <% end %> <% end %> - <%= f.field_container :payment_method_stores, class: ['form-group'] do %> - <%= label_tag :payment_method_stores, Spree.t(:stores) %> - <%= collection_select(:payment_method, :store_ids, @stores, :id, :unique_name, {}, { multiple: true, class: 'select2' }) %> - <% end %> - <%= f.field_container :payment_method_display_on, class: ['form-group'] do %> <%= label_tag :payment_method_display_on, Spree.t(:display) %> <%= select(:payment_method, :display_on, Spree::PaymentMethod::DISPLAY.collect { |display| [Spree.t(display), display.to_s] }, {}, {:class => 'select2'}) %> diff --git a/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb b/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb index b6189f4..8932090 100644 --- a/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb +++ b/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb @@ -44,7 +44,9 @@


<% elsif dropin %> +
+
<% end %>
@@ -53,17 +55,8 @@ <% end %>
-<% if hosted %> - - - -<% elsif dropin %> - -<% elsif paypal %> - - - -<% end %> + + diff --git a/app/views/spree/braintree_vzero/_paypal_checkout.html.erb b/app/views/spree/braintree_vzero/_paypal_checkout.html.erb index decea70..0a7e79f 100644 --- a/app/views/spree/braintree_vzero/_paypal_checkout.html.erb +++ b/app/views/spree/braintree_vzero/_paypal_checkout.html.erb @@ -102,7 +102,4 @@ } - - - <% end %> diff --git a/app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb deleted file mode 100644 index a26eb43..0000000 --- a/app/views/spree/checkout/payment/braintree_vzero/_WIP_paypal.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -return setupPaypal(clientToken).then(function(paypalInstance) { - paypalInstance.loadPayPalSDK({ - vault: false - }, function() { - paypal.Buttons({ - fundingSource: paypal.FUNDING.PAYPAL, - createBillingAgreement: function () { - return paypalInstance.createPayment({ - flow: 'vault' // Required - }); - }, diff --git a/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb index d2efaa2..ac441e7 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb @@ -6,6 +6,6 @@ <%= Spree.t(:save_and_continue) %> <% else %> - <%= submit_tag Spree.t(submit_label_key), class: 'btn btn-primary text-uppercase font-weight-bold w-100 checkout-content-save-continue-button braintree-submit', style: 'display: none;', method_id: method.id %> + <%= submit_tag Spree.t(:save_and_continue), class: 'btn btn-lg btn-success primary braintree-submit', style: 'display: none;', method_id: method.id %> <% end %> <% end %> diff --git a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb index bfc8ca9..4b158e6 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_non_three_d_secure.html.erb @@ -7,15 +7,11 @@ function setupPayment() { $('#order_payments_attributes__payment_method_id_<%= payment_method.id %>').click(function (e) { - var checkoutFormId = "<%= payment_method.preferred_checkout_form_id %>" - SpreeBraintreeVzero.advancedFraudTools = <%= payment_method.preferred_advanced_fraud_tools %>; - SpreeBraintreeVzero.paymentMethodID = "<%= payment_method.id %>"; - SpreeBraintreeVzero.checkoutFormId = "#" + checkoutFormId; - SpreeBraintreeVzero.threeDSecure = <%= payment_method.try(:preferred_3dsecure) || false %>; + var threeDSecure; + var checkoutFormId = "<%= payment_method.preferred_checkout_form_id %>" + var formId = "#" + checkoutFormId; - var formId = "#" + checkoutFormId; - - var clientToken = "<%= payment_method.client_token(@order) %>"; + var clientToken = "<%= payment_method.client_token(@order) %>"; <% if hosted %> var hf, threeDS; @@ -24,7 +20,7 @@ var dropin; <% end %> - var payBtn = document.getElementsByClassName('braintree-submit')[0]; + var payBtn = document.getElementsByName('commit')[0]; var payGroup = $('.pay-group'); $('.credit-card-pay-success').css('display', 'none'); @@ -78,27 +74,7 @@ function setupDropin (clientToken) { return braintree.dropin.create({ authorization: clientToken, - container: '#drop-in', - dataCollector: true, - paypal: { - flow: 'vault', - buttonStyle: { - label: 'paypal', - tagline: false, - size: 'medium' - } - } - }) - } - - function setupPaypal (clientToken) { - return braintree.dropin.create({ - authorization: clientToken, - container: '#paypal-container', - card: false, - paypal: { - flow: 'vault' - } + container: '#drop-in' }) } @@ -110,10 +86,8 @@ <% elsif dropin %> return setupDropin(clientToken).then(function(instance) { dropin = instance; - <% elsif paypal %> - return setupPaypal(clientToken).then(function(instance) { - paypal = instance; - <% end %> + <% end %> + setupForm(); }).catch(function (err) { console.log('component error:', err); @@ -169,7 +143,7 @@ <% if hosted %> hf.tokenize().then(function (payload) { - <% elsif dropin || paypal %> + <% elsif dropin %> dropin.requestPaymentMethod( function(err, payload) { if (err) { @@ -182,16 +156,10 @@ } <% end %> + $(formId).append(""); + $(formId).append(""); $(formId).append(""); - $(formId).append(""); - - if (payload.type == "CreditCard") { - $(formId).append(""); - $(formId).append(""); - $(formId).append(""); - } else if (payload.type == "PayPalAccount") { - $(formId).append(""); - } + $(formId).append(""); setTimeout(function () { $(payBtn).attr("disabled", false) $('#checkout form').submit() diff --git a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb index c5c47bd..95f0229 100644 --- a/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +++ b/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb @@ -17,6 +17,7 @@
<% end %> <% end %> +
<% if paypal %>
@@ -88,19 +89,15 @@ <% elsif dropin %> - -<% elsif paypal %> - - - + <% end %> <% if payment_method.try(:preferred_3dsecure) == "true" %> <%= render partial: 'spree/checkout/payment/braintree_vzero/three_d_secure', - locals: { payment_method: payment_method, hosted: hosted, dropin: dropin, paypal: paypal } + locals: { payment_method: payment_method, hosted: hosted, dropin: dropin } %> <% else %> <%= render partial: 'spree/checkout/payment/braintree_vzero/non_three_d_secure', - locals: { payment_method: payment_method, hosted: hosted, dropin: dropin, paypal: paypal } + locals: { payment_method: payment_method, hosted: hosted, dropin: dropin } %> <% end %> diff --git a/app/views/spree/shared/braintree_vzero/_dropin.js.erb b/app/views/spree/shared/braintree_vzero/_dropin.js.erb index 9517826..bbedfbb 100644 --- a/app/views/spree/shared/braintree_vzero/_dropin.js.erb +++ b/app/views/spree/shared/braintree_vzero/_dropin.js.erb @@ -1,79 +1,69 @@ -if(document.readyState !== 'loading') { - setupPayment() -} else { - window.addEventListener('DOMContentLoaded', setupPayment); -} - -function setupPayment() { - var formId = "#" + checkoutFormId; - var dropin; - var payBtn = document.getElementsByClassName('braintree-submit')[0]; - var payGroup = $('.pay-group'); - - function start() { - getClientToken(); +container: container, +paypal: { + singleUse: <%= payment_method.preferred_store_payments_in_vault.eql?('do_not_store') %>, + amount: <%= @order.order_total_after_store_credit %>, + currency: "<%= current_currency %>", + enableShippingAddress: true, + shippingAddressOverride: { + recipientName: '<%= "#{shipping_address.firstname} #{shipping_address.lastname}" %>', + streetAddress: '<%= shipping_address.address1 %>', + extendedAddress: '<%= shipping_address.address2 %>', + locality: '<%= shipping_address.city %>', + countryCodeAlpha2: '<%= shipping_address.country.try(:iso) %>', + postalCode: '<%= shipping_address.zipcode %>', + region: '<%= shipping_address.state.try(:abbr) %>', + phone: '<%= shipping_address.phone %>', + editable: false } +}, - function getClientToken() { - onFetchClientToken(clientToken); - } +onPaymentMethodReceived: function (result) { + var formId = "#" + checkoutFormId; - function setupDropin (clientToken) { - return braintree.dropin.create({ - authorization: clientToken, - container: '#' + container - }) + function submitWithAttributes(data) { + switch (data.type) { + case "CreditCard": + $(formId).append(""); + $(formId).append(""); + break; + case "PayPalAccount": + $(formId).append(""); + break; + } + if(SpreeBraintreeVzero.admin) + $(formId).append(""); + else + $(formId).append(""); + $(formId)[0].submit(); } - function onFetchClientToken(clientToken) { - return setupDropin(clientToken).then(function(instance) { - dropin = instance; - setupForm(); - }).catch(function (err) { - console.log('component error:', err); + if (SpreeBraintreeVzero.threeDSecure && result.type == "CreditCard") { + var client = new braintree.api.Client({ + clientToken: clientToken }); - } - - function setupForm() { - enablePayNow(); - } - function enablePayNow() { - payBtn.value = "<%= Spree.t(:save_and_continue) %>"; - payBtn.removeAttribute('disabled'); - } - - payBtn.addEventListener('click', function(event) { - event.preventDefault() - payBtn.setAttribute('disabled', 'disabled'); - payBtn.value = "<%= Spree.t(:processing_credit_card) %>"; - - dropin.requestPaymentMethod( - function(err, payload) { - if (err) { - console.log('tokenization error:'); - console.log(err); - dropin.clearSelectedPaymentMethod(); - enablePayNow(); - - return; - } - - $(formId).append(""); + client.verify3DS({ + amount: <%= @order.order_total_after_store_credit %>, + creditCard: result.nonce + }, function (error, response) { + if (!error) { + submitWithAttributes(response); + } else { + $(errorMessagesContainer).prepend("
<%= I18n.t(:gateway_error, scope: 'braintree.error') %>
") + } + }); + } else { + submitWithAttributes(result); + } +}, - if (payload.type == "CreditCard") { - $(formId).append(""); - $(formId).append(""); - $(formId).append(""); - } else if (payload.type == "PayPalAccount") { - $(formId).append(""); - } - setTimeout(function () { - $(payBtn).attr("disabled", false) - $(formId).submit() - }, 200); - }); - }); +onReady: function (integration) { + if(!SpreeBraintreeVzero.admin) + SpreeBraintreeVzero.deviceData = integration.deviceData; + <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_ready_callback', formats: [:js] %> +}, - start(); - } +onError: function (error) { + SpreeBraintreeVzero.enableSubmitButton(); + <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_error_callback', formats: [:js] %> +} From bf1ed15c692a3100861f4965a816a1142e173877 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Thu, 1 Sep 2022 21:02:43 +1000 Subject: [PATCH 16/18] Revert back to master --- app/models/spree/braintree_vzero/order_decorator.rb | 1 - app/overrides/spree/checkout/_payment.rb | 2 +- app/overrides/spree/shared/_payment.rb | 2 +- .../payments/source_forms/braintree_vzero/_payments.html.erb | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/models/spree/braintree_vzero/order_decorator.rb b/app/models/spree/braintree_vzero/order_decorator.rb index 49a3c01..4ac5007 100644 --- a/app/models/spree/braintree_vzero/order_decorator.rb +++ b/app/models/spree/braintree_vzero/order_decorator.rb @@ -114,7 +114,6 @@ def remove_phone_number_placeholder private - def braintree_confirmation_required? paid_with_braintree? && state.eql?('payment') end diff --git a/app/overrides/spree/checkout/_payment.rb b/app/overrides/spree/checkout/_payment.rb index bea3d94..f6c1e68 100644 --- a/app/overrides/spree/checkout/_payment.rb +++ b/app/overrides/spree/checkout/_payment.rb @@ -13,7 +13,7 @@ ) Deface::Override.new( - virtual_path: 'spree/checkout/edit', + virtual_path: 'spree/checkout/_payment', name: 'Adds necessary buttons for Braintree payment methods', insert_after: 'erb[loud]:contains("submit_tag")', partial: 'spree/checkout/payment/braintree_vzero/buttons' diff --git a/app/overrides/spree/shared/_payment.rb b/app/overrides/spree/shared/_payment.rb index 3836ee2..2529b15 100644 --- a/app/overrides/spree/shared/_payment.rb +++ b/app/overrides/spree/shared/_payment.rb @@ -22,7 +22,7 @@ PayPal Logo <%= paypal_email %> <% end %> - + <% else %> } ) diff --git a/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb b/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb index 8932090..24f6a22 100644 --- a/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb +++ b/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb @@ -80,7 +80,6 @@ var checkout; braintree.setup(clientToken, '<%= payment_method_type %>', { - <%= render(partial: 'spree/shared/braintree_vzero/dropin', locals: { shipping_address: shipping_address, payment_method: payment_method }, formats: [:js]) if dropin %> <%= render(partial: 'spree/shared/braintree_vzero/hosted', locals: { payment_method: payment_method }, formats: [:js]) if hosted %> }); From 931b703b0531e7ac985ce50870ff0f491ffc3840 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Thu, 1 Sep 2022 21:10:14 +1000 Subject: [PATCH 17/18] Revert changes to master --- app/overrides/spree/shared/_payment.rb | 2 +- app/views/spree/shared/braintree_vzero/_dropin.js.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/overrides/spree/shared/_payment.rb b/app/overrides/spree/shared/_payment.rb index 2529b15..15b452e 100644 --- a/app/overrides/spree/shared/_payment.rb +++ b/app/overrides/spree/shared/_payment.rb @@ -22,7 +22,7 @@ PayPal Logo <%= paypal_email %> <% end %> - + <% else %> } ) diff --git a/app/views/spree/shared/braintree_vzero/_dropin.js.erb b/app/views/spree/shared/braintree_vzero/_dropin.js.erb index bbedfbb..3e75c59 100644 --- a/app/views/spree/shared/braintree_vzero/_dropin.js.erb +++ b/app/views/spree/shared/braintree_vzero/_dropin.js.erb @@ -66,4 +66,4 @@ onReady: function (integration) { onError: function (error) { SpreeBraintreeVzero.enableSubmitButton(); <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_error_callback', formats: [:js] %> -} +} \ No newline at end of file From b6ee35b73e71564d73e775990d0ec037ad970d38 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Thu, 1 Sep 2022 21:12:27 +1000 Subject: [PATCH 18/18] Revert to master --- app/views/spree/shared/braintree_vzero/_dropin.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/shared/braintree_vzero/_dropin.js.erb b/app/views/spree/shared/braintree_vzero/_dropin.js.erb index 3e75c59..bbedfbb 100644 --- a/app/views/spree/shared/braintree_vzero/_dropin.js.erb +++ b/app/views/spree/shared/braintree_vzero/_dropin.js.erb @@ -66,4 +66,4 @@ onReady: function (integration) { onError: function (error) { SpreeBraintreeVzero.enableSubmitButton(); <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_error_callback', formats: [:js] %> -} \ No newline at end of file +}