solidus_paypal_braintree 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,188 +1 @@
1
- //= require spree/braintree_hosted_form
2
-
3
- window.SolidusPaypalBraintree = {
4
- APPLE_PAY_API_VERSION: 1,
5
-
6
- // Override to provide your own error messages.
7
- braintreeErrorHandle: function(braintreeError) {
8
- var $contentContainer = $("#content");
9
- var $flash = $("<div class='flash error'>" + braintreeError.name + ": " + braintreeError.message + "</div>");
10
- $contentContainer.prepend($flash);
11
-
12
- $flash.show().delay(5000).fadeOut(500);
13
- },
14
-
15
- fetchToken: function(tokenCallback) {
16
- Spree.ajax({
17
- dataType: 'json',
18
- type: 'POST',
19
- url: Spree.pathFor('solidus_paypal_braintree/client_token'),
20
- success: function(response) {
21
- tokenCallback(response.client_token, response.payment_method_id);
22
- },
23
- error: function(xhr) {
24
- console.error("Error fetching braintree token");
25
- }
26
- });
27
- },
28
-
29
- initialize: function(authToken, clientReadyCallback) {
30
- braintree.client.create({
31
- authorization: authToken
32
- }, function (clientErr, clientInstance) {
33
- if (clientErr) {
34
- console.error('Error creating client:', clientErr);
35
- return;
36
- }
37
- clientReadyCallback(clientInstance);
38
- });
39
- },
40
-
41
- initializeWithDataCollector: function(authToken, clientReadyCallback) {
42
- braintree.client.create({
43
- authorization: authToken
44
- }, function (clientErr, clientInstance) {
45
- braintree.dataCollector.create({
46
- client: clientInstance,
47
- paypal: true
48
- }, function (err, dataCollectorInstance) {
49
- if (err) {
50
- console.error('Error creating data collector:', err);
51
- return;
52
- }
53
- });
54
- if (clientErr) {
55
- console.error('Error creating client:', clientErr);
56
- return;
57
- }
58
- clientReadyCallback(clientInstance);
59
- });
60
- },
61
-
62
- setupApplePay: function(braintreeClient, merchantId, readyCallback) {
63
- if(window.ApplePaySession && location.protocol == "https:") {
64
- var promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantId);
65
- promise.then(function (canMakePayments) {
66
- if (canMakePayments) {
67
- braintree.applePay.create({
68
- client: braintreeClient
69
- }, function (applePayErr, applePayInstance) {
70
- if (applePayErr) {
71
- console.error("Error creating ApplePay:", applePayErr);
72
- return;
73
- }
74
- readyCallback(applePayInstance);
75
- });
76
- }
77
- });
78
- };
79
- },
80
-
81
- /* Initializes and begins the ApplePay session
82
- *
83
- * @param config Configuration settings for the session
84
- * @param config.applePayInstance {object} The instance returned from applePay.create
85
- * @param config.storeName {String} The name of the store
86
- * @param config.paymentRequest {object} The payment request to submit
87
- * @param config.currentUserEmail {String|undefined} The active user's email
88
- * @param config.paymentMethodId {Integer} The SolidusPaypalBraintree::Gateway id
89
- */
90
- initializeApplePaySession: function(config, sessionCallback) {
91
-
92
- var requiredFields = ['postalAddress', 'phone'];
93
-
94
- if (!config.currentUserEmail) {
95
- requiredFields.push('email');
96
- }
97
-
98
- config.paymentRequest['requiredShippingContactFields'] = requiredFields
99
- var paymentRequest = config.applePayInstance.createPaymentRequest(config.paymentRequest);
100
-
101
- var session = new ApplePaySession(SolidusPaypalBraintree.APPLE_PAY_API_VERSION, paymentRequest);
102
- session.onvalidatemerchant = function (event) {
103
- config.applePayInstance.performValidation({
104
- validationURL: event.validationURL,
105
- displayName: config.storeName,
106
- }, function (validationErr, merchantSession) {
107
- if (validationErr) {
108
- console.error('Error validating Apple Pay:', validationErr);
109
- session.abort();
110
- return;
111
- };
112
- session.completeMerchantValidation(merchantSession);
113
- });
114
- };
115
-
116
- session.onpaymentauthorized = function (event) {
117
- config.applePayInstance.tokenize({
118
- token: event.payment.token
119
- }, function (tokenizeErr, payload) {
120
- if (tokenizeErr) {
121
- console.error('Error tokenizing Apple Pay:', tokenizeErr);
122
- session.completePayment(ApplePaySession.STATUS_FAILURE);
123
- }
124
-
125
- var contact = event.payment.shippingContact;
126
-
127
- Spree.ajax({
128
- data: SolidusPaypalBraintree.buildTransaction(payload, config, contact),
129
- dataType: 'json',
130
- type: 'POST',
131
- url: Spree.pathFor('solidus_paypal_braintree/transactions'),
132
- success: function(response) {
133
- session.completePayment(ApplePaySession.STATUS_SUCCESS);
134
- window.location.replace(response.redirectUrl);
135
- },
136
- error: function(xhr) {
137
- if (xhr.status === 422) {
138
- var errors = xhr.responseJSON.errors
139
-
140
- if (errors && errors["Address"]) {
141
- session.completePayment(ApplePaySession.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS);
142
- } else {
143
- session.completePayment(ApplePaySession.STATUS_FAILURE);
144
- }
145
- }
146
- }
147
- });
148
-
149
- });
150
- };
151
-
152
- sessionCallback(session);
153
-
154
- session.begin();
155
- },
156
-
157
- buildTransaction: function(payload, config, shippingContact) {
158
- return {
159
- transaction: {
160
- nonce: payload.nonce,
161
- phone: shippingContact.phoneNumber,
162
- email: config.currentUserEmail || shippingContact.emailAddress,
163
- payment_type: payload.type,
164
- address_attributes: SolidusPaypalBraintree.buildAddress(shippingContact)
165
- },
166
- payment_method_id: config.paymentMethodId
167
- };
168
- },
169
-
170
- buildAddress: function(shippingContact) {
171
- var addressHash = {
172
- country_name: shippingContact.country,
173
- country_code: shippingContact.countryCode,
174
- first_name: shippingContact.givenName,
175
- last_name: shippingContact.familyName,
176
- state_code: shippingContact.administrativeArea,
177
- city: shippingContact.locality,
178
- zip: shippingContact.postalCode,
179
- address_line_1: shippingContact.addressLines[0]
180
- };
181
-
182
- if(shippingContact.addressLines.length > 1) {
183
- addressHash['address_line_2'] = shippingContact.addressLines[1];
184
- }
185
-
186
- return addressHash;
187
- }
188
- }
1
+ //= require solidus_paypal_braintree/frontend
@@ -14,3 +14,26 @@ the installer will append this file to the app vendored assets here: 'vendor/ass
14
14
  .paypal-button-widget .paypal-button:hover {
15
15
  background: transparent;
16
16
  }
