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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +3 -0
- data/.travis.yml +39 -0
- data/Gemfile +9 -0
- data/Guardfile +9 -0
- data/LICENSE.md +26 -0
- data/README.md +105 -0
- data/Rakefile +15 -0
- data/app/models/spree/billing_integration.rb +21 -0
- data/app/models/spree/check.rb +41 -0
- data/app/models/spree/gateway/authorize_net.rb +45 -0
- data/app/models/spree/gateway/authorize_net_cim.rb +213 -0
- data/app/models/spree/gateway/balanced_gateway.rb +64 -0
- data/app/models/spree/gateway/banwire.rb +15 -0
- data/app/models/spree/gateway/beanstream.rb +193 -0
- data/app/models/spree/gateway/braintree_gateway.rb +184 -0
- data/app/models/spree/gateway/card_save.rb +10 -0
- data/app/models/spree/gateway/cyber_source.rb +10 -0
- data/app/models/spree/gateway/data_cash.rb +10 -0
- data/app/models/spree/gateway/epay.rb +10 -0
- data/app/models/spree/gateway/eway.rb +18 -0
- data/app/models/spree/gateway/eway_rapid.rb +14 -0
- data/app/models/spree/gateway/maxipago.rb +14 -0
- data/app/models/spree/gateway/migs.rb +11 -0
- data/app/models/spree/gateway/moneris.rb +10 -0
- data/app/models/spree/gateway/pay_junction.rb +14 -0
- data/app/models/spree/gateway/pay_pal_gateway.rb +12 -0
- data/app/models/spree/gateway/payflow_pro.rb +15 -0
- data/app/models/spree/gateway/paymill.rb +12 -0
- data/app/models/spree/gateway/payu_polska_gateway.rb +24 -0
- data/app/models/spree/gateway/pin_gateway.rb +60 -0
- data/app/models/spree/gateway/quickpay.rb +9 -0
- data/app/models/spree/gateway/sage_pay.rb +11 -0
- data/app/models/spree/gateway/secure_pay_au.rb +10 -0
- data/app/models/spree/gateway/spreedly_core_gateway.rb +11 -0
- data/app/models/spree/gateway/stripe_ach_gateway.rb +60 -0
- data/app/models/spree/gateway/stripe_apple_pay_gateway.rb +10 -0
- data/app/models/spree/gateway/stripe_elements_gateway.rb +61 -0
- data/app/models/spree/gateway/stripe_gateway.rb +151 -0
- data/app/models/spree/gateway/usa_epay_transaction.rb +9 -0
- data/app/models/spree/gateway/worldpay.rb +91 -0
- data/app/models/spree/payu_polska.rb +41 -0
- data/app/models/spree_gateway/apple_pay_order_decorator.rb +20 -0
- data/app/models/spree_gateway/apple_pay_payment_decorator.rb +9 -0
- data/app/models/spree_gateway/credit_card_decorator.rb +10 -0
- data/app/models/spree_gateway/order_decorator.rb +28 -0
- data/app/models/spree_gateway/payment_decorator.rb +36 -0
- data/app/views/spree/checkout/_payment_confirm.html.erb +39 -0
- data/app/views/spree/checkout/_payu.html +12 -0
- data/config/initializers/inflections.rb +3 -0
- data/config/initializers/spree_permitted_attributes.rb +5 -0
- data/config/locales/bg.yml +4 -0
- data/config/locales/de.yml +4 -0
- data/config/locales/en.yml +47 -0
- data/config/locales/sv.yml +4 -0
- data/config/routes.rb +19 -0
- data/db/migrate/20200317135551_add_spree_check_payment_source.rb +22 -0
- data/db/migrate/20200422114908_add_intent_key_to_payment.rb +5 -0
- data/lib/active_merchant/billing/stripe_gateway_decorator.rb +33 -0
- data/lib/controllers/spree/api/v2/storefront/intents_controller.rb +45 -0
- data/lib/controllers/spree/apple_pay_domain_verification_controller.rb +11 -0
- data/lib/generators/spree_gateway/install/install_generator.rb +19 -0
- data/lib/spree_frontend/controllers/spree/checkout_controller_decorator.rb +19 -0
- data/lib/spree_gateway/engine.rb +80 -0
- data/lib/spree_gateway/version.rb +5 -0
- data/lib/spree_gateway.rb +4 -0
- data/lib/views/backend/spree/admin/log_entries/_braintree.html.erb +31 -0
- data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +28 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_quickcheckout.html.erb +8 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +79 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_stripe_ach.html.erb +86 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_stripe_apple_pay.html.erb +0 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_stripe_elements.html.erb +79 -0
- data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +1 -0
- data/lib/views/backend/spree/admin/payments/source_views/_stripe_ach.html.erb +21 -0
- data/lib/views/backend/spree/admin/payments/source_views/_stripe_apple_pay.html.erb +1 -0
- data/lib/views/backend/spree/admin/payments/source_views/_stripe_elements.html.erb +1 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +86 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe_ach.html.erb +81 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe_ach_verify.html.erb +16 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe_additional_info.html.erb +16 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe_apple_pay.html.erb +109 -0
- data/lib/views/frontend/spree/checkout/payment/_stripe_elements.html.erb +110 -0
- data/script/rails +7 -0
- data/spec/factories/check_factory.rb +10 -0
- data/spec/features/admin/stripe_elements_payment_spec.rb +100 -0
- data/spec/features/stripe_checkout_spec.rb +130 -0
- data/spec/features/stripe_elements_3ds_checkout_spec.rb +225 -0
- data/spec/models/gateway/authorize_net_cim_spec.rb +29 -0
- data/spec/models/gateway/authorize_net_spec.rb +23 -0
- data/spec/models/gateway/balanced_gateway_spec.rb +17 -0
- data/spec/models/gateway/banwire_spec.rb +11 -0
- data/spec/models/gateway/beanstream_spec.rb +17 -0
- data/spec/models/gateway/braintree_gateway_spec.rb +420 -0
- data/spec/models/gateway/card_save_spec.rb +11 -0
- data/spec/models/gateway/cyber_source_spec.rb +11 -0
- data/spec/models/gateway/data_cash_spec.rb +11 -0
- data/spec/models/gateway/epay_spec.rb +11 -0
- data/spec/models/gateway/eway_rapid_spec.rb +23 -0
- data/spec/models/gateway/eway_spec.rb +29 -0
- data/spec/models/gateway/maxipago_spec.rb +17 -0
- data/spec/models/gateway/moneris_spec.rb +11 -0
- data/spec/models/gateway/pay_junction_spec.rb +23 -0
- data/spec/models/gateway/pay_pal_spec.rb +11 -0
- data/spec/models/gateway/payflow_pro_spec.rb +23 -0
- data/spec/models/gateway/paymill_spec.rb +11 -0
- data/spec/models/gateway/pin_gateway_spec.rb +54 -0
- data/spec/models/gateway/quickpay_spec.rb +11 -0
- data/spec/models/gateway/sage_pay_spec.rb +11 -0
- data/spec/models/gateway/secure_pay_au_spec.rb +11 -0
- data/spec/models/gateway/stripe_ach_gateway_spec.rb +186 -0
- data/spec/models/gateway/stripe_gateway_spec.rb +199 -0
- data/spec/models/gateway/usa_epay_transaction_spec.rb +49 -0
- data/spec/models/gateway/worldpay_spec.rb +11 -0
- data/spec/models/spree/order_spec.rb +79 -0
- data/spec/requests/apple_pay_domain_verification.rb +45 -0
- data/spec/requests/spree/api/v2/storefront/intents_controller_spec.rb +198 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/order_walktrough.rb +73 -0
- data/spec/support/wait_for_stripe.rb +27 -0
- data/spec/support/within_stripe_3ds_popup.rb +10 -0
- data/spree_gateway.gemspec +37 -0
- metadata +277 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f5d09441469ac5dede82534c51cabe9f81584cb3c07909c852e1fb08101574b1
|
|
4
|
+
data.tar.gz: 319f475d119d8b552201331626935ce439c4dc9199e738c779df2f19d8cbd696
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 99d8aaec4ffd482c9dfc52e6873222ed604b36c5cd03c6a0ce5df80a465740ca1dba779d5337eae27b84b6b96f5cfe3d091000c769c410f475115afbe3bfb6fd
|
|
7
|
+
data.tar.gz: 0f32987262dc458ce2e662cd1286cf0f90dc5ed5ee354a9fd8267522da99374ea6e0389edbec07d964fc0f33eb2571c83280a41c75979ece41155b90dc388365
|
data/.gitignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
\#*
|
|
2
|
+
*~
|
|
3
|
+
.#*
|
|
4
|
+
.DS_Store
|
|
5
|
+
.idea
|
|
6
|
+
.localeapp/locales
|
|
7
|
+
.project
|
|
8
|
+
coverage
|
|
9
|
+
default
|
|
10
|
+
Gemfile.lock
|
|
11
|
+
tmp
|
|
12
|
+
nbproject
|
|
13
|
+
pkg
|
|
14
|
+
*.sw?
|
|
15
|
+
spec/dummy
|
|
16
|
+
.rvmrc
|
|
17
|
+
.sass-cache
|
|
18
|
+
public/spree
|
|
19
|
+
.ruby-version
|
|
20
|
+
.ruby-gemset
|
|
21
|
+
gemfiles/*.gemfile.lock
|
data/.rspec
ADDED
data/.travis.yml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
os: linux
|
|
2
|
+
dist: bionic
|
|
3
|
+
|
|
4
|
+
cache: bundler
|
|
5
|
+
|
|
6
|
+
addons:
|
|
7
|
+
apt:
|
|
8
|
+
sources:
|
|
9
|
+
- google-chrome
|
|
10
|
+
packages:
|
|
11
|
+
- google-chrome-stable
|
|
12
|
+
|
|
13
|
+
services:
|
|
14
|
+
- mysql
|
|
15
|
+
- postgresql
|
|
16
|
+
- redis-server
|
|
17
|
+
|
|
18
|
+
language: ruby
|
|
19
|
+
|
|
20
|
+
rvm:
|
|
21
|
+
- 2.7
|
|
22
|
+
- 3.0
|
|
23
|
+
|
|
24
|
+
env:
|
|
25
|
+
- DB=mysql
|
|
26
|
+
- DB=postgres
|
|
27
|
+
|
|
28
|
+
before_install:
|
|
29
|
+
- mysql -u root -e "GRANT ALL ON *.* TO 'travis'@'%';"
|
|
30
|
+
|
|
31
|
+
before_script:
|
|
32
|
+
- CHROME_MAIN_VERSION=`google-chrome-stable --version | sed -E 's/(^Google Chrome |\.[0-9]+ )//g'`
|
|
33
|
+
- CHROMEDRIVER_VERSION=`curl -s "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_$CHROME_MAIN_VERSION"`
|
|
34
|
+
- curl "https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip" -O
|
|
35
|
+
- unzip chromedriver_linux64.zip -d ~/bin
|
|
36
|
+
|
|
37
|
+
script:
|
|
38
|
+
- bundle exec rake test_app
|
|
39
|
+
- bundle exec rake spec
|
data/Gemfile
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gem 'rails-controller-testing'
|
|
4
|
+
gem 'spree', github: 'spree/spree', branch: 'main'
|
|
5
|
+
gem 'spree_backend', github: 'spree/spree_backend', branch: 'main'
|
|
6
|
+
gem 'spree_frontend', github: 'spree/spree_legacy_frontend', branch: 'main'
|
|
7
|
+
gem 'activemerchant', github: 'archetype2142/active-merchant', branch: 'master'
|
|
8
|
+
|
|
9
|
+
gemspec
|
data/Guardfile
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
guard "rspec", cmd: "bundle exec rspec", all_after_pass: false, all_on_start: false do
|
|
2
|
+
watch("spec/spec_helper.rb") { "spec" }
|
|
3
|
+
watch("config/routes.rb") { "spec/controllers" }
|
|
4
|
+
watch(%r{^spec/(.+)_spec\.rb$}) { |m| "spec/#{m[1]}_spec.rb"}
|
|
5
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
|
6
|
+
watch(%r{^app/(.*)\.erb$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
|
8
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb" }
|
|
9
|
+
end
|
data/LICENSE.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Copyright (c) 2014 Spree Commerce Inc. and other contributors.
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
5
|
+
are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
|
11
|
+
and/or other materials provided with the distribution.
|
|
12
|
+
* Neither the name Spree nor the names of its contributors may be used to
|
|
13
|
+
endorse or promote products derived from this software without specific
|
|
14
|
+
prior written permission.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
17
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
18
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
19
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
20
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
21
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
22
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
23
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
24
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
26
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Spree Gateway
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/spree/spree_gateway)
|
|
4
|
+
[](https://codeclimate.com/github/spree/spree_gateway)
|
|
5
|
+
|
|
6
|
+
Community supported Spree Payment Method Gateways. It works as a wrapper for
|
|
7
|
+
[active_merchant](https://github.com/activemerchant/active_merchant) gateway.
|
|
8
|
+
|
|
9
|
+
Supported payment gateways:
|
|
10
|
+
* Authorize.net (with CIM support)
|
|
11
|
+
* Apple Pay (via Stripe)
|
|
12
|
+
* BanWire
|
|
13
|
+
* Bambora (previously Beanstream)
|
|
14
|
+
* Braintree
|
|
15
|
+
* CyberSource
|
|
16
|
+
* ePay
|
|
17
|
+
* eWay
|
|
18
|
+
* maxipago
|
|
19
|
+
* MasterCard Payment Gateway Service (formerly MiGS)
|
|
20
|
+
* Moneris
|
|
21
|
+
* PayJunction
|
|
22
|
+
* Payflow
|
|
23
|
+
* Paymill
|
|
24
|
+
* Pin Payments
|
|
25
|
+
* QuickPay
|
|
26
|
+
* sage Pay
|
|
27
|
+
* SecurePay
|
|
28
|
+
* Spreedly
|
|
29
|
+
* Stripe (with Stripe Elements)
|
|
30
|
+
* USAePay
|
|
31
|
+
* Worldpay (previously Cardsave)
|
|
32
|
+
|
|
33
|
+
For`PayPal` support head over to [braintree_vzero](https://github.com/spree-contrib/spree_braintree_vzero) extension.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
1. Add this extension to your Gemfile with this line:
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
gem 'spree_gateway', '~> 3.7'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. Install the gem using Bundler:
|
|
44
|
+
```ruby
|
|
45
|
+
bundle install
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
3. Copy & run migrations
|
|
49
|
+
```ruby
|
|
50
|
+
bundle exec rails g spree_gateway:install
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Finally, make sure to **restart your app**. Navigate to *Configuration > Payment Methods > New Payment Method* in the admin panel and you should see that a bunch of additional gateways have been added to the list.
|
|
54
|
+
|
|
55
|
+
## Contributing
|
|
56
|
+
|
|
57
|
+
In the spirit of [free software][1], **everyone** is encouraged to help improve this project.
|
|
58
|
+
|
|
59
|
+
Here are some ways *you* can contribute:
|
|
60
|
+
|
|
61
|
+
* by using prerelease versions
|
|
62
|
+
* by reporting [bugs][2]
|
|
63
|
+
* by suggesting new features
|
|
64
|
+
* by writing or editing documentation
|
|
65
|
+
* by writing specifications
|
|
66
|
+
* by writing code (*no patch is too small*: fix typos, add comments, clean up inconsistent whitespace)
|
|
67
|
+
* by refactoring code
|
|
68
|
+
* by resolving [issues][2]
|
|
69
|
+
* by reviewing patches
|
|
70
|
+
|
|
71
|
+
Starting point:
|
|
72
|
+
|
|
73
|
+
* Fork the repo
|
|
74
|
+
* Clone your repo
|
|
75
|
+
* (You will need to `brew install mysql postgres` if you don't already have them installed)
|
|
76
|
+
* Run `bundle`
|
|
77
|
+
* (You may need to `bundle update` if bundler gets stuck)
|
|
78
|
+
* Run `bundle exec rake test_app` to create the test application in `spec/test_app`
|
|
79
|
+
* Make your changes
|
|
80
|
+
* Ensure specs pass by running `bundle exec rspec spec`
|
|
81
|
+
* (You will need to `brew install phantomjs` if you don't already have it installed)
|
|
82
|
+
* Submit your pull request
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
License
|
|
86
|
+
----------------------
|
|
87
|
+
|
|
88
|
+
Spree is released under the [New BSD License][3].
|
|
89
|
+
|
|
90
|
+
About Spark Solutions
|
|
91
|
+
----------------------
|
|
92
|
+
[][spark]
|
|
93
|
+
|
|
94
|
+
Spree Gateway is maintained by [Spark Solutions Sp. z o.o.][spark].
|
|
95
|
+
|
|
96
|
+
We are passionate about open source software.
|
|
97
|
+
We are [available for hire][spark].
|
|
98
|
+
|
|
99
|
+
[spark]:http://sparksolutions.co?utm_source=github
|
|
100
|
+
|
|
101
|
+
[1]: http://www.fsf.org/licensing/essays/free-sw.html
|
|
102
|
+
[2]: https://github.com/spree/spree_gateway/issues
|
|
103
|
+
[3]: https://github.com/spree/spree_gateway/blob/main/LICENSE.md
|
|
104
|
+
[4]: https://github.com/spree
|
|
105
|
+
[5]: https://github.com/spree/spree_gateway/graphs/contributors
|
data/Rakefile
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
Bundler::GemHelper.install_tasks
|
|
3
|
+
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
require 'spree/testing_support/extension_rake'
|
|
6
|
+
|
|
7
|
+
RSpec::Core::RakeTask.new
|
|
8
|
+
|
|
9
|
+
task :default => [:spec]
|
|
10
|
+
|
|
11
|
+
desc "Generates a dummy app for testing"
|
|
12
|
+
task :test_app do
|
|
13
|
+
ENV['LIB_NAME'] = 'spree_gateway'
|
|
14
|
+
Rake::Task['extension:test_app'].invoke
|
|
15
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class BillingIntegration < PaymentMethod
|
|
3
|
+
validates :name, presence: true
|
|
4
|
+
|
|
5
|
+
preference :server, :string, default: 'test'
|
|
6
|
+
preference :test_mode, :boolean, default: true
|
|
7
|
+
|
|
8
|
+
def provider
|
|
9
|
+
integration_options = options
|
|
10
|
+
ActiveMerchant::Billing::Base.integration_mode = integration_options[:server].to_sym
|
|
11
|
+
integration_options[:test] = true if integration_options[:test_mode]
|
|
12
|
+
@provider ||= provider_class.new(integration_options)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def options
|
|
16
|
+
options_hash = {}
|
|
17
|
+
preferences.each { |key, value| options_hash[key.to_sym] = value }
|
|
18
|
+
options_hash
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -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,45 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class Gateway::AuthorizeNet < Gateway
|
|
3
|
+
preference :login, :string
|
|
4
|
+
preference :password, :string
|
|
5
|
+
preference :server, :string, default: "test"
|
|
6
|
+
|
|
7
|
+
def provider_class
|
|
8
|
+
ActiveMerchant::Billing::AuthorizeNetGateway
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def options
|
|
12
|
+
if !['live','test'].include?(self.preferred_server)
|
|
13
|
+
raise "You must set the 'server' preference in your payment method (Gateway::AuthorizeNet) to either 'live' or 'test'"
|
|
14
|
+
end
|
|
15
|
+
super().merge(test: (self.preferred_server != "live"))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def cancel(response_code)
|
|
19
|
+
provider
|
|
20
|
+
# From: http://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Refunds-in-Retail-A-user-friendly-approach-using-AIM/ba-p/9848
|
|
21
|
+
# DD: if unsettled, void needed
|
|
22
|
+
response = provider.void(response_code)
|
|
23
|
+
# DD: if settled, credit/refund needed (CAN'T DO WITHOUT CREDIT CARD ON AUTH.NET)
|
|
24
|
+
#response = provider.refund(response_code) unless response.success?
|
|
25
|
+
|
|
26
|
+
response
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def credit(amount, response_code, refund, gateway_options = {})
|
|
30
|
+
gateway_options[:card_number] = refund[:originator].payment.source.last_digits
|
|
31
|
+
auth_net_gateway.refund(amount, response_code, gateway_options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def auth_net_gateway
|
|
37
|
+
@_auth_net_gateway ||= begin
|
|
38
|
+
ActiveMerchant::Billing::Base.gateway_mode = preferred_server.to_sym
|
|
39
|
+
gateway_options = options
|
|
40
|
+
gateway_options[:test_requests] = false # DD: never ever do test requests because just returns transaction_id = 0
|
|
41
|
+
ActiveMerchant::Billing::AuthorizeNetGateway.new(gateway_options)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class Gateway::AuthorizeNetCim < Gateway
|
|
3
|
+
preference :login, :string
|
|
4
|
+
preference :password, :string
|
|
5
|
+
preference :server, :string, default: "test"
|
|
6
|
+
preference :test_mode, :boolean, default: false
|
|
7
|
+
preference :validate_on_profile_create, :boolean, default: false
|
|
8
|
+
|
|
9
|
+
ActiveMerchant::Billing::Response.class_eval do
|
|
10
|
+
attr_writer :authorization
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def provider_class
|
|
14
|
+
self.class
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def options
|
|
18
|
+
if !['live','test'].include?(self.preferred_server)
|
|
19
|
+
raise "You must set the 'server' preference in your payment method (Gateway::AuthorizeNetCim) to either 'live' or 'test'"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# add :test key in the options hash, as that is what the
|
|
23
|
+
# ActiveMerchant::Billing::AuthorizeNetGateway expects
|
|
24
|
+
if self.preferred_server != "live"
|
|
25
|
+
self.preferences[:test] = true
|
|
26
|
+
else
|
|
27
|
+
self.preferences.delete(:test)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
super
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def authorize(amount, creditcard, gateway_options)
|
|
34
|
+
create_transaction(amount, creditcard, :auth_only, transaction_options(gateway_options))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def purchase(amount, creditcard, gateway_options)
|
|
38
|
+
create_transaction(amount, creditcard, :auth_capture, transaction_options(gateway_options))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# capture is only one where source is not passed in for payment profile
|
|
42
|
+
def capture(amount, response_code, gateway_options)
|
|
43
|
+
# no credit card needed
|
|
44
|
+
create_transaction(amount, nil, :prior_auth_capture, trans_id: response_code)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def credit(amount, creditcard, response_code, gateway_options = {})
|
|
48
|
+
create_transaction(amount, creditcard, :refund, transaction_options(gateway_options).merge(trans_id: response_code))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def void(response_code, creditcard, gateway_options = {})
|
|
52
|
+
create_transaction(nil, creditcard, :void, transaction_options(gateway_options).merge(trans_id: response_code))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def cancel(response_code)
|
|
56
|
+
# From: http://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Refunds-in-Retail-A-user-friendly-approach-using-AIM/ba-p/9848
|
|
57
|
+
# DD: if unsettled, void needed
|
|
58
|
+
response = void(response_code, nil)
|
|
59
|
+
# DD: if settled, credit/refund needed
|
|
60
|
+
response = credit(nil, nil, response_code) unless response.success?
|
|
61
|
+
|
|
62
|
+
response
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def payment_profiles_supported?
|
|
66
|
+
true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Create a new CIM customer profile ready to accept a payment. Called by Spree::Payment on after_save.
|
|
70
|
+
def create_profile(payment)
|
|
71
|
+
if payment.source.gateway_customer_profile_id.nil?
|
|
72
|
+
profile_hash = create_customer_profile(payment)
|
|
73
|
+
payment.source.update(gateway_customer_profile_id: profile_hash[:customer_profile_id], gateway_payment_profile_id: profile_hash[:customer_payment_profile_id])
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Get the CIM payment profile; Needed for updates.
|
|
78
|
+
def get_profile(payment)
|
|
79
|
+
if payment.source.has_payment_profile?
|
|
80
|
+
profile = cim_gateway.get_customer_profile({
|
|
81
|
+
customer_profile_id: payment.source.gateway_customer_profile_id
|
|
82
|
+
})
|
|
83
|
+
if profile
|
|
84
|
+
profile.params['profile'].deep_symbolize_keys!
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Get the CIM payment profile; Needed for updates.
|
|
90
|
+
def get_payment_profile(payment)
|
|
91
|
+
if payment.source.has_payment_profile?
|
|
92
|
+
profile = cim_gateway.get_customer_payment_profile({
|
|
93
|
+
customer_profile_id: payment.source.gateway_customer_profile_id,
|
|
94
|
+
customer_payment_profile_id: payment.source.gateway_payment_profile_id
|
|
95
|
+
})
|
|
96
|
+
if profile
|
|
97
|
+
profile.params['payment_profile'].deep_symbolize_keys!
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Update billing address on the CIM payment profile
|
|
103
|
+
def update_payment_profile(payment)
|
|
104
|
+
if payment.source.has_payment_profile?
|
|
105
|
+
if hash = get_payment_profile(payment)
|
|
106
|
+
hash[:bill_to] = generate_address_hash(payment.order.bill_address)
|
|
107
|
+
if hash[:payment][:credit_card]
|
|
108
|
+
# activemerchant expects a credit card object with 'number', 'year', 'month', and 'verification_value?' defined
|
|
109
|
+
payment.source.define_singleton_method(:number) { "XXXXXXXXX#{payment.source.last_digits}" }
|
|
110
|
+
hash[:payment][:credit_card] = payment.source
|
|
111
|
+
end
|
|
112
|
+
cim_gateway.update_customer_payment_profile({
|
|
113
|
+
customer_profile_id: payment.source.gateway_customer_profile_id,
|
|
114
|
+
payment_profile: hash
|
|
115
|
+
})
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
def transaction_options(gateway_options = {})
|
|
123
|
+
{ order: { invoice_number: gateway_options[:order_id] } }
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Create a transaction on a creditcard
|
|
127
|
+
# Set up a CIM profile for the card if one doesn't exist
|
|
128
|
+
# Valid transaction_types are :auth_only, :capture_only and :auth_capture
|
|
129
|
+
def create_transaction(amount, creditcard, transaction_type, options = {})
|
|
130
|
+
creditcard.save if creditcard
|
|
131
|
+
|
|
132
|
+
transaction_options = {
|
|
133
|
+
type: transaction_type
|
|
134
|
+
}.update(options)
|
|
135
|
+
|
|
136
|
+
if amount
|
|
137
|
+
amount = "%.2f" % (amount / 100.0) # This gateway requires formated decimal, not cents
|
|
138
|
+
transaction_options.update({
|
|
139
|
+
amount: amount
|
|
140
|
+
})
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
if creditcard
|
|
144
|
+
transaction_options.update({
|
|
145
|
+
customer_profile_id: creditcard.gateway_customer_profile_id,
|
|
146
|
+
customer_payment_profile_id: creditcard.gateway_payment_profile_id
|
|
147
|
+
})
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
logger.debug("\nAuthorize Net CIM Request")
|
|
151
|
+
logger.debug(" transaction_options: #{transaction_options.inspect}")
|
|
152
|
+
t = cim_gateway.create_customer_profile_transaction(transaction: transaction_options)
|
|
153
|
+
logger.debug("\nAuthorize Net CIM Response")
|
|
154
|
+
logger.debug(" response: #{t.inspect}\n")
|
|
155
|
+
t
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Create a new CIM customer profile ready to accept a payment
|
|
159
|
+
def create_customer_profile(payment)
|
|
160
|
+
options = options_for_create_customer_profile(payment)
|
|
161
|
+
response = cim_gateway.create_customer_profile(options)
|
|
162
|
+
if response.success?
|
|
163
|
+
{ customer_profile_id: response.params['customer_profile_id'],
|
|
164
|
+
customer_payment_profile_id: response.params['customer_payment_profile_id_list'].values.first }
|
|
165
|
+
else
|
|
166
|
+
payment.send(:gateway_error, response)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def options_for_create_customer_profile(payment)
|
|
171
|
+
if payment.is_a? CreditCard
|
|
172
|
+
info = { bill_to: generate_address_hash(payment.address),
|
|
173
|
+
payment: { credit_card: payment } }
|
|
174
|
+
else
|
|
175
|
+
info = { bill_to: generate_address_hash(payment.order.bill_address),
|
|
176
|
+
payment: { credit_card: payment.source } }
|
|
177
|
+
end
|
|
178
|
+
validation_mode = preferred_validate_on_profile_create ? preferred_server.to_sym : :none
|
|
179
|
+
|
|
180
|
+
{ profile: { merchant_customer_id: "#{Time.now.to_f}",
|
|
181
|
+
ship_to_list: generate_address_hash(payment.order.ship_address),
|
|
182
|
+
email: payment.order.email,
|
|
183
|
+
payment_profiles: info },
|
|
184
|
+
validation_mode: validation_mode }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# As in PaymentGateway but with separate name fields
|
|
188
|
+
def generate_address_hash(address)
|
|
189
|
+
return {} if address.nil?
|
|
190
|
+
{
|
|
191
|
+
first_name: address.firstname,
|
|
192
|
+
last_name: address.lastname,
|
|
193
|
+
address1: address.address1,
|
|
194
|
+
address2: address.address2,
|
|
195
|
+
city: address.city,
|
|
196
|
+
state: address.state_text,
|
|
197
|
+
zip: address.zipcode,
|
|
198
|
+
country: address.country.iso,
|
|
199
|
+
phone_number: address.phone
|
|
200
|
+
}
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def cim_gateway
|
|
204
|
+
@_cim_gateway ||= begin
|
|
205
|
+
ActiveMerchant::Billing::Base.gateway_mode = preferred_server.to_sym
|
|
206
|
+
gateway_options = options
|
|
207
|
+
gateway_options[:test_requests] = false # DD: never ever do test requests because just returns transaction_id = 0
|
|
208
|
+
ActiveMerchant::Billing::AuthorizeNetCimGateway.new(gateway_options)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
end
|
|
213
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class Gateway::BalancedGateway < Gateway
|
|
3
|
+
preference :login, :string
|
|
4
|
+
preference :on_behalf_of_uri, :string
|
|
5
|
+
|
|
6
|
+
def authorize(money, creditcard, gateway_options)
|
|
7
|
+
if token = creditcard.gateway_payment_profile_id
|
|
8
|
+
# The Balanced ActiveMerchant gateway supports passing the token directly as the creditcard parameter
|
|
9
|
+
creditcard = token
|
|
10
|
+
end
|
|
11
|
+
provider.authorize(money, creditcard, gateway_options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def capture(authorization, creditcard, gateway_options)
|
|
15
|
+
gateway_options[:on_behalf_of_uri] = self.preferred_on_behalf_of_uri
|
|
16
|
+
provider.capture((authorization.amount * 100).round, authorization.response_code, gateway_options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def create_profile(payment)
|
|
20
|
+
return unless payment.source.gateway_payment_profile_id.nil?
|
|
21
|
+
|
|
22
|
+
options = {}
|
|
23
|
+
options[:email] = payment.order.email
|
|
24
|
+
options[:login] = preferred_login
|
|
25
|
+
|
|
26
|
+
card_store_response = provider.store(payment.source, options)
|
|
27
|
+
card_uri = card_store_response.authorization.split(';').first
|
|
28
|
+
|
|
29
|
+
# A success just returns a string of the token. A failed request returns a bad request response with a message.
|
|
30
|
+
payment.source.update!(:gateway_payment_profile_id => card_uri)
|
|
31
|
+
rescue Error => ex
|
|
32
|
+
payment.send(:gateway_error, ex.message)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def options
|
|
36
|
+
super().merge(:test => self.preferred_test_mode)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def payment_profiles_supported?
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def purchase(money, creditcard, gateway_options)
|
|
44
|
+
if token = creditcard.gateway_payment_profile_id
|
|
45
|
+
# The Balanced ActiveMerchant gateway supports passing the token directly as the creditcard parameter
|
|
46
|
+
creditcard = token
|
|
47
|
+
end
|
|
48
|
+
provider.purchase(money, creditcard, gateway_options)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def provider_class
|
|
52
|
+
ActiveMerchant::Billing::BalancedGateway
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def credit(money, creditcard, response_code, gateway_options)
|
|
56
|
+
provider.refund(money, response_code, {})
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def void(response_code, creditcard, gateway_options)
|
|
60
|
+
provider.void(response_code)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
class Gateway::Banwire < Gateway
|
|
3
|
+
preference :login, :string
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def provider_class
|
|
7
|
+
ActiveMerchant::Billing::BanwireGateway
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def purchase(money, creditcard, gateway_options)
|
|
11
|
+
gateway_options[:description] = "Spree Order"
|
|
12
|
+
provider.purchase(money, creditcard, gateway_options)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|