solidus_gateway 0.9.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.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +23 -0
  5. data/Gemfile +9 -0
  6. data/LICENSE.md +26 -0
  7. data/README.md +38 -0
  8. data/Rakefile +21 -0
  9. data/app/models/spree/billing_integration/skrill/quick_checkout.rb +48 -0
  10. data/app/models/spree/gateway/authorize_net.rb +31 -0
  11. data/app/models/spree/gateway/authorize_net_cim.rb +201 -0
  12. data/app/models/spree/gateway/balanced_gateway.rb +65 -0
  13. data/app/models/spree/gateway/banwire.rb +15 -0
  14. data/app/models/spree/gateway/beanstream.rb +193 -0
  15. data/app/models/spree/gateway/braintree_gateway.rb +184 -0
  16. data/app/models/spree/gateway/card_save.rb +10 -0
  17. data/app/models/spree/gateway/data_cash.rb +10 -0
  18. data/app/models/spree/gateway/eway.rb +20 -0
  19. data/app/models/spree/gateway/linkpoint.rb +28 -0
  20. data/app/models/spree/gateway/maxipago.rb +14 -0
  21. data/app/models/spree/gateway/migs.rb +11 -0
  22. data/app/models/spree/gateway/moneris.rb +10 -0
  23. data/app/models/spree/gateway/pay_junction.rb +16 -0
  24. data/app/models/spree/gateway/pay_pal_gateway.rb +12 -0
  25. data/app/models/spree/gateway/payflow_pro.rb +18 -0
  26. data/app/models/spree/gateway/paymill.rb +12 -0
  27. data/app/models/spree/gateway/pin_gateway.rb +60 -0
  28. data/app/models/spree/gateway/sage_pay.rb +11 -0
  29. data/app/models/spree/gateway/secure_pay_au.rb +10 -0
  30. data/app/models/spree/gateway/spreedly_core_gateway.rb +10 -0
  31. data/app/models/spree/gateway/stripe_gateway.rb +126 -0
  32. data/app/models/spree/gateway/usa_epay.rb +9 -0
  33. data/app/models/spree/gateway/worldpay.rb +91 -0
  34. data/app/models/spree/skrill_transaction.rb +19 -0
  35. data/bin/rails +7 -0
  36. data/circle.yml +6 -0
  37. data/config/locales/bg.yml +11 -0
  38. data/config/locales/de.yml +11 -0
  39. data/config/locales/en.yml +30 -0
  40. data/config/locales/sv.yml +11 -0
  41. data/config/routes.rb +12 -0
  42. data/db/migrate/20111118164631_create_skrill_transactions.rb +14 -0
  43. data/db/migrate/20121017004102_update_braintree_payment_method_type.rb +9 -0
  44. data/db/migrate/20130213222555_update_stripe_payment_method_type.rb +9 -0
  45. data/db/migrate/20130415222802_update_balanced_payment_method_type.rb +9 -0
  46. data/db/migrate/20131008221012_update_paypal_payment_method_type.rb +9 -0
  47. data/db/migrate/20131112133401_migrate_stripe_preferences.rb +8 -0
  48. data/lib/active_merchant/billing/skrill.rb +18 -0
  49. data/lib/assets/javascripts/spree/frontend/solidus_gateway.js +1 -0
  50. data/lib/assets/stylesheets/spree/frontend/solidus_gateway.css +3 -0
  51. data/lib/controllers/frontend/spree/checkout_controller_decorator.rb +51 -0
  52. data/lib/controllers/frontend/spree/skrill_status_controller.rb +39 -0
  53. data/lib/generators/solidus_gateway/install/install_generator.rb +28 -0
  54. data/lib/solidus_gateway.rb +4 -0
  55. data/lib/spree_gateway/engine.rb +67 -0
  56. data/lib/views/backend/spree/admin/log_entries/_braintree.html.erb +31 -0
  57. data/lib/views/backend/spree/admin/log_entries/_stripe.html.erb +28 -0
  58. data/lib/views/backend/spree/admin/payments/source_forms/_quickcheckout.html.erb +8 -0
  59. data/lib/views/backend/spree/admin/payments/source_forms/_stripe.html.erb +1 -0
  60. data/lib/views/backend/spree/admin/payments/source_views/_quickcheckout.html.erb +39 -0
  61. data/lib/views/backend/spree/admin/payments/source_views/_stripe.html.erb +1 -0
  62. data/lib/views/frontend/spree/checkout/payment/_quickcheckout.html.erb +26 -0
  63. data/lib/views/frontend/spree/checkout/payment/_stripe.html.erb +80 -0
  64. data/solidus_gateway.gemspec +33 -0
  65. data/spec/factories/skrill_factory.rb +6 -0
  66. data/spec/features/stripe_checkout_spec.rb +78 -0
  67. data/spec/lib/active_merchant/billing_skrill_spec.rb +18 -0
  68. data/spec/models/billing_integration/skrill_quick_checkout_spec.rb +11 -0
  69. data/spec/models/gateway/authorize_net_cim_spec.rb +29 -0
  70. data/spec/models/gateway/authorize_net_spec.rb +23 -0
  71. data/spec/models/gateway/balanced_gateway_spec.rb +17 -0
  72. data/spec/models/gateway/banwire_spec.rb +11 -0
  73. data/spec/models/gateway/beanstream_spec.rb +17 -0
  74. data/spec/models/gateway/braintree_gateway_spec.rb +437 -0
  75. data/spec/models/gateway/card_save_spec.rb +11 -0
  76. data/spec/models/gateway/data_cache_spec.rb +11 -0
  77. data/spec/models/gateway/eway_spec.rb +29 -0
  78. data/spec/models/gateway/linkpoint_spec.rb +62 -0
  79. data/spec/models/gateway/maxipago_spec.rb +17 -0
  80. data/spec/models/gateway/moneris_spec.rb +11 -0
  81. data/spec/models/gateway/pay_junction_spec.rb +23 -0
  82. data/spec/models/gateway/pay_pal_spec.rb +11 -0
  83. data/spec/models/gateway/payflow_pro_spec.rb +23 -0
  84. data/spec/models/gateway/paymill_spec.rb +11 -0
  85. data/spec/models/gateway/pin_gateway_spec.rb +55 -0
  86. data/spec/models/gateway/sage_pay_spec.rb +11 -0
  87. data/spec/models/gateway/secure_pay_au_spec.rb +11 -0
  88. data/spec/models/gateway/stripe_gateway_spec.rb +200 -0
  89. data/spec/models/gateway/usa_epay_spec.rb +49 -0
  90. data/spec/models/gateway/worldpay_spec.rb +11 -0
  91. data/spec/models/skrill_transaction_spec.rb +9 -0
  92. data/spec/spec_helper.rb +50 -0
  93. metadata +317 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ce4994806351d5327bf00d2f9bf191338bbeecb