17
+
18
+ .apple-pay-button {
19
+ -webkit-appearance: -apple-pay-button;
20
+ -apple-pay-button-type: buy;
21
+ visibility: hidden;
22
+ display: inline-block;
23
+ min-height: 30px;
24
+ border: 1px solid black;
25
+ background-image: -webkit-named-image(apple-pay-logo-black);
26
+ background-size: 100% calc(60% + 2px);
27
+ background-repeat: no-repeat;
28
+ background-color: white;
29
+ background-position: 50% 50%;
30
+ border-radius: 5px;
31
+ padding: 0;
32
+ margin: 5px auto;
33
+ transition: background-color .15s;
34
+ width: auto;
35
+ }
36
+
37
+ .apple-pay-button.visible {
38
+ visibility: visible;
39
+ }
@@ -4,7 +4,7 @@ module SolidusPaypalBraintree
4
4
  class_option :auto_run_migrations, type: :boolean, default: false
5
5
 
6
6
  def add_javascripts
7
- append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/solidus_paypal_braintree\n"
7
+ append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require solidus_paypal_braintree/frontend\n"
8
8
  append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/paypal_button\n"
9
9
  append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_paypal_braintree\n"
10
10
  end
@@ -31,9 +31,10 @@ module SolidusPaypalBraintree
31
31
 
32
32
  if frontend_available?
33
33
  config.assets.precompile += [
34
- 'spree/frontend/solidus_paypal_braintree.js',
34
+ 'solidus_paypal_braintree/checkout.js',
35
+ 'solidus_paypal_braintree/frontend.js',
35
36
  'spree/frontend/paypal_button.js',
36
- 'spree/checkout/braintree.js'
37
+ 'spree/frontend/apple_pay_button.js'
37
38
  ]
38
39
  paths["app/controllers"] << "lib/controllers/frontend"
