solidus_stripe 4.4.1 → 5.0.0.alpha.1

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.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +92 -52
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +94 -4
  5. data/.yardopts +1 -0
  6. data/Gemfile +10 -30
  7. data/LICENSE +2 -2
  8. data/Procfile.dev +3 -0
  9. data/README.md +145 -215
  10. data/Rakefile +5 -44
  11. data/app/assets/javascripts/spree/backend/solidus_stripe.js +2 -0
  12. data/app/assets/stylesheets/spree/backend/solidus_stripe.css +4 -0
  13. data/app/controllers/solidus_stripe/intents_controller.rb +36 -52
  14. data/app/controllers/solidus_stripe/webhooks_controller.rb +28 -0
  15. data/app/models/concerns/solidus_stripe/log_entries.rb +31 -0
  16. data/app/models/solidus_stripe/customer.rb +21 -0
  17. data/app/models/solidus_stripe/gateway.rb +231 -0
  18. data/app/models/solidus_stripe/payment_intent.rb +111 -0
  19. data/app/models/solidus_stripe/payment_method.rb +106 -0
  20. data/app/models/solidus_stripe/payment_source.rb +31 -0
  21. data/app/models/solidus_stripe/slug_entry.rb +20 -0
  22. data/app/models/solidus_stripe.rb +7 -0
  23. data/app/subscribers/solidus_stripe/webhook/charge_subscriber.rb +28 -0
  24. data/app/subscribers/solidus_stripe/webhook/payment_intent_subscriber.rb +112 -0
  25. data/app/views/spree/admin/payments/source_forms/_stripe.html.erb +29 -0
  26. data/app/views/spree/admin/payments/source_forms/existing_payment/_stripe.html.erb +14 -0
  27. data/app/views/spree/admin/payments/source_forms/existing_payment/stripe/_card.html.erb +8 -0
  28. data/app/views/spree/admin/payments/source_forms/existing_payment/stripe/_default.html.erb +7 -0
  29. data/app/views/spree/admin/payments/source_views/_stripe.html.erb +15 -0
  30. data/app/views/spree/api/payments/source_views/_stripe.json.jbuilder +8 -0
  31. data/bin/dev +13 -0
  32. data/bin/dummy-app +29 -0
  33. data/bin/rails +38 -3
  34. data/bin/rails-dummy-app +3 -0
  35. data/bin/rails-engine +1 -11
  36. data/bin/rails-new +55 -0
  37. data/bin/rails-sandbox +1 -14
  38. data/bin/rspec +10 -0
  39. data/bin/sandbox +12 -74
  40. data/bin/setup +1 -0
  41. data/bin/update-migrations +56 -0
  42. data/codecov.yml +12 -0
  43. data/config/locales/en.yml +16 -1
  44. data/config/routes.rb +5 -11
  45. data/coverage.rb +42 -0
  46. data/db/migrate/20230109183332_create_solidus_stripe_payment_sources.rb +10 -0
  47. data/db/migrate/20230303154931_create_solidus_stripe_setup_intent.rb +10 -0
  48. data/db/migrate/20230306105520_create_solidus_stripe_payment_intents.rb +10 -0
  49. data/db/migrate/20230308122414_create_solidus_stripe_webhook_endpoints.rb +10 -0
  50. data/db/migrate/20230310152615_add_payment_method_reference_to_stripe_intents.rb +6 -0
  51. data/db/migrate/20230310171444_normalize_stripe_intent_id_attributes.rb +6 -0
  52. data/db/migrate/20230313150008_create_solidus_stripe_customers.rb +16 -0
  53. data/db/migrate/20230323154931_drop_solidus_stripe_setup_intent.rb +13 -0
  54. data/db/migrate/20230403094916_rename_webhook_endpoint_to_payment_method_slug_entries.rb +5 -0
  55. data/db/seeds.rb +6 -24
  56. data/lib/generators/solidus_stripe/install/install_generator.rb +121 -14
  57. data/lib/generators/solidus_stripe/install/templates/app/assets/stylesheets/spree/frontend/solidus_stripe.css +13 -0
  58. data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_confirm_controller.js +39 -0
  59. data/lib/generators/solidus_stripe/install/templates/app/javascript/controllers/solidus_stripe_payment_controller.js +89 -0
  60. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/_stripe.html.erb +16 -0
  61. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/stripe/_card.html.erb +8 -0
  62. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/existing_payment/stripe/_default.html.erb +7 -0
  63. data/lib/generators/solidus_stripe/install/templates/app/views/checkouts/payment/_stripe.html.erb +39 -0
  64. data/lib/generators/solidus_stripe/install/templates/app/views/orders/payment_info/_stripe.html.erb +20 -0
  65. data/lib/generators/solidus_stripe/install/templates/config/initializers/solidus_stripe.rb +31 -0
  66. data/lib/solidus_stripe/configuration.rb +24 -3
  67. data/lib/solidus_stripe/engine.rb +19 -6
  68. data/lib/solidus_stripe/money_to_stripe_amount_converter.rb +109 -0
  69. data/lib/solidus_stripe/refunds_synchronizer.rb +96 -0
  70. data/lib/solidus_stripe/seeds.rb +19 -0
  71. data/lib/solidus_stripe/testing_support/factories.rb +153 -0
  72. data/lib/solidus_stripe/version.rb +1 -1
  73. data/lib/solidus_stripe/webhook/event.rb +90 -0
  74. data/lib/solidus_stripe.rb +0 -2
  75. data/solidus_stripe.gemspec +29 -6
  76. data/spec/lib/solidus_stripe/configuration_spec.rb +21 -0
  77. data/spec/lib/solidus_stripe/money_to_stripe_amount_converter_spec.rb +133 -0
  78. data/spec/lib/solidus_stripe/refunds_synchronizer_spec.rb +238 -0
  79. data/spec/lib/solidus_stripe/seeds_spec.rb +43 -0
  80. data/spec/lib/solidus_stripe/webhook/event_spec.rb +134 -0
  81. data/spec/models/concerns/solidus_stripe/log_entries_spec.rb +54 -0
  82. data/spec/models/solidus_stripe/customer_spec.rb +47 -0
  83. data/spec/models/solidus_stripe/gateway_spec.rb +283 -0
  84. data/spec/models/solidus_stripe/payment_intent_spec.rb +17 -0
  85. data/spec/models/solidus_stripe/payment_method_spec.rb +137 -0
  86. data/spec/models/solidus_stripe/payment_source_spec.rb +25 -0
  87. data/spec/requests/solidus_stripe/intents_controller_spec.rb +29 -0
  88. data/spec/requests/solidus_stripe/webhooks_controller/charge/refunded_spec.rb +31 -0
  89. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/canceled_spec.rb +23 -0
  90. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/payment_failed_spec.rb +23 -0
  91. data/spec/requests/solidus_stripe/webhooks_controller/payment_intent/succeeded_spec.rb +29 -0
  92. data/spec/requests/solidus_stripe/webhooks_controller_spec.rb +52 -0
  93. data/spec/solidus_stripe_spec_helper.rb +10 -0
  94. data/spec/subscribers/solidus_stripe/webhook/charge_subscriber_spec.rb +33 -0
  95. data/spec/subscribers/solidus_stripe/webhook/payment_intent_subscriber_spec.rb +297 -0
  96. data/spec/support/solidus_stripe/backend_test_helper.rb +210 -0
  97. data/spec/support/solidus_stripe/checkout_test_helper.rb +339 -0
  98. data/spec/support/solidus_stripe/factories.rb +5 -0
  99. data/spec/support/solidus_stripe/webhook/data_fixtures.rb +106 -0
  100. data/spec/support/solidus_stripe/webhook/event_with_context_factory.rb +82 -0
  101. data/spec/support/solidus_stripe/webhook/request_helper.rb +32 -0
  102. data/spec/system/backend/solidus_stripe/orders/payments_spec.rb +119 -0
  103. data/spec/system/frontend/.keep +0 -0
  104. data/spec/system/frontend/solidus_stripe/checkout_spec.rb +187 -0
  105. data/tmp/.keep +0 -0
  106. metadata +202 -78
  107. data/.rubocop_todo.yml +0 -298
  108. data/.travis.yml +0 -28
  109. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-cart-page-checkout.js +0 -122
  110. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-elements.js +0 -148
  111. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-init.js +0 -20
  112. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-intents.js +0 -84
  113. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment-request-button-shared.js +0 -160
  114. data/app/assets/javascripts/spree/frontend/solidus_stripe/stripe-payment.js +0 -16
  115. data/app/assets/javascripts/spree/frontend/solidus_stripe.js +0 -6
  116. data/app/controllers/solidus_stripe/payment_request_controller.rb +0 -52
  117. data/app/controllers/spree/stripe_controller.rb +0 -13
  118. data/app/decorators/models/spree/order_update_attributes_decorator.rb +0 -39
  119. data/app/decorators/models/spree/payment_decorator.rb +0 -11
  120. data/app/decorators/models/spree/refund_decorator.rb +0 -9
  121. data/app/models/solidus_stripe/address_from_params_service.rb +0 -72
  122. data/app/models/solidus_stripe/create_intents_payment_service.rb +0 -114
  123. data/app/models/solidus_stripe/prepare_order_for_payment_service.rb +0 -46
  124. data/app/models/solidus_stripe/shipping_rates_service.rb +0 -46
  125. data/app/models/spree/payment_method/stripe_credit_card.rb +0 -230
  126. data/bin/r +0 -13
  127. data/bin/sandbox_rails +0 -18
  128. data/db/migrate/20181010123508_update_stripe_payment_method_type_to_credit_card.rb +0 -21
  129. data/lib/assets/stylesheets/spree/frontend/solidus_stripe.scss +0 -11
  130. data/lib/solidus_stripe/testing_support/card_input_helper.rb +0 -34
  131. data/lib/tasks/solidus_stripe/db/seed.rake +0 -14
  132. data/lib/views/api/spree/api/payments/source_views/_stripe.json.jbuilder +0 -3
  133. data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +0 -28
  134. data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +0 -1
  135. data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +0 -1
  136. data/lib/views/frontend/spree/checkout/existing_payment/_stripe.html.erb +0 -1
  137. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +0 -8
  138. data/lib/views/frontend/spree/checkout/payment/v2/_javascript.html.erb +0 -78
  139. data/lib/views/frontend/spree/checkout/payment/v3/_elements.html.erb +0 -1
  140. data/lib/views/frontend/spree/checkout/payment/v3/_form_elements.html.erb +0 -40
  141. data/lib/views/frontend/spree/checkout/payment/v3/_intents.html.erb +0 -1
  142. data/lib/views/frontend/spree/checkout/payment/v3/_stripe.html.erb +0 -2
  143. data/lib/views/frontend/spree/orders/_stripe_payment_request_button.html.erb +0 -14
  144. data/spec/features/stripe_checkout_spec.rb +0 -486
  145. data/spec/models/solidus_stripe/address_from_params_service_spec.rb +0 -87
  146. data/spec/models/solidus_stripe/create_intents_payment_service_spec.rb +0 -127
  147. data/spec/models/solidus_stripe/prepare_order_for_payment_service_spec.rb +0 -65
  148. data/spec/models/solidus_stripe/shipping_rates_service_spec.rb +0 -54
  149. data/spec/models/spree/payment_method/stripe_credit_card_spec.rb +0 -354
  150. data/spec/requests/payment_requests_spec.rb +0 -152
  151. data/spec/solidus_frontend_app_template.rb +0 -17
  152. data/spec/spec_helper.rb +0 -37
  153. data/spec/support/solidus_address_helper.rb +0 -15
