solidus_stripe 4.3.0 → 5.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +98 -23
  3. data/.github/stale.yml +1 -17
  4. data/.gitignore +3 -0
  5. data/.rubocop.yml +94 -2
  6. data/.yardopts +1 -0
  7. data/CHANGELOG.md +1 -231
  8. data/Gemfile +10 -25
  9. data/LICENSE +2 -2
  10. data/Procfile.dev +3 -0
  11. data/README.md +155 -223
  12. data/Rakefile +7 -3
  13. data/app/assets/javascripts/spree/backend/solidus_stripe.js +2 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_stripe.css +4 -0
  15. data/app/controllers/solidus_stripe/intents_controller.rb +36 -52
  16. data/app/controllers/solidus_stripe/webhooks_controller.rb +28 -0
  17. data/app/models/concerns/solidus_stripe/log_entries.rb +31 -0
  18. data/app/models/solidus_stripe/customer.rb +21 -0
  19. data/app/models/solidus_stripe/gateway.rb +231 -0
  20. data/app/models/solidus_stripe/payment_intent.rb +111 -0
  21. data/app/models/solidus_stripe/payment_method.rb +106 -0
  22. data/app/models/solidus_stripe/payment_source.rb +31 -0
  23. data/app/models/solidus_stripe/slug_entry.rb +20 -0
  24. data/app/models/solidus_stripe.rb +7 -0
  25. data/app/subscribers/solidus_stripe/webhook/charge_subscriber.rb +28 -0
  26. data/app/subscribers/solidus_stripe/webhook/payment_intent_subscriber.rb +112 -0
  27. data/app/views/spree/admin/payments/source_forms/_stripe.html.erb +29 -0
  28. data/app/views/spree/admin/payments/source_forms/existing_payment/_stripe.html.erb +14 -0
  29. data/app/views/spree/admin/payments/source_forms/existing_payment/stripe/_card.html.erb +8 -0
  30. data/app/views/spree/admin/payments/source_forms/existing_payment/stripe/_default.html.erb +7 -0
  31. data/app/views/spree/admin/payments/source_views/_stripe.html.erb +15 -0
  32. data/app/views/spree/api/payments/source_views/_stripe.json.jbuilder +8 -0
  33. data/bin/dev +13 -0
  34. data/bin/dummy-app +29 -0
  35. data/bin/rails +38 -3
  36. data/bin/rails-dummy-app +3 -0
  37. data/bin/rails-engine +1 -11
  38. data/bin/rails-new +55 -0
  39. data/bin/rails-sandbox +1 -14
  40. data/bin/rspec +10 -0
  41. data/bin/sandbox +12 -74
  42. data/bin/setup +1 -0
  43. data/bin/update-migrations +56 -0
  44. data/codecov.yml +12 -0
  45. data/config/locales/en.yml +16 -1
  46. data/config/routes.rb +5 -11
  47. data/coverage.rb +42 -0
  48. data/db/migrate/20230109183332_create_solidus_stripe_payment_sources.rb +10 -0
  49. data/db/migrate/20230303154931_create_solidus_stripe_setup_intent.rb +10 -0
  50. data/db/migrate/20230306105520_create_solidus_stripe_payment_intents.rb +10 -0
  51. data/db/migrate/20230308122414_create_solidus_stripe_webhook_endpoints.rb +10 -0
  52. data/db/migrate/20230310152615_add_payment_method_reference_to_stripe_intents.rb +6 -0
  53. data/db/migrate/20230310171444_normalize_stripe_intent_id_attributes.rb +6 -0
  54. data/db/migrate/20230313150008_create_solidus_stripe_customers.rb +16 -0
  55. data/db/migrate/20230323154931_drop_solidus_stripe_setup_intent.rb +13 -0
  56. data/db/migrate/20230403094916_rename_webhook_endpoint_to_payment_method_slug_entries.rb +5 -0
  57. data/db/seeds.rb +6 -24
  58. data/lib/generators/solidus_stripe/install/install_generator.rb +121 -14
  59. data/lib/generators/solidus_stripe/install/templates/app/assets/stylesheets/spree/frontend/solidus_stripe.css +13 -0
  60. data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_confirm_controller.js +39 -0
  61. data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_payment_controller.js +89 -0
  62. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/_stripe.html.erb +16 -0
  63. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/stripe/_card.html.erb +8 -0
  64. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/stripe/_default.html.erb +7 -0
  65. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/payment/_stripe.html.erb +39 -0
  66. data/lib/generators/solidus_stripe/install/templates/app/views/orders/payment_info/_stripe.html.erb +20 -0
  67. data/lib/generators/solidus_stripe/install/templates/config/initializers/solidus_stripe.rb +31 -0
  68. data/lib/solidus_stripe/configuration.rb +24 -3
  69. data/lib/solidus_stripe/engine.rb +19 -6
  70. data/lib/solidus_stripe/money_to_stripe_amount_converter.rb +109 -0
  71. data/lib/solidus_stripe/refunds_synchronizer.rb +96 -0
  72. data/lib/solidus_stripe/seeds.rb +19 -0
  73. data/lib/solidus_stripe/testing_support/factories.rb +153 -0
  74. data/lib/solidus_stripe/version.rb +1 -1
  75. data/lib/solidus_stripe/webhook/event.rb +90 -0
  76. data/lib/solidus_stripe.rb +0 -2
  77. data/solidus_stripe.gemspec +29 -5
  78. data/spec/lib/solidus_stripe/configuration_spec.rb +21 -0
  79. data/spec/lib/solidus_stripe/money_to_stripe_amount_converter_spec.rb +133 -0
  80. data/spec/lib/solidus_stripe/refunds_synchronizer_spec.rb +238 -0
  81. data/spec/lib/solidus_stripe/seeds_spec.rb +43 -0
  82. data/spec/lib/solidus_stripe/webhook/event_spec.rb +134 -0
  83. data/spec/models/concerns/solidus_stripe/log_entries_spec.rb +54 -0
  84. data/spec/models/solidus_stripe/customer_spec.rb +47 -0
  85. data/spec/models/solidus_stripe/gateway_spec.rb +283 -0
  86. data/spec/models/solidus_stripe/payment_intent_spec.rb +17 -0
  87. data/spec/models/solidus_stripe/payment_method_spec.rb +137 -0
  88. data/spec/models/solidus_stripe/payment_source_spec.rb +25 -0
  89. data/spec/requests/solidus_stripe/intents_controller_spec.rb +29 -0
  90. data/spec/requests/solidus_stripe/webhooks_controller/charge/refunded_spec.rb +31 -0
  91. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/canceled_spec.rb +23 -0
  92. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/payment_failed_spec.rb +23 -0
  93. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/succeeded_spec.rb +29 -0
  94. data/spec/requests/solidus_stripe/webhooks_controller_spec.rb +52 -0
  95. data/spec/solidus_stripe_spec_helper.rb +10 -0
  96. data/spec/subscribers/solidus_stripe/webhook/charge_subscriber_spec.rb +33 -0
  97. data/spec/subscribers/solidus_stripe/webhook/payment_intent_subscriber_spec.rb +297 -0
  98. data/spec/support/solidus_stripe/backend_test_helper.rb +210 -0
  99. data/spec/support/solidus_stripe/checkout_test_helper.rb +339 -0
  100. data/spec/support/solidus_stripe/factories.rb +5 -0
  101. data/spec/support/solidus_stripe/webhook/data_fixtures.rb +106 -0
  102. data/spec/support/solidus_stripe/webhook/event_with_context_factory.rb +82 -0
  103. data/spec/support/solidus_stripe/webhook/request_helper.rb +32 -0
  104. data/spec/system/backend/solidus_stripe/orders/payments_spec.rb +119 -0
  105. data/spec/system/frontend/.keep +0 -0
  106. data/spec/system/frontend/solidus_stripe/checkout_spec.rb +187 -0
  107. data/tmp/.keep +0 -0
  108. metadata +210 -69
  109. data/.travis.yml +0 -28
  110. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-cart-page-checkout.js +0 -122
  111. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-elements.js +0 -148
  112. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-init.js +0 -20
  113. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-intents.js +0 -84
  114. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-request-button-shared.js +0 -160
  115. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment.js +0 -16
  116. data/app/assets/javascripts/spree/frontend/solidus_stripe.js +0 -6
  117. data/app/controllers/solidus_stripe/payment_request_controller.rb +0 -52
  118. data/app/controllers/spree/stripe_controller.rb +0 -13
  119. data/app/decorators/models/spree/order_update_attributes_decorator.rb +0 -39
  120. data/app/decorators/models/spree/payment_decorator.rb +0 -11
  121. data/app/decorators/models/spree/refund_decorator.rb +0 -9
  122. data/app/models/solidus_stripe/address_from_params_service.rb +0 -72
  123. data/app/models/solidus_stripe/create_intents_payment_service.rb +0 -114
  124. data/app/models/solidus_stripe/prepare_order_for_payment_service.rb +0 -46
  125. data/app/models/solidus_stripe/shipping_rates_service.rb +0 -46
  126. data/app/models/spree/payment_method/stripe_credit_card.rb +0 -217
  127. data/bin/r +0 -13
  128. data/bin/sandbox_rails +0 -18
  129. data/db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb +0 -21
  130. data/lib/assets/stylesheets/spree/frontend/solidus_stripe.scss +0 -11
  131. data/lib/solidus_stripe/testing_support/card_input_helper.rb +0 -34
  132. data/lib/tasks/solidus_stripe/db/seed.rake +0 -14
  133. data/lib/views/api/spree/api/payments/source_views/_stripe.json.jbuilder +0 -3
  134. data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +0 -28
  135. data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +0 -1
  136. data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +0 -1
  137. data/lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb +0 -1
  138. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +0 -8
  139. data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +0 -78
  140. data/lib/views/frontend/spree/checkout/payment/v3/_elements.html.erb +0 -1
  141. data/lib/views/frontend/spree/checkout/payment/v3/_form_elements.html.erb +0 -40
  142. data/lib/views/frontend/spree/checkout/payment/v3/_intents.html.erb +0 -1
  143. data/lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb +0 -2
  144. data/lib/views/frontend/spree/orders/_stripe_payment_request_button.html.erb +0 -14
  145. data/spec/features/stripe_checkout_spec.rb +0 -486
  146. data/spec/models/solidus_stripe/address_from_params_service_spec.rb +0 -87
  147. data/spec/models/solidus_stripe/create_intents_payment_service_spec.rb +0 -127
  148. data/spec/models/solidus_stripe/prepare_order_for_payment_service_spec.rb +0 -65
  149. data/spec/models/solidus_stripe/shipping_rates_service_spec.rb +0 -54
  150. data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +0 -316
  151. data/spec/requests/payment_requests_spec.rb +0 -152
  152. data/spec/spec_helper.rb +0 -37
  153. data/spec/support/solidus_address_helper.rb +0 -15