4
+ data.tar.gz: c5bbc490c8db7133c29e686a9d0bb76e201863ca
5
+ SHA512:
6
+ metadata.gz: 5470ee6c4a91f27f7ad7ba187ab7978f879331f3ea6235520ed3940988432a3b3ac81b132371ea1e261e3ce0ad0bec3ae5041cd99aadd6dc794f7e98f29c6fa7
7
+ data.tar.gz: 158ab601aa3a283aefe1b5f21b40b8e2de54c3fccb701dc3271bc2d467a8d5849fd8f2ecfa5b1a036ec1ab3e4c1e2766b33f8d528205a3503587510f0a708b85
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ .DS_Store
5
+ tmp
6
+ spec/dummy
7
+ Gemfile.lock
8
+ .rvmrc
9
+ coverage
10
+ .ruby-version
11
+ pkg
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+ before_script:
3
+ - sh -e /etc/init.d/xvfb start
4
+ - export DISPLAY=:99.0
5
+ - bundle exec rake test_app
6
+ env:
7
+ - DB=sqlite
8
+ - DB=mysql
9
+ - DB=postgres
10
+ script:
11
+ - bundle exec rspec spec
12
+ notifications:
13
+ email:
14
+ - ryan@spreecommerce.com
15
+ irc:
16
+ use_notice: true
17
+ skip_join: true
18
+ channels:
19
+ - "irc.freenode.org#spree"
20
+ rvm:
21
+ - 1.9.3
22
+ - 2.0.0
23
+ - 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "solidus", github: "solidusio/solidus", branch: "v1.0"
4
+
5
+ group :development, :test do
6
+ gem "pry-rails"
7
+ end
8
+
9
+ gemspec
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,38 @@
1
+ Solidus Gateway
2
+ ===============
3
+
4
+ Community supported Solidus Payment Method Gateways. It works as a wrapper for
5
+ active_merchant gateway. Note that for some gateways you might still need to
6
+ add another gem to your Gemfile to make it work. For example active_merchant
7
+ require `braintree` but it doesn't include that gem on its gemspec. So you
8
+ need to manually add it to your rails app Gemfile.
9
+
10
+ Installation
11
+ ------------
12
+
13
+ In your Gemfile:
14
+
15
+ ```ruby
16
+ gem "solidus_gateway"
17
+ ```
18
+
19
+ Then run from the command line:
20
+
21
+ ```shell
22
+ bundle install
23
+ rails g solidus_gateway:install
24
+ ```
25
+
26
+ Finally, make sure to **restart your app**. Navigate to *Configuration >
27
+ Payment Methods > New Payment Method* in the admin panel and you should see
28
+ that a bunch of additional gateways have been added to the list.
29
+
30
+ Testing
31
+ -------
32
+
33
+ Then just run the following to automatically build a dummy app if necessary and
34
+ run the tests:
35
+
36
+ ```shell
37
+ bundle exec rake
38
+ ```
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/common_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default do
10
+ if Dir["spec/dummy"].empty?
11
+ Rake::Task[:test_app].invoke
12
+ Dir.chdir("../../")
13
+ end
14
+ Rake::Task[:spec].invoke
15
+ end
16
+
17
+ desc "Generates a dummy app for testing"
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'solidus_gateway'
20
+ Rake::Task['common:test_app'].invoke
21
+ end
@@ -0,0 +1,48 @@
1
+ module Spree
2
+ class BillingIntegration::Skrill::QuickCheckout < BillingIntegration
3
+ preference :merchant_id, :string
4
+ preference :language, :string, :default => 'EN'
5
+ preference :currency, :string, :default => 'EUR'
6
+ preference :payment_options, :string, :default => 'ACC'
7
+ preference :pay_to_email, :string , :default => 'your@merchant.email_here'
8
+
9
+ def provider_class
10
+ ActiveMerchant::Billing::Skrill
11
+ end
12
+
13
+ def redirect_url(order, opts = {})
14
+ opts.merge! self.preferences
15
+
16
+ set_global_options(opts)
17
+
18
+ opts[:detail1_text] = order.number
19
+ opts[:detail1_description] = "Order:"
20
+
21
+ opts[:pay_from_email] = order.email
22
+ opts[:firstname] = order.bill_address.firstname
23
+ opts[:lastname] = order.bill_address.lastname
24
+ opts[:address] = order.bill_address.address1
25
+ opts[:address2] = order.bill_address.address2
26
+ opts[:phone_number] = order.bill_address.phone.gsub(/\D/,'') if order.bill_address.phone
27
+ opts[:city] = order.bill_address.city
28
+ opts[:postal_code] = order.bill_address.zipcode
29
+ opts[:state] = order.bill_address.state.nil? ? order.bill_address.state_name.to_s : order.bill_address.state.abbr
30
+ opts[:country] = order.bill_address.country.name
31
+ opts[:pay_to_email] = self.preferred_pay_to_email
32
+ opts[:hide_login] = 1
33
+ opts[:merchant_fields] = 'platform,order_id,payment_method_id'
34
+ opts[:platform] = 'Spree'
35
+ opts[:order_id] = order.number
36
+
37
+ skrill = self.provider
38
+ skrill.payment_url(opts)
39
+ end
40
+
41
+ private
42
+ def set_global_options(opts)
43
+ opts[:recipient_description] = Spree::Config[:site_name]
44
+ opts[:payment_methods] = self.preferred_payment_options
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module Spree
2
+ class Gateway::AuthorizeNet < Gateway
3
+ preference :login, :string
4
+ preference :password, :string
5
+
6
+ def provider_class
7
+ ActiveMerchant::Billing::AuthorizeNetGateway
8
+ end
9
+
10
+ def options_with_test_preference
11
+ options_without_test_preference.merge(test: self.preferred_test_mode)
12
+ end
13
+ alias_method_chain :options, :test_preference
14
+
15
+ def credit(amount, response_code, refund, gateway_options = {})
16
+ gateway_options[:card_number] = refund[:originator].payment.source.last_digits
17
+ auth_net_gateway.refund(amount, response_code, gateway_options)
18
+ end
19
+
20
+ private
21
+
22
+ def auth_net_gateway
23
+ @_auth_net_gateway ||= begin
24
+ ActiveMerchant::Billing::Base.gateway_mode = preferred_server.to_sym
25
+ gateway_options = options
26
+ gateway_options[:test_requests] = false # DD: never ever do test requests because just returns transaction_id = 0
27
+ ActiveMerchant::Billing::AuthorizeNetGateway.new(gateway_options)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,201 @@
1
+ module Spree
2
+ class Gateway::AuthorizeNetCim < Gateway
3
+ preference :login, :string
4
+ preference :password, :string
5
+ preference :test_mode, :boolean, :default => false
6
+ preference :validate_on_profile_create, :boolean, :default => false
7
+
8
+ def provider_class
9
+ self.class
10
+ end
11
+
12
+ def options
13
+ # add :test key in the options hash, as that is what the ActiveMerchant::Billing::AuthorizeNetGateway expects
14
+ if self.preferred_test_mode
15
+ self.preferences[:test] = true
16
+ else
17
+ self.preferences.delete(:test)
18
+ end
19
+
20
+ super
21
+ end
22
+
23
+ def authorize(amount, creditcard, gateway_options)
24
+ create_transaction(amount, creditcard, :auth_only, transaction_options(gateway_options))
25
+ end
26
+
27
+ def purchase(amount, creditcard, gateway_options)
28
+ create_transaction(amount, creditcard, :auth_capture, transaction_options(gateway_options))
29
+ end
30
+
31
+ # capture is only one where source is not passed in for payment profile
32
+ def capture(amount, response_code, gateway_options)
33
+ # no credit card needed
34
+ create_transaction(amount, nil, :prior_auth_capture, trans_id: response_code)
35
+ end
36
+
37
+ def credit(amount, creditcard, response_code, gateway_options = {})
38
+ create_transaction(amount, creditcard, :refund, transaction_options(gateway_options).merge(trans_id: response_code))
39
+ end
40
+
41
+ def void(response_code, creditcard, gateway_options = {})
42
+ create_transaction(nil, creditcard, :void, transaction_options(gateway_options).merge(trans_id: response_code))
43
+ end
44
+
45
+ def cancel(response_code)
46
+ # From: http://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/Refunds-in-Retail-A-user-friendly-approach-using-AIM/ba-p/9848
47
+ # DD: if unsettled, void needed
48
+ response = void(response_code, nil)
49
+ # DD: if settled, credit/refund needed
50
+ response = credit(nil, nil, response_code) unless response.success?
51
+
52
+ response
53
+ end
54
+
55
+ def payment_profiles_supported?
56
+ true
57
+ end
58
+
59
+ # Create a new CIM customer profile ready to accept a payment. Called by Spree::Payment on after_save.
60
+ def create_profile(payment)
61
+ if payment.source.gateway_customer_profile_id.nil?
62
+ profile_hash = create_customer_profile(payment)
63
+ payment.source.update_attributes(gateway_customer_profile_id: profile_hash[:customer_profile_id], gateway_payment_profile_id: profile_hash[:customer_payment_profile_id])
64
+ end
65
+ end
66
+
67
+ # Get the CIM payment profile; Needed for updates.
68
+ def get_profile(payment)
69
+ if payment.source.has_payment_profile?
70
+ profile = cim_gateway.get_customer_profile({
71
+ customer_profile_id: payment.source.gateway_customer_profile_id
72
+ })
73
+ if profile
74
+ profile.params['profile'].deep_symbolize_keys!
75
+ end
76
+ end
77
+ end
78
+
79
+ # Get the CIM payment profile; Needed for updates.
80
+ def get_payment_profile(payment)
81
+ if payment.source.has_payment_profile?
82
+ profile = cim_gateway.get_customer_payment_profile({
83
+ customer_profile_id: payment.source.gateway_customer_profile_id,
84
+ customer_payment_profile_id: payment.source.gateway_payment_profile_id
85
+ })
86
+ if profile
87
+ profile.params['payment_profile'].deep_symbolize_keys!
88
+ end
89
+ end
90
+ end
91
+
92
+ # Update billing address on the CIM payment profile
93
+ def update_payment_profile(payment)
94
+ if payment.source.has_payment_profile?
95
+ if hash = get_payment_profile(payment)
96
+ hash[:bill_to] = generate_address_hash(payment.order.bill_address)
97
+ if hash[:payment][:credit_card]
98
+ # activemerchant expects a credit card object with 'number', 'year', 'month', and 'verification_value?' defined
99
+ payment.source.define_singleton_method(:number) { "XXXXXXXXX#{payment.source.last_digits}" }
100
+ hash[:payment][:credit_card] = payment.source
101
+ end
102
+ cim_gateway.update_customer_payment_profile({
103
+ customer_profile_id: payment.source.gateway_customer_profile_id,
104
+ payment_profile: hash
105
+ })
106
+ end
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def transaction_options(gateway_options = {})
113
+ { order: { invoice_number: gateway_options[:order_id] } }
114
+ end
115
+
116
+ # Create a transaction on a creditcard
117
+ # Set up a CIM profile for the card if one doesn't exist
118
+ # Valid transaction_types are :auth_only, :capture_only and :auth_capture
119
+ def create_transaction(amount, creditcard, transaction_type, options = {})
120
+ creditcard.save if creditcard
121
+
122
+ transaction_options = {
123
+ type: transaction_type
124
+ }.update(options)
125
+
126
+ if amount
127
+ amount = "%.2f" % (amount / 100.0) # This gateway requires formated decimal, not cents
128
+ transaction_options.update({
129
+ amount: amount
130
+ })
131
+ end
132
+
133
+ transaction_options.update({
134
+ customer_profile_id: creditcard.gateway_customer_profile_id,
135
+ customer_payment_profile_id: creditcard.gateway_payment_profile_id
136
+ }) if creditcard
137
+
138
+ logger.debug("\nAuthorize Net CIM Request")
139
+ logger.debug(" transaction_options: #{transaction_options.inspect}")
140
+ t = cim_gateway.create_customer_profile_transaction(:transaction => transaction_options)
141
+ logger.debug("\nAuthorize Net CIM Response")
142
+ logger.debug(" response: #{t.inspect}\n")
143
+ t
144
+ end
145
+
146
+ # Create a new CIM customer profile ready to accept a payment
147
+ def create_customer_profile(payment)
148
+ options = options_for_create_customer_profile(payment)
149
+ response = cim_gateway.create_customer_profile(options)
150
+ if response.success?
151
+ { customer_profile_id: response.params['customer_profile_id'],
152
+ customer_payment_profile_id: response.params['customer_payment_profile_id_list'].values.first }
153
+ else
154
+ payment.send(:gateway_error, response)
155
+ end
156
+ end
157
+
158
+ def options_for_create_customer_profile(payment)
159
+ if payment.is_a? CreditCard
160
+ info = { bill_to: generate_address_hash(payment.address),
161
+ payment: { credit_card: payment } }
162
+ else
163
+ info = { bill_to: generate_address_hash(payment.order.bill_address),
164
+ payment: { credit_card: payment.source } }
165
+ end
166
+ validation_mode = preferred_validate_on_profile_create ? preferred_server.to_sym : :none
167
+
168
+ { profile: { merchant_customer_id: "#{Time.now.to_f}",
169
+ ship_to_list: generate_address_hash(payment.order.ship_address),
170
+ email: payment.order.email,
171
+ payment_profiles: info },
172
+ validation_mode: validation_mode }
173
+ end
174
+
175
+ # As in PaymentGateway but with separate name fields
176
+ def generate_address_hash(address)
177
+ return {} if address.nil?
178
+ {
179
+ first_name: address.firstname,
180
+ last_name: address.lastname,
181
+ address1: address.address1,
182
+ address2: address.address2,
183
+ city: address.city,
184
+ state: address.state_text,
185
+ zip: address.zipcode,
186
+ country: address.country.iso,
187
+ phone_number: address.phone
188
+ }
189
+ end
190
+
191
+ def cim_gateway
192
+ @_cim_gateway ||= begin
193
+ ActiveMerchant::Billing::Base.gateway_mode = preferred_server.to_sym
194
+ gateway_options = options
195
+ gateway_options[:test_requests] = false # DD: never ever do test requests because just returns transaction_id = 0
196
+ ActiveMerchant::Billing::AuthorizeNetCimGateway.new(gateway_options)
197
+ end
198
+ end
199
+
200
+ end
201
+ end
@@ -0,0 +1,65 @@
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_attributes!(:gateway_payment_profile_id => card_uri)
31
+ rescue Error => ex
32
+ payment.send(:gateway_error, ex.message)
33
+ end
34
+
35
+ def options_with_test_preference
36
+ options_without_test_preference.merge(:test => self.preferred_test_mode)
37
+ end
38
+ alias_method_chain :options, :test_preference
39
+
40
+ def payment_profiles_supported?
41
+ true
42
+ end
43
+
44
+ def purchase(money, creditcard, gateway_options)
45
+ if token = creditcard.gateway_payment_profile_id
46
+ # The Balanced ActiveMerchant gateway supports passing the token directly as the creditcard parameter
47
+ creditcard = token
48
+ end
49
+ provider.purchase(money, creditcard, gateway_options)
50
+ end
51
+
52
+ def provider_class
53
+ ActiveMerchant::Billing::BalancedGateway
54
+ end
55
+
56
+ def credit(money, creditcard, response_code, gateway_options)
57
+ provider.refund(money, response_code, {})
58
+ end
59
+
60
+ def void(response_code, creditcard, gateway_options)
61
+ provider.void(response_code)
62
+ end
63
+
64
+ end
65
+ end