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.
- checksums.yaml +4 -4
- data/README.md +49 -36
- data/app/assets/javascripts/solidus_paypal_braintree/apple_pay_button.js +179 -0
- data/app/assets/javascripts/{spree/checkout/braintree.js → solidus_paypal_braintree/checkout.js} +35 -16
- data/app/assets/javascripts/solidus_paypal_braintree/client.js +186 -0
- data/app/assets/javascripts/solidus_paypal_braintree/constants.js +58 -0
- data/app/assets/javascripts/solidus_paypal_braintree/frontend.js +12 -0
- data/app/assets/javascripts/solidus_paypal_braintree/hosted_form.js +36 -0
- data/app/assets/javascripts/solidus_paypal_braintree/paypal_button.js +114 -0
- data/app/assets/javascripts/solidus_paypal_braintree/promise.js +20 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_braintree.js +34 -4
- data/app/assets/javascripts/spree/frontend/paypal_button.js +9 -159
- data/app/assets/javascripts/spree/frontend/solidus_paypal_braintree.js +1 -188
- data/app/assets/stylesheets/spree/frontend/solidus_paypal_braintree.css +23 -0
- data/lib/generators/solidus_paypal_braintree/install/install_generator.rb +1 -1
- data/lib/solidus_paypal_braintree/engine.rb +3 -2
- data/lib/solidus_paypal_braintree/version.rb +1 -1
- data/lib/views/frontend/spree/checkout/payment/_paypal_braintree.html.erb +52 -14
- metadata +11 -5
- data/app/assets/javascripts/spree/braintree_hosted_form.js +0 -98
@@ -1,188 +1 @@
|
|
1
|
-
//= require
|
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
|
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
|
-
'
|
34
|
+
'solidus_paypal_braintree/checkout.js',
|
35
|
+
'solidus_paypal_braintree/frontend.js',
|
35
36
|
'spree/frontend/paypal_button.js',
|
36
|
-
'spree/
|
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"
|
@@ -2,7 +2,22 @@
|
|
2
2
|
<% id = payment_method.id %>
|
3
3
|
|
4
4
|
<% content_for :head do %>
|
5
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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.
|
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-
|
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.
|
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
|
-
};
|