39
40
  paths["app/views"] << "lib/views/frontend"
@@ -1,3 +1,3 @@
1
1
  module SolidusPaypalBraintree
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -2,7 +2,22 @@
2
2
  <% id = payment_method.id %>
3
3
 
4
4
  <% content_for :head do %>
5
- <%= javascript_include_tag "spree/checkout/braintree" %>
5
+ <script src="https://js.braintreegateway.com/web/3.14.0/js/client.min.js"></script>
6
+ <script src="https://js.braintreegateway.com/web/3.14.0/js/data-collector.min.js"></script>
7
+
8
+ <% if current_store.braintree_configuration.paypal? %>
9
+ <script src="https://js.braintreegateway.com/web/3.14.0/js/paypal.min.js"></script>
10
+ <% end %>
11
+
12
+ <% if current_store.braintree_configuration.credit_card? %>
13
+ <script src="https://js.braintreegateway.com/web/3.14.0/js/hosted-fields.min.js"></script>
14
+ <% end %>
15
+
16
+ <% if current_store.braintree_configuration.apple_pay? %>
17
+ <script src="https://js.braintreegateway.com/web/3.14.0/js/apple-pay.min.js"></script>
18
+ <% end %>
19
+
20
+ <%= javascript_include_tag "solidus_paypal_braintree/checkout" %>
6
21
  <% end %>
7
22
 
8
23
  <% if current_store.braintree_configuration.paypal? %>
@@ -29,19 +44,15 @@
29
44
  recipientName: '<%= "#{address.firstname} #{address.lastname}" %>'
30
45
  }
31
46
 
32
- $.when(
33
- $.getScript("https://js.braintreegateway.com/web/3.9.0/js/client.min.js"),
34
- $.getScript("https://js.braintreegateway.com/web/3.9.0/js/paypal.min.js"),
35
- $.getScript("https://js.braintreegateway.com/web/3.9.0/js/data-collector.min.js")
36
- ).done(function() {
37
- var button = new PaypalButton(document.querySelector("#paypal-button"));
38
- button.initialize({
39
- flow: 'vault',
40
- enableShippingAddress: true,
41
- shippingAddressOverride: address,
42
- shippingAddressEditable: false
43
- });
44
- });
47
+ var paypalOptions = {
48
+ flow: 'vault',
49
+ enableShippingAddress: true,
50
+ shippingAddressOverride: address,
51
+ shippingAddressEditable: false
52
+ }
53
+
54
+ var button = new SolidusPaypalBraintree.createPaypalButton(document.querySelector("#paypal-button"), paypalOptions);
55
+ button.initialize();
45
56
  </script>
46
57
  <% end %>
47
58
 
@@ -50,3 +61,30 @@
50
61
  <%= render "spree/shared/braintree_hosted_fields", id: id %>
51
62
  </fieldset>
52
63
  <% end %>
64
+
65
+ <% if current_store.braintree_configuration.apple_pay? %>
66
+ <button id="apple-pay-button" class="apple-pay-button"></button>
67
+ <script>
68
+ var applePayButtonElement = document.getElementById('apple-pay-button');
69
+ var applePayOptions = {
70
+ paymentMethodId: <%= id %>,
71
+ storeName: "<%= current_store.name %>",
72
+ orderEmail: "<%= current_order.email %>",
73
+ amount: "<%= current_order.total %>",
74
+ shippingContact: {
75
+ emailAddress: '<%= current_order.email %>',
76
+ familyName: '<%= address.firstname %>',
77
+ givenName: '<%= address.lastname %>',
78
+ phoneNumber: '<%= address.phone %>',
79
+ addressLines: ['<%= address.address1 %>','<%= address.address2 %>'],
80
+ locality: '<%= address.city %>',
81
+ administrativeArea: '<%= address.state.name %>',
82
+ postalCode: '<%= address.zipcode %>',
83
+ country: '<%= address.country.name %>',
84
+ countryCode: '<%= address.country.iso %>'
85
+ }
86
+ };
87
+ var button = new SolidusPaypalBraintree.createApplePayButton(applePayButtonElement, applePayOptions);
88
+ button.initialize();
89
+ </script>
90
+ <% end %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_paypal_braintree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stembolt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-17 00:00:00.000000000 Z
11
+ date: 2017-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: solidus
@@ -277,9 +277,15 @@ files:
277
277
  - LICENSE
278
278
  - README.md
279
279
  - Rakefile
