spree_gateway 3.7.5 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b9d8d20653e071378252663b95cfdafd7bb5dfcd6611e7b558888109fb776fa
4
- data.tar.gz: 79ab6d2ed89462c48aa23bc649d368bcd77f8c411949ae6b4d202854a1b79950
3
+ metadata.gz: '015491170e10b6b22d98da98f5b8e466ae2df12474e5029bff6bd8926d86732e'
4
+ data.tar.gz: 39713d557a03b1170dc36f4fcf4a6ec2e4fecb45b3a80376b00a23fd396c200b
5
5
  SHA512:
6
- metadata.gz: adaf238270f0c8c9d0bf447d595e56b9d606ecd9e6a538509c38c995a74e44923569e18a055f7c4863370cd3ae45e2cf7c1df3e7e2436cf6ed135522dd6c8968
7
- data.tar.gz: f25c7958e583b13e936aa01e23f23d30810346cf1da2ae8cea4414ecb7bd6e74c1d18411ec29703cc90ad528219378361489cf0e2edfd3c102c80b06dfa1df08
6
+ metadata.gz: c9d5003e95dc31701dbea5239a10dc587300d27659f29ea6deba81a309df2d24729ec3259d253d99f4c327c7f8889bc52b28dc8015d785fbde376a128d05a6f1
7
+ data.tar.gz: 11a5083fba9163eabd567cef8173d949d6f6ac5b86a97f3c65281671d3fd82f6ed93d2f4626c2ac39e7ae71d16cc559735a9d5eb4024960041a1ba2128997ba8
@@ -1,51 +1,44 @@
1
- sudo: required
2
- dist: trusty
1
+ os: linux
2
+ dist: bionic
3
+
4
+ addons:
5
+ apt:
6
+ sources:
7
+ - google-chrome
8
+ packages:
9
+ - google-chrome-stable
10
+
11
+ services:
12
+ - mysql
13
+ - postgresql
3
14
 
4
15
  language: ruby
5
16
 
6
- addons:
7
- chrome: stable
8
- postgresql: 9.4
17
+ rvm:
18
+ - 2.6
9
19
 
10
20
  env:
11
- - DB=postgres
12
21
  - DB=mysql
22
+ - DB=postgres
13
23
 
14
24
  gemfile:
15
- - gemfiles/spree_3_5.gemfile
16
- - gemfiles/spree_3_7.gemfile
17
- - gemfiles/spree_4_0.gemfile
25
+ # - gemfiles/spree_4_1.gemfile
26
+ - gemfiles/spree_4_2.gemfile
18
27
  - gemfiles/spree_master.gemfile
19
28
 
20
- script:
21
- - bundle exec rake test_app
22
- - bundle exec rake spec
23
-
24
- rvm:
25
- - 2.5.1
26
- - 2.4.4
27
- - 2.3.8
28
-
29
- matrix:
30
- allow_failures:
31
- - gemfile: gemfiles/spree_master.gemfile
32
- exclude:
33
- - rvm: 2.3.8
34
- gemfile: gemfiles/spree_master.gemfile
35
- - rvm: 2.4.4
36
- gemfile: gemfiles/spree_master.gemfile
37
- - rvm: 2.3.8
38
- gemfile: gemfiles/spree_4_0.gemfile
39
- - rvm: 2.4.4
40
- gemfile: gemfiles/spree_4_0.gemfile
41
- - rvm: 2.5.1
42
- gemfile: gemfiles/spree_3_5.gemfile
29
+ jobs:
30
+ allow_failures:
31
+ - gemfile: gemfiles/spree_master.gemfile
43
32
 
44
33
  before_install:
45
34
  - mysql -u root -e "GRANT ALL ON *.* TO 'travis'@'%';"
46
- - wget -N https://chromedriver.storage.googleapis.com/2.35/chromedriver_linux64.zip -P ~/
47
- - unzip ~/chromedriver_linux64.zip -d ~/
48
- - rm ~/chromedriver_linux64.zip
49
- - sudo mv -f ~/chromedriver /usr/local/share/
50
- - sudo chmod +x /usr/local/share/chromedriver
51
- - sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
35
+
36
+ before_script:
37
+ - CHROME_MAIN_VERSION=`google-chrome-stable --version | sed -E 's/(^Google Chrome |\.[0-9]+ )//g'`
38
+ - CHROMEDRIVER_VERSION=`curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_MAIN_VERSION"`
39
+ - curl "https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip" -O
40
+ - unzip chromedriver_linux64.zip -d ~/bin
41
+
42
+ script:
43
+ - bundle exec rake test_app
44
+ - bundle exec rake spec
data/Appraisals CHANGED
@@ -1,16 +1,10 @@
1
- appraise 'spree-3-5' do
2
- gem 'spree', '~> 3.5.0'
1
+ appraise 'spree-4-1' do
2
+ gem 'spree', '~> 4.1.0'
3
3
  gem 'rails-controller-testing'
4
4
  end
5
5
 
