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
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'pry'
|
|
3
|
+
|
|
4
|
+
describe Spree::Gateway::BraintreeGateway do
|
|
5
|
+
before do
|
|
6
|
+
country = Spree::Country.find_by(name: 'United States of America')
|
|
7
|
+
country.update(name: 'United States', iso_name: 'UNITED STATES', iso3: 'USA', iso: 'US', numcode: 840)
|
|
8
|
+
state = create(:state, name: 'Maryland', abbr: 'MD', country: country)
|
|
9
|
+
@address = create(:address,
|
|
10
|
+
firstname: 'John',
|
|
11
|
+
lastname: 'Doe',
|
|
12
|
+
address1: '1234 My Street',
|
|
13
|
+
address2: 'Apt 1',
|
|
14
|
+
city: 'Washington DC',
|
|
15
|
+
zipcode: '20123',
|
|
16
|
+
phone: '(555)555-5555',
|
|
17
|
+
state: state,
|
|
18
|
+
country: country)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Spree::Gateway.update_all(active: false)
|
|
22
|
+
@gateway = Spree::Gateway::BraintreeGateway.create!(name: 'Braintree Gateway', active: true, stores: [::Spree::Store.default])
|
|
23
|
+
@gateway.preferences = {
|
|
24
|
+
environment: 'sandbox',
|
|
25
|
+
merchant_id: 'zbn5yzq9t7wmwx42',
|
|
26
|
+
public_key: 'ym9djwqpkxbv3xzt',
|
|
27
|
+
private_key: '4ghghkyp2yy6yqc8'
|
|
28
|
+
}
|
|
29
|
+
@gateway.save!
|
|
30
|
+
|
|
31
|
+
with_payment_profiles_off do
|
|
32
|
+
order = create(:order_with_totals, bill_address: @address, ship_address: @address)
|
|
33
|
+
order.update_with_updater!
|
|
34
|
+
|
|
35
|
+
# Use a valid CC from braintree sandbox: https://www.braintreepayments.com/docs/ruby/reference/sandbox
|
|
36
|
+
|
|
37
|
+
@credit_card = create(:credit_card,
|
|
38
|
+
verification_value: '123',
|
|
39
|
+
number: '5555555555554444',
|
|
40
|
+
month: 9,
|
|
41
|
+
year: Time.now.year + 1,
|
|
42
|
+
name: 'John Doe',
|
|
43
|
+
cc_type: 'mastercard')
|
|
44
|
+
|
|
45
|
+
@payment = create(:payment, source: @credit_card, order: order, payment_method: @gateway, amount: 10.00)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe 'payment profile creation' do
|
|
50
|
+
before do
|
|
51
|
+
order = create(:order_with_totals, bill_address: @address, ship_address: @address)
|
|
52
|
+
order.update_with_updater!
|
|
53
|
+
|
|
54
|
+
@credit_card = create(:credit_card,
|
|
55
|
+
verification_value: '123',
|
|
56
|
+
number: '5555555555554444',
|
|
57
|
+
month: 9,
|
|
58
|
+
year: Time.now.year + 1,
|
|
59
|
+
name: 'John Doe',
|
|
60
|
+
cc_type: 'mastercard')
|
|
61
|
+
|
|
62
|
+
@payment = create(:payment, source: @credit_card, order: order, payment_method: @gateway, amount: 10.00)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when a credit card is created' do
|
|
66
|
+
it 'it has the address associated on the remote payment profile' do
|
|
67
|
+
remote_customer = @gateway.provider.instance_variable_get(:@braintree_gateway).customer.find(@credit_card.gateway_customer_profile_id)
|
|
68
|
+
remote_address = remote_customer.addresses.first rescue nil
|
|
69
|
+
expect(remote_address).not_to be_nil
|
|
70
|
+
expect(remote_address.street_address).to eq(@address.address1)
|
|
71
|
+
expect(remote_address.extended_address).to eq(@address.address2)
|
|
72
|
+
expect(remote_address.locality).to eq(@address.city)
|
|
73
|
+
expect(remote_address.region).to eq(@address.state.name)
|
|
74
|
+
expect(remote_address.country_code_alpha2).to eq(@address.country.iso)
|
|
75
|
+
expect(remote_address.postal_code).to eq(@address.zipcode)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe 'payment profile failure' do
|
|
82
|
+
before do
|
|
83
|
+
country = Spree::Country.default
|
|
84
|
+
state = country.states.first
|
|
85
|
+
address = create(:address,
|
|
86
|
+
firstname: 'John',
|
|
87
|
+
lastname: 'Doe',
|
|
88
|
+
address1: '1234 My Street',
|
|
89
|
+
address2: 'Apt 1',
|
|
90
|
+
city: 'Washington DC',
|
|
91
|
+
zipcode: '20123',
|
|
92
|
+
phone: '(555)555-5555',
|
|
93
|
+
state: state,
|
|
94
|
+
country: country
|
|
95
|
+
)
|
|
96
|
+
@address = address
|
|
97
|
+
|
|
98
|
+
@order = create(:order_with_totals, bill_address: address, ship_address: address)
|
|
99
|
+
@order.update_with_updater!
|
|
100
|
+
|
|
101
|
+
@credit_card = create(:credit_card,
|
|
102
|
+
verification_value: '123',
|
|
103
|
+
number: '5105105105105100',
|
|
104
|
+
month: 9,
|
|
105
|
+
year: Time.now.year + 1,
|
|
106
|
+
name: 'John Doe',
|
|
107
|
+
cc_type: 'mastercard')
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'should fail creation' do
|
|
111
|
+
expect{ create(:payment, source: @credit_card, order: @order, payment_method: @gateway, amount: 10.00) }.to raise_error Spree::Core::GatewayError
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe 'merchant_account_id' do
|
|
117
|
+
before do
|
|
118
|
+
@gateway.preferences[:merchant_account_id] = merchant_account_id
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context 'with merchant_account_id empty' do
|
|
122
|
+
let(:merchant_account_id) { '' }
|
|
123
|
+
|
|
124
|
+
it 'does not be present in options' do
|
|
125
|
+
expect(@gateway.options.keys.include?(:merchant_account_id)).to be false
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context 'with merchant_account_id set on gateway' do
|
|
130
|
+
let(:merchant_account_id) { 'test' }
|
|
131
|
+
|
|
132
|
+
it 'have a perferred_merchant_account_id' do
|
|
133
|
+
expect(@gateway.preferred_merchant_account_id).to eq merchant_account_id
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'have a preferences[:merchant_account_id]' do
|
|
137
|
+
expect(@gateway.preferences.keys.include?(:merchant_account_id)).to be true
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'is present in options' do
|
|
141
|
+
expect(@gateway.options.keys.include?(:merchant_account_id)).to be true
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context '.provider_class' do
|
|
147
|
+
it 'is a BraintreeBlue gateway' do
|
|
148
|
+
expect(@gateway.provider_class).to eq ::ActiveMerchant::Billing::BraintreeBlueGateway
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context '.payment_profiles_supported?' do
|
|
153
|
+
it 'return true' do
|
|
154
|
+
expect(@gateway.payment_profiles_supported?).to be true
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context 'preferences' do
|
|
159
|
+
it 'does not include server + test_mode' do
|
|
160
|
+
expect { @gateway.preferences.fetch(:server) }.to raise_error(StandardError)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
describe 'authorize' do
|
|
165
|
+
context "the credit card has a token" do
|
|
166
|
+
before(:each) do
|
|
167
|
+
@credit_card.update(gateway_payment_profile_id: 'test')
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'calls provider#authorize using the gateway_payment_profile_id' do
|
|
171
|
+
expect(@gateway.provider).to receive(:authorize).with(500, 'test', { payment_method_token: true } )
|
|
172
|
+
@gateway.authorize(500, @credit_card)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
context "the given credit card does not have a token" do
|
|
177
|
+
context "the credit card has a customer profile id" do
|
|
178
|
+
before(:each) do
|
|
179
|
+
@credit_card.update(gateway_customer_profile_id: '12345')
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'calls provider#authorize using the gateway_customer_profile_id' do
|
|
183
|
+
expect(@gateway.provider).to receive(:authorize).with(500, '12345', {})
|
|
184
|
+
@gateway.authorize(500, @credit_card)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context "no customer profile id" do
|
|
189
|
+
it 'calls provider#authorize with the credit card object' do
|
|
190
|
+
expect(@gateway.provider).to receive(:authorize).with(500, @credit_card, {})
|
|
191
|
+
@gateway.authorize(500, @credit_card)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it 'return a success response with an authorization code' do
|
|
197
|
+
result = @gateway.authorize(500, @credit_card)
|
|
198
|
+
|
|
199
|
+
expect(result.success?).to be true
|
|
200
|
+
expect(result.authorization).to match /\A\w{6,}\z/
|
|
201
|
+
expect(Braintree::Transaction::Status::Authorized).to eq Braintree::Transaction.find(result.authorization).status
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
shared_examples 'a valid credit card' do
|
|
205
|
+
it 'work through the spree payment interface' do
|
|
206
|
+
Spree::Config.set auto_capture: false
|
|
207
|
+
expect(@payment.log_entries.size).to eq(0)
|
|
208
|
+
|
|
209
|
+
@payment.process!
|
|
210
|
+
expect(@payment.log_entries.size).to eq(1)
|
|
211
|
+
expect(@payment.transaction_id).to match /\A\w{6,}\z/
|
|
212
|
+
expect(@payment.state).to eq 'pending'
|
|
213
|
+
|
|
214
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
215
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::Authorized
|
|
216
|
+
|
|
217
|
+
card_number = @credit_card.number[0..5] + '******' + @credit_card.number[-4..-1]
|
|
218
|
+
expect(transaction.credit_card_details.masked_number).to eq card_number
|
|
219
|
+
expect(transaction.credit_card_details.expiration_date).to eq "09/#{Time.now.year + 1}"
|
|
220
|
+
expect(transaction.customer_details.first_name).to eq 'John'
|
|
221
|
+
expect(transaction.customer_details.last_name).to eq 'Doe'
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context 'when the card is a mastercard' do
|
|
226
|
+
before do
|
|
227
|
+
@credit_card.number = '5555555555554444'
|
|
228
|
+
@credit_card.cc_type = 'mastercard'
|
|
229
|
+
@credit_card.save
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
it_behaves_like 'a valid credit card'
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
context 'when the card is a visa' do
|
|
236
|
+
before do
|
|
237
|
+
@credit_card.number = '4111111111111111'
|
|
238
|
+
@credit_card.cc_type = 'visa'
|
|
239
|
+
@credit_card.save
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it_behaves_like 'a valid credit card'
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
context 'when the card is an amex' do
|
|
246
|
+
before do
|
|
247
|
+
@credit_card.number = '378282246310005'
|
|
248
|
+
@credit_card.verification_value = '1234'
|
|
249
|
+
@credit_card.cc_type = 'amex'
|
|
250
|
+
@credit_card.save
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it_behaves_like 'a valid credit card'
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context 'when the card is a JCB' do
|
|
257
|
+
before do
|
|
258
|
+
@credit_card.number = '3530111333300000'
|
|
259
|
+
@credit_card.cc_type = 'jcb'
|
|
260
|
+
@credit_card.save
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it_behaves_like 'a valid credit card'
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
context 'when the card is a diners club' do
|
|
267
|
+
before do
|
|
268
|
+
@credit_card.number = '36050000000003'
|
|
269
|
+
@credit_card.cc_type = 'dinersclub'
|
|
270
|
+
@credit_card.save
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it_behaves_like 'a valid credit card'
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
describe 'capture' do
|
|
278
|
+
it 'do capture a previous authorization' do
|
|
279
|
+
@payment.process!
|
|
280
|
+
expect(@payment.log_entries.size).to eq(1)
|
|
281
|
+
expect(@payment.transaction_id).to match /\A\w{6,}\z/
|
|
282
|
+
|
|
283
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
284
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::Authorized
|
|
285
|
+
|
|
286
|
+
capture_result = @gateway.capture(@payment.amount, @payment.transaction_id)
|
|
287
|
+
expect(capture_result.success?).to be true
|
|
288
|
+
|
|
289
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
290
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::SubmittedForSettlement
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it 'raise an error if capture fails using spree interface' do
|
|
294
|
+
Spree::Config.set(auto_capture: false)
|
|
295
|
+
expect(@payment.log_entries.size).to eq(0)
|
|
296
|
+
|
|
297
|
+
@payment.process!
|
|
298
|
+
expect(@payment.log_entries.size).to eq(1)
|
|
299
|
+
|
|
300
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
301
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::Authorized
|
|
302
|
+
|
|
303
|
+
@payment.capture! # as done in PaymentsController#fire
|
|
304
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
305
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::SubmittedForSettlement
|
|
306
|
+
expect(@payment.completed?).to be true
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
context 'purchase' do
|
|
311
|
+
it 'return a success response with an authorization code' do
|
|
312
|
+
result = @gateway.purchase(500, @credit_card)
|
|
313
|
+
expect(result.success?).to be true
|
|
314
|
+
expect(result.authorization).to match /\A\w{6,}\z/
|
|
315
|
+
expect(Braintree::Transaction::Status::SubmittedForSettlement).to eq Braintree::Transaction.find(result.authorization).status
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it 'work through the spree payment interface with payment profiles' do
|
|
319
|
+
purchase_using_spree_interface
|
|
320
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
321
|
+
expect(transaction.credit_card_details.token).not_to be_nil
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it 'work through the spree payment interface without payment profiles' do
|
|
325
|
+
with_payment_profiles_off do
|
|
326
|
+
purchase_using_spree_interface(false)
|
|
327
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
328
|
+
expect(transaction.credit_card_details.token).to be_nil
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
context 'credit' do
|
|
334
|
+
it 'work through the spree interface' do
|
|
335
|
+
@payment.amount += 100.00
|
|
336
|
+
purchase_using_spree_interface
|
|
337
|
+
skip "Braintree does not provide a way to settle a transaction manually: https://twitter.com/braintree/status/446099537224933376"
|
|
338
|
+
credit_using_spree_interface
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
context 'void' do
|
|
343
|
+
before do
|
|
344
|
+
Spree::Config.set(auto_capture: true)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
it 'work through the spree credit_card / payment interface' do
|
|
348
|
+
expect(@payment.log_entries.size).to eq(0)
|
|
349
|
+
@payment.process!
|
|
350
|
+
|
|
351
|
+
expect(@payment.log_entries.size).to eq(1)
|
|
352
|
+
expect(@payment.transaction_id).to match /\A\w{6,}\z/
|
|
353
|
+
|
|
354
|
+
transaction = Braintree::Transaction.find(@payment.transaction_id)
|
|
355
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::SubmittedForSettlement
|
|
356
|
+
|
|
357
|
+
@payment.void_transaction!
|
|
358
|
+
transaction = Braintree::Transaction.find(transaction.id)
|
|
359
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::Voided
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
context 'update_card_number' do
|
|
364
|
+
it 'passes through gateway_payment_profile_id' do
|
|
365
|
+
credit_card = { 'token' => 'testing', 'last_4' => '1234', 'masked_number' => '555555******4444' }
|
|
366
|
+
@gateway.update_card_number(@payment.source, credit_card)
|
|
367
|
+
expect(@payment.source.gateway_payment_profile_id).to eq 'testing'
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def credit_using_spree_interface
|
|
372
|
+
expect(@payment.log_entries.size).to eq(1)
|
|
373
|
+
@payment.credit!
|
|
374
|
+
expect(@payment.log_entries.size).to eq(2)
|
|
375
|
+
|
|
376
|
+
# Let's get the payment record associated with the credit
|
|
377
|
+
@payment = @order.payments.last
|
|
378
|
+
expect(@payment.transaction_id).to match /\A\w{6,}\z/
|
|
379
|
+
|
|
380
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
381
|
+
expect(transaction.type).to eq Braintree::Transaction::Type::Credit
|
|
382
|
+
expect(transaction.status).to eq Braintree::Transaction::Status::SubmittedForSettlement
|
|
383
|
+
expect(transaction.credit_card_details.masked_number).to eq '555555******4444'
|
|
384
|
+
expect(transaction.credit_card_details.expiration_date).to eq "09/#{Time.now.year + 1}"
|
|
385
|
+
expect(transaction.customer_details.first_name).to eq 'John'
|
|
386
|
+
expect(transaction.customer_details.last_name).to eq 'Doe'
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def purchase_using_spree_interface(profile=true)
|
|
390
|
+
Spree::Config.set(auto_capture: true)
|
|
391
|
+
@payment.send(:create_payment_profile) if profile
|
|
392
|
+
@payment.log_entries.size == 0
|
|
393
|
+
@payment.process! # as done in PaymentsController#create
|
|
394
|
+
@payment.log_entries.size == 1
|
|
395
|
+
expect(@payment.transaction_id).to match /\A\w{6,}\z/
|
|
396
|
+
expect(@payment.state).to eq 'completed'
|
|
397
|
+
|
|
398
|
+
transaction = ::Braintree::Transaction.find(@payment.transaction_id)
|
|
399
|
+
expect(Braintree::Transaction::Status::SubmittedForSettlement).to eq transaction.status
|
|
400
|
+
expect(transaction.credit_card_details.masked_number).to eq '555555******4444'
|
|
401
|
+
expect(transaction.credit_card_details.expiration_date).to eq "09/#{Time.now.year + 1}"
|
|
402
|
+
expect(transaction.customer_details.first_name).to eq 'John'
|
|
403
|
+
expect(transaction.customer_details.last_name).to eq 'Doe'
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def with_payment_profiles_off(&block)
|
|
407
|
+
Spree::Gateway::BraintreeGateway.class_eval do
|
|
408
|
+
def payment_profiles_supported?
|
|
409
|
+
false
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
yield
|
|
413
|
+
ensure
|
|
414
|
+
Spree::Gateway::BraintreeGateway.class_eval do
|
|
415
|
+
def payment_profiles_supported?
|
|
416
|
+
true
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::CardSave do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'CardSave', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a CardSave gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::CardSaveGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::CyberSource do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'CyberSource') }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a CyberSource gateway' do
|
|
8
|
+
expect(subject.provider_class).to eq ::ActiveMerchant::Billing::CyberSourceGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::DataCash do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'DataCash', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a DataCash gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::DataCashGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::Epay do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'Epay', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a Epay gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::EpayGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::EwayRapid do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'eWAY Rapid', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
describe '#provider_class' do
|
|
7
|
+
it 'should be an eWAY Rapid gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::EwayRapidGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '#options' do
|
|
13
|
+
it 'should flag test option if preferred_test_mode is true' do
|
|
14
|
+
gateway.preferred_test_mode = true
|
|
15
|
+
expect(gateway.options[:test]).to be true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should unflag test option if preferred_test_mode is false' do
|
|
19
|
+
gateway.preferred_test_mode = false
|
|
20
|
+
expect(gateway.options[:test]).to be false
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::Eway do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'Eway', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a Eway gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::EwayGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context '.auto_capture?' do
|
|
13
|
+
it 'supports purchase method only' do
|
|
14
|
+
expect(gateway.auto_capture?).to be true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe 'options' do
|
|
19
|
+
it 'include :test => true in when :test_mode is true' do
|
|
20
|
+
gateway.preferred_test_mode = true
|
|
21
|
+
expect(gateway.options[:test]).to be true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'does not include :test when test_mode is false' do
|
|
25
|
+
gateway.preferred_test_mode = false
|
|
26
|
+
expect(gateway.options[:test]).to be false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::Maxipago do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'Maxipago') }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a Maxipago gateway' do
|
|
8
|
+
expect(subject.provider_class).to eq ::ActiveMerchant::Billing::MaxipagoGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
context '.auto_capture?' do
|
|
13
|
+
it 'return true' do
|
|
14
|
+
expect(subject.auto_capture?).to be true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::Moneris do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'Moneris', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a Moneris gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::MonerisGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::PayJunction do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'PayJunction', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a PayJunction gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::PayJunctionGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe 'options' do
|
|
13
|
+
it 'include :test => true in when :test_mode is true' do
|
|
14
|
+
gateway.preferred_test_mode = true
|
|
15
|
+
expect(gateway.options[:test]).to be true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'does not include :test when test_mode is false' do
|
|
19
|
+
gateway.preferred_test_mode = false
|
|
20
|
+
expect(gateway.options[:test]).to be false
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::PayPalGateway do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'PayPal', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a PayPal gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::PaypalGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::PayflowPro do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'PayflowPro', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a Payflow gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::PayflowGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe 'options' do
|
|
13
|
+
it 'include :test => true when :test_mode is true' do
|
|
14
|
+
gateway.preferred_test_mode = true
|
|
15
|
+
expect(gateway.options[:test]).to be true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'does not include :test when test_mode is false' do
|
|
19
|
+
gateway.preferred_test_mode = false
|
|
20
|
+
expect(gateway.options[:test]).to be false
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::Paymill do
|
|
4
|
+
let(:gateway) { described_class.create!(name: 'Paymill', stores: [::Spree::Store.default]) }
|
|
5
|
+
|
|
6
|
+
context '.provider_class' do
|
|
7
|
+
it 'is a Paymill gateway' do
|
|
8
|
+
expect(gateway.provider_class).to eq ::ActiveMerchant::Billing::PaymillGateway
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Gateway::PinGateway do
|
|
4
|
+
|
|
5
|
+
before do
|
|
6
|
+
Spree::Gateway.update_all(active: false)
|
|
7
|
+
@gateway = described_class.create!(name: 'Pin Gateway', active: true, stores: [::Spree::Store.default])
|
|
8
|
+
@gateway.set_preference(:api_key, 'W_VzkRCZSILiKWUS-dndUg')
|
|
9
|
+
@gateway.save!
|
|
10
|
+
|
|
11
|
+
country = create(:country, name: 'Australia', iso_name: 'Australia', iso3: 'AUS', iso: 'AU', numcode: 61)
|
|
12
|
+
state = create(:state, name: 'Victoria', abbr: 'VIC', country: country)
|
|
13
|
+
address = create(:address,
|
|
14
|
+
firstname: 'Ronald C',
|
|
15
|
+
lastname: 'Robot',
|
|
16
|
+
address1: '1234 My Street',
|
|
17
|
+
address2: 'Apt 1',
|
|
18
|
+
city: 'Melbourne',
|
|
19
|
+
zipcode: '3000',
|
|
20
|
+
phone: '88888888',
|
|
21
|
+
state: state,
|
|
22
|
+
country: country
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
order = create(:order_with_totals, bill_address: address, ship_address: address)
|
|
26
|
+
order.update_with_updater!
|
|
27
|
+
|
|
28
|
+
credit_card = create(:credit_card,
|
|
29
|
+
verification_value: '123',
|
|
30
|
+
number: '5520000000000000',
|
|
31
|
+
month: 5,
|
|
32
|
+
year: Time.now.year + 1,
|
|
33
|
+
name: 'Ronald C Robot',
|
|
34
|
+
cc_type: 'mastercard'
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
@payment = create(:payment, source: credit_card, order: order, payment_method: @gateway, amount: 10.00)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'can purchase' do
|
|
41
|
+
@payment.purchase!
|
|
42
|
+
expect(@payment.state).to eq 'completed'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Regression test for #106
|
|
46
|
+
it 'uses auto capturing' do
|
|
47
|
+
expect(@gateway.auto_capture?).to be true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'always uses purchase' do
|
|
51
|
+
@payment.should_receive(:purchase!)
|
|
52
|
+
@payment.process!
|
|
53
|
+
end
|
|
54
|
+
end
|