solidus_open_pay 1.0.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 (53) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +61 -0
  3. data/.github/stale.yml +1 -0
  4. data/.gitignore +22 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +249 -0
  7. data/Gemfile +49 -0
  8. data/LICENSE +26 -0
  9. data/README.md +37 -0
  10. data/Rakefile +11 -0
  11. data/app/assets/images/solidus_open_pay/.gitkeep +0 -0
  12. data/app/assets/javascripts/spree/backend/solidus_open_pay.js +2 -0
  13. data/app/assets/javascripts/spree/frontend/solidus_open_pay.js +2 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_openpay.css +3 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_openpay.css +3 -0
  16. data/app/models/concerns/solidus_open_pay/attributes_access.rb +83 -0
  17. data/app/models/solidus_open_pay/builders/charge.rb +72 -0
  18. data/app/models/solidus_open_pay/gateway.rb +98 -0
  19. data/app/models/solidus_open_pay/payment_method.rb +30 -0
  20. data/app/models/solidus_open_pay/payment_source.rb +25 -0
  21. data/app/models/solidus_open_pay/response.rb +63 -0
  22. data/app/views/checkouts/payment/_open_pay.html.erb +171 -0
  23. data/app/views/spree/admin/payments/source_views/_open_pay.html.erb +21 -0
  24. data/app/views/spree/api/payments/source_views/_open_pay.json.jbuilder +3 -0
  25. data/app/views/spree/checkout/payment/_open_pay.html.erb +183 -0
  26. data/bin/console +17 -0
  27. data/bin/rails +7 -0
  28. data/bin/rails-engine +13 -0
  29. data/bin/rails-sandbox +16 -0
  30. data/bin/rake +7 -0
  31. data/bin/sandbox +86 -0
  32. data/bin/setup +8 -0
  33. data/config/locales/en.yml +44 -0
  34. data/config/locales/es-MX.yml +44 -0
  35. data/config/locales/es.yml +44 -0
  36. data/config/routes.rb +7 -0
  37. data/db/migrate/20241120003957_add_open_pay_sources.rb +23 -0
  38. data/lib/generators/solidus_open_pay/install/install_generator.rb +113 -0
  39. data/lib/generators/solidus_open_pay/install/templates/config/initializers/solidus_open_pay.rb +6 -0
  40. data/lib/solidus_open_pay/configuration.rb +27 -0
  41. data/lib/solidus_open_pay/engine.rb +38 -0
  42. data/lib/solidus_open_pay/testing_support/factories.rb +34 -0
  43. data/lib/solidus_open_pay/version.rb +5 -0
  44. data/lib/solidus_open_pay.rb +5 -0
  45. data/lib/tasks/solidus_openpay_tasks.rake +6 -0
  46. data/solidus_open_pay.gemspec +39 -0
  47. data/spec/models/solidus_open_pay/payment_method_spec.rb +417 -0
  48. data/spec/solidus_open_pay_spec_helper.rb +5 -0
  49. data/spec/spec_helper.rb +34 -0
  50. data/spec/support/factory_bot.rb +10 -0
  51. data/spec/support/solidus.rb +18 -0
  52. data/spec/support/solidus_open_pay/gateway_helpers.rb +27 -0
  53. metadata +197 -0