280
+ - app/assets/javascripts/solidus_paypal_braintree/apple_pay_button.js
281
+ - app/assets/javascripts/solidus_paypal_braintree/checkout.js
282
+ - app/assets/javascripts/solidus_paypal_braintree/client.js
283
+ - app/assets/javascripts/solidus_paypal_braintree/constants.js
284
+ - app/assets/javascripts/solidus_paypal_braintree/frontend.js
285
+ - app/assets/javascripts/solidus_paypal_braintree/hosted_form.js
286
+ - app/assets/javascripts/solidus_paypal_braintree/paypal_button.js
287
+ - app/assets/javascripts/solidus_paypal_braintree/promise.js
280
288
  - app/assets/javascripts/spree/backend/solidus_paypal_braintree.js
281
- - app/assets/javascripts/spree/braintree_hosted_form.js
282
- - app/assets/javascripts/spree/checkout/braintree.js
283
289
  - app/assets/javascripts/spree/frontend/paypal_button.js
284
290
  - app/assets/javascripts/spree/frontend/solidus_paypal_braintree.js
285
291
  - app/assets/stylesheets/spree/backend/solidus_paypal_braintree.scss
@@ -343,7 +349,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
343
349
  version: '0'
344
350
  requirements: []
345
351
  rubyforge_project:
346
- rubygems_version: 2.6.12
352
+ rubygems_version: 2.6.11
347
353
  signing_key:
348
354
  specification_version: 4
349
355
  summary: Officially supported Paypal/Braintree extension
@@ -1,98 +0,0 @@
1
- function BraintreeHostedForm($paymentForm, $hostedFields, paymentMethodId) {
2
- this.paymentForm = $paymentForm;
3
- this.hostedFields = $hostedFields;
4
- this.paymentMethodId = paymentMethodId;
5
- }
6
-
7
- BraintreeHostedForm.prototype.initializeHostedFields = function() {
8
- return this.getToken().
9
- then(this.createClient.bind(this)).
10
- then(this.createHostedFields());
11
- };
12
-
13
- BraintreeHostedForm.prototype.promisify = function (fn, args, self) {
14
- var d = $.Deferred();
15
-
16
- fn.apply(self || this, (args || []).concat(function (err, data) {
17
- if (err) d.reject(err);
18
- d.resolve(data);
19
- }));
20
-
21
- return d.promise();
22
- };
23
-
24
- BraintreeHostedForm.prototype.getToken = function () {
25
- var opts = {
26
- url: "/solidus_paypal_braintree/client_token",
27
- method: "POST",
28
- data: {
29
- payment_method_id: this.paymentMethodId
30
- },
31
- };
32
-
33
- function onSuccess(data) {
34
- return data.client_token;
35
- }
36
-
37
- return Spree.ajax(opts).then(onSuccess);
38
- };
39
-
40
- BraintreeHostedForm.prototype.createClient = function (token) {
41
- var opts = { authorization: token };
42
- return this.promisify(braintree.client.create, [opts]);
43
- };
44
-
45
- BraintreeHostedForm.prototype.createHostedFields = function () {
46
- var self = this;
47
- var id = this.paymentMethodId;
48
-
49
- return function(client) {
50
- var opts = {
51
- client: client,
52
-
53
- fields: {
54
- number: {
55
- selector: "#card_number" + id
56
- },
57
-
58
- cvv: {
59
- selector: "#card_code" + id
60
- },
61
-
62
- expirationDate: {
63
- selector: "#card_expiry" + id
64
- }
65
- }
66
- };
67
-
68
- return self.promisify(braintree.hostedFields.create, [opts]);
69
- };
70
- };
71
-
72
- BraintreeHostedForm.prototype.addFormHook = function (errorCallback) {
73
- var self = this;
74
- var shouldSubmit = false;
75
-
76
- function submit(payload) {
77
- shouldSubmit = true;
78
-
79
- $("#payment_method_nonce", self.hostedFields).val(payload.nonce);
80
- self.paymentForm.submit();
81
- }
82
-
83
- return function(hostedFields) {
84
- self.paymentForm.on("submit", function(e) {
85
- if (self.hostedFields.is(":visible") && !shouldSubmit) {
86
- e.preventDefault();
87
-
88
- hostedFields.tokenize(function(err, payload) {
89
- if (err) {
90
- errorCallback(err);
91
- } else {
92
- submit(payload);
93
- }
94
- });
95
- }
96
- });
97
- };
98
- };