6
- appraise 'spree-3-7' do
7
- gem 'spree', '~> 3.7.0'
8
- gem 'sass-rails'
9
- gem 'rails-controller-testing'
10
- end
11
-
12
- appraise 'spree-4-0' do
13
- gem 'spree', '~> 4.0.0.rc2'
6
+ appraise 'spree-4-2' do
7
+ gem 'spree', '~> 4.2.0.beta'
14
8
  gem 'rails-controller-testing'
15
9
  end
16
10
 
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ class Check < 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,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,29 @@
1
+ module Spree
2
+ module PaymentDecorator
3
+ def verify!(**options)
4
+ process_verification(options)
5
+ end
6
+
7
+ private
8
+
9
+ def process_verification(**options)
10
+ protect_from_connection_error do
11
+ response = payment_method.verify(source, options)
12
+
13
+ record_response(response)
14
+
15
+ if response.success?
16
+ unless response.authorization.nil?
17
+ self.response_code = response.authorization
18
+
19
+ source.update(status: response.params['status'])
20
+ end
21
+ else
22
+ gateway_error(response)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ Spree::Payment.prepend Spree::PaymentDecorator
@@ -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
@@ -1,6 +1,14 @@
1
1
  ---
2
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
3
10
  spree:
11
+ check: Check
4
12
  payment_has_been_cancelled: The payment has been cancelled.
5
13
  log_entry:
6
14
  braintree:
@@ -21,3 +29,14 @@ en:
21
29
  cvv_result: CVV Result
22
30
  cvc_check: CVC Check
23
31
  address_zip_check: Address ZIP check
32
+ stripe:
33
+ ach:
34
+ account_holder_name: Account Holder Name
35
+ account_holder_type: Account Holder Type
36
+ routing_number: Routing Number
37
+ account_number: Account Number
38
+ verify_account_number: Verify Account Number
39
+ verify_bank_account: Verify Bank Account
40
+ first_deposit: First Deposit
41
+ second_deposit: Second Deposit
42
+ bank_transfer: bank_transfer
@@ -0,0 +1,22 @@
1
+ class AddSpreeCheckPaymentSource < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :spree_checks do |t|
4
+ t.references :payment_method
5
+ t.references :user
6
+ t.string "account_holder_name"
7
+ t.string "account_holder_type"
8
+ t.string "routing_number"
9
+ t.string "account_number"
10
+ t.string "account_type", default: 'checking'
11
+ t.string "status"
12
+ t.string "last_digits"
13
+ t.string "gateway_customer_profile_id"
14
+ t.string "gateway_payment_profile_id"
15
+
16
+ t.datetime "created_at", null: false
17
+ t.datetime "updated_at", null: false
18
+ t.datetime "deleted_at"
19
+ end
20
+ add_index :spree_payment_methods, :id
21
+ end
22
+ end
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails-controller-testing"
6
- gem "spree", "~> 3.5.0"
6
+ gem "spree", "~> 4.1.0"
7
7
 
8
8
  gemspec path: "../"
@@ -3,6 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rails-controller-testing"
6
- gem "spree", "~> 4.0.0.rc2"
6
+ gem "spree", "~> 4.2.0.beta"
7
7
 
8
8
  gemspec path: "../"
@@ -1,6 +1,19 @@
1
1
  module ActiveMerchant
2
2
  module Billing
3
3
  module StripeGatewayDecorator
4
+ def verify(source, **options)
5
+ customer = source.gateway_customer_profile_id
6
+ bank_account_token = source.gateway_payment_profile_id
7
+
8
+ commit(:post, "customers/#{CGI.escape(customer)}/sources/#{bank_account_token}/verify", amounts: options[:amounts])
9
+ end
10
+
11
+ def retrieve(source, **options)
12
+ customer = source.gateway_customer_profile_id
13
+ bank_account_token = source.gateway_payment_profile_id
14
+ commit(:get, "customers/#{CGI.escape(customer)}/bank_accounts/#{bank_account_token}")
15
+ end
16
+
4
17
  private
5
18
 
6
19
  def headers(options = {})
@@ -32,6 +32,7 @@ module SpreeGateway
32
32
  app.config.spree.payment_methods << Spree::Gateway::StripeGateway
33
33
  app.config.spree.payment_methods << Spree::Gateway::StripeElementsGateway
34
34
  app.config.spree.payment_methods << Spree::Gateway::StripeApplePayGateway
35
+ app.config.spree.payment_methods << Spree::Gateway::StripeAchGateway
35
36
  app.config.spree.payment_methods << Spree::Gateway::UsaEpayTransaction
36
37
  app.config.spree.payment_methods << Spree::Gateway::Worldpay
37
38
  end
@@ -1,5 +1,5 @@
1
1
  module SpreeGateway
2
2
  def self.version
3
- '3.7.5'
3
+ '3.8.0'
4
4
  end
5
5
  end
