solidus_paypal_braintree 0.1.0 → 0.2.0

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.
@@ -0,0 +1,58 @@
1
+ SolidusPaypalBraintree = {
2
+ APPLE_PAY_API_VERSION: 1,
3
+
4
+ config: {
5
+ paths: {
6
+ clientTokens: Spree.pathFor('solidus_paypal_braintree/client_token'),
7
+ transactions: Spree.pathFor('solidus_paypal_braintree/transactions')
8
+ },
9
+
10
+ // Override to provide your own error messages.
11
+ braintreeErrorHandle: function(braintreeError) {
12
+ var $contentContainer = $("#content");
13
+ var $flash = $("<div class='flash error'>" + braintreeError.name + ": " + braintreeError.message + "</div>");
14
+ $contentContainer.prepend($flash);
15
+
16
+ $flash.show().delay(5000).fadeOut(500);
17
+ },
18
+
19
+ classes: {
20
+ hostedForm: function() {
21
+ return SolidusPaypalBraintree.HostedForm;
22
+ },
23
+
24
+ client: function() {
25
+ return SolidusPaypalBraintree.Client;
26
+ },
27
+
28
+ paypalButton: function() {
29
+ return SolidusPaypalBraintree.PaypalButton;
30
+ },
31
+
32
+ applepayButton: function() {
33
+ return SolidusPaypalBraintree.ApplepayButton;
34
+ }
35
+ }
36
+ },
37
+
38
+ createHostedForm: function() {
39
+ return SolidusPaypalBraintree._factory(SolidusPaypalBraintree.config.classes.hostedForm(), arguments);
40
+ },
41
+
42
+ createClient: function() {
43
+ return SolidusPaypalBraintree._factory(SolidusPaypalBraintree.config.classes.client(), arguments);
44
+ },
45
+
46
+ createPaypalButton: function() {
47
+ return SolidusPaypalBraintree._factory(SolidusPaypalBraintree.config.classes.paypalButton(), arguments);
48
+ },
49
+
50
+ createApplePayButton: function() {
51
+ return SolidusPaypalBraintree._factory(SolidusPaypalBraintree.config.classes.applepayButton(), arguments);
52
+ },
53
+
54
+ _factory: function(klass, args) {
55
+ var normalizedArgs = Array.prototype.slice.call(args);
56
+ return new (Function.prototype.bind.apply(klass, [null].concat(normalizedArgs)));
57
+ }
58
+ };
@@ -0,0 +1,12 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require solidus_paypal_braintree/constants
8
+ //= require solidus_paypal_braintree/promise
9
+ //= require solidus_paypal_braintree/client
10
+ //= require solidus_paypal_braintree/hosted_form
11
+ //= require solidus_paypal_braintree/paypal_button
12
+ //= require solidus_paypal_braintree/apple_pay_button
@@ -0,0 +1,36 @@
1
+ SolidusPaypalBraintree.HostedForm = function(paymentMethodId) {
2
+ this.paymentMethodId = paymentMethodId;
3
+ this.client = null;
4
+ };
5
+
6
+ SolidusPaypalBraintree.HostedForm.prototype.initialize = function() {
7
+ this.client = SolidusPaypalBraintree.createClient({paymentMethodId: this.paymentMethodId});
8
+ return this.client.initialize().
9
+ then(this._createHostedFields.bind(this));
10
+ };
11
+
12
+ SolidusPaypalBraintree.HostedForm.prototype._createHostedFields = function () {
13
+ if (!this.client) {
14
+ throw new Error("Client not initialized, please call initialize first!");
15
+ }
16
+
17
+ var opts = {
18
+ client: this.client.getBraintreeInstance(),
19
+
20
+ fields: {
21
+ number: {
22
+ selector: "#card_number" + this.paymentMethodId
23
+ },
24
+
25
+ cvv: {
26
+ selector: "#card_code" + this.paymentMethodId
27
+ },
28
+
29
+ expirationDate: {
30
+ selector: "#card_expiry" + this.paymentMethodId
31
+ }
32
+ }
33
+ };
34
+
35
+ return SolidusPaypalBraintree.PromiseShim.convertBraintreePromise(braintree.hostedFields.create, [opts]);
36
+ };
@@ -0,0 +1,114 @@
1
+ //= require solidus_paypal_braintree/constants
2
+ /**
3
+ * Constructor for PayPal button object
4
+ * @constructor
5
+ * @param {object} element - The DOM element of your PayPal button
6
+ */
7
+ SolidusPaypalBraintree.PaypalButton = function(element, paypalOptions) {
8
+ this._element = element;
9
+ this._paypalOptions = paypalOptions || {};
10
+ this._client = null;
11
+
12
+ if(!this._element) {
13
+ throw new Error("Element for the paypal button must be present on the page");
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Creates the PayPal session using the provided options and enables the button
19
+ *
20
+ * @param {object} options - The options passed to tokenize when constructing
21
+ * the PayPal instance
22
+ *
23
+ * See {@link https://braintree.github.io/braintree-web/3.9.0/PayPal.html#tokenize}
24
+ */
25
+ SolidusPaypalBraintree.PaypalButton.prototype.initialize = function() {
26
+ this._client = new SolidusPaypalBraintree.createClient({useDataCollector: true, usePaypal: true});
27
+
28
+ return this._client.initialize().then(this.initializeCallback.bind(this));
29
+ };
30
+
31
+ SolidusPaypalBraintree.PaypalButton.prototype.initializeCallback = function() {
32
+ this._paymentMethodId = this._client.paymentMethodId;
33
+
34
+ this._element.removeAttribute('disabled');
35
+ this._element.addEventListener('click', function(event) {
36
+ this._client.getPaypalInstance().tokenize(this._paypalOptions, this._tokenizeCallback.bind(this));
37
+ }.bind(this), false);
38
+ };
39
+
40
+ /**
41
+ * Default callback function for when tokenization completes
42
+ *
43
+ * @param {object|null} tokenizeErr - The error returned by Braintree on failure
44
+ * @param {object} payload - The payload returned by Braintree on success
45
+ */
46
+ SolidusPaypalBraintree.PaypalButton.prototype._tokenizeCallback = function(tokenizeErr, payload) {
47
+ if (tokenizeErr) {
48
+ SolidusPaypalBraintree.config.braintreeErrorHandle(tokenizeErr);
49
+ return;
50
+ }
51
+
52
+ var params = this._transactionParams(payload);
53
+
54
+ return Spree.ajax({
55
+ url: SolidusPaypalBraintree.config.paths.transactions,
56
+ type: 'POST',
57
+ dataType: 'json',
58
+ data: params,
59
+ success: function(response) {
60
+ window.location.href = response.redirectUrl;
61
+ },
62
+ error: function(xhr) {
63
+ console.error("Error submitting transaction")
64
+ },
65
+ });
66
+ };
67
+
68
+ /**
69
+ * Builds the transaction parameters to submit to Solidus for the given
70
+ * payload returned by Braintree
71
+ *
72
+ * @param {object} payload - The payload returned by Braintree after tokenization
73
+ */
74
+ SolidusPaypalBraintree.PaypalButton.prototype._transactionParams = function(payload) {
75
+ return {
76
+ "payment_method_id" : this._paymentMethodId,
77
+ "transaction" : {
78
+ "email" : payload.details.email,
79
+ "phone" : payload.details.phone,
80
+ "nonce" : payload.nonce,
81
+ "payment_type" : payload.type,
82
+ "address_attributes" : this._addressParams(payload)
83
+ }
84
+ }
85
+ };
86
+
87
+ /**
88
+ * Builds the address parameters to submit to Solidus using the payload
89
+ * returned by Braintree
90
+ *
91
+ * @param {object} payload - The payload returned by Braintree after tokenization
92
+ */
93
+ SolidusPaypalBraintree.PaypalButton.prototype._addressParams = function(payload) {
94
+ if (payload.details.shippingAddress.recipientName) {
95
+ var first_name = payload.details.shippingAddress.recipientName.split(" ")[0];
96
+ var last_name = payload.details.shippingAddress.recipientName.split(" ")[1];
97
+ }
98
+ if (first_name == null || last_name == null) {
99
+ var first_name = payload.details.firstName;
100
+ var last_name = payload.details.lastName;
101
+ }
102
+
103
+ return {
104
+ "first_name" : first_name,
105
+ "last_name" : last_name,
106
+ "address_line_1" : payload.details.shippingAddress.line1,
107
+ "address_line_2" : payload.details.shippingAddress.line2,
108
+ "city" : payload.details.shippingAddress.city,
109
+ "state_code" : payload.details.shippingAddress.state,
110
+ "zip" : payload.details.shippingAddress.postalCode,
111
+ "country_code" : payload.details.shippingAddress.countryCode
112
+ }
113
+ };
114
+
@@ -0,0 +1,20 @@
1
+ SolidusPaypalBraintree.PromiseShim = {
2
+ convertBraintreePromise: function(fn, args, context) {
3
+ var jqPromise = $.Deferred();
4
+
5
+ args = args || [];
6
+ context = context || this;
7
+
8
+ args = args.concat(function(error, data) {
9
+ if (error) {
10
+ jqPromise.reject(error);
11
+ } else {
12
+ jqPromise.resolve(data);
13
+ }
14
+ });
15
+
16
+ fn.apply(context, args);
17
+
18
+ return jqPromise.promise();
19
+ }
20
+ }
@@ -1,4 +1,7 @@
1
- //= require spree/braintree_hosted_form.js
1
+ //= require solidus_paypal_braintree/constants
2
+ //= require solidus_paypal_braintree/client
3
+ //= require solidus_paypal_braintree/promise
4
+ //= require solidus_paypal_braintree/hosted_form
2
5
 
3
6
  $(function() {
4
7
  var $paymentForm = $("#new_payment"),
@@ -18,6 +21,33 @@ $(function() {
18
21
  $("#card_form" + id).hide();
19
22
  }
20
23
 
24
+ function addFormHook(braintreeForm, errorCallback) {
25
+ var shouldSubmit = false;
26
+
27
+ function submit(payload) {
28
+ shouldSubmit = true;
29
+
30
+ $("#payment_method_nonce", braintreeForm.hostedFields).val(payload.nonce);
31
+ $paymentForm.submit();
32
+ }
33
+
34
+ return function(hostedFields) {
35
+ $paymentForm.on("submit", function(e) {
36
+ if ($hostedFields.is(":visible") && !shouldSubmit) {
37
+ e.preventDefault();
38
+
39
+ hostedFields.tokenize(function(err, payload) {
40
+ if (err) {
41
+ errorCallback(err);
42
+ } else {
43
+ submit(payload);
44
+ }
45
+ });
46
+ }
47
+ });
48
+ };
49
+ }
50
+
21
51
  function initFields($container, id) {
22
52
  function setHostedFieldsInstance(instance) {
23
53
  hostedFieldsInstance = instance;
@@ -25,10 +55,10 @@ $(function() {
25
55
  }
26
56
 
27
57
  if (hostedFieldsInstance === null) {
28
- braintreeForm = new BraintreeHostedForm($paymentForm, $container, id);
29
- braintreeForm.initializeHostedFields().
58
+ braintreeForm = new SolidusPaypalBraintree.createHostedForm(id);
59
+ braintreeForm.initialize().
30
60
  then(setHostedFieldsInstance).
31
- then(braintreeForm.addFormHook(onError)).
61
+ then(addFormHook(braintreeForm, onError)).
32
62
  fail(onError);
33
63
  }
34
64
  }
@@ -1,162 +1,11 @@
1
- /**
2
- * Constructor for PayPal button object
3
- * @constructor
4
- * @param {object} element - The DOM element of your PayPal button
5
- */
6
- function PaypalButton(element) {
7
- this.element = element;
8
- }
9
-
10
- /**
11
- * Creates the PayPal session using the provided options and enables the button
12
- *
13
- * @param {object} options - The options passed to tokenize when constructing
14
- * the PayPal instance
15
- *
16
- * See {@link https://braintree.github.io/braintree-web/3.9.0/PayPal.html#tokenize}
17
- */
18
- PaypalButton.prototype.initialize = function(options) {
19
- var self = this;
20
-
21
- /* This sets the payment method id returned by fetchToken on the PaypalButton
22
- * instance so that we can use it to build the transaction params later. */
23
- SolidusPaypalBraintree.fetchToken(function(token, paymentMethodId) {
24
- self.paymentMethodId = paymentMethodId;
25
-
26
- SolidusPaypalBraintree.initializeWithDataCollector(token, function(client) {
27
- self.createPaypalInstance(client, function(paypal) {
28
-
29
- self.initializePaypalSession({
30
- paypalInstance: paypal,
31
- paypalButton: self.element,
32
- paypalOptions: options
33
- }, self.tokenizeCallback.bind(self));
34
- });
35
-
36
- });
37
- });
38
- };
39
-
40
- PaypalButton.prototype.createPaypalInstance = function(braintreeClient, readyCallback) {
41
- braintree.paypal.create({
42
- client: braintreeClient
43
- }, function (paypalErr, paypalInstance) {
44
- if (paypalErr) {
45
- console.error("Error creating PayPal:", paypalErr);
46
- return;
47
- }
48
- readyCallback(paypalInstance);
49
- });
50
- };
51
-
52
- /* Initializes and begins the Paypal session
53
- *
54
- * @param config Configuration settings for the session
55
- * @param config.paypalInstance {object} The Paypal instance returned by Braintree
56
- * @param config.paypalButton {object} The button DOM element
57
- * @param config.paypalOptions {object} Configuration options for Paypal
58
- * @param config.error {tokenizeErrorCallback} Callback function for tokenize errors
59
- * @param {tokenizeCallback} callback Callback function for tokenization
60
- */
61
- PaypalButton.prototype.initializePaypalSession = function(config, callback) {
62
- config.paypalButton.removeAttribute('disabled');
63
- config.paypalButton.addEventListener('click', function(event) {
64
- config.paypalInstance.tokenize(config.paypalOptions, callback);
65
- }, false);
66
- },
67
-
68
- /**
69
- * Default callback function for when tokenization completes
70
- *
71
- * @param {object|null} tokenizeErr - The error returned by Braintree on failure
72
- * @param {object} payload - The payload returned by Braintree on success
73
- */
74
- PaypalButton.prototype.tokenizeCallback = function(tokenizeErr, payload) {
75
- if (tokenizeErr) {
76
- console.error('Error tokenizing:', tokenizeErr);
77
- } else {
78
- var params = this.transactionParams(payload);
79
-
80
- Spree.ajax({
81
- url: Spree.pathFor("solidus_paypal_braintree/transactions"),
82
- type: 'POST',
83
- dataType: 'json',
84
- data: params,
85
- success: function(response) {
86
- window.location.href = response.redirectUrl;
87
- },
88
- error: function(xhr) {
89
- console.error("Error submitting transaction")
90
- },
91
- });
92
- }
93
- };
94
-
95
- /**
96
- * Assigns a new callback function for when tokenization completes
97
- *
98
- * @callback callback - The callback function to assign
99
- */
100
- PaypalButton.prototype.setTokenizeCallback = function(callback) {
101
- this.tokenizeCallback = callback;
102
- };
103
-
104
- /**
105
- * Builds the transaction parameters to submit to Solidus for the given
106
- * payload returned by Braintree
107
- *
108
- * @param {object} payload - The payload returned by Braintree after tokenization
109
- */
110
- PaypalButton.prototype.transactionParams = function(payload) {
111
- return {
112
- "payment_method_id" : this.paymentMethodId,
113
- "transaction" : {
114
- "email" : payload.details.email,
115
- "phone" : payload.details.phone,
116
- "nonce" : payload.nonce,
117
- "payment_type" : payload.type,
118
- "address_attributes" : this.addressParams(payload)
119
- }
120
- }
121
- };
122
-
123
- /**
124
- * Builds the address parameters to submit to Solidus using the payload
125
- * returned by Braintree
126
- *
127
- * @param {object} payload - The payload returned by Braintree after tokenization
128
- */
129
- PaypalButton.prototype.addressParams = function(payload) {
130
- if (payload.details.shippingAddress.recipientName) {
131
- var first_name = payload.details.shippingAddress.recipientName.split(" ")[0];
132
- var last_name = payload.details.shippingAddress.recipientName.split(" ")[1];
133
- }
134
- if (first_name == null || last_name == null) {
135
- var first_name = payload.details.firstName;
136
- var last_name = payload.details.lastName;
137
- }
138
-
139
- return {
140
- "first_name" : first_name,
141
- "last_name" : last_name,
142
- "address_line_1" : payload.details.shippingAddress.line1,
143
- "address_line_2" : payload.details.shippingAddress.line2,
144
- "city" : payload.details.shippingAddress.city,
145
- "state_code" : payload.details.shippingAddress.state,
146
- "zip" : payload.details.shippingAddress.postalCode,
147
- "country_code" : payload.details.shippingAddress.countryCode
148
- }
149
- };
1
+ //= require solidus_paypal_braintree/paypal_button
150
2
 
151
3
  $(document).ready(function() {
152
4
  if (document.getElementById("empty-cart")) {
153
5
  $.when(
154
- $.getScript("https://js.braintreegateway.com/web/3.9.0/js/client.min.js"),
155
- $.getScript("https://js.braintreegateway.com/web/3.9.0/js/paypal.min.js"),
156
- $.getScript("https://js.braintreegateway.com/web/3.9.0/js/data-collector.min.js"),
157
- $.Deferred(function( deferred ){
158
- $( deferred.resolve );
159
- })
6
+ $.getScript("https://js.braintreegateway.com/web/3.14.0/js/client.min.js"),
7
+ $.getScript("https://js.braintreegateway.com/web/3.14.0/js/paypal.min.js"),
8
+ $.getScript("https://js.braintreegateway.com/web/3.14.0/js/data-collector.min.js")
160
9
  ).done(function() {
161
10
  $('<script/>').attr({
162
11
  'data-merchant' : "braintree",
@@ -169,11 +18,12 @@ $(document).ready(function() {
169
18
  'data-button_disabled' : "true"
170
19
  }).
171
20
  load(function() {
172
- var button = new PaypalButton(document.querySelector("#paypal-button"));
173
- button.initialize({
21
+ var paypalOptions = {
174
22
  flow: 'vault',
175
- enableShippingAddress: true,
176
- });
23
+ enableShippingAddress: true
24
+ }
25
+ var button = new SolidusPaypalBraintree.createPaypalButton(document.querySelector("#paypal-button"), paypalOptions);
26
+ return button.initialize();
177
27
  }).
178
28
  insertAfter("#content").
179
29
  attr('src', 'https://www.paypalobjects.com/api/button.js?')