spree_braintree_vzero 3.5.1

Sign up to get free protection for your applications and to get access to all the features.
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?