archetype_spree_gateway 3.9.5

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 (124) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +39 -0
  5. data/Gemfile +9 -0
  6. data/Guardfile +9 -0
  7. data/LICENSE.md +26 -0
  8. data/README.md +105 -0
  9. data/Rakefile +15 -0
  10. data/app/models/spree/billing_integration.rb +21 -0
  11. data/app/models/spree/check.rb +41 -0
  12. data/app/models/spree/gateway/authorize_net.rb +45 -0
  13. data/app/models/spree/gateway/authorize_net_cim.rb +213 -0
  14. data/app/models/spree/gateway/balanced_gateway.rb +64 -0
  15. data/app/models/spree/gateway/banwire.rb +15 -0
  16. data/app/models/spree/gateway/beanstream.rb +193 -0
  17. data/app/models/spree/gateway/braintree_gateway.rb +184 -0
  18. data/app/models/spree/gateway/card_save.rb +10 -0
  19. data/app/models/spree/gateway/cyber_source.rb +10 -0
  20. data/app/models/spree/gateway/data_cash.rb +10 -0
  21. data/app/models/spree/gateway/epay.rb +10 -0
  22. data/app/models/spree/gateway/eway.rb +18 -0
  23. data/app/models/spree/gateway/eway_rapid.rb +14 -0
  24. data/app/models/spree/gateway/maxipago.rb +14 -0
  25. data/app/models/spree/gateway/migs.rb +11 -0
  26. data/app/models/spree/gateway/moneris.rb +10 -0
  27. data/app/models/spree/gateway/pay_junction.rb +14 -0
  28. data/app/models/spree/gateway/pay_pal_gateway.rb +12 -0
  29. data/app/models/spree/gateway/payflow_pro.rb +15 -0
  30. data/app/models/spree/gateway/paymill.rb +12 -0
  31. data/app/models/spree/gateway/payu_polska_gateway.rb +24 -0
  32. data/app/models/spree/gateway/pin_gateway.rb +60 -0
  33. data/app/models/spree/gateway/quickpay.rb +9 -0
  34. data/app/models/spree/gateway/sage_pay.rb +11 -0
  35. data/app/models/spree/gateway/secure_pay_au.rb +10 -0
  36. data/app/models/spree/gateway/spreedly_core_gateway.rb +11 -0
  37. data/app/models/spree/gateway/stripe_ach_gateway.rb +60 -0
  38. data/app/models/spree/gateway/stripe_apple_pay_gateway.rb +10 -0
  39. data/app/models/spree/gateway/stripe_elements_gateway.rb +61 -0
  40. data/app/models/spree/gateway/stripe_gateway.rb +151 -0
  41. data/app/models/spree/gateway/usa_epay_transaction.rb +9 -0
  42. data/app/models/spree/gateway/worldpay.rb +91 -0
  43. data/app/models/spree/payu_polska.rb +41 -0
  44. data/app/models/spree_gateway/apple_pay_order_decorator.rb +20 -0
  45. data/app/models/spree_gateway/apple_pay_payment_decorator.rb +9 -0
  46. data/app/models/spree_gateway/credit_card_decorator.rb +10 -0
  47. data/app/models/spree_gateway/order_decorator.rb +28 -0
  48. data/app/models/spree_gateway/payment_decorator.rb +36 -0
  49. data/app/views/spree/checkout/_payment_confirm.html.erb +39 -0
  50. data/app/views/spree/checkout/_payu.html +12 -0
  51. data/config/initializers/inflections.rb +3 -0
  52. data/config/initializers/spree_permitted_attributes.rb +5 -0
  53. data/config/locales/bg.yml +4 -0
  54. data/config/locales/de.yml +4 -0
  55. data/config/locales/en.yml +47 -0
  56. data/config/locales/sv.yml +4 -0
  57. data/config/routes.rb +19 -0
  58. data/db/migrate/20200317135551_add_spree_check_payment_source.rb +22 -0
  59. data/db/migrate/20200422114908_add_intent_key_to_payment.rb +5 -0
  60. data/lib/active_merchant/billing/stripe_gateway_decorator.rb +33 -0
  61. data/lib/controllers/spree/api/v2/storefront/intents_controller.rb +45 -0
  62. data/lib/controllers/spree/apple_pay_domain_verification_controller.rb +11 -0
  63. data/lib/generators/spree_gateway/install/install_generator.rb +19 -0
  64. data/lib/spree_frontend/controllers/spree/checkout_controller_decorator.rb +19 -0
  65. data/lib/spree_gateway/engine.rb +80 -0
  66. data/lib/spree_gateway/version.rb +5 -0
  67. data/lib/spree_gateway.rb +4 -0
  68. data/lib/views/backend/spree/admin/log_entries/_braintree.html.erb +31 -0
  69. data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +28 -0
  70. data/lib/views/backend/spree/admin/payments/source_forms/_quickcheckout.html.erb +8 -0
  71. data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +79 -0
  72. data/lib/views/backend/spree/admin/payments/source_forms/_stripe_ach.html.erb +86 -0
  73. data/lib/views/backend/spree/admin/payments/source_forms/_stripe_apple_pay.html.erb +0 -0
  74. data/lib/views/backend/spree/admin/payments/source_forms/_stripe_elements.html.erb +79 -0
  75. data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +1 -0
  76. data/lib/views/backend/spree/admin/payments/source_views/_stripe_ach.html.erb +21 -0
  77. data/lib/views/backend/spree/admin/payments/source_views/_stripe_apple_pay.html.erb +1 -0
  78. data/lib/views/backend/spree/admin/payments/source_views/_stripe_elements.html.erb +1 -0
  79. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +86 -0
  80. data/lib/views/frontend/spree/checkout/payment/_stripe_ach.html.erb +81 -0
  81. data/lib/views/frontend/spree/checkout/payment/_stripe_ach_verify.html.erb +16 -0
  82. data/lib/views/frontend/spree/checkout/payment/_stripe_additional_info.html.erb +16 -0
  83. data/lib/views/frontend/spree/checkout/payment/_stripe_apple_pay.html.erb +109 -0
  84. data/lib/views/frontend/spree/checkout/payment/_stripe_elements.html.erb +110 -0
  85. data/script/rails +7 -0
  86. data/spec/factories/check_factory.rb +10 -0
  87. data/spec/features/admin/stripe_elements_payment_spec.rb +100 -0
  88. data/spec/features/stripe_checkout_spec.rb +130 -0
  89. data/spec/features/stripe_elements_3ds_checkout_spec.rb +225 -0
  90. data/spec/models/gateway/authorize_net_cim_spec.rb +29 -0
  91. data/spec/models/gateway/authorize_net_spec.rb +23 -0
  92. data/spec/models/gateway/balanced_gateway_spec.rb +17 -0
  93. data/spec/models/gateway/banwire_spec.rb +11 -0
  94. data/spec/models/gateway/beanstream_spec.rb +17 -0
  95. data/spec/models/gateway/braintree_gateway_spec.rb +420 -0
  96. data/spec/models/gateway/card_save_spec.rb +11 -0
  97. data/spec/models/gateway/cyber_source_spec.rb +11 -0
  98. data/spec/models/gateway/data_cash_spec.rb +11 -0
  99. data/spec/models/gateway/epay_spec.rb +11 -0
  100. data/spec/models/gateway/eway_rapid_spec.rb +23 -0
  101. data/spec/models/gateway/eway_spec.rb +29 -0
  102. data/spec/models/gateway/maxipago_spec.rb +17 -0
  103. data/spec/models/gateway/moneris_spec.rb +11 -0
  104. data/spec/models/gateway/pay_junction_spec.rb +23 -0
  105. data/spec/models/gateway/pay_pal_spec.rb +11 -0
  106. data/spec/models/gateway/payflow_pro_spec.rb +23 -0
  107. data/spec/models/gateway/paymill_spec.rb +11 -0
  108. data/spec/models/gateway/pin_gateway_spec.rb +54 -0
  109. data/spec/models/gateway/quickpay_spec.rb +11 -0
  110. data/spec/models/gateway/sage_pay_spec.rb +11 -0
  111. data/spec/models/gateway/secure_pay_au_spec.rb +11 -0
  112. data/spec/models/gateway/stripe_ach_gateway_spec.rb +186 -0
  113. data/spec/models/gateway/stripe_gateway_spec.rb +199 -0
  114. data/spec/models/gateway/usa_epay_transaction_spec.rb +49 -0
  115. data/spec/models/gateway/worldpay_spec.rb +11 -0
  116. data/spec/models/spree/order_spec.rb +79 -0
  117. data/spec/requests/apple_pay_domain_verification.rb +45 -0
  118. data/spec/requests/spree/api/v2/storefront/intents_controller_spec.rb +198 -0
  119. data/spec/spec_helper.rb +10 -0
  120. data/spec/support/order_walktrough.rb +73 -0
  121. data/spec/support/wait_for_stripe.rb +27 -0
  122. data/spec/support/within_stripe_3ds_popup.rb +10 -0
  123. data/spree_gateway.gemspec +37 -0
  124. metadata +277 -0
