archetype_spree_gateway 3.9.5

Sign up to get free protection for your applications and to get access to all the features.
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.