@@ -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: :internal_server_error
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: :internal_server_error
36
- end
37
- else
38
- render json: { success: false, error: address.errors.full_messages.to_sentence }, status: :internal_server_error
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
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidusStripe
4
- class AddressFromParamsService
5
- attr_reader :address_params, :user
6
-
7
- def initialize(address_params, user = nil)
8
- @address_params, @user = address_params, user
9
- end
10
-
11
- def call
12
- if user
13
- user.addresses.find_or_initialize_by(attributes)
14
- else
15
- Spree::Address.new(attributes)
16
- end
17
- end
18
-
19
- private
20
-
21
- def attributes
22
- @attributes ||= begin
23
- default_attributes.tap do |attributes|
24
- # possibly anonymized attributes:
25
- phone = address_params[:phone]
26
- lines = address_params[:addressLine]
27
- names = address_params[:recipient].split(' ')
28
-
29
- name_attributes = if SolidusSupport.combined_first_and_last_name_in_address? && Spree::Address.column_names.include?("name")
30
- {
31
- name: address_params[:recipient]
32
- }
33
- else
34
- {
35
- firstname: names.first,
36
- lastname: names.last,
37
- }
38
- end
39
-
40
- attributes
41
- .merge!(name_attributes)
42
- .merge!(
43
- state_id: state&.id,
44
- phone: phone,
45
- address1: lines.first,
46
- address2: lines.second
47
- )
48
- .reject! { |_, value| value.blank? }
49
- end
50
- end
51
- end
52
-
53
- def country
54
- @country ||= Spree::Country.find_by_iso(address_params[:country])
55
- end
56
-
57
- def state
58
- @state ||= begin
59
- region = address_params[:region]
60
- country.states.find_by(abbr: region) || country.states.find_by(name: region)
61
- end
62
- end
63
-
64
- def default_attributes
65
- {
66
- country_id: country.id,
67
- city: address_params[:city],
68
- zipcode: address_params[:postalCode]
69
- }
70
- end
71
- end
72
- end
@@ -1,114 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidusStripe
4
- class CreateIntentsPaymentService
5
- attr_reader :intent_id, :stripe, :controller
6
-
7
- delegate :request, :current_order, :params, to: :controller
8
-
9
- def initialize(intent_id, stripe, controller)
10
- @intent_id, @stripe, @controller = intent_id, stripe, controller
11
- end
12
-
13
- def call
14
- invalidate_previous_payment_intents_payments
15
- if (payment = create_payment)
16
- description = "Solidus Order ID: #{payment.gateway_order_identifier}"
17
- stripe.update_intent(nil, intent_id, nil, description: description)
18
- true
19
- else
20
- invalidate_current_payment_intent
21
- false
22
- end
23
- end
24
-
25
- private
26
-
27
- def intent
28
- @intent ||= stripe.show_intent(intent_id, {})
29
- end
30
-
31
- def invalidate_current_payment_intent
32
- stripe.cancel(intent_id)
33
- end
34
-
35
- def invalidate_previous_payment_intents_payments
36
- if stripe.v3_intents?
37
- current_order.payments.pending.where(payment_method: stripe).each(&:void_transaction!)
38
- end
39
- end
40
-
41
- def create_payment
42
- Spree::OrderUpdateAttributes.new(
43
- current_order,
44
- payment_params,
45
- request_env: request.headers.env
46
- ).apply
47
-
48
- created_payment = Spree::Payment.find_by(response_code: intent_id)
49
- created_payment&.tap { |payment| payment.update!(state: :pending) }
50
- end
51
-
52
- def payment_params
53
- {
54
- payments_attributes: [{
55
- payment_method_id: stripe.id,
56
- amount: current_order.total,
57
- response_code: intent_id,
58
- source_attributes: {
59
- month: intent_card['exp_month'],
60
- year: intent_card['exp_year'],
61
- cc_type: intent_card['brand'],
62
- last_digits: intent_card['last4'],
63
- gateway_payment_profile_id: intent_customer_profile,
64
- name: card_holder_name || address_full_name,
65
- address_attributes: address_attributes
66
- }
67
- }]
68
- }
69
- end
70
-
71
- def intent_card
72
- intent_data['payment_method_details']['card']
73
- end
74
-
75
- def intent_customer_profile
76
- intent.params['payment_method']
77
- end
78
-
79
- def card_holder_name
80
- (html_payment_source_data['name'] || intent_data['billing_details']['name']).presence
81
- end
82
-
83
- def intent_data
84
- intent.params['charges']['data'][0]
85
- end
86
-
87
- def form_data
88
- params[:form_data]
89
- end
90
-
91
- def html_payment_source_data
92
- if form_data.is_a?(String)
93
- data = Rack::Utils.parse_nested_query(form_data)
94
- data['payment_source'][stripe.id.to_s]
95
- else
96
- {}
97
- end
98
- end
99
-
100
- def address_attributes
101
- html_payment_source_data['address_attributes'] || SolidusStripe::AddressFromParamsService.new(form_data).call.attributes
102
- end
103
-
104
- def address_full_name
105
- bill_address_name = SolidusSupport.combined_first_and_last_name_in_address? ? current_order.bill_address&.name : current_order.bill_address&.full_name
106
- bill_address_name || form_data[:recipient]
107
- end
108
-
109
- def update_stripe_payment_description
110
- description = "Solidus Order ID: #{payment.gateway_order_identifier}"
111
- stripe.update_intent(nil, intent_id, nil, description: description)
112
- end
113
- end
114
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidusStripe
4
- class PrepareOrderForPaymentService
5
- attr_reader :order, :address, :user, :email, :shipping_id
6
-
7
- def initialize(address, controller)
8
- @address = address
9
- @order = controller.current_order
10
- @user = controller.spree_current_user
11
- @email = controller.params[:email]
12
- @shipping_id = controller.params[:shipping_option][:id]
13
- end
14
-
15
- def call
16
- set_order_addresses
17
- manage_guest_checkout
18
- advance_order_to_payment_state
19
- end
20
-
21
- private
22
-
23
- def set_shipping_rate
24
- order.shipments.each do |shipment|
25
- rate = shipment.shipping_rates.find_by(shipping_method: shipping_id)
26
- shipment.selected_shipping_rate_id = rate.id
27
- end
28
- end
29
-
30
- def set_order_addresses
31
- order.ship_address = address
32
- order.bill_address ||= address
33
- end
34
-
35
- def manage_guest_checkout
36
- order.email = email unless user
37
- end
38
-
39
- def advance_order_to_payment_state
40
- while !order.payment?
41
- set_shipping_rate if order.state == "delivery"
42
- order.next || break
43
- end
44
- end
45
- end
46
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SolidusStripe
4
- class ShippingRatesService
5
- attr_reader :order, :user, :shipping_address_params
6
-
7
- def initialize(order, user, shipping_address_params)
8
- @order = order
9
- @user = user
10
- @shipping_address_params = shipping_address_params
11
- end
12
-
13
- def call
14
- # setting a temporary and probably incomplete address to the order
15
- # only to calculate the available shipping options:
16
- order.ship_address = address_from_params
17
-
18
- available_shipping_methods.each_with_object([]) do |(id, rates), options|
19
- options << shipping_method_data(id, rates)
20
- end
21
- end
22
-
23
- private
24
-
25
- def available_shipping_methods
26
- shipments = Spree::Stock::SimpleCoordinator.new(order).shipments
27
- all_rates = shipments.map(&:shipping_rates).flatten
28
-
29
- all_rates.group_by(&:shipping_method_id).select do |_, rates|
30
- rates.size == shipments.size
31
- end
32
- end
33
-
34
- def shipping_method_data(id, rates)
35
- {
36
- id: id.to_s,
37
- label: Spree::ShippingMethod.find(id).name,
38
- amount: (rates.sum(&:cost) * 100).to_i
39
- }
40
- end
41
-
42
- def address_from_params
43
- SolidusStripe::AddressFromParamsService.new(shipping_address_params, user).call
44
- end
45
- end
46
- end