@@ -0,0 +1,86 @@
1
+ <fieldset data-id="bank_transfer">
2
+ <div id="bank_transfer_form<%= payment_method.id %>" class="margint" data-hook>
3
+ <% param_prefix = "payment_source[#{payment_method.id}]" %>
4
+
5
+ <div data-hook="account_holder_name" class="form-group">
6
+ <%= label_tag "account_holder_name#{payment_method.id}", raw(Spree.t('stripe.ach.account_holder_name') + required_span_tag) %>
7
+ <%= text_field_tag "#{param_prefix}[account_holder_name]", '', class: 'required form-control', id: "account_holder_name#{payment_method.id}" %>
8
+ </div>
9
+
10
+ <div data-hook="account_holder_type">
11
+ <%= label_tag "account_holder_type#{payment_method.id}", raw(Spree.t('stripe.ach.account_holder_type') + required_span_tag) %>
12
+ <%= select_tag "#{param_prefix}[account_holder_type]", options_for_select(%w(Individual Company)), {id: "account_holder_type#{payment_method.id}", class: 'required form-control'} %>
13
+ </div>
14
+
15
+ <div data-hook="routing_number">
16
+ <%= label_tag "routing_number#{payment_method.id}", raw(Spree.t('stripe.ach.routing_number') + required_span_tag)%>
17
+ <%= text_field_tag "#{param_prefix}[routing_number]", '', class: 'required form-control', id: "routing_number#{payment_method.id}", maxlength: 9 %>
18
+ </div>
19
+ <div data-hook="account_number">
20
+ <%= label_tag "account_number#{payment_method.id}", raw(Spree.t('stripe.ach.account_number') + required_span_tag) %>
21
+ <%= text_field_tag "#{param_prefix}[account_number]", '', class: 'required form-control', id: "account_number#{payment_method.id}" %>
22
+ </div>
23
+ <div data-hook="account_number">
24
+ <%= label_tag "verify_account_number#{payment_method.id}", raw(Spree.t('stripe.ach.verify_account_number') + required_span_tag) %>
25
+ <%= text_field_tag "#{param_prefix}[verify_account_number]", '', class: 'required form-control', id: "verify_account_number#{payment_method.id}" %>
26
+ </div>
27
+ </div>
28
+ </fieldset>
29
+
30
+ <script type="text/javascript" src="https://js.stripe.com/v3/"></script>
31
+ <script type="text/javascript">
32
+ var stripe = Stripe("<%= payment_method.preferred_publishable_key %>");
33
+ </script>
34
+
35
+ <script>
36
+ stripeResponseHandler = function(response) {
37
+ var token, paymentMethodId;
38
+ if (response.error) {
39
+ $('#stripeError').html(response.error.message);
40
+ const param_map = {
41
+ account_holder_name: '#account_holder_name',
42
+ account_holder_type: '#account_holder_type',
43
+ account_number: '#account_number',
44
+ routing_number: '#routing_number'
45
+ }
46
+ if (response.error.param){
47
+ errorField = Spree.stripePaymentMethod.find(param_map[response.error.param])
48
+ errorField.addClass('error');
49
+ errorField.parent().addClass('has-error');
50
+ }
51
+ return $('#stripeError').show();
52
+ } else {
53
+ Spree.stripePaymentMethod.find('#account_holder_name, #account_holder_type, #account_number, #routing_number').prop("disabled", true);
54
+ token = response.token['id'];
55
+ paymentMethodId = Spree.stripePaymentMethod.prop('id').split("_")[2];
56
+ Spree.stripePaymentMethod.append("<input type='hidden' class='stripeToken' name='payment_source[" + paymentMethodId + "][gateway_payment_profile_id]' value='" + token + "'/>");
57
+ return Spree.stripePaymentMethod.parents("form").trigger('submit');
58
+ }
59
+ };
60
+
61
+ window.addEventListener('DOMContentLoaded', function() {
62
+ Spree.stripePaymentMethod = $('#payment_method_' + <%= payment_method.id %>);
63
+
64
+ Spree.ready(function() {
65
+ Spree.stripePaymentMethod.prepend("<div id='stripeError' class='errorExplanation alert alert-danger' style='display:none'></div>");
66
+ return $('#new_payment [data-hook=buttons]').click(function() {
67
+ var params;
68
+ $('#stripeError').hide();
69
+ Spree.stripePaymentMethod.find('#account_holder_name, #account_holder_type, #account_number, #routing_number').removeClass('error');
70
+ if (Spree.stripePaymentMethod.is(':visible')) {
71
+ params = $.extend({
72
+ country: 'US',
73
+ currency: 'usd',
74
+ account_holder_name: $('.account_holder_name:visible').val(),
75
+ account_holder_type: $('.account_holder_type:visible').val(),
76
+ routing_number: $('.routing_number:visible').val(),
77
+ account_number: $('.account_number:visible').val()
78
+ }, Spree.stripeAdditionalInfo);
79
+ stripe.createToken('bank_account', params).then(stripeResponseHandler);
80
+ return false;
81
+ }
82
+ });
83
+ });
84
+ });
85
+ </script>
86
+