spree_braintree_vzero 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +15 -0
  3. data/.gitignore +19 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +63 -0
  6. data/Appraisals +45 -0
  7. data/CONTRIBUTING.md +28 -0
  8. data/Gemfile +14 -0
  9. data/LICENSE +26 -0
  10. data/README.md +83 -0
  11. data/Rakefile +21 -0
  12. data/app/assets/images/credit_cards/icons/jcb.png +0 -0
  13. data/app/assets/javascripts/spree/backend/payments.js +19 -0
  14. data/app/assets/javascripts/spree/backend/spree_braintree_vzero.js +81 -0
  15. data/app/assets/javascripts/spree/frontend/spree_braintree_vzero.js +68 -0
  16. data/app/assets/stylesheets/spree/backend/spree_braintree_vzero.css +5 -0
  17. data/app/controllers/spree/admin/payments_controller_decorator.rb +43 -0
  18. data/app/controllers/spree/api/v1/braintree_client_token_controller.rb +31 -0
  19. data/app/controllers/spree/checkout_controller_decorator.rb +38 -0
  20. data/app/controllers/spree/orders_controller_decorator.rb +62 -0
  21. data/app/controllers/spree/user_sessions_controller_decorator.rb +15 -0
  22. data/app/helpers/spree/admin/decorated_navigation_helper.rb +10 -0
  23. data/app/helpers/spree/admin/payment_methods_helper.rb +101 -0
  24. data/app/helpers/spree/braintree_helper.rb +27 -0
  25. data/app/models/braintree/successful_result_decorator.rb +21 -0
  26. data/app/models/spree/address_decorator.rb +18 -0
  27. data/app/models/spree/braintree_checkout.rb +105 -0
  28. data/app/models/spree/gateway/braintree_vzero_base.rb +168 -0
  29. data/app/models/spree/gateway/braintree_vzero_base/address.rb +33 -0
  30. data/app/models/spree/gateway/braintree_vzero_base/braintree_user.rb +25 -0
  31. data/app/models/spree/gateway/braintree_vzero_base/purchase_data.rb +48 -0
  32. data/app/models/spree/gateway/braintree_vzero_base/transaction.rb +39 -0
  33. data/app/models/spree/gateway/braintree_vzero_base/utils.rb +108 -0
  34. data/app/models/spree/gateway/braintree_vzero_drop_in_ui.rb +24 -0
  35. data/app/models/spree/gateway/braintree_vzero_hosted_fields.rb +28 -0
  36. data/app/models/spree/gateway/braintree_vzero_paypal_express.rb +36 -0
  37. data/app/models/spree/order_decorator.rb +153 -0
  38. data/app/models/spree/payment_decorator.rb +10 -0
  39. data/app/models/spree/payment_processing_decorator.rb +61 -0
  40. data/app/models/spree/preferences/preferable_decorator.rb +54 -0
  41. data/app/overrides/spree/admin/orders/customer_details/_form.rb +8 -0
  42. data/app/overrides/spree/admin/payment_methods/_form.rb +10 -0
  43. data/app/overrides/spree/admin/shared/_order_summary.rb +23 -0
  44. data/app/overrides/spree/admin/shared/_refunds.rb +13 -0
  45. data/app/overrides/spree/checkout/_new_user.rb +6 -0
  46. data/app/overrides/spree/checkout/_payment.rb +20 -0
  47. data/app/overrides/spree/checkout/registration.rb +6 -0
  48. data/app/overrides/spree/orders/edit.rb +6 -0
  49. data/app/overrides/spree/shared/_order_details.rb +13 -0
  50. data/app/overrides/spree/shared/_payment.rb +28 -0
  51. data/app/views/spree/admin/payment_methods/_braintree_vzero_form.html.erb +83 -0
  52. data/app/views/spree/admin/payments/source_forms/_braintree_vzero_dropin_ui.html.erb +1 -0
  53. data/app/views/spree/admin/payments/source_forms/_braintree_vzero_hosted_fields.html.erb +1 -0
  54. data/app/views/spree/admin/payments/source_forms/_braintree_vzero_paypal_express.html.erb +1 -0
  55. data/app/views/spree/admin/payments/source_forms/braintree_vzero/_payments.html.erb +87 -0
  56. data/app/views/spree/admin/payments/source_views/_braintree_vzero_dropin_ui.html.erb +1 -0
  57. data/app/views/spree/admin/payments/source_views/_braintree_vzero_hosted_fields.html.erb +1 -0
  58. data/app/views/spree/admin/payments/source_views/_braintree_vzero_paypal_express.html.erb +1 -0
  59. data/app/views/spree/admin/payments/source_views/braintree_vzero/_payment.html.erb +17 -0
  60. data/app/views/spree/braintree_vzero/_paypal_checkout.html.erb +87 -0
  61. data/app/views/spree/checkout/payment/_braintree_vzero_dropin_ui.html.erb +4 -0
  62. data/app/views/spree/checkout/payment/_braintree_vzero_hosted_fields.html.erb +4 -0
  63. data/app/views/spree/checkout/payment/_braintree_vzero_paypal_express.html.erb +4 -0
  64. data/app/views/spree/checkout/payment/braintree_vzero/_buttons.html.erb +11 -0
  65. data/app/views/spree/checkout/payment/braintree_vzero/_dropin_on_error_callback.js.erb +3 -0
  66. data/app/views/spree/checkout/payment/braintree_vzero/_dropin_on_ready_callback.js.erb +1 -0
  67. data/app/views/spree/checkout/payment/braintree_vzero/_hosted_fields_on_field_event_callback.js.erb +12 -0
  68. data/app/views/spree/checkout/payment/braintree_vzero/_hosted_fields_styles.js.erb +29 -0
  69. data/app/views/spree/checkout/payment/braintree_vzero/_payment.html.erb +84 -0
  70. data/app/views/spree/checkout/payment/braintree_vzero/_three_d_secure.html.erb +218 -0
  71. data/app/views/spree/shared/braintree_vzero/_dropin.js.erb +70 -0
  72. data/app/views/spree/shared/braintree_vzero/_hosted.js.erb +66 -0
  73. data/app/views/spree/shared/braintree_vzero/_paypal.js.erb +39 -0
  74. data/bin/rails +7 -0
  75. data/config/initializers/extend_spree_permitted_checkout_attributes.rb +5 -0
  76. data/config/initializers/prepend_helpers.rb +1 -0
  77. data/config/locales/en.yml +79 -0
  78. data/config/routes.rb +7 -0
  79. data/db/migrate/20150904143013_create_spree_braintree_checkouts.rb +9 -0
  80. data/db/migrate/20151002094655_add_braintree_id_to_spree_addresses.rb +5 -0
  81. data/db/migrate/20151018123907_add_braintree_token_and_nonce_to_spree_payments.rb +6 -0
  82. data/db/migrate/20151027135109_add_paypal_email_to_spree_braintree_checkout.rb +5 -0
  83. data/db/migrate/20151028095515_add_advanced_fraud_data_to_spree_braintree_checkout.rb +5 -0
  84. data/db/migrate/20151202095956_add_risk_id_and_risk_decision_to_spree_braintree_checkouts.rb +6 -0
  85. data/db/migrate/20151211100203_add_braintree_last_digits_and_braintree_card_type_to_spree_braintree_checkouts.rb +6 -0
  86. data/db/migrate/20160112153422_add_admin_payment_to_spree_braintree_checkout.rb +5 -0
  87. data/gemfiles/spree_3_5.gemfile +12 -0
  88. data/gemfiles/spree_3_5_spree_auth_devise.gemfile +13 -0
  89. data/gemfiles/spree_3_7.gemfile +12 -0
  90. data/gemfiles/spree_3_7_spree_auth_devise.gemfile +13 -0
  91. data/gemfiles/spree_4_0.gemfile +11 -0
  92. data/gemfiles/spree_4_0_spree_auth_devise.gemfile +12 -0
  93. data/gemfiles/spree_master.gemfile +11 -0
  94. data/gemfiles/spree_master_spree_auth_devise.gemfile +12 -0
  95. data/lib/generators/spree_braintree_vzero/install/install_generator.rb +34 -0
  96. data/lib/spree_braintree_vzero.rb +6 -0
  97. data/lib/spree_braintree_vzero/engine.rb +28 -0
  98. data/lib/spree_braintree_vzero/factories.rb +10 -0
  99. data/lib/spree_braintree_vzero/railtie.rb +8 -0
  100. data/lib/spree_braintree_vzero/version.rb +17 -0
  101. data/lib/tasks/spree_braintree_vzero.rake +6 -0
  102. data/spec/controllers/spree/api/v1/braintree_client_token_controller_spec.rb +49 -0
  103. data/spec/controllers/spree/checkout_controller_spec.rb +85 -0
  104. data/spec/controllers/spree/orders_controller_spec.rb +97 -0
  105. data/spec/factories/braintree_checkout_factory.rb +7 -0
  106. data/spec/factories/braintree_gateway_factory.rb +35 -0
  107. data/spec/factories/payment_factory_decorator.rb +28 -0
  108. data/spec/features/spree/admin/log_entries_spec.rb +63 -0
  109. data/spec/models/gateway/braintree_vzero_base/address_spec.rb +28 -0
  110. data/spec/models/gateway/braintree_vzero_base/purchase_data_spec.rb +57 -0
  111. data/spec/models/gateway/braintree_vzero_base_spec.rb +346 -0
  112. data/spec/models/gateway/braintree_vzero_dropin_ui_spec.rb +35 -0
  113. data/spec/models/gateway/braintree_vzero_hosted_fields_spec.rb +35 -0
  114. data/spec/models/spree/order_spec.rb +186 -0
  115. data/spec/spec_helper.rb +100 -0
  116. data/spec/support/vcr.rb +10 -0
  117. data/spec/vcr/Log_entries/with_a_failed_log_entry/shows_a_failed_attempt.yml +91 -0
  118. data/spec/vcr/Log_entries/with_a_successful_log_entry/shows_a_successful_attempt.yml +113 -0
  119. data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/guest_checkout/returns_proper_json_data_when_gateway_not_specified.yml +90 -0
  120. data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/guest_checkout/returns_proper_json_data_when_gateway_specified.yml +90 -0
  121. data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/user_checkout/returns_proper_json_data_when_gateway_not_specified.yml +191 -0
  122. data/spec/vcr/Spree_Api_V1_BraintreeClientTokenController/POST_create/user_checkout/returns_proper_json_data_when_gateway_specified.yml +191 -0
  123. data/spec/vcr/Spree_CheckoutController/_update/braintree_payment/advanced_fraud_data_in_source_should_be_updated.yml +71 -0
  124. data/spec/vcr/Spree_CheckoutController/_update/braintree_payment/when_token_credit_card_data_in_source_should_be_updated_from_Braintree_Vault.yml +139 -0
  125. data/spec/vcr/Spree_CheckoutController/_update/braintree_paypal_express_payment/amount_in_payment_should_be_updated.yml +280 -0
  126. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_capture/captures_authorized_amount/updates_Payment_state.yml +206 -0
  127. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_credit/with_refundable_state/should_be_a_success.yml +211 -0
  128. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_credit/with_unrefundable_state/should_not_be_a_success.yml +177 -0
  129. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/data_from_admin_panel/should_include_only_essential_data.yml +78 -0
  130. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/does_not_store_Transaction_in_Vault_by_default.yml +111 -0
  131. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_false_with_invalid_nonce.yml +88 -0
  132. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_false_with_invalid_token.yml +88 -0
  133. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_success_with_valid_token.yml +113 -0
  134. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/returns_suceess_with_valid_nonce.yml +111 -0
  135. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/saves_Braintree_Address_id_to_Spree_Address_when_address_is_being_saved.yml +130 -0
  136. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/saves_unique_Braintree_Addresses_ids.yml +143 -0
  137. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/sends_empty_address_id_when_address_is_already_in_vault.yml +553 -0
  138. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/using_Vault/stores_Transaction.yml +181 -0
  139. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_3DSecure_option_turned_on/performs_3DSecure_check.yml +112 -0
  140. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_3DSecure_option_turned_on/returns_error.yml +112 -0
  141. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_advanced_fraud_tool_enabled/returns_fraud_data.yml +111 -0
  142. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_purchase/with_advanced_fraud_tool_enabled/returns_success.yml +111 -0
  143. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/does_not_update_Order_payment_state.yml +204 -0
  144. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/prepares_Checkout_for_status_updating.yml +204 -0
  145. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/submits_Transaction_for_settlement.yml +377 -0
  146. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_settle/settles_authorized_amount/updates_Payment_state.yml +203 -0
  147. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/does_not_update_completed_Checkout_on_subsequent_runs.yml +202 -0
  148. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_Order_payment_state_when_Checkout_is_updated.yml +202 -0
  149. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_Payment_state_when_Checkout_is_updated.yml +202 -0
  150. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_update_states/updates_payment_State.yml +202 -0
  151. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_void/with_unvoidable_state/should_not_change_payment_source_state.yml +178 -0
  152. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/_void/with_voidable_state/should_change_payment_source_state_to_voided.yml +199 -0
  153. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_for_User_registered_in_Braintree.yml +356 -0
  154. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_for_new_User.yml +189 -0
  155. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/valid_credentials/generates_token_without_User.yml +89 -0
  156. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase/with_invalid_credentials/raises_Braintree_error.yml +62 -0
  157. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/creates_Braintree_Address.yml +84 -0
  158. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/deletes_Braintree_Address.yml +141 -0
  159. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/finds_Braintree_Address.yml +148 -0
  160. data/spec/vcr/Spree_Gateway_BraintreeVzeroBase_Address/_create/updates_Braintree_Address.yml +154 -0
  161. data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_complete_payment.yml +116 -0
  162. data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_update_payment_s_response_code.yml +111 -0
  163. data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/with_auto_capture/should_update_payment_s_source_state_and_transaction_id.yml +111 -0
  164. data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_pend_payment.yml +111 -0
  165. data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_update_payment_s_response_code.yml +111 -0
  166. data/spec/vcr/Spree_Order/complete_with_braintree_vzero_standard_payment/without_auto_capture/should_update_payment_s_source_state_and_transaction_id.yml +110 -0
  167. data/spree_braintree_vzero.gemspec +52 -0
  168. data/vendor/assets/javascripts/maskedinput/jquery.maskedinput.min.js +7 -0
  169. metadata +643 -0