@@ -0,0 +1,417 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # rubocop:disable Style/HashSyntax
6
+ RSpec.describe SolidusOpenPay::PaymentMethod, type: :model do
7
+ let(:user) { create(:user) }
8
+ let(:address) do
9
+ create(:address)
10
+ end
11
+ let(:open_pay_payment_method) do
12
+ create(:open_pay_payment_method)
13
+ end
14
+ let(:source) do
15
+ create(
16
+ :open_pay_payment_source,
17
+ payment_method: open_pay_payment_method
18
+ )
19
+ end
20
+ let(:order) do
21
+ create(
22
+ :order_with_line_items,
23
+ user: user,
24
+ ship_address: address,
25
+ bill_address: address
26
+ )
27
+ end
28
+ let(:payment) do
29
+ order.payments.create!(
30
+ payment_method: open_pay_payment_method,
31
+ source: source,
32
+ amount: 55
33
+ )
34
+ end
35
+
36
+ describe 'preferences' do
37
+ describe 'saving preference hashes as strings' do
38
+ context 'with valid hash syntax' do
39
+ let(:update_params) do
40
+ {
41
+ :server => 'test',
42
+ :test_mode => true,
43
+ :merchant_id => '1',
44
+ :private_key => 'sk_xxxx1',
45
+ :public_key => 'pk_xxxx1',
46
+ :country => '',
47
+ :test => true
48
+ }
49
+ end
50
+
51
+ before do
52
+ open_pay_payment_method.update(preferences: update_params)
53
+ end
54
+
55
+ it 'successfully updates the preference' do
56
+ expect(open_pay_payment_method.preferred_merchant_id)
57
+ .to eq('1')
58
+ expect(open_pay_payment_method.preferred_private_key)
59
+ .to eq('sk_xxxx1')
60
+ expect(open_pay_payment_method.preferred_public_key)
61
+ .to eq('pk_xxxx1')
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ describe '#authorize' do
68
+ let(:authorization_response) do
69
+ {
70
+ 'id' => 'triitam7thhlqfvunpsd',
71
+ 'authorization' => '801585',
72
+ 'operation_type' => 'in',
73
+ 'transaction_type' => 'charge',
74
+ 'status' => 'in_progress',
75
+ 'conciliated' => false,
76
+ 'creation_date' => '2024-11-22T13:58:05-06:00',
77
+ 'operation_date' => '2024-11-22T13:58:05-06:00',
78
+ 'description' => 'Cargo inicial',
79
+ 'error_message' => nil,
80
+ 'order_id' => 'R709462453-YBR2C8GT',
81
+ 'card' => {
82
+ 'type' => 'credit',
83
+ 'brand' => 'visa',
84
+ 'address' => nil,
85
+ 'card_number' => '424242XXXXXX4242',
86
+ 'holder_name' => 'User Test',
87
+ 'expiration_year' => '29',
88
+ 'expiration_month' => '09',
89
+ 'allows_charges' => true,
90
+ 'allows_payouts' => false,
91
+ 'bank_name' => 'BANCOMER',
92
+ 'points_type' => 'bancomer',
93
+ 'card_business_type' => nil,
94
+ 'dcc' => nil,
95
+ 'bank_code' => '012',
96
+ 'points_card' => true
97
+ },
98
+ 'gateway_card_present' => 'BANCOMER',
99
+ 'amount' => 10.0,
100
+ 'customer' => {
101
+ 'name' => 'User',
102
+ 'last_name' => 'Test',
103
+ 'email' => 'admin@example.com',
104
+ 'phone_number' => nil,
105
+ 'address' => nil,
106
+ 'creation_date' => '2024-11-22T13:58:05-06:00',
107
+ 'external_id' => nil,
108
+ 'clabe' => nil
109
+ },
110
+ 'currency' => 'MXN',
111
+ 'method' => 'card'
112
+ }
113
+ end
114
+
115
+ before do
116
+ allow_any_instance_of(OpenpayApi).to receive(:create)
117
+ .with(:charges) { Charges.new({}, nil, nil) }
118
+ allow_any_instance_of(Charges)
119
+ .to receive(:create) { authorization_response }
120
+ end
121
+
122
+ it 'sends an authorize request to open pay' do
123
+ response = open_pay_payment_method.authorize(
124
+ 1000,
125
+ source,
126
+ {
127
+ order_id: order.number,
128
+ email: user.email
129
+ }
130
+ )
131
+
132
+ expect(response).to be_success
133
+ expect(response.class).to be(SolidusOpenPay::Response)
134
+ end
135
+ end
136
+
137
+ describe '#capture' do
138
+ let(:capture_response) do
139
+ {
140
+ 'id' => 'triitam7thhlqfvunpsd',
141
+ 'authorization' => '801585',
142
+ 'operation_type' => 'in',
143
+ 'transaction_type' => 'charge',
144
+ 'status' => 'completed',
145
+ 'conciliated' => false,
146
+ 'creation_date' => '2024-11-22T13:58:05-06:00',
147
+ 'operation_date' => '2024-11-22T14:01:19-06:00',
148
+ 'description' => 'Cargo inicial',
149
+ 'error_message' => nil,
150
+ 'order_id' => 'R709462453-YBR2C8GT',
151
+ 'card' => {
152
+ 'type' => 'credit',
153
+ 'brand' => 'visa',
154
+ 'address' => nil,
155
+ 'card_number' => '424242XXXXXX4242',
156
+ 'holder_name' => 'User Test',
157
+ 'expiration_year' => '29',
158
+ 'expiration_month' => '09',
159
+ 'allows_charges' => true,
160
+ 'allows_payouts' => false,
161
+ 'bank_name' => 'BANCOMER',
162
+ 'points_type' => 'bancomer',
163
+ 'card_business_type' => nil,
164
+ 'dcc' => nil,
165
+ 'bank_code' => '012',
166
+ 'points_card' => true
167
+ },
168
+ 'fee' => {
169
+ 'amount' => 2.79,
170
+ 'tax' => 0.4464,
171
+ 'surcharge' => nil,
172
+ 'base_commission' => nil,
173
+ 'currency' => 'MXN'
174
+ },
175
+ 'amount' => 10.0,
176
+ 'customer' => {
177
+ 'name' => 'User',
178
+ 'last_name' => 'Test',
179
+ 'email' => 'admin@example.com',
180
+ 'phone_number' => nil,
181
+ 'address' => nil,
182
+ 'creation_date' => '2024-11-22T13:58:06-06:00',
183
+ 'external_id' => nil,
184
+ 'clabe' => nil
185
+ },
186
+ 'currency' => 'MXN',
187
+ 'method' => 'card'
188
+ }
189
+ end
190
+
191
+ before do
192
+ allow_any_instance_of(Charges)
193
+ .to receive(:capture) { RestClient::Response.new }
194
+ allow_any_instance_of(RestClient::Response)
195
+ .to receive(:body) { capture_response.to_json }
196
+ end
197
+
198
+ it 'sends an capture request to open pay' do
199
+ response = open_pay_payment_method.capture(
200
+ 1000,
201
+ 'triitam7thhlqfvunpsd',
202
+ {
203
+ order_id: order.number,
204
+ email: user.email
205
+ }
206
+ )
207
+
208
+ expect(response).to be_success
209
+ expect(response.class).to be(SolidusOpenPay::Response)
210
+ end
211
+ end
212
+
213
+ describe '#purchase' do
214
+ let(:purchase_response) do
215
+ {
216
+ 'id' => 'tr6jtfjrksvqe1ifqpvy',
217
+ 'authorization' => '801585',
218
+ 'operation_type' => 'in',
219
+ 'transaction_type' => 'charge',
220
+ 'status' => 'completed',
221
+ 'conciliated' => false,
222
+ 'creation_date' => '2024-11-26T16:26:08-06:00',
223
+ 'operation_date' => '2024-11-26T16:26:25-06:00',
224
+ 'description' => 'Cargo inicial',
225
+ 'error_message' => nil,
226
+ 'order_id' => 'R069147136-8AK5U5HC',
227
+ 'card' => {
228
+ 'type' => 'credit',
229
+ 'brand' => 'visa',
230
+ 'address' => nil,
231
+ 'card_number' => '424242XXXXXX4242',
232
+ 'holder_name' => 'User Test',
233
+ 'expiration_year' => '29',
234
+ 'expiration_month' => '09',
235
+ 'allows_charges' => true,
236
+ 'allows_payouts' => false,
237
+ 'bank_name' => 'BANCOMER',
238
+ 'points_type' => 'bancomer',
239
+ 'card_business_type' => nil,
240
+ 'dcc' => nil,
241
+ 'points_card' => true,
242
+ 'bank_code' => '012'
243
+ },
244
+ 'amount' => 10.0,
245
+ 'currency' => 'MXN',
246
+ 'customer' => {
247
+ 'name' => 'User',
248
+ 'last_name' => 'Test',
249
+ 'email' => 'pedidos@donmanolito.com',
250
+ 'phone_number' => nil,
251
+ 'address' => nil,
252
+ 'creation_date' => '2024-11-26T16:26:08-06:00',
253
+ 'external_id' => nil,
254
+ 'clabe' => nil
255
+ },
256
+ 'fee' => {
257
+ 'amount' => 2.79,
258
+ 'tax' => 0.4464,
259
+ 'surcharge' => nil,
260
+ 'base_commission' => nil,
261
+ 'currency' => 'MXN'
262
+ },
263
+ 'method' => 'card'
264
+ }
265
+ end
266
+
267
+ before do
268
+ allow_any_instance_of(OpenpayApi).to receive(:create)
269
+ .with(:charges) { Charges.new({}, nil, nil) }
270
+ allow_any_instance_of(Charges)
271
+ .to receive(:create) { purchase_response }
272
+ end
273
+
274
+ it 'sends an purchase request to open pay' do
275
+ response = open_pay_payment_method.purchase(
276
+ 1000,
277
+ source,
278
+ {
279
+ order_id: order.number,
280
+ email: user.email
281
+ }
282
+ )
283
+
284
+ expect(response).to be_success
285
+ expect(response.class).to be(SolidusOpenPay::Response)
286
+ end
287
+ end
288
+
289
+ describe '#void' do
290
+ let(:void_response) do
291
+ {
292
+ 'id' => 'trhp1prb21hweym5zoxq',
293
+ 'authorization' => '801585',
294
+ 'operation_type' => 'in',
295
+ 'transaction_type' => 'charge',
296
+ 'status' => 'cancelled',
297
+ 'conciliated' => true,
298
+ 'creation_date' => '2024-11-22T22:20:28-06:00',
299
+ 'operation_date' => '2024-11-22T22:21:05-06:00',
300
+ 'description' => 'Cargo inicial',
301
+ 'error_message' => nil,
302
+ 'order_id' => 'R161167589-DBHXWAP6',
303
+ 'card' =>
304
+ {
305
+ 'type' => 'credit',
306
+ 'brand' => 'visa',
307
+ 'address' => nil,
308
+ 'card_number' => '424242XXXXXX4242',
309
+ 'holder_name' => 'User Test',
310
+ 'expiration_year' => '29',
311
+ 'expiration_month' => '09',
312
+ 'allows_charges' => true,
313
+ 'allows_payouts' => false,
314
+ 'bank_name' => 'BANCOMER',
315
+ 'points_type' => 'bancomer',
316
+ 'card_business_type' => nil,
317
+ 'dcc' => nil,
318
+ 'points_card' => true,
319
+ 'bank_code' => '012'
320
+ },
321
+ 'customer' => {
322
+ 'name' => 'User',
323
+ 'last_name' => 'Test',
324
+ 'email' => 'pedidos@donmanolito.com',
325
+ 'phone_number' => nil,
326
+ 'address' => nil,
327
+ 'creation_date' => '2024-11-22T22:20:29-06:00',
328
+ 'external_id' => nil,
329
+ 'clabe' => nil
330
+ },
331
+ 'amount' => 10.0,
332
+ 'currency' => 'MXN',
333
+ 'method' => 'card'
334
+ }
335
+ end
336
+
337
+ before do
338
+ allow_any_instance_of(Charges)
339
+ .to receive(:refund) { void_response }
340
+ end
341
+
342
+ it 'sends an void request to open pay' do
343
+ response = open_pay_payment_method.void(
344
+ 'triitam7thhlqfvunpsd',
345
+ {}
346
+ )
347
+
348
+ expect(response).to be_success
349
+ expect(response.class).to be(SolidusOpenPay::Response)
350
+ end
351
+ end
352
+
353
+ describe '#credit' do
354
+ let(:credit_response) do
355
+ {
356
+ 'id' => 'trhp1prb21hweym5zoxq',
357
+ 'authorization' => '801585',
358
+ 'operation_type' => 'in',
359
+ 'transaction_type' => 'charge',
360
+ 'status' => 'cancelled',
361
+ 'conciliated' => true,
362
+ 'creation_date' => '2024-11-22T22:20:28-06:00',
363
+ 'operation_date' => '2024-11-22T22:21:05-06:00',
364
+ 'description' => 'Cargo inicial',
365
+ 'error_message' => nil,
366
+ 'order_id' => 'R161167589-DBHXWAP6',
367
+ 'card' =>
368
+ {
369
+ 'type' => 'credit',
370
+ 'brand' => 'visa',
371
+ 'address' => nil,
372
+ 'card_number' => '424242XXXXXX4242',
373
+ 'holder_name' => 'User Test',
374
+ 'expiration_year' => '29',
375
+ 'expiration_month' => '09',
376
+ 'allows_charges' => true,
377
+ 'allows_payouts' => false,
378
+ 'bank_name' => 'BANCOMER',
379
+ 'points_type' => 'bancomer',
380
+ 'card_business_type' => nil,
381
+ 'dcc' => nil,
382
+ 'points_card' => true,
383
+ 'bank_code' => '012'
384
+ },
385
+ 'customer' => {
386
+ 'name' => 'User',
387
+ 'last_name' => 'Test',
388
+ 'email' => 'pedidos@donmanolito.com',
389
+ 'phone_number' => nil,
390
+ 'address' => nil,
391
+ 'creation_date' => '2024-11-22T22:20:29-06:00',
392
+ 'external_id' => nil,
393
+ 'clabe' => nil
394
+ },
395
+ 'amount' => 10.0,
396
+ 'currency' => 'MXN',
397
+ 'method' => 'card'
398
+ }
399
+ end
400
+
401
+ before do
402
+ allow_any_instance_of(Charges)
403
+ .to receive(:refund) { credit_response }
404
+ end
405
+
406
+ it 'sends an credit request to open pay' do
407
+ response = open_pay_payment_method.credit(
408
+ 'triitam7thhlqfvunpsd',
409
+ {}
410
+ )
411
+
412
+ expect(response).to be_success
413
+ expect(response.class).to be(SolidusOpenPay::Response)
414
+ end
415
+ end
416
+ end
417
+ # rubocop:enable Style/HashSyntax
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openpay'
4
+
5
+ Dir["#{__dir__}/support/solidus_open_pay/**/*.rb"].sort.each { |f| require f }
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Configure Rails Environment
4
+ ENV['RAILS_ENV'] = 'test'
5
+
6
+ require 'openpay'
7
+ require 'rails-controller-testing'
8
+
9
+ # Run Coverage report
10
+ require 'solidus_dev_support/rspec/coverage'
11
+
12
+ # Create the dummy app if it's still missing.
13
+ dummy_env = "#{__dir__}/dummy/config/environment.rb"
14
+ system 'bin/rake extension:test_app' unless File.exist? dummy_env
15
+ require dummy_env
16
+
17
+ # Requires factories and other useful helpers defined in spree_core.
18
+ require 'solidus_dev_support/rspec/feature_helper'
19
+
20
+ # Requires supporting ruby files with custom matchers and macros, etc,
21
+ # in spec/support/ and its subdirectories.
22
+ Dir["#{__dir__}/support/**/*.rb"].sort.each { |f| require f }
23
+
24
+ # Requires factories defined in lib/solidus_open_pay/testing_support/factories.rb
25
+ SolidusDevSupport::TestingSupport::Factories.load_for(SolidusOpenPay::Engine)
26
+
27
+ RSpec.configure do |config|
28
+ config.infer_spec_type_from_file_location!
29
+ config.use_transactional_fixtures = false
30
+
31
+ if Spree.solidus_gem_version < Gem::Version.new('2.11')
32
+ config.extend Spree::TestingSupport::AuthorizationHelpers::Request, type: :system
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'factory_bot'
4
+ require 'spree/testing_support/factory_bot'
5
+
6
+ Spree::TestingSupport::FactoryBot.add_paths_and_load!
7
+
8
+ RSpec.configure do |config|
9
+ config.include FactoryBot::Syntax::Methods
10
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spree/testing_support/flash'
4
+ require 'spree/testing_support/url_helpers'
5
+ require 'spree/testing_support/controller_requests'
6
+ require 'spree/testing_support/authorization_helpers'
7
+ require 'spree/testing_support/translations'
8
+ require 'spree/testing_support/order_walkthrough'
9
+
10
+ RSpec.configure do |config|
11
+ config.include Spree::TestingSupport::Flash
12
+ config.include Spree::TestingSupport::UrlHelpers
13
+ config.include Spree::TestingSupport::Translations
14
+ config.include Spree::TestingSupport::ControllerRequests, type: :controller
15
+
16
+ config.include Rails.application.routes.url_helpers
17
+ config.include Spree::Core::Engine.routes.url_helpers
18
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusOpenPay
4
+ module GatewayHelpers
5
+ def new_gateway(opts = {})
6
+ SolidusOpenPay::Gateway.new({
7
+ name: 'OpenPay',
8
+ preferences: {
9
+ environment: 'sandbox',
10
+ public_key: 'dummy_public_key',
11
+ private_key: 'dummy_private_key',
12
+ merchant_id: 'dummy_merchant_id',
13
+ country: nil,
14
+ test_mode: true
15
+ }
16
+ }.merge(opts))
17
+ end
18
+
19
+ def create_gateway(opts = {})
20
+ new_gateway(opts).tap(&:save!)
21
+ end
22
+ end
23
+ end
24
+
25
+ RSpec.configure do |config|
26
+ config.include SolidusOpenPay::GatewayHelpers
27
+ end