@@ -1,122 +0,0 @@
1
- SolidusStripe.CartPageCheckout = function() {
2
- SolidusStripe.Payment.call(this);
3
-
4
- this.errorElement = $('#card-errors');
5
- };
6
-
7
- SolidusStripe.CartPageCheckout.prototype = Object.create(SolidusStripe.Payment.prototype);
8
- Object.defineProperty(SolidusStripe.CartPageCheckout.prototype, 'constructor', {
9
- value: SolidusStripe.CartPageCheckout,
10
- enumerable: false,
11
- writable: true
12
- });
13
-
14
- SolidusStripe.CartPageCheckout.prototype.init = function() {
15
- this.setUpPaymentRequest({requestShipping: true});
16
- };
17
-
18
- SolidusStripe.CartPageCheckout.prototype.showError = function(error) {
19
- var message = error.message || error;
20
-
21
- this.errorElement.text(message).show();
22
- };
23
-
24
- SolidusStripe.CartPageCheckout.prototype.submitPayment = function(payment) {
25
- var showError = this.showError.bind(this);
26
- var prTokenHandler = this.prTokenHandler.bind(this);
27
-
28
- $.ajax({
29
- url: $('[data-submit-url]').data('submit-url'),
30
- headers: {
31
- 'X-Spree-Order-Token': $('[data-order-token]').data('order-token')
32
- },
33
- type: 'PATCH',
34
- contentType: 'application/json',
35
- data: JSON.stringify(prTokenHandler(payment.paymentMethod)),
36
- success: function() {
37
- window.location = $('[data-complete-url]').data('complete-url');
38
- },
39
- error: function(xhr,status,error) {
40
- showError(xhr.responseJSON.error);
41
- }
42
- });
43
- };
44
-
45
- SolidusStripe.CartPageCheckout.prototype.onPrPayment = function(payment) {
46
- var createIntent = this.createIntent.bind(this);
47
-
48
- fetch('/stripe/update_order', {
49
- method: 'POST',
50
- headers: { 'Content-Type': 'application/json' },
51
- body: JSON.stringify({
52
- shipping_address: payment.shippingAddress,
53
- shipping_option: payment.shippingOption,
54
- email: payment.payerEmail,
55
- name: payment.payerName,
56
- phone: payment.payerPhone,
57
- authenticity_token: this.authToken
58
- })
59
- }).then(function(response) {
60
- response.json().then(function(json) {
61
- createIntent(json, payment);
62
- })
63
- });
64
- };
65
-
66
- SolidusStripe.CartPageCheckout.prototype.createIntent = function(result, payment) {
67
- var handleServerResponse = this.handleServerResponse.bind(this);
68
-
69
- if (result.error) {
70
- this.completePaymentRequest(payment, 'fail');
71
- this.showError(result.error);
72
- } else {
73
- if (payment.error) {
74
- this.showError(payment.error.message);
75
- } else {
76
- fetch('/stripe/create_intent', {
77
- method: 'POST',
78
- headers: {
79
- 'Content-Type': 'application/json'
80
- },
81
- body: JSON.stringify({
82
- form_data: payment.shippingAddress,
83
- spree_payment_method_id: this.config.id,
84
- stripe_payment_method_id: payment.paymentMethod.id,
85
- authenticity_token: this.authToken
86
- })
87
- }).then(function(response) {
88
- response.json().then(function(result) {
89
- handleServerResponse(result, payment)
90
- })
91
- });
92
- }
93
- }
94
- };
95
-
96
- SolidusStripe.CartPageCheckout.prototype.onPrButtonMounted = function(buttonId, success) {
97
- var container = document.getElementById(buttonId).parentElement;
98
-
99
- if (success) {
100
- container.style.display = '';
101
- } else {
102
- container.style.display = 'none';
103
- }
104
- };
105
-
106
- SolidusStripe.CartPageCheckout.prototype.prTokenHandler = function(token) {
107
- return {
108
- order: {
109
- payments_attributes: [
110
- {
111
- payment_method_id: this.config.id,
112
- source_attributes: {
113
- gateway_payment_profile_id: token.id,
114
- last_digits: token.card.last4,
115
- month: token.card.exp_month,
116
- year: token.card.exp_year
117
- }
118
- }
119
- ]
120
- }
121
- }
122
- };
@@ -1,148 +0,0 @@
1
- SolidusStripe.Elements = function() {
2
- SolidusStripe.Payment.call(this);
3
-
4
- this.form = this.element.parents('form');
5
- this.errorElement = this.form.find('#card-errors');
6
- this.submitButton = this.form.find('input[type="submit"]');
7
- };
8
-
9
- SolidusStripe.Elements.prototype = Object.create(SolidusStripe.Payment.prototype);
10
- Object.defineProperty(SolidusStripe.Elements.prototype, 'constructor', {
11
- value: SolidusStripe.Elements,
12
- enumerable: false,
13
- writable: true
14
- });
15
-
16
- SolidusStripe.Elements.prototype.init = function() {
17
- this.initElements();
18
- };
19
-
20
- SolidusStripe.Elements.prototype.initElements = function() {
21
- var cardExpiry = this.elements.create('cardExpiry', this.cardExpiryElementOptions());
22
- cardExpiry.mount('#card_expiry');
23
-
24
- var cardCvc = this.elements.create('cardCvc', this.cardCvcElementOptions());
25
- cardCvc.mount('#card_cvc');
26
-
27
- this.cardNumber = this.elements.create('cardNumber', this.cardNumberElementOptions());
28
- this.cardNumber.mount('#card_number');
29
-
30
- this.form.bind('submit', this.onFormSubmit.bind(this));
31
-
32
- // Listen for errors from each input field.
33
- // Adapted from https://github.com/stripe/elements-examples/blob/master/js/index.js
34
- var savedErrors = {};
35
- [cardExpiry, cardCvc, this.cardNumber].forEach(function(element, idx) {
36
- element.on('change', function(event) {
37
- if (event.error) {
38
- savedErrors[idx] = event.error.message;
39
- this.showError(event.error.message);
40
- } else {
41
- savedErrors[idx] = null;
42
-
43
- // Loop over the saved errors and find the first one, if any.
44
- var nextError = Object.keys(savedErrors)
45
- .sort()
46
- .reduce(function(maybeFoundError, key) {
47
- return maybeFoundError || savedErrors[key];
48
- }, null);
49
-
50
- if (nextError) {
51
- // Now that they've fixed the current error, show another one.
52
- this.showError(nextError);
53
- } else {
54
- // The user fixed the last error; no more errors.
55
- this.errorElement.hide().text('');
56
- }
57
- }
58
- }.bind(this));
59
- }.bind(this));
60
- };
61
-
62
- SolidusStripe.Elements.prototype.baseStyle = function () {
63
- return {
64
- base: {
65
- color: 'black',
66
- fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
67
- fontSmoothing: 'antialiased',
68
- fontSize: '14px',
69
- '::placeholder': {
70
- color: 'silver'
71
- }
72
- },
73
- invalid: {
74
- color: 'red',
75
- iconColor: 'red'
76
- }
77
- };
78
- };
79
-
80
- SolidusStripe.Elements.prototype.cardNumberElementOptions = function () {
81
- return {
82
- style: this.baseStyle()
83
- }
84
- }
85
-
86
- SolidusStripe.Elements.prototype.cardExpiryElementOptions = function () {
87
- return {
88
- style: this.baseStyle()
89
- }
90
- }
91
-
92
- SolidusStripe.Elements.prototype.cardCvcElementOptions = function () {
93
- return {
94
- style: this.baseStyle()
95
- }
96
- }
97
-
98
- SolidusStripe.Elements.prototype.showError = function(error) {
99
- var message = error.message || error;
100
-
101
- this.errorElement.text(message).show();
102
- this.submitButton.removeAttr('disabled').removeClass('disabled');
103
- };
104
-
105
- SolidusStripe.Elements.prototype.onFormSubmit = function(event) {
106
- if (this.element.is(':visible')) {
107
- event.preventDefault();
108
-
109
- var onTokenCreate = function(result) {
110
- if (result.error) {
111
- this.showError(result.error.message);
112
- } else {
113
- this.elementsTokenHandler(result.token);
114
- this.form[0].submit();
115
- }
116
- };
117
-
118
- this.stripe.createToken(this.cardNumber).then(onTokenCreate.bind(this));
119
- }
120
- };
121
-
122
- SolidusStripe.Elements.prototype.elementsTokenHandler = function(token) {
123
- var mapCC = function(ccType) {
124
- if (ccType === 'MasterCard' || ccType === 'mastercard') {
125
- return 'mastercard';
126
- } else if (ccType === 'Visa' || ccType === 'visa') {
127
- return 'visa';
128
- } else if (ccType === 'American Express' || ccType === 'amex') {
129
- return 'amex';
130
- } else if (ccType === 'Discover' || ccType === 'discover') {
131
- return 'discover';
132
- } else if (ccType === 'Diners Club' || ccType === 'diners') {
133
- return 'dinersclub';
134
- } else if (ccType === 'JCB' || ccType === 'jcb') {
135
- return 'jcb';
136
- } else if (ccType === 'Unionpay' || ccType === 'unionpay') {
137
- return 'unionpay';
138
- }
139
- };
140
-
141
- var baseSelector = `<input type='hidden' class='stripeToken' name='payment_source[${this.config.id}]`;
142
-
143
- this.element.append(`${baseSelector}[gateway_payment_profile_id]' value='${token.id}'/>`);
144
- this.element.append(`${baseSelector}[last_digits]' value='${token.card.last4}'/>`);
145
- this.element.append(`${baseSelector}[month]' value='${token.card.exp_month}'/>`);
146
- this.element.append(`${baseSelector}[year]' value='${token.card.exp_year}'/>`);
147
- this.form.find('input#cc_type').val(mapCC(token.card.brand || token.card.type));
148
- };
@@ -1,20 +0,0 @@
1
- $(function() {
2
- var stripeV3Api = $('[data-v3-api]').data('v3-api');
3
-
4
- if (stripeV3Api) {
5
- $.getScript('https://js.stripe.com/v3/')
6
- .done(function() {
7
- switch (stripeV3Api) {
8
- case 'elements':
9
- new SolidusStripe.Elements().init();
10
- break;
11
- case 'payment-intents':
12
- new SolidusStripe.PaymentIntents().init();
13
- break;
14
- case 'payment-request-button':
15
- new SolidusStripe.CartPageCheckout().init();
16
- break;
17
- }
18
- });
19
- }
20
- });
@@ -1,84 +0,0 @@
1
- SolidusStripe.PaymentIntents = function() {
2
- SolidusStripe.Elements.call(this);
3
- };
4
-
5
- SolidusStripe.PaymentIntents.prototype = Object.create(SolidusStripe.Elements.prototype);
6
- Object.defineProperty(SolidusStripe.PaymentIntents.prototype, 'constructor', {
7
- value: SolidusStripe.PaymentIntents,
8
- enumerable: false,
9
- writable: true
10
- });
11
-
12
- SolidusStripe.PaymentIntents.prototype.init = function() {
13
- this.setUpPaymentRequest();
14
- this.initElements();
15
- };
16
-
17
- SolidusStripe.PaymentIntents.prototype.onPrPayment = function(payment) {
18
- if (payment.error) {
19
- this.showError(payment.error.message);
20
- } else {
21
- var that = this;
22
-
23
- this.elementsTokenHandler(payment.paymentMethod);
24
- fetch('/stripe/create_intent', {
25
- method: 'POST',
26
- headers: {
27
- 'Content-Type': 'application/json'
28
- },
29
- body: JSON.stringify({
30
- form_data: this.form.serialize(),
31
- spree_payment_method_id: this.config.id,
32
- stripe_payment_method_id: payment.paymentMethod.id,
33
- authenticity_token: this.authToken
34
- })
35
- }).then(function(response) {
36
- response.json().then(function(json) {
37
- that.handleServerResponse(json, payment);
38
- })
39
- });
40
- }
41
- };
42
-
43
- SolidusStripe.PaymentIntents.prototype.onFormSubmit = function(event) {
44
- if (this.element.is(':visible')) {
45
- event.preventDefault();
46
-
47
- this.errorElement.text('').hide();
48
-
49
- this.stripe.createPaymentMethod(
50
- 'card',
51
- this.cardNumber
52
- ).then(this.onIntentsPayment.bind(this));
53
- }
54
- };
55
-
56
- SolidusStripe.PaymentIntents.prototype.submitPayment = function(_payment) {
57
- this.form.unbind('submit').submit();
58
- };
59
-
60
- SolidusStripe.PaymentIntents.prototype.onIntentsPayment = function(payment) {
61
- if (payment.error) {
62
- this.showError(payment.error.message);
63
- } else {
64
- var that = this;
65
-
66
- this.elementsTokenHandler(payment.paymentMethod);
67
- fetch('/stripe/create_intent', {
68
- method: 'POST',
69
- headers: {
70
- 'Content-Type': 'application/json'
71
- },
72
- body: JSON.stringify({
73
- form_data: this.form.serialize(),
74
- spree_payment_method_id: this.config.id,
75
- stripe_payment_method_id: payment.paymentMethod.id,
76
- authenticity_token: this.authToken
77
- })
78
- }).then(function(response) {
79
- response.json().then(function(json) {
80
- that.handleServerResponse(json, payment);
81
- })
82
- });
83
- }
84
- };
@@ -1,160 +0,0 @@
1
- // Shared code between Payment Intents and Payment Request Button on cart page
2
-
3
- (function() {
4
- var PaymentRequestButtonShared;
5
-
6
- PaymentRequestButtonShared = {
7
- authToken: $('meta[name="csrf-token"]').attr('content'),
8
-
9
- setUpPaymentRequest: function(opts) {
10
- var opts = opts || {};
11
- var config = this.config.payment_request;
12
-
13
- if (config) {
14
- config.requestShipping = opts.requestShipping || false;
15
-
16
- var paymentRequest = this.stripe.paymentRequest({
17
- country: config.country,
18
- currency: config.currency,
19
- total: {
20
- label: config.label,
21
- amount: config.amount
22
- },
23
- requestPayerName: true,
24
- requestPayerEmail: true,
25
- requestPayerPhone: true,
26
- requestShipping: config.requestShipping,
27
- shippingOptions: []
28
- });
29
-
30
- var prButton = this.elements.create('paymentRequestButton', {
31
- paymentRequest: paymentRequest
32
- });
33
-
34
- var onButtonMount = function(result) {
35
- var id = 'payment-request-button';
36
-
37
- if (result) {
38
- prButton.mount('#' + id);
39
- } else {
40
- document.getElementById(id).style.display = 'none';
41
- }
42
- if (typeof this.onPrButtonMounted === 'function') {
43
- this.onPrButtonMounted(id, result);
44
- }
45
- }
46
- paymentRequest.canMakePayment().then(onButtonMount.bind(this));
47
-
48
- var onPrPaymentMethod = function(result) {
49
- this.errorElement.text('').hide();
50
- this.onPrPayment(result);
51
- };
52
- paymentRequest.on('paymentmethod', onPrPaymentMethod.bind(this));
53
-
54
- var onShippingAddressChange = function(ev) {
55
- var showError = this.showError.bind(this);
56
-
57
- fetch('/stripe/shipping_rates', {
58
- method: 'POST',
59
- headers: { 'Content-Type': 'application/json' },
60
- body: JSON.stringify({
61
- authenticity_token: this.authToken,
62
- shipping_address: ev.shippingAddress
63
- })
64
- }).then(function(response) {
65
- return response.json();
66
- }).then(function(result) {
67
- if (result.error) {
68
- showError(result.error);
69
- return false;
70
- } else {
71
- ev.updateWith({
72
- status: 'success',
73
- shippingOptions: result.shipping_rates
74
- });
75
- }
76
- });
77
- };
78
- paymentRequest.on('shippingaddresschange', onShippingAddressChange.bind(this));
79
- }
80
- },
81
-
82
- handleServerResponse: function(response, payment) {
83
- if (response.error) {
84
- this.showError(response.error);
85
- this.completePaymentRequest(payment, 'fail');
86
- } else if (response.requires_action) {
87
- var clientSecret = response.stripe_payment_intent_client_secret;
88
- var onConfirmCardPayment = this.onConfirmCardPayment.bind(this);
89
-
90
- this.stripe.confirmCardPayment(
91
- clientSecret,
92
- {payment_method: payment.paymentMethod.id},
93
- {handleActions: false}
94
- ).then(function(confirmResult) {
95
- onConfirmCardPayment(confirmResult, payment, clientSecret)
96
- });
97
- } else {
98
- this.completePayment(payment, response.stripe_payment_intent_id)
99
- }
100
- },
101
-
102
- onConfirmCardPayment: function(confirmResult, payment, clientSecret) {
103
- onStripeResponse = function(response, payment) {
104
- if (response.error) {
105
- this.showError(response.error);
106
- } else {
107
- this.completePayment(payment, response.paymentIntent.id)
108
- }
109
- }.bind(this);
110
-
111
- if (confirmResult.error) {
112
- this.completePaymentRequest(payment, 'fail');
113
- this.showError(confirmResult.error);
114
- } else {
115
- this.completePaymentRequest(payment, 'success');
116
- this.stripe.confirmCardPayment(clientSecret).then(function(response) {
117
- onStripeResponse(response, payment);
118
- });
119
- }
120
- },
121
-
122
- completePayment: function(payment, stripePaymentIntentId) {
123
- var onCreateBackendPayment = function (response) {
124
- if (response.error) {
125
- this.completePaymentRequest(payment, 'fail');
126
- this.showError(response.error);
127
- } else {
128
- this.completePaymentRequest(payment, 'success');
129
- this.submitPayment(payment);
130
- }
131
- }.bind(this);
132
-
133
- fetch('/stripe/create_payment', {
134
- method: 'POST',
135
- headers: { 'Content-Type': 'application/json' },
136
- body: JSON.stringify({
137
- form_data: this.form ? this.form.serialize() : payment.shippingAddress,
138
- spree_payment_method_id: this.config.id,
139
- stripe_payment_intent_id: stripePaymentIntentId,
140
- authenticity_token: this.authToken
141
- })
142
- }).then(function(solidusPaymentResponse) {
143
- return solidusPaymentResponse.json();
144
- }).then(onCreateBackendPayment)
145
- },
146
-
147
- completePaymentRequest: function(payment, state) {
148
- if (payment && typeof payment.complete === 'function') {
149
- payment.complete(state);
150
- if (state === 'fail') {
151
- // restart the button (required in order to force address choice)
152
- new SolidusStripe.CartPageCheckout().init();
153
- }
154
- }
155
- }
156
- };
157
-
158
- Object.assign(SolidusStripe.PaymentIntents.prototype, PaymentRequestButtonShared);
159
- Object.assign(SolidusStripe.CartPageCheckout.prototype, PaymentRequestButtonShared);
160
- })()
@@ -1,16 +0,0 @@
1
- window.SolidusStripe = window.SolidusStripe || {};
2
-
3
- SolidusStripe.Payment = function() {
4
- this.config = $('[data-stripe-config]').data('stripe-config');
5
- this.element = $('#payment_method_' + this.config.id);
6
- this.authToken = $('meta[name="csrf-token"]').attr('content');
7
-
8
- this.stripe = Stripe(this.config.publishable_key);
9
- this.elements = this.stripe.elements(this.elementsBaseOptions());
10
- };
11
-
12
- SolidusStripe.Payment.prototype.elementsBaseOptions = function () {
13
- return {
14
- locale: 'en'
15
- };
16
- };
@@ -1,6 +0,0 @@
1
- //= require ./solidus_stripe/stripe-payment
2
- //= require ./solidus_stripe/stripe-elements
3
- //= require ./solidus_stripe/stripe-payment-intents
4
- //= require ./solidus_stripe/stripe-cart-page-checkout
5
- //= require ./solidus_stripe/stripe-payment-request-button-shared
6
- //= require ./solidus_stripe/stripe-init
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidusStripe
4
- class PaymentRequestController < Spree::BaseController
5
- include Spree::Core::ControllerHelpers::Order
6
-
7
- def shipping_rates
8
- rates = SolidusStripe::ShippingRatesService.new(
9
- current_order,
10
- spree_current_user,
11
- params[:shipping_address]
12
- ).call
13
-
14
- if rates.any?
15
- render json: { success: true, shipping_rates: rates }
16
- else
17
- render json: { success: false, error: 'No shipping method available for that address' }, status: 500
18
- end
19
- end
20
-
21
- def update_order
22
- current_order.restart_checkout_flow
23
-
24
- address = SolidusStripe::AddressFromParamsService.new(
25
- shipping_address_from_params,
26
- spree_current_user
27
- ).call
28
-
29
- if address.valid?
30
- SolidusStripe::PrepareOrderForPaymentService.new(address, self).call
31
-
32
- if current_order.payment?
33
- render json: { success: true }
34
- else
35
- render json: { success: false, error: 'Order not ready for payment. Try manual checkout.' }, status: 500
36
- end
37
- else
38
- render json: { success: false, error: address.errors.full_messages.to_sentence }, status: 500
39
- end
40
- end
41
-
42
- private
43
-
44
- def shipping_address_from_params
45
- return {} unless params[:shipping_address]
46
- return params[:shipping_address] if params.dig(:shipping_address, :phone).present?
47
-
48
- params[:shipping_address][:phone] = params[:phone]
49
- params[:shipping_address]
50
- end
51
- end
52
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spree
4
- class StripeController < SolidusStripe::IntentsController
5
- include Core::ControllerHelpers::Order
6
-
7
- def confirm_payment
8
- Deprecation.warn "please use SolidusStripe::IntentsController#confirm"
9
-
10
- confirm
11
- end
12
- end
13
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spree
4
- module OrderUpdateAttributesDecorator
5
- def assign_payments_attributes
6
- return if payments_attributes.empty?
7
- return if adding_new_stripe_payment_intents_card?
8
-
9
- stripe_intents_pending_payments.each(&:void_transaction!)
10
-
11
- super
12
- end
13
-
14
- private
15
-
16
- def adding_new_stripe_payment_intents_card?
17
- paying_with_stripe_intents? && stripe_intents_pending_payments.any?
18
- end
19
-
20
- def stripe_intents_pending_payments
21
- @stripe_intents_pending_payments ||= order.payments.valid.select do |payment|
22
- payment_method = payment.payment_method
23
- payment.pending? && stripe_intents?(payment_method)
24
- end
25
- end
26
-
27
- def paying_with_stripe_intents?
28
- if id = payments_attributes.first&.dig(:payment_method_id)
29
- stripe_intents?(Spree::PaymentMethod.find(id))
30
- end
31
- end
32
-
33
- def stripe_intents?(payment_method)
34
- payment_method.respond_to?(:v3_intents?) && payment_method.v3_intents?
35
- end
36
-
37
- ::Spree::OrderUpdateAttributes.prepend(self)
38
- end
39
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spree
4
- module PaymentDecorator
5
- def gateway_order_identifier
6
- gateway_order_id
7
- end
8
-
9
- ::Spree::Payment.prepend(self)
10
- end
11
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spree
4
- module RefundDecorator
5
- attr_reader :response
6
-
7
- ::Spree::Refund.prepend(self)
8
- end
9
- end