@@ -0,0 +1,218 @@
1
+ <script type="text/javascript">
2
+ $('#order_payments_attributes__payment_method_id_<%= payment_method.id %>').click(function (e) {
3
+ var threeDSecure;
4
+ var checkoutFormId = "<%= payment_method.preferred_checkout_form_id %>"
5
+ var formId = "#" + checkoutFormId;
6
+
7
+ var clientToken = "<%= payment_method.client_token(@order) %>";
8
+
9
+ <% if hosted %>
10
+ var hf, threeDS;
11
+ var hostedFieldsContainer = document.getElementById('hosted-fields');
12
+ <% elsif dropin%>
13
+ var dropin;
14
+ <% end %>
15
+
16
+ var payBtn = document.getElementsByName('commit')[0];
17
+ var payGroup = $('.pay-group');
18
+ var billingFields = [
19
+ 'email',
20
+ ].reduce(function (fields, fieldName) {
21
+ var field = fields[fieldName] = {
22
+ input: document.getElementById(fieldName),
23
+ help: document.getElementById('help-' + fieldName)
24
+ };
25
+
26
+ field.input.addEventListener('focus', function() {
27
+ clearFieldValidations(field);
28
+ });
29
+
30
+ return fields;
31
+ }, {});
32
+
33
+ function clearFieldValidations (field) {
34
+ field.help.innerText = '';
35
+ field.help.parentNode.classList.remove('has-error');
36
+ }
37
+
38
+ function validateBillingFields() {
39
+ var isValid = true;
40
+
41
+ Object.keys(billingFields).forEach(function (fieldName) {
42
+ var fieldEmpty = false;
43
+ var field = billingFields[fieldName];
44
+
45
+ if (field.optional) {
46
+ return;
47
+ }
48
+
49
+ fieldEmpty = field.input.value.trim() === '';
50
+
51
+ if (fieldEmpty) {
52
+ isValid = false;
53
+ field.help.innerText = "<%= Spree.t(:required) %>";
54
+ field.help.parentNode.classList.add('has-error');
55
+ } else {
56
+ clearFieldValidations(field);
57
+ }
58
+ });
59
+
60
+ return isValid;
61
+ }
62
+
63
+ function start() {
64
+ getClientToken();
65
+ }
66
+
67
+ function getClientToken() {
68
+ onFetchClientToken(clientToken);
69
+ }
70
+
71
+ function setupComponents (clientToken) {
72
+ return Promise.all([
73
+ braintree.hostedFields.create({
74
+ authorization: clientToken,
75
+ styles: {
76
+ input: {
77
+ 'font-size': '14px',
78
+ 'font-family': 'monospace'
79
+ }
80
+ },
81
+ fields: {
82
+ number: {
83
+ selector: '#hosted-fields-number'
84
+ },
85
+ cvv: {
86
+ selector: '#hosted-fields-cvv'
87
+ },
88
+ expirationDate: {
89
+ selector: '#hosted-fields-expiration-date'
90
+ }
91
+ }
92
+ }),
93
+ braintree.threeDSecure.create({
94
+ authorization: clientToken,
95
+ version: 2
96
+ })
97
+ ]);
98
+ }
99
+
100
+ function setupDropin (clientToken) {
101
+ return braintree.dropin.create({
102
+ authorization: clientToken,
103
+ container: '#drop-in',
104
+ threeDSecure: true
105
+ })
106
+ }
107
+
108
+ function onFetchClientToken(clientToken) {
109
+ <% if hosted %>
110
+ return setupComponents(clientToken).then(function(instances) {
111
+ hf = instances[0];
112
+ threeDS = instances[1];
113
+ <% elsif dropin %>
114
+ return setupDropin(clientToken).then(function(instance) {
115
+ dropin = instance;
116
+ <% end %>
117
+
118
+ setupForm();
119
+ }).catch(function (err) {
120
+ console.log('component error:', err);
121
+ });
122
+ }
123
+
124
+ function setupForm() {
125
+ enablePayNow();
126
+ }
127
+
128
+ function enablePayNow() {
129
+ payBtn.value = "<%= Spree.t(:save_and_continue) %>";
130
+ payBtn.removeAttribute('disabled');
131
+ }
132
+
133
+ function showErrors() {
134
+ payGroup.addClass('hidden');
135
+ payGroup.css('display', 'none');
136
+ $('.credit-card-pay-success').addClass('hidden')
137
+ $('.credit-card-pay-errors').removeClass('hidden')
138
+ }
139
+
140
+ function showSuccess() {
141
+ payGroup.addClass('hidden');
142
+ payGroup.css('display', 'none');
143
+ <% if hosted %>
144
+ hostedFieldsContainer.style.display = 'none';
145
+ <% end %>
146
+ $('.credit-card-pay-errors').addClass('hidden')
147
+ $('.credit-card-pay-success').removeClass('hidden')
148
+ }
149
+
150
+ payBtn.addEventListener('click', function(event) {
151
+ event.preventDefault()
152
+ payBtn.setAttribute('disabled', 'disabled');
153
+ payBtn.value = "<%= Spree.t(:processing_credit_card) %>";
154
+
155
+ var billingIsValid = validateBillingFields();
156
+
157
+ if (!billingIsValid) {
158
+ enablePayNow();
159
+
160
+ return;
161
+ }
162
+ <% if hosted %>
163
+ hf.tokenize().then(function (payload) {
164
+ return threeDS.verifyCard({
165
+ onLookupComplete: function (data, next) {
166
+ next();
167
+ },
168
+ nonce: payload.nonce,
169
+ bin: payload.details.bin,
170
+ <% elsif dropin %>
171
+ dropin.requestPaymentMethod({
172
+ threeDSecure: {
173
+ <% end %>
174
+ amount: "<%= @order.total %>",
175
+ email: billingFields.email.input.value,
176
+ <% if hosted %>
177
+ })
178
+ }).then(function (payload) {
179
+ <% elsif dropin %>
180
+ }
181
+ }, function(err, payload) {
182
+ if (err) {
183
+ console.log('tokenization error:');
184
+ console.log(err);
185
+ dropin.clearSelectedPaymentMethod();
186
+ enablePayNow();
187
+
188
+ return;
189
+ }
190
+ <% end %>
191
+
192
+ if (!payload.liabilityShifted) {
193
+ console.log('Liability did not shift', payload);
194
+ showErrors();
195
+ return;
196
+ }
197
+
198
+ console.log('verification success:', payload);
199
+ showSuccess();
200
+ $(formId).append("<input type='hidden' name='braintree_last_two' value=" + payload.details.lastTwo + ">");
201
+ $(formId).append("<input type='hidden' name='braintree_card_type' value=" + payload.details.cardType.replace(/\s/g, "") + ">");
202
+ $(formId).append("<input type='hidden' name='order[payments_attributes][][braintree_nonce]' value=" + payload.nonce + ">");
203
+ $(formId).append("<input type='hidden' name='payment_method_nonce' value=" + payload.nonce + ">");
204
+ setTimeout(function () {
205
+ $('.checkout-btn').attr("disabled", false)
206
+ $('form.edit_order').submit()
207
+ }, 200);
208
+ <% if hosted %>
209
+ }).catch(function (err) {
210
+ enablePayNow();
211
+ showErrors();
212
+ <% end %>
213
+ });
214
+ });
215
+
216
+ start();
217
+ });
218
+ </script>
@@ -0,0 +1,70 @@
1
+ container: container,
2
+ paypal: {
3
+ singleUse: <%= payment_method.preferred_store_payments_in_vault.eql?('do_not_store') %>,
4
+ amount: <%= @order.order_total_after_store_credit %>,
5
+ currency: "<%= current_currency %>",
6
+ enableShippingAddress: true,
7
+ shippingAddressOverride: {
8
+ recipientName: '<%= "#{shipping_address.firstname} #{shipping_address.lastname}" %>',
9
+ streetAddress: '<%= shipping_address.address1 %>',
10
+ extendedAddress: '<%= shipping_address.address2 %>',
11
+ locality: '<%= shipping_address.city %>',
12
+ countryCodeAlpha2: '<%= shipping_address.country.try(:iso) %>',
13
+ postalCode: '<%= shipping_address.zipcode %>',
14
+ region: '<%= shipping_address.state.try(:abbr) %>',
15
+ phone: '<%= shipping_address.phone %>',
16
+ editable: false
17
+ }
18
+ },
19
+
20
+ onPaymentMethodReceived: function (result) {
21
+ var formId = "#" + checkoutFormId;
22
+
23
+ function submitWithAttributes(data) {
24
+ switch (data.type) {
25
+ case "CreditCard":
26
+ $(formId).append("<input type='hidden' name='braintree_last_two' value=" + result.details.lastTwo + ">");
27
+ $(formId).append("<input type='hidden' name='braintree_card_type' value=" + result.details.cardType.replace(/\s/g, "") + ">");
28
+ break;
29
+ case "PayPalAccount":
30
+ $(formId).append("<input type='hidden' name='paypal_email' value=" + (result.details.email)+ ">");
31
+ break;
32
+ }
33
+ if(SpreeBraintreeVzero.admin)
34
+ $(formId).append("<input type='hidden' name='payment_method_nonce' value=" + data.nonce + ">");
35
+ else
36
+ $(formId).append("<input type='hidden' name='order[payments_attributes][][braintree_nonce]' value=" + data.nonce + ">");
37
+ $(formId)[0].submit();
38
+ }
39
+
40
+ if (SpreeBraintreeVzero.threeDSecure && result.type == "CreditCard") {
41
+ var client = new braintree.api.Client({
42
+ clientToken: clientToken
43
+ });
44
+
45
+ client.verify3DS({
46
+ amount: <%= @order.order_total_after_store_credit %>,
47
+ creditCard: result.nonce
48
+ }, function (error, response) {
49
+ if (!error) {
50
+ submitWithAttributes(response);
51
+ } else {
52
+ $(errorMessagesContainer).prepend("<div class='alert alert-error'><%= I18n.t(:gateway_error, scope: 'braintree.error') %></div>")
53
+ }
54
+ });
55
+ } else {
56
+ submitWithAttributes(result);
57
+ }
58
+ },
59
+
60
+ onReady: function (integration) {
61
+ if(!SpreeBraintreeVzero.admin)
62
+ SpreeBraintreeVzero.deviceData = integration.deviceData;
63
+ <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_ready_callback', formats: [:js] %>
64
+ },
65
+
66
+ onError: function (error) {
67
+ SpreeBraintreeVzero.enableSubmitButton();
68
+ <%= render partial: 'spree/checkout/payment/braintree_vzero/dropin_on_error_callback', formats: [:js] %>
69
+ }
70
+
@@ -0,0 +1,66 @@
1
+ id: checkoutFormId,
2
+ hostedFields: {
3
+ styles: {
4
+ <%= render partial: 'spree/checkout/payment/braintree_vzero/hosted_fields_styles', formats: [:js] %>
5
+ },
6
+ number: {
7
+ selector: "<%= payment_method.preferred_number_selector %>",
8
+ placeholder: "<%= payment_method.preferred_number_placeholder %>"
9
+ },
10
+ cvv: {
11
+ selector: "<%= payment_method.preferred_cvv_selector %>",
12
+ placeholder: "<%= payment_method.preferred_cvv_placeholder %>"
13
+ },
14
+ expirationDate: {
15
+ selector: "<%= payment_method.preferred_expiration_date_selector %>",
16
+ placeholder: "<%= payment_method.preferred_expiration_date_placeholder %>"
17
+ },
18
+
19
+ onFieldEvent: function (event) {
20
+ <%= render partial: 'spree/checkout/payment/braintree_vzero/hosted_fields_on_field_event_callback', formats: [:js] %>
21
+ }
22
+ },
23
+
24
+ onError: function (error) {
25
+ SpreeBraintreeVzero.enableSubmitButton();
26
+ },
27
+
28
+ onReady: function (integration) {
29
+ if(!SpreeBraintreeVzero.admin)
30
+ SpreeBraintreeVzero.deviceData = integration.deviceData;
31
+ },
32
+
33
+ onPaymentMethodReceived: function (result) {
34
+ var formId = "#" + checkoutFormId;
35
+
36
+ function submitWithAttributes(data) {
37
+ $(formId).append("<input type='hidden' name='braintree_last_two' value=" + result.details.lastTwo + ">");
38
+ $(formId).append("<input type='hidden' name='braintree_card_type' value=" + result.details.cardType.replace(/\s/g, "") + ">");
39
+
40
+ if(SpreeBraintreeVzero.admin)
41
+ $(formId).append("<input type='hidden' name='payment_method_nonce' value=" + data.nonce + ">");
42
+ else
43
+ $(formId).append("<input type='hidden' name='order[payments_attributes][][braintree_nonce]' value=" + data.nonce + ">");
44
+ $(formId)[0].submit();
45
+ }
46
+
47
+ if (SpreeBraintreeVzero.threeDSecure && result.type == "CreditCard") {
48
+ var client = new braintree.api.Client({
49
+ clientToken: clientToken
50
+ });
51
+
52
+ client.verify3DS({
53
+ amount: <%= @order.order_total_after_store_credit %>,
54
+ creditCard: result.nonce
55
+ }, function (error, response) {
56
+ if (!error) {
57
+ submitWithAttributes(response);
58
+ } else {
59
+ $(errorMessagesContainer).prepend("<div class='alert alert-error'><%= I18n.t(:gateway_error, scope: 'braintree.error') %></div>")
60
+ }
61
+ });
62
+ } else {
63
+ submitWithAttributes(result);
64
+ }
65
+ }
66
+
@@ -0,0 +1,39 @@
1
+ container: "paypal-container",
2
+ singleUse: <%= payment_method.preferred_store_payments_in_vault.eql?('do_not_store') %>,
3
+ amount: <%= @order.order_total_after_store_credit %>,
4
+ currency: "<%= current_currency %>",
5
+ locale: "en_us",
6
+ displayName: "<%= payment_method.preferred_paypal_display_name %>",
7
+ enableShippingAddress: true,
8
+ shippingAddressOverride: {
9
+ recipientName: '<%= "#{shipping_address.firstname} #{shipping_address.lastname}" %>',
10
+ streetAddress: '<%= shipping_address.address1 %>',
11
+ extendedAddress: '<%= shipping_address.address2 %>',
12
+ locality: '<%= shipping_address.city %>',
13
+ countryCodeAlpha2: '<%= shipping_address.country.try(:iso) %>',
14
+ postalCode: '<%= shipping_address.zipcode %>',
15
+ region: '<%= shipping_address.state.try(:abbr) %>',
16
+ phone: '<%= shipping_address.phone %>',
17
+ editable: false
18
+ },
19
+
20
+ onReady: function (integration) {
21
+ if(!SpreeBraintreeVzero.admin)
22
+ SpreeBraintreeVzero.deviceData = integration.deviceData;
23
+ checkout = integration;
24
+ },
25
+ headless: true,
26
+
27
+ onPaymentMethodReceived: function (result) {
28
+ var formId = "#" + checkoutFormId;
29
+
30
+ if (result.nonce.length) {
31
+ $(formId).append("<input type='hidden' name='order[payments_attributes][][braintree_nonce]' value=" + result.nonce + ">");
32
+ $(formId).append("<input type='hidden' name='paypal_email' value=" + result.details.email + ">");
33
+ paymentMethodSelect = $("#order_payments_attributes__braintree_token")
34
+ if(paymentMethodSelect.length) paymentMethodSelect.val("");
35
+ $(formId)[0].submit();
36
+ } else {
37
+ $(errorMessagesContainer).prepend("<div class='alert alert-error'><%= I18n.t(:gateway_error, scope: 'braintree.error') %>></div>")
38
+ }
39
+ }
@@ -0,0 +1,7 @@
1
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
2
+
3
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
+ ENGINE_PATH = File.expand_path('../../lib/spree_braintree_vzero/engine', __FILE__)
5
+
6
+ require 'rails/all'
7
+ require 'rails/engine/commands'
@@ -0,0 +1,5 @@
1
+ module Spree
2
+ module PermittedAttributes
3
+ @@payment_attributes = [:amount, :payment_method_id, :payment_method, :braintree_token, :braintree_nonce]
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ Spree::Admin::NavigationHelper.prepend(Spree::Admin::DecoratedNavigationHelper)
@@ -0,0 +1,79 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ braintree:
6
+ admin:
7
+ no_paypal_payments: No vaulted paypal payments for this user
8
+ guest_checkout_warning: To use braintree vaulted payment methods do not modify this section. Use Customer Select from above.
9
+ channel_parameter: SpreeCommerceInc_Cart_Braintree
10
+ checkout:
11
+ saved_payment_method:
12
+ custom: Use a Saved Credit Card
13
+ dropin: Use a Saved Payment Method
14
+ paypal: Use a Saved Paypal Account
15
+ blank_saved_payment_method: Click to Choose
16
+ error:
17
+ three_d_secure: There was a problem with processing your credit card!
18
+ fraud: There was a problem with processing your credit card!
19
+ duplicate: Duplicated transaction, please try again!
20
+ cvv: Wrong CVV!
21
+ avs_and_cvv: Wrong AVS and CVV!
22
+ avs: Wrong AVS!
23
+ gateway_error: An error occured, please try again
24
+ phone_number_placeholder: XXXXXXXXX
25
+ preferences:
26
+ do_not_store: Do not store
27
+ production: production
28
+ sandbox: sandbox
29
+ store_only_on_success: Store only on success
30
+ store_all: Store all
31
+ state: Braintree State
32
+ title:
33
+ custom: Hosted Fields
34
+ dropin: Drop-in UI
35
+ paypal: Paypal Express
36
+
37
+ spree:
38
+ 3dsecure: 3D Secure
39
+ add_new_credit_card: Add new credit card
40
+ add_new_payment_method: Add new payment method
41
+ admin:
42
+ risk_id: Braintree Risk ID
43
+ risk_decision: Braintree Risk Decision
44
+ vaulted_payments:
45
+ credit_card: "%{card_type} ending with %{last_4}"
46
+ paypal: "Paypal %{email}"
47
+ cant_create_note: Can't create payment. No payment methods stored for this user.
48
+ advanced_fraud_tools: Advanced Fraud Tools
49
+ advanced_settings: Advanced settings
50
+ back_end: Back End
51
+ checkout_form_id: Checkout Form
52
+ cc_type: Type
53
+ cvv_placeholder: CVV Placeholder
54
+ cvv_selector: CVV Selector
55
+ descriptor_name: Card or Bank Statement Name
56
+ descriptor_name_information_box_text: "This field will be displayed on the consumer’s bank or card statement.<br/><br/>If this field is not enabled by Braintree, please call Sales Rep or Braintree Support to set this up."
57
+ dropin_container: Drop-in UI Container
58
+ dropin_error_messages_container_id: DropinUI Error Messages Container
59
+ error_messages_container_id: Error Messages Container
60
+ expiration_date_placeholder: Expiration Date Placeholder
61
+ expiration_date_selector: Expiration Date Selector
62
+ how_paypal_works: How PayPal works?
63
+ kount_merchant_id: Kount Merchant
64
+ merchant_id: Merchant ID
65
+ number_placeholder: Number Placeholder
66
+ numner_selector: Number Selector
67
+ pass_billing_and_shipping_address: Pass Billing and Shipping Address
68
+ verify_card: Verify card
69
+ verify_credit_card_failed: Verify credit card failed
70
+ credit_card_veryfied_successfully: Credit Card verified successfully.
71
+ paypal_display_name: PayPal Display Name
72
+ paypal_display_on_cart: PayPal Display on Cart
73
+ private_key: Private Key
74
+ processing_credit_card: Processing Credit Card
75
+ public_key: Public Key
76
+ required: Required
77
+ store_payments_in_vault: Store Payments In Vault
78
+ settle: Settle
79
+ what_is_paypal: What is PayPal?