@@ -0,0 +1,60 @@
1
+ module Spree
2
+ class Gateway::StripeAchGateway < Gateway::StripeGateway
3
+
4
+ def method_type
5
+ 'stripe_ach'
6
+ end
7
+
8
+ def payment_source_class
9
+ Check
10
+ end
11
+
12
+ def verify(source, gateway_options)
13
+ provider.verify(source, gateway_options)
14
+ end
15
+
16
+ def create_profile(payment)
17
+ return unless payment.source&.gateway_customer_profile_id.nil?
18
+
19
+ options = {
20
+ email: payment.order.user&.email || payment.order.email,
21
+ login: preferred_secret_key,
22
+ }.merge! address_for(payment)
23
+
24
+ source = payment.source
25
+ bank_account = if source.gateway_payment_profile_id.present?
26
+ source.gateway_payment_profile_id
27
+ else
28
+ source
29
+ end
30
+
31
+ response = provider.store(bank_account, options)
32
+
33
+ if response.success?
34
+ payment.source.update!({
35
+ gateway_customer_profile_id: response.params['id'],
36
+ gateway_payment_profile_id: response.params['default_source'] || response.params['default_card']
37
+ })
38
+
39
+ else
40
+ payment.send(:gateway_error, response.message)
41
+ end
42
+ end
43
+
44
+ def supports?(_source)
45
+ true
46
+ end
47
+
48
+ def available_for_order?(order)
49
+ # Stripe ACH payments are supported only for US customers
50
+ # Therefore we need to check order's addresses
51
+ return unless order.ship_address_id && order.bill_address_id
52
+ return unless order.ship_address && order.bill_address_id
53
+
54
+ usa_id = ::Spree::Country.find_by(iso: 'US')&.id
55
+ return false unless usa_id
56
+
57
+ order.ship_address.country_id == usa_id && order.bill_address.country_id == usa_id
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,10 @@
1
+ module Spree
2
+ class Gateway::StripeApplePayGateway < Gateway::StripeGateway
3
+ preference :country_code, :string, default: 'US'
4
+ preference :domain_verification_certificate, :text
5
+
6
+ def method_type
7
+ 'stripe_apple_pay'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,61 @@
1
+ module Spree
2
+ class Gateway::StripeElementsGateway < Gateway::StripeGateway
3
+ preference :intents, :boolean, default: true
4
+
5
+ def method_type
6
+ 'stripe_elements'
7
+ end
8
+
9
+ def provider_class
10
+ if get_preference(:intents)
11
+ ActiveMerchant::Billing::StripePaymentIntentsGateway
12
+ else
13
+ ActiveMerchant::Billing::StripeGateway
14
+ end
15
+ end
16
+
17
+ def create_profile(payment)
18
+ return unless payment.source.gateway_customer_profile_id.nil?
19
+
20
+ options = {
21
+ email: payment.order.email,
22
+ login: preferred_secret_key
23
+ }.merge! address_for(payment)
24
+
25
+ source = update_source!(payment.source)
26
+ creditcard = source.gateway_payment_profile_id.present? ? source.gateway_payment_profile_id : source
27
+ response = provider.store(creditcard, options)
28
+ if response.success?
29
+ if get_preference(:intents)
30
+ payment.source.update!(
31
+ cc_type: payment.source.cc_type,
32
+ gateway_customer_profile_id: response.params['id'],
33
+ gateway_payment_profile_id: response.params['sources']['data'].first['id']
34
+ )
35
+ else
36
+ response_cc_type = response.params['sources']['data'].first['brand']
37
+ cc_type = CARD_TYPE_MAPPING.include?(response_cc_type) ? CARD_TYPE_MAPPING[response_cc_type] : payment.source.cc_type
38
+ payment.source.update!({
39
+ cc_type: cc_type, # side-effect of update_source!
40
+ gateway_customer_profile_id: response.params['id'],
41
+ gateway_payment_profile_id: response.params['default_source'] || response.params['default_card']
42
+ })
43
+ end
44
+ else
45
+ payment.send(:gateway_error, response.message)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def options_for_purchase_or_auth(money, creditcard, gateway_options)
52
+ money, creditcard, options = super
53
+ options[:execute_threed] = get_preference(:intents)
54
+ return money, creditcard, options
55
+ end
56
+
57
+ def public_preference_keys
58
+ %i[publishable_key test_mode intents]
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,151 @@
1
+ module Spree
2
+ class Gateway::StripeGateway < Gateway
3
+ preference :secret_key, :string
4
+ preference :publishable_key, :string
5
+
6
+ CARD_TYPE_MAPPING = {
7
+ 'American Express' => 'american_express',
8
+ 'Diners Club' => 'diners_club',
9
+ 'Discover' => 'discover',
10
+ 'JCB' => 'jcb',
11
+ 'Laser' => 'laser',
12
+ 'Maestro' => 'maestro',
13
+ 'MasterCard' => 'master',
14
+ 'Solo' => 'solo',
15
+ 'Switch' => 'switch',
16
+ 'Visa' => 'visa'
17
+ }
18
+
19
+ def method_type
20
+ 'stripe'
21
+ end
22
+
23
+ def provider_class
24
+ ActiveMerchant::Billing::StripeGateway
25
+ end
26
+
27
+ def payment_profiles_supported?
28
+ true
29
+ end
30
+
31
+ def purchase(money, creditcard, gateway_options)
32
+ provider.purchase(*options_for_purchase_or_auth(money, creditcard, gateway_options))
33
+ end
34
+
35
+ def authorize(money, creditcard, gateway_options)
36
+ provider.authorize(*options_for_purchase_or_auth(money, creditcard, gateway_options))
37
+ end
38
+
39
+ def capture(money, response_code, gateway_options)
40
+ provider.capture(money, response_code, gateway_options)
41
+ end
42
+
43
+ def credit(money, creditcard, response_code, gateway_options)
44
+ provider.refund(money, response_code, {})
45
+ end
46
+
47
+ def void(response_code, creditcard, gateway_options)
48
+ provider.void(response_code, {})
49
+ end
50
+
51
+ def cancel(response_code)
52
+ provider.void(response_code, {})
53
+ end
54
+
55
+ def create_profile(payment)
56
+ return unless payment.source.gateway_customer_profile_id.nil?
57
+
58
+ options = {
59
+ email: payment.order.email,
60
+ login: preferred_secret_key,
61
+ }.merge! address_for(payment)
62
+
63
+ source = update_source!(payment.source)
64
+ if source.gateway_payment_profile_id.present?
65
+ creditcard = source.gateway_payment_profile_id
66
+ else
67
+ creditcard = source
68
+ end
69
+
70
+ response = provider.store(creditcard, options)
71
+ if response.success?
72
+ cc_type=payment.source.cc_type
73
+ response_cc_type = response.params['sources']['data'].first['brand']
74
+ cc_type = CARD_TYPE_MAPPING[response_cc_type] if CARD_TYPE_MAPPING.include?(response_cc_type)
75
+
76
+ payment.source.update!({
77
+ cc_type: cc_type, # side-effect of update_source!
78
+ gateway_customer_profile_id: response.params['id'],
79
+ gateway_payment_profile_id: response.params['default_source'] || response.params['default_card']
80
+ })
81
+
82
+ else
83
+ payment.send(:gateway_error, response.message)
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ # In this gateway, what we call 'secret_key' is the 'login'
90
+ def options
91
+ super.merge(
92
+ login: preferred_secret_key,
93
+ application: app_info
94
+ )
95
+ end
96
+
97
+ def options_for_purchase_or_auth(money, creditcard, gateway_options)
98
+ options = {}
99
+ options[:description] = "Spree Order ID: #{gateway_options[:order_id]}"
100
+ options[:currency] = gateway_options[:currency]
101
+ options[:application] = app_info
102
+
103
+ if customer = creditcard.gateway_customer_profile_id
104
+ options[:customer] = customer
105
+ end
106
+ if token_or_card_id = creditcard.gateway_payment_profile_id
107
+ # The Stripe ActiveMerchant gateway supports passing the token directly as the creditcard parameter
108
+ # The Stripe ActiveMerchant gateway supports passing the customer_id and credit_card id
109
+ # https://github.com/Shopify/active_merchant/issues/770
110
+ creditcard = token_or_card_id
111
+ end
112
+ return money, creditcard, options
113
+ end
114
+
115
+ def address_for(payment)
116
+ {}.tap do |options|
117
+ if address = payment.order.bill_address
118
+ options.merge!(address: {
119
+ address1: address.address1,
120
+ address2: address.address2,
121
+ city: address.city,
122
+ zip: address.zipcode
123
+ })
124
+
125
+ if country = address.country
126
+ options[:address].merge!(country: country.name)
127
+ end
128
+
129
+ if state = address.state
130
+ options[:address].merge!(state: state.name)
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ def update_source!(source)
137
+ source.cc_type = CARD_TYPE_MAPPING[source.cc_type] if CARD_TYPE_MAPPING.include?(source.cc_type)
138
+ source
139
+ end
140
+
141
+ def app_info
142
+ name_with_version = "SpreeGateway/#{SpreeGateway.version}"
143
+ url = 'https://spreecommerce.org'
144
+ "#{name_with_version} #{url}"
145
+ end
146
+
147
+ def public_preference_keys
148
+ %i[publishable_key test_mode]
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,9 @@
1
+ module Spree
2
+ class Gateway::UsaEpayTransaction < Gateway
3
+ preference :login, :string
4
+
5
+ def provider_class
6
+ ActiveMerchant::Billing::UsaEpayTransactionGateway
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,91 @@
1
+ module Spree
2
+ class Gateway::Worldpay < Gateway
3
+ preference :login, :string
4
+ preference :password, :string
5
+ preference :currency, :string, :default => 'GBP'
6
+ preference :installation_id, :string
7
+
8
+ preference :american_express_login, :string
9
+ preference :discover_login, :string
10
+ preference :jcb_login, :string
11
+ preference :mastercard_login, :string
12
+ preference :maestro_login, :string
13
+ preference :visa_login, :string
14
+
15
+ def provider_class
16
+ ActiveMerchant::Billing::WorldpayGateway
17
+ end
18
+
19
+ def purchase(money, credit_card, options = {})
20
+ provider = credit_card_provider(credit_card, options)
21
+ provider.purchase(money, credit_card, options)
22
+ end
23
+
24
+ def authorize(money, credit_card, options = {})
25
+ provider = credit_card_provider(credit_card, options)
26
+ provider.authorize(money, credit_card, options)
27
+ end
28
+
29
+ def capture(money, authorization, options = {})
30
+ provider = credit_card_provider(auth_credit_card(authorization), options)
31
+ provider.capture(money, authorization, options)
32
+ end
33
+
34
+ def refund(money, authorization, options = {})
35
+ provider = credit_card_provider(auth_credit_card(authorization), options)
36
+ provider.refund(money, authorization, options)
37
+ end
38
+
39
+ def credit(money, authorization, options = {})
40
+ refund(money, authorization, options)
41
+ end
42
+
43
+ def void(authorization, options = {})
44
+ provider = credit_card_provider(auth_credit_card(authorization), options)
45
+ provider.void(authorization, options)
46
+ end
47
+
48
+ private
49
+
50
+ def options_for_card(credit_card, options)
51
+ options[:login] = login_for_card(credit_card)
52
+ options = options().merge( options )
53
+ end
54
+
55
+ def auth_credit_card(authorization)
56
+ Spree::Payment.find_by_response_code(authorization).source
57
+ end
58
+
59
+ def credit_card_provider(credit_card, options = {})
60
+ gateway_options = options_for_card(credit_card, options)
61
+ gateway_options.delete :login if gateway_options.has_key?(:login) and gateway_options[:login].nil?
62
+ gateway_options[:currency] = self.preferred_currency
63
+ gateway_options[:inst_id] = self.preferred_installation_id
64
+ ActiveMerchant::Billing::Base.gateway_mode = gateway_options[:server].to_sym
65
+ @provider = provider_class.new(gateway_options)
66
+ end
67
+
68
+ def login_for_card(card)
69
+ case card.brand
70
+ when 'american_express'
71
+ choose_login preferred_american_express_login
72
+ when 'discover'
73
+ choose_login preferred_discover_login
74
+ when 'jcb'
75
+ choose_login preferred_jcb_login
76
+ when 'maestro'
77
+ choose_login preferred_maestro_login
78
+ when 'master'
79
+ choose_login preferred_mastercard_login
80
+ when 'visa'
81
+ choose_login preferred_visa_login
82
+ else
83
+ preferred_login
84
+ end
85
+ end
86
+
87
+ def choose_login(login)
88
+ return login ? login : preferred_login
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ class PayuPolska < Spree::Base
3
+
4
+ attr_accessor :imported
5
+
6
+ belongs_to :payment_method
7
+ belongs_to :user, class_name: Spree.user_class.to_s, foreign_key: 'user_id',
8
+ optional: true
9
+ has_many :payments, as: :source
10
+
11
+ scope :with_payment_profile, -> { where.not(gateway_customer_profile_id: nil) }
12
+
13
+ validates :account_holder_name, presence: true
14
+ validates :account_holder_type, presence: true, inclusion: { in: %w[Individual Company] }
15
+ validates :account_number, presence: true, numericality: { only_integer: true }
16
+ validates :routing_number, presence: true, numericality: { only_integer: true }
17
+
18
+ def has_payment_profile?
19
+ gateway_customer_profile_id.present? || gateway_payment_profile_id.present?
20
+ end
21
+
22
+ def actions
23
+ %w[capture void credit]
24
+ end
25
+
26
+ def can_capture?(payment)
27
+ payment.pending? || payment.checkout?
28
+ end
29
+
30
+ # Indicates whether its possible to void the payment.
31
+ def can_void?(payment)
32
+ !payment.failed? && !payment.void?
33
+ end
34
+
35
+ # Indicates whether its possible to credit the payment. Note that most gateways require that the
36
+ # payment be settled first which generally happens within 12-24 hours of the transaction.
37
+ def can_credit?(payment)
38
+ payment.completed? && payment.credit_allowed > 0
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ module SpreeGateway
2
+ module ApplePayOrderDecorator
3
+ def confirmation_required?
4
+ return false if paid_with_apple_pay?
5
+
6
+ # Little hacky fix for #4117
7
+ # If this wasn't here, order would transition to address state on confirm failure
8
+ # because there would be no valid payments any more.
9
+ Spree::Config[:always_include_confirm_step] ||
10
+ payments.valid.map(&:payment_method).compact.any?(&:payment_profiles_supported?) ||
11
+ confirm?
12
+ end
13
+
14
+ def paid_with_apple_pay?
15
+ payments.valid.any?(&:apple_pay?)
16
+ end
17
+ end
18
+ end
19
+
20
+ ::Spree::Order.prepend(::SpreeGateway::ApplePayOrderDecorator)
@@ -0,0 +1,9 @@
1
+ module SpreeGateway
2
+ module ApplePayPaymentDecorator
3
+ def apple_pay?
4
+ payment_method.is_a? Spree::Gateway::StripeApplePayGateway
5
+ end
6
+ end
7
+ end
8
+
9
+ ::Spree::Payment.prepend(::SpreeGateway::ApplePayPaymentDecorator)
@@ -0,0 +1,10 @@
1
+ module SpreeGateway
2
+ module CreditCardDecorator
3
+ def set_last_digits
4
+ self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
5
+ end
6
+
7
+ end
8
+ end
9
+
10
+ ::Spree::CreditCard.prepend(::SpreeGateway::CreditCardDecorator)
@@ -0,0 +1,28 @@
1
+ module SpreeGateway
2
+ module OrderDecorator
3
+ def self.prepended(base)
4
+ return if base.checkout_steps.key?(:payment_confirm)
5
+
6
+ base.insert_checkout_step(
7
+ :payment_confirm,
8
+ before: :complete,
9
+ if: ->(order) { order.intents? }
10
+ )
11
+ end
12
+
13
+ def process_payments!
14
+ # Payments are processed in confirm_payment step where after successful
15
+ # 3D Secure authentication `intent_client_key` is saved for payment.
16
+ # In case authentication is unsuccessful, `intent_client_key` is removed.
17
+ return if intents? && payments.valid.last.intent_client_key.present?
18
+
19
+ super
20
+ end
21
+
22
+ def intents?
23
+ payments.valid.map { |p| p.payment_method&.has_preference?(:intents) && p.payment_method&.get_preference(:intents) }.any?
24
+ end
25
+ end
26
+ end
27
+
28
+ ::Spree::Order.prepend(::SpreeGateway::OrderDecorator)
@@ -0,0 +1,36 @@
1
+ module SpreeGateway
2
+ module PaymentDecorator
3
+ def handle_response(response, success_state, failure_state)
4
+ if response.success? && response.respond_to?(:params)
5
+ self.intent_client_key = response.params['client_secret'] if response.params['client_secret']
6
+ end
7
+ super
8
+ end
9
+
10
+ def verify!(**options)
11
+ process_verification(options)
12
+ end
13
+
14
+ private
15
+
16
+ def process_verification(**options)
17
+ protect_from_connection_error do
18
+ response = payment_method.verify(source, options)
19
+
20
+ record_response(response)
21
+
22
+ if response.success?
23
+ unless response.authorization.nil?
24
+ self.response_code = response.authorization
25
+
26
+ source.update(status: response.params['status'])
27
+ end
28
+ else
29
+ gateway_error(response)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ ::Spree::Payment.prepend(::SpreeGateway::PaymentDecorator)
@@ -0,0 +1,39 @@
1
+ <div id='errorBox' class='errorExplanation alert alert-danger' style='display:none'></div>
2
+ <div id='successBox' class='alert alert-success' style='display:none'></div>
3
+ <div id='infoBox' class='alert alert-info'><%= t('spree.please_wait_for_confirmation_popup') %></div>
4
+
5
+ <% if @client_secret.present? && @pk_key.present? %>
6
+ <script type="text/javascript" src="https://js.stripe.com/v3/"></script>
7
+ <script>
8
+ var form = document.getElementById('checkout_form_payment_confirm');
9
+
10
+ function confirmCardPaymentResponseHandler(response) {
11
+ $.post("/api/v2/storefront/intents/handle_response", { response: response, order_token: "<%= @order.token %>" }).done(function (result) {
12
+ // conditional needs for spree 3.7
13
+ if(form.elements["commit"]) {
14
+ form.elements["commit"].disabled = false;
15
+ }
16
+ $('#successBox').html(result.message);
17
+ $('#successBox').show();
18
+ form.submit();
19
+ }).fail(function(result) {
20
+ if(form.elements["commit"]) {
21
+ form.elements["commit"].disabled = false;
22
+ }
23
+ $('#errorBox').html(result.responseJSON.error);
24
+ $('#errorBox').show();
25
+ });
26
+ }
27
+
28
+ var stripeElements = Stripe("<%= @pk_key %>");
29
+ stripeElements.confirmCardPayment("<%= @client_secret %>").then(function(result) {
30
+ $('#infoBox').hide();
31
+ confirmCardPaymentResponseHandler(result);
32
+ });
33
+
34
+ document.addEventListener('DOMContentLoaded', function(){
35
+ form.elements["commit"].value = "continue"
36
+ form.elements["commit"].disabled = true
37
+ });
38
+ </script>
39
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <div class="text-center">
2
+ <img width="150px" src="https://poland.payu.com/wp-content/uploads/sites/14/2020/05/PAYU_LOGO_LIME-990x640.png" />
3
+ <br/>
4
+ </div>
5
+
6
+
7
+ <script type="text/javascript">
8
+ button = document.getElementsByClassName("checkout-content-save-continue-button")[0]
9
+ button.addEventListener("click", (e) => {
10
+ e.preventDefault();
11
+ });
12
+ </script>
@@ -0,0 +1,3 @@
1
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
2
+ inflect.acronym 'AU'
3
+ end
@@ -0,0 +1,5 @@
1
+ module Spree
2
+ module PermittedAttributes
3
+ @@source_attributes += %i[account_number routing_number account_holder_type account_holder_name status]
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ bg:
3
+ spree:
4
+ payment_has_been_cancelled: Плащането беше прекъснато.
@@ -0,0 +1,4 @@
1
+ ---
2
+ de:
3
+ spree:
4
+ payment_has_been_cancelled: Die Zahlung wurde abgebrochen.
@@ -0,0 +1,47 @@
1
+ ---
2
+ en:
3
+ activerecord:
4
+ attributes:
5
+ spree/check:
6
+ account_holder_name: Account Holder Name
7
+ account_holder_type: Account Holder Type
8
+ account_number: Account Number
9
+ routing_number: Routing Number
10
+ spree:
11
+ check: Check
12
+ payment_has_been_cancelled: The payment has been cancelled.
13
+ please_wait_for_confirmation_popup: Please wait for payment confirmation popup to appear.
14
+ payment_successfully_authorized: The payment was successfully authorized.
15
+ no_payment_authorization_needed: Payment autorization not needed.
16
+ order_state:
17
+ payment_confirm: Verify payment
18
+ log_entry:
19
+ braintree:
20
+ message: Message
21
+ status: Status
22
+ cc_token: Braintree Credit Card Token
23
+ customer_id: Braintree Customer ID
24
+ cvv_result: CVV Result
25
+ avs_result_title: AVS result
26
+ avs_result:
27
+ message: Message
28
+ street_match: Street Match
29
+ postal_match: Postal Match
30
+ stripe:
31
+ message: Message
32
+ charge_id: Stripe Charge ID
33
+ card_id: Stripe Card ID
34
+ cvv_result: CVV Result
35
+ cvc_check: CVC Check
36
+ address_zip_check: Address ZIP check
37
+ stripe:
38
+ ach:
39
+ account_holder_name: Account Holder Name
40
+ account_holder_type: Account Holder Type
41
+ routing_number: Routing Number
42
+ account_number: Account Number
43
+ verify_account_number: Verify Account Number
44
+ verify_bank_account: Verify Bank Account
45
+ first_deposit: First Deposit
46
+ second_deposit: Second Deposit
47
+ bank_transfer: bank_transfer
@@ -0,0 +1,4 @@
1
+ ---
2
+ sv:
3
+ spree:
4
+ payment_has_been_cancelled: Betalningen har avbrutits.