openpay_copemx 3.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 (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +1984 -0
  7. data/Rakefile +16 -0
  8. data/lib/openpay/bankaccounts.rb +58 -0
  9. data/lib/openpay/cards.rb +73 -0
  10. data/lib/openpay/charges.rb +101 -0
  11. data/lib/openpay/colombia/cards_co.rb +73 -0
  12. data/lib/openpay/colombia/charges_co.rb +76 -0
  13. data/lib/openpay/colombia/customers_co.rb +166 -0
  14. data/lib/openpay/colombia/plans_co.rb +17 -0
  15. data/lib/openpay/colombia/pse_co.rb +17 -0
  16. data/lib/openpay/colombia/subscriptions_co.rb +50 -0
  17. data/lib/openpay/colombia/tokens_co.rb +5 -0
  18. data/lib/openpay/colombia/webhooks_co.rb +5 -0
  19. data/lib/openpay/customers.rb +200 -0
  20. data/lib/openpay/errors/openpay_connection_exception.rb +3 -0
  21. data/lib/openpay/errors/openpay_exception.rb +29 -0
  22. data/lib/openpay/errors/openpay_exception_factory.rb +56 -0
  23. data/lib/openpay/errors/openpay_transaction_exception.rb +5 -0
  24. data/lib/openpay/fees.rb +5 -0
  25. data/lib/openpay/open_pay_resource.rb +295 -0
  26. data/lib/openpay/open_pay_resource_factory.rb +17 -0
  27. data/lib/openpay/openpay_api.rb +72 -0
  28. data/lib/openpay/payouts.rb +55 -0
  29. data/lib/openpay/peru/cards_pe.rb +73 -0
  30. data/lib/openpay/peru/charges_pe.rb +76 -0
  31. data/lib/openpay/peru/checkouts_pe.rb +51 -0
  32. data/lib/openpay/peru/customers_pe.rb +79 -0
  33. data/lib/openpay/peru/tokens_pe.rb +5 -0
  34. data/lib/openpay/peru/webhooks_pe.rb +5 -0
  35. data/lib/openpay/plans.rb +17 -0
  36. data/lib/openpay/points.rb +10 -0
  37. data/lib/openpay/subscriptions.rb +50 -0
  38. data/lib/openpay/tokens.rb +7 -0
  39. data/lib/openpay/transfers.rb +39 -0
  40. data/lib/openpay/utils/country.rb +3 -0
  41. data/lib/openpay/utils/search_params.rb +24 -0
  42. data/lib/openpay/webhooks.rb +9 -0
  43. data/lib/openpay.rb +55 -0
  44. data/lib/version.rb +3 -0
  45. data/openpay.gemspec +30 -0
  46. data/test/Factories.rb +524 -0
  47. data/test/spec/bankaccounts_spec.rb +52 -0
  48. data/test/spec/cards_spec.rb +437 -0
  49. data/test/spec/charges_spec.rb +382 -0
  50. data/test/spec/colombia/cards_col_spec.rb +364 -0
  51. data/test/spec/colombia/charges_col_spec.rb +258 -0
  52. data/test/spec/colombia/customers_co_spec.rb +151 -0
  53. data/test/spec/colombia/plans_col_spec.rb +133 -0
  54. data/test/spec/colombia/pse_col_spec.rb +49 -0
  55. data/test/spec/colombia/subscriptions_col_spec.rb +230 -0
  56. data/test/spec/colombia/tokens_col_spec.rb +38 -0
  57. data/test/spec/customers_spec.rb +172 -0
  58. data/test/spec/exceptions_spec.rb +105 -0
  59. data/test/spec/fees_spec.rb +166 -0
  60. data/test/spec/openpayresource_spec.rb +54 -0
  61. data/test/spec/payouts_spec.rb +231 -0
  62. data/test/spec/peru/cards_pe_spec.rb +363 -0
  63. data/test/spec/peru/charges_pe_spec.rb +218 -0
  64. data/test/spec/peru/checkouts_pe_spec.rb +71 -0
  65. data/test/spec/peru/customers_pe_spec.rb +151 -0
  66. data/test/spec/peru/tokens_pe_spec.rb +38 -0
  67. data/test/spec/peru/webhook_pe_spec.rb +50 -0
  68. data/test/spec/plans_spec.rb +158 -0
  69. data/test/spec/points_spec.rb +26 -0
  70. data/test/spec/requesttimeout_spec.rb +22 -0
  71. data/test/spec/subscriptions_spec.rb +294 -0
  72. data/test/spec/transfers_spec.rb +219 -0
  73. data/test/spec/utils/search_params_spec.rb +36 -0
  74. data/test/spec_helper.rb +24 -0
  75. metadata +219 -0
data/README.md ADDED
@@ -0,0 +1,1984 @@
1
+ ![Openpay Ruby](https://www.openpay.mx/img/github/ruby.jpg)
2
+
3
+ [![Build Status](https://travis-ci.org/open-pay/openpay-ruby.png?branch=master)](https://travis-ci.org/open-pay/openpay-ruby)
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/openpay.svg)](http://badge.fury.io/rb/openpay)
6
+
7
+ # Openpay México
8
+
9
+ ## Description
10
+
11
+ ruby client for *Openpay api* services (version 3.0.0)
12
+
13
+ This is a ruby client implementing the payment services for *Openpay* at openpay.mx
14
+
15
+ For more information about Openpay visit:
16
+
17
+ - http://openpay.mx/
18
+
19
+ For the full *Openpay api* documentation take a look at:
20
+
21
+ - http://docs.openpay.mx/
22
+
23
+ ## Installation
24
+
25
+ Add the following line to your Gem file
26
+
27
+ #openpay gem
28
+ gem 'openpay'
29
+
30
+ Update your bundle:
31
+
32
+ $ bundle
33
+
34
+ Or install it from the command line:
35
+
36
+ $ gem install openpay
37
+
38
+ ### Requirements
39
+
40
+ * ruby 2.4 or higher
41
+
42
+ ## Usage
43
+
44
+ ### Initialization
45
+
46
+ ```ruby
47
+ require 'openpay'
48
+
49
+ #merchant and private key
50
+ merchant_id = 'mywvupjjs9xdnryxtplq'
51
+ private_key = 'sk_92b25d3baec149e6b428d81abfe37006'
52
+ country = 'mx'
53
+
54
+ #An openpay resource factory instance is created out of the OpenpayApi
55
+ #it points to the development environment by default.
56
+ #The country value can take 'mx' to Mexico or 'co' for Colombia
57
+ openpay = OpenpayApi.new(merchant_id, private_key, country)
58
+
59
+ #To enable production mode you should pass a third argument as true.
60
+ #openpay_prod=OpenpayApi.new(merchant_id,private_key,true)
61
+
62
+ #This ruby client manages a default timeout of 90 seconds to make the request
63
+ # to Openpay services, if you need to modify this value, you need to explicitly
64
+ # define the type of environment and followed by the new value for the timeout.
65
+ #Syntax:
66
+ # openpay_prod=OpenpayApi.new(merchant_id,private_key,isProduction,timeout)
67
+ #Example:
68
+ # openpay_prod=OpenpayApi.new(merchant_id,private_key,false,30)
69
+ ```
70
+
71
+ The openpay factory instance is in charge to generate the required resources through a factory method (create). Resource
72
+ classes should be initialized using the factory method as described below.
73
+
74
+ ```ruby
75
+ #creating an instance for each available resource
76
+ bankaccounts = openpay.create(:bankaccounts)
77
+ cards = openpay.create(:cards)
78
+ charges = openpay.create(:charges)
79
+ customers = openpay.create(:customers)
80
+ fees = openpay.create(:fees)
81
+ payouts = openpay.create(:payouts)
82
+ plans = openpay.create(:plans)
83
+ subscriptions = openpay.create(:subscriptions)
84
+ transfers = openpay.create(:transfers)
85
+ ```
86
+
87
+ According to the current version of the *Openpay api* the available resources are:
88
+
89
+ - *bankaccounts*
90
+ - *cards*
91
+ - *charges*
92
+ - *customers*
93
+ - *fees*
94
+ - *payouts*
95
+ - *plans*
96
+ - *subscriptions*
97
+ - *transfers*
98
+
99
+ Each rest resource exposed in the rest *Openpay api* is represented by a class in this ruby API, being **
100
+ OpenpayResource** the base class.
101
+
102
+ ### Implementation
103
+
104
+ Each resource depending of its structure and available methods, will have one or more of the methods described under the
105
+ methods subsection. Below a short description about the implementation high level details. For detailed documentation
106
+ take a look a the openpay api documentation.
107
+
108
+ #### Arguments
109
+
110
+ Given most resources belong, either to a merchant or a customer, the api was designed taking this in consideration, so:
111
+
112
+ The first argument represent the json/hash object, while the second argument which is optional represents the **
113
+ customer_id**. So if just one argument is provided the action will be performed at the merchant level, but if the second
114
+ argument is provided passing the **customer_id**, the action will be performed at the customer level.
115
+
116
+ The following illustrates the api design.
117
+
118
+ ```ruby
119
+ #Merchant
120
+ hash_out = open_pay_resource.create(hash_in)
121
+ json_out = open_pay_resource.create(json_in)
122
+
123
+ #Customer
124
+ hash_out = open_pay_resource.create(hash_in, customer_id)
125
+ json_out = open_pay_resource.create(json_in, customer_id)
126
+
127
+ ```
128
+
129
+ #### Methods Inputs/Outputs
130
+
131
+ This api supports both ruby hashes and json strings as inputs and outputs. (See previous example)
132
+ If a ruby hash is passed in as in input, a hash will be returned as the method output. if a json string is passed in as
133
+ an input, a json string will be returned as the method function output.
134
+
135
+ This code excerpt from a specification demonstrates how you can use hashes and json strings interchangeably.
136
+
137
+ Methods without inputs will return a ruby hash.
138
+
139
+ ```ruby
140
+ it 'creates a fee using a json message' do
141
+ #create new customer
142
+ customer_hash = FactoryBot.build(:customer)
143
+ customer = @customers.create(customer_hash)
144
+
145
+ #create customer card , using factory girl to build the hash for us
146
+ card_hash = FactoryBot.build(:valid_card)
147
+ card = @cards.create(card_hash, customer['id'])
148
+
149
+ #create charge
150
+ charge_hash = FactoryBot.build(:card_charge, source_id: card['id'], order_id: card['id'], amount: 4000)
151
+ charge = @charges.create(charge_hash, customer['id'])
152
+
153
+ #create customer fee , using json as input, we get json as ouput
154
+ fee_json = %^{"customer_id":"#{customer['id']}","amount":"12.50","description":"Cobro de Comisión"}^
155
+ expect(@fees.create(fee_json)).to have_json_path('amount')
156
+ end
157
+ ```
158
+
159
+ Here you can see how the **card_hash** representation looks like.
160
+
161
+ ```ruby
162
+ require 'pp'
163
+ pp card_hash =>
164
+
165
+ { :bank_name => "visa",
166
+ :holder_name => "Vicente Olmos",
167
+ :expiration_month => "09",
168
+ :card_number => "4111111111111111",
169
+ :expiration_year => "14",
170
+ :bank_code => "bmx",
171
+ :cvv2 => "111",
172
+ :address =>
173
+ { :postal_code => "76190",
174
+ :state => "QRO",
175
+ :line1 => "LINE1",
176
+ :line2 => "LINE2",
177
+ :line3 => "LINE3",
178
+ :country_code => "MX",
179
+ :city => "Queretaro" } }
180
+ ```
181
+
182
+ Next, how we construct the preceding hash using **FactoryBot**.
183
+ **FactoryBot** was used in our test suite to facilitate hash construction. It may help you as well at your final
184
+ implementation if you decide to use hashes.
185
+ (more examples at *test/Factories.rb*)
186
+
187
+ ```ruby
188
+
189
+ FactoryBot.define do
190
+ factory :valid_card, class: Hash do
191
+ bank_name 'visa'
192
+ holder_name 'Vicente Olmos'
193
+ expiration_month '09'
194
+ card_number '4111111111111111'
195
+ expiration_year '14'
196
+ bank_code 'bmx'
197
+ cvv2 '111'
198
+ address { {
199
+ postal_code: '76190',
200
+ state: 'QRO',
201
+ line1: 'LINE1',
202
+ line2: 'LINE2',
203
+ line3: 'LINE3',
204
+ country_code: 'MX',
205
+ city: 'Queretaro',
206
+ } }
207
+ initialize_with { attributes }
208
+ end
209
+ ```
210
+
211
+ ### Methods design
212
+
213
+ This ruby API standardize the method names across all different resources using the **create**,**get**,**update** and **
214
+ delete** verbs.
215
+
216
+ For full method documentation take a look at:
217
+
218
+ - http://docs.openpay.mx/
219
+
220
+ The test suite at *test/spec* is a good source of reference.
221
+
222
+ ##### create
223
+
224
+ Creates the given resource
225
+
226
+ ```ruby
227
+ open_pay_resource.create(representation, customer_id = nil)
228
+ ```
229
+
230
+ ##### get
231
+
232
+ Gets an instance of a given resource
233
+
234
+ ```ruby
235
+ open_pay_resource.get(object_id, customer_id = nil)
236
+ ```
237
+
238
+ ##### update
239
+
240
+ Updates an instance of a given resource
241
+
242
+ ```ruby
243
+ open_pay_resource.update(representation, customer_id = nil)
244
+ ```
245
+
246
+ ##### delete
247
+
248
+ Deletes an instance of the given resource
249
+
250
+ ```ruby
251
+ open_pay_resource.delete(object_id, customer_id = nil)
252
+ ```
253
+
254
+ ##### all
255
+
256
+ Returns an array of all instances of a resource
257
+
258
+ ```ruby
259
+ open_pay_resource.all(customer_id = nil)
260
+ ```
261
+
262
+ ##### each
263
+
264
+ Returns a block for each instance resource
265
+
266
+ ```ruby
267
+ open_pay_resource.each(customer_id = nil)
268
+ ```
269
+
270
+ ##### delete_all(available only under the development environment)
271
+
272
+ Deletes all instances of the given resource
273
+
274
+ ```ruby
275
+ #in case this method is executed under the production environment an OpenpayException will be raised.
276
+ open_pay_resource.delete_all(customer_id = nil)
277
+ ```
278
+
279
+ ### API Methods
280
+
281
+ #### bank_accounts
282
+
283
+ - creates a merchant bank account , is not supported through the API, use the console instead.
284
+
285
+ - creates a customer bank account
286
+
287
+ bank_accounts.create(account_hash,customer_id)
288
+
289
+ - get a given bank account for a given customer
290
+
291
+ bank_account=bank_accounts.get(customer_id,bankaccount_id)
292
+
293
+ - each customer bank account
294
+
295
+ bank_accounts.each(customer_id) do |bank_account|
296
+ bank_account['alias']
297
+ end
298
+
299
+ - list merchant / customer bank accounts
300
+
301
+ search_params = OpenpayUtils::SearchParams.new
302
+ search_params.limit = 1
303
+
304
+ merchant_filtered_list = bank_accounts.list(search_params)
305
+ customer_filtered_list = bank_accounts.list(search_params, customer_id)
306
+
307
+ - all bank accounts for a given customer
308
+
309
+ accounts=bank_accounts.all(customer_id)
310
+
311
+ - deletes a given customer bank account
312
+
313
+ bank_accounts.delete(customer_id,bank_id)
314
+
315
+ - deletes all customer bank accounts (sandbox mode only)
316
+
317
+ bank_accounts.delete_all(customer['id'])
318
+
319
+ #### cards
320
+
321
+ - creates a merchant card
322
+
323
+ cards.create(card_json)
324
+
325
+ - creates a customer card
326
+
327
+ cards.create(card_hash, customer_id)
328
+
329
+ - gets merchant card
330
+
331
+ card=cards.get(card_id)
332
+
333
+ - gets customer card
334
+
335
+ card=cards.get(card_id, customer_id)
336
+
337
+ - each merchant card
338
+
339
+ cards.each {|merchant_card| p card}
340
+
341
+ - list merchant / customer cards
342
+
343
+ search_params = OpenpayUtils::SearchParams.new
344
+ search_params.limit = 1
345
+
346
+ merchant_filtered_list = cards.list(search_params)
347
+ customer_filtered_list = cards.list(search_params, customer_id)
348
+
349
+ - each customer card
350
+
351
+ cards.each(customer_id) {|customer_card | p customer_card }
352
+
353
+ - all merchant cards
354
+
355
+ merchant_cards=cards.all
356
+
357
+ - all customer cards
358
+
359
+ customer_cards=cards.all(customer_id)
360
+
361
+ - delete merchant card
362
+
363
+ cards.delete(card_id)
364
+
365
+ - delete customer card
366
+
367
+ cards.delete(card_id,customer_id)
368
+
369
+ - delete all merchant cards
370
+
371
+ cards.delete_all
372
+
373
+ - delete all customer cards
374
+
375
+ cards.delete_all(customer_id)
376
+
377
+ #### charges
378
+
379
+ - creates merchant charge
380
+
381
+ charges.create(charge_hash)
382
+
383
+ - creates customer charge
384
+
385
+ charges.create(charge_hash,customer_id)
386
+
387
+ - gets merchant charge
388
+
389
+ merchant_charge=charges.get(charge_id)
390
+
391
+ - gets customer charge
392
+
393
+ customer_charge=charges.get(charge_id,customer_id)
394
+
395
+ - each merchant charge
396
+
397
+ charges.each {|charge| p charge}
398
+
399
+ - list merchant / customer charges
400
+
401
+ search_params = OpenpayUtils::SearchParams.new
402
+ search_params.limit = 1
403
+
404
+ merchant_filtered_list = charges.list(search_params)
405
+ customer_filtered_list = charges.list(search_params, customer_id)
406
+
407
+ - each customer charge
408
+
409
+ charges.each(customer_id) {|charge| p charge}
410
+
411
+
412
+ - all merchant charge
413
+
414
+ charges.all
415
+
416
+ - all customer charge
417
+
418
+ charges.all(customer_id)
419
+
420
+ - capture merchant card
421
+
422
+ charges.capture(charge_id)
423
+
424
+ - capture customer card
425
+
426
+ charges.capture(charge['id'],customer['id'])
427
+
428
+ - confirm capture merchant
429
+
430
+ #pass a hash with the following options, no customer_id needed
431
+ confirm_capture_options = { transaction_id: transaction['id'], amount: 100 }
432
+ charges.confirm_capture(confirm_capture_options)
433
+
434
+ - confirm capture customer
435
+
436
+ #pass a hash with the following options, pass the customer_id
437
+ confirm_capture_options = { customer_id: customer['id'], transaction_id: charge['id'], amount: 100 }
438
+ charges.confirm_capture(confirm_capture_options)
439
+
440
+ - refund merchant charge
441
+
442
+ charges.refund(charge_id, refund_description_hash)
443
+
444
+ - refund merchant charge
445
+
446
+ charges.refund(charge_id, refund_description_hash)
447
+
448
+ #### customers
449
+
450
+ - creates customer
451
+
452
+ customers.create(customer_json)
453
+
454
+ - get customer
455
+
456
+ customer=customers.get(customer_id)
457
+
458
+ - update customer
459
+
460
+ customers.update(customer_hash)
461
+
462
+ - delete customer
463
+
464
+ customers.delete(customer_id)
465
+
466
+ - each customer
467
+
468
+ customers.each do {|customer| p customer }
469
+
470
+ - list customers
471
+
472
+ search_params = OpenpayUtils::SearchParams.new
473
+ search_params.limit = 1
474
+
475
+ customers_filtered_list = customers.list(search_params)
476
+
477
+
478
+ - all customer
479
+
480
+ all_customers=customers.all
481
+
482
+ - delete all customers (sand box mode only)
483
+
484
+ all_customers=customers.all
485
+
486
+ #### fees
487
+
488
+ - creates fee
489
+
490
+ #In order to create a fee a charge should exists
491
+ fee.create(fee_hash)
492
+
493
+ - gets all fees
494
+
495
+ all_fees=fees.all
496
+
497
+ - list customer fees
498
+
499
+ search_params = OpenpayUtils::SearchParams.new
500
+ search_params.limit = 1
501
+
502
+ merchant_filtered_list = fees.list(search_params)
503
+
504
+ #### payouts
505
+
506
+ - creates a merchant payout
507
+
508
+ payouts.create(payout_json)
509
+
510
+ - creates a customer payout
511
+
512
+ payouts.create(payout_hash,customer_id)
513
+
514
+ - gets a merchant payout
515
+
516
+ payouts.get(payout_id)
517
+ - gets a customer payout
518
+
519
+ payouts.get(payout_id,customer_id)
520
+
521
+ - all merchant payouts
522
+
523
+ merchant_payouts=payouts.all
524
+
525
+ - all customer payouts
526
+
527
+ customer_payouts=payouts.all(customer_id)
528
+
529
+ - each merchant payout
530
+
531
+ payouts.each { |payout| p payout }
532
+
533
+ - each customer payout
534
+
535
+ payouts.each(customer_id) { |payout| p payout }
536
+
537
+ - list merchant/customer payouts
538
+
539
+ search_params = OpenpayUtils::SearchParams.new
540
+ search_params.limit = 1
541
+
542
+ merchant_filtered_list = payouts.list(search_params)
543
+ customer_filtered_list = payouts.list(search_params, customer_id)
544
+
545
+ #### plans
546
+
547
+ - create merchant plan
548
+
549
+ plans.create(plan_hash)
550
+
551
+
552
+ - create customer plan
553
+
554
+ plans.create(plan_hash,customer_id)
555
+
556
+ - get a merchant plan
557
+
558
+ merchant_plan=plans.get(plan_id)
559
+
560
+ - get a customer plan
561
+
562
+ customer_plan=plans.get(plan_id,customer_id)
563
+
564
+
565
+ - updates a merchant plan
566
+
567
+ plans.update(plan_hash,customer_id)
568
+
569
+ - updates a customer plan
570
+
571
+ plans.update(plan_hash,customer_id)
572
+
573
+ - each merchant plan
574
+
575
+ plans.each do {|plan| p plan }
576
+
577
+ - each customer plans
578
+
579
+ plans.each(customer_id) do {|plan| p plan }
580
+
581
+
582
+ - list merchant /customer plan
583
+
584
+ search_params = OpenpayUtils::SearchParams.new
585
+ search_params.limit = 1
586
+
587
+ merchant_filtered_list = plans.list(search_params)
588
+ customer_filtered_list = plans.list(search_params, customer_id)
589
+
590
+
591
+ - all merchant plans
592
+
593
+ plans.all
594
+
595
+ - all customer plans
596
+
597
+ plans.all(customer_id)
598
+
599
+ #### subscriptions
600
+
601
+ - create customer subscriptions
602
+
603
+ subscriptions.create(subscriptions_hash,customer_id)
604
+
605
+ - get customer subscription
606
+
607
+ subscriptions.get(subscriptions_hash,customer_id)
608
+
609
+ - update customer subscription
610
+
611
+ subscription_update_hash={ trial_end_date: "2016-01-12" }
612
+ subscriptions.update(subscription_id,customer_id, subscription_update_hash )
613
+
614
+ - all customer subscription
615
+
616
+ subscriptions.all(customer_id)
617
+
618
+
619
+ - each customer subscription
620
+
621
+ subscriptions.each(customer_id) {|subscription| p subscription }
622
+
623
+
624
+ - list customer subscriptions
625
+
626
+ search_params = OpenpayUtils::SearchParams.new
627
+ search_params.limit = 1
628
+
629
+ customer_filtered_list = subscriptions.list(search_params, customer_id)
630
+
631
+ - deletes customer subscription
632
+
633
+ subscriptions.delete(customer_id)
634
+
635
+ - deletes all customer subscriptions ( sandbox mode only)
636
+
637
+ subscriptions.delete(customer_id)
638
+
639
+ #### transfers
640
+
641
+ - create transfer
642
+
643
+ transfers.create(transfer_hash,customer_id)
644
+
645
+
646
+ - get transfer
647
+
648
+ transfers.get(transfer_id,customer_id)
649
+
650
+ - all customer transfers
651
+
652
+ transfers.all(customer_id)
653
+
654
+
655
+ - each customer transfer
656
+
657
+ transfers.each(customer_id) {|transfer| p transfer }
658
+
659
+ - list customer transfers
660
+
661
+ search_params = OpenpayUtils::SearchParams.new
662
+ search_params.limit = 1
663
+
664
+ customer_filtered_list = transfers.list(search_params, customer_id)
665
+
666
+ #### Exceptions
667
+
668
+ This API generates 3 different Exception classes.
669
+
670
+ - **OpenpayException**: Generic base API exception class, Generic API exceptions.
671
+
672
+ - Internal server error (500 Internal Server Error).
673
+ - OpenpayApi factory method, invalid resource name.
674
+
675
+ Examples:
676
+
677
+ ```ruby
678
+ #production mode
679
+ openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
680
+ customers = openpay_prod.create(:customers)
681
+ customers.delete_all # will raise an OpenpayException
682
+ ```
683
+
684
+ ```ruby
685
+ #production mode
686
+ openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
687
+ customers = openpay_prod.create(:non_existing_resource) # will raise an OpenpayException
688
+ ```
689
+
690
+ - **OpenpayConnectionException**: Exception class for connection related issues, errors happening prior the server
691
+ connection.
692
+
693
+ - Authentication Error (401 Unauthorized)
694
+ - Connection Errors.
695
+ - SSL Errors.
696
+
697
+ Example:
698
+ ```ruby
699
+ #invalid id and key
700
+ merchant_id='santa'
701
+ private_key='invalid'
702
+
703
+ openpay=OpenpayApi.new(merchant_id, private_key)
704
+ customers=openpay.create(:customers)
705
+
706
+ begin
707
+ customers.get('23444422211')
708
+ rescue OpenpayConnectionException => e
709
+ e.http_code # => 401
710
+ e.error_code # => 1002
711
+ e.description# => 'The api key or merchant id are invalid.'
712
+ e.json_body # {"category":"request","description":"The api key or merchant id are invalid.","http_code":401,"error_code":1002,"request_id":null}
713
+ end
714
+ ```
715
+
716
+ - **OpenpayTransactionException**: Errors happening after the initial connection has been initiated, errors during
717
+ transactions.
718
+
719
+ - Bad Request (e.g. Malformed json,Invalid data)
720
+ - Unprocessable Entity (e.g. invalid data)
721
+ - Resource not found (404 Not Found)
722
+ - Conflict (e.g. resource already exists)
723
+ - PaymentRequired (e.g. insufficient funds)
724
+ - UnprocessableEntity ( e.g. stolen card )
725
+
726
+ *Bad Request* Example:
727
+
728
+ ```ruby
729
+ email = 'foo'
730
+ customer_hash = FactoryBot.build(:customer, email: email)
731
+ begin
732
+ customers.create(customer_hash)
733
+ rescue OpenpayTransactionException => e
734
+ e.http_code # => 400
735
+ e.error_code # => 1001
736
+ e.description # => 'email\' not a well-formed email address'
737
+ end
738
+ ```
739
+
740
+ *Resource not found* Example:
741
+
742
+ ```ruby
743
+
744
+ begin
745
+ #non existing customer
746
+ customers.delete('1111')
747
+ rescue OpenpayApiTransactionError => e
748
+ e.http_code # => 404
749
+ e.error_code # =>1005
750
+ e.description # =>"The customer with id '1111' does not exist"
751
+ end
752
+ ```
753
+
754
+ ### These exceptions have the following attributes:
755
+
756
+ - *category*
757
+ - *description*
758
+ - *http_code*
759
+ - *error_code*
760
+ - *json_message*
761
+
762
+ For more information about categories, descriptions and codes take a look at:
763
+
764
+ - http://docs.openpay.mx/#errores
765
+ - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
766
+
767
+ ## Debug
768
+
769
+ In the Openpay dashboard you are able to see every request and its corresponding request/response.
770
+
771
+ - https://sandbox-dashboard.openpay.mx
772
+
773
+ ## Developer Notes
774
+
775
+ - bank accounts for merchant cannot be created using the api. It should be done through the dashboard.
776
+ - Is recommended to reset your account using the dashboard when running serious testing (assure clean state)
777
+ - check openpay_api.rb for Logger configuration
778
+ - travis https://travis-ci.org/open-pay/openpay-ruby , if a test fails it will leave some records, it may affect
779
+ posterior tests. it is recommended to reset the console/account to assure a clean state after a failure occurs.
780
+
781
+ ## More information
782
+
783
+ For more use cases take a look at the *test/spec* folder
784
+
785
+ 1. http://docs.openpay.mx/
786
+
787
+ # Openpay Colombia
788
+
789
+ ## Description
790
+
791
+ ruby client for *Openpay api* services (version 3.0.0)
792
+
793
+ This is a ruby client implementing the payment services for *Openpay* at openpay.co
794
+
795
+ For more information about Openpay visit:
796
+
797
+ - http://openpay.co/
798
+
799
+ For the full *Openpay api* documentation take a look at:
800
+
801
+ - https://www.openpay.co/api/
802
+
803
+ ## Installation
804
+
805
+ Add the following line to your Gem file
806
+
807
+ #openpay gem
808
+ gem 'openpay'
809
+
810
+ Update your bundle:
811
+
812
+ $ bundle
813
+
814
+ Or install it from the command line:
815
+
816
+ $ gem install openpay
817
+
818
+ ### Requirements
819
+
820
+ * ruby 2.4 or higher
821
+
822
+ ## Usage
823
+
824
+ ### Initialization
825
+
826
+ ```ruby
827
+ require 'openpay'
828
+
829
+ #merchant and private key
830
+ merchant_id = 'mywvupjjs9xdnryxtplq'
831
+ private_key = 'sk_92b25d3baec149e6b428d81abfe37006'
832
+ country = 'co'
833
+
834
+ #An openpay resource factory instance is created out of the OpenpayApi
835
+ #it points to the development environment by default.
836
+ #The country value can take 'mx' to Mexico or 'co' for Colombia
837
+ openpay = OpenpayApi.new(merchant_id, private_key, country)
838
+
839
+ #To enable production mode you should pass a third argument as true.
840
+ #openpay_prod=OpenpayApi.new(merchant_id,private_key,true)
841
+
842
+ #This ruby client manages a default timeout of 90 seconds to make the request
843
+ # to Openpay services, if you need to modify this value, you need to explicitly
844
+ # define the type of environment and followed by the new value for the timeout.
845
+ #Syntax:
846
+ # openpay_prod=OpenpayApi.new(merchant_id,private_key,isProduction,timeout)
847
+ #Example:
848
+ # openpay_prod=OpenpayApi.new(merchant_id,private_key,false,30)
849
+ ```
850
+
851
+ The openpay factory instance is in charge to generate the required resources through a factory method (create). Resource
852
+ classes should be initialized using the factory method as described below.
853
+
854
+ ```ruby
855
+ #creating an instance for each available resource
856
+ cards = openpay.create(:cards)
857
+ charges = openpay.create(:charges)
858
+ customers = openpay.create(:customers)
859
+ plans = openpay.create(:plans)
860
+ subscriptions = openpay.create(:subscriptions)
861
+ transfers = openpay.create(:transfers)
862
+ pse = openpay.create(:pse)
863
+ ```
864
+
865
+ According to the current version of the *Openpay api* the available resources are:
866
+
867
+ - *cards*
868
+ - *charges*
869
+ - *customers*
870
+ - *plans*
871
+ - *subscriptions*
872
+ - *pse*
873
+
874
+ Each rest resource exposed in the rest *Openpay api* is represented by a class in this ruby API, being **
875
+ OpenpayResource** the base class.
876
+
877
+ ### Implementation
878
+
879
+ Each resource depending of its structure and available methods, will have one or more of the methods described under the
880
+ methods subsection. Below a short description about the implementation high level details. For detailed documentation
881
+ take a look a the openpay api documentation.
882
+
883
+ #### Arguments
884
+
885
+ Given most resources belong, either to a merchant or a customer, the api was designed taking this in consideration, so:
886
+
887
+ The first argument represent the json/hash object, while the second argument which is optional represents the **
888
+ customer_id**. So if just one argument is provided the action will be performed at the merchant level, but if the second
889
+ argument is provided passing the **customer_id**, the action will be performed at the customer level.
890
+
891
+ The following illustrates the api design.
892
+
893
+ ```ruby
894
+ #Merchant
895
+ hash_out = open_pay_resource.create(hash_in)
896
+ json_out = open_pay_resource.create(json_in)
897
+
898
+ #Customer
899
+ hash_out = open_pay_resource.create(hash_in, customer_id)
900
+ json_out = open_pay_resource.create(json_in, customer_id)
901
+
902
+ ```
903
+
904
+ #### Methods Inputs/Outputs
905
+
906
+ This api supports both ruby hashes and json strings as inputs and outputs. (See previous example)
907
+ If a ruby hash is passed in as in input, a hash will be returned as the method output. if a json string is passed in as
908
+ an input, a json string will be returned as the method function output.
909
+
910
+ This code excerpt from a specification demonstrates how you can use hashes and json strings interchangeably.
911
+
912
+ Methods without inputs will return a ruby hash.
913
+
914
+ ```ruby
915
+ it 'creates a fee using a json message' do
916
+ #create new customer
917
+ customer_hash = FactoryBot.build(:customer_col)
918
+ customer = @customers.create(customer_hash)
919
+
920
+ #create customer card , using factory girl to build the hash for us
921
+ card_hash = FactoryBot.build(:valid_card_col)
922
+ card = @cards.create(card_hash, customer['id'])
923
+
924
+ #create charge
925
+ charge_hash = FactoryBot.build(:card_charge_col, source_id: card['id'], order_id: card['id'], amount: 4000)
926
+ charge = @charges.create(charge_hash, customer['id'])
927
+
928
+ end
929
+ ```
930
+
931
+ Here you can see how the **card_hash** representation looks like.
932
+
933
+ ```ruby
934
+ require 'pp'
935
+ pp card_hash =>
936
+
937
+ { :holder_name => 'Vicente Olmos',
938
+ :card_number => '4111111111111111',
939
+ :cvv2 => '111',
940
+ :expiration_month => '09',
941
+ :expiration_year => '25' }
942
+ ```
943
+
944
+ Next, how we construct the preceding hash using **FactoryBot**.
945
+ **FactoryBot** was used in our test suite to facilitate hash construction. It may help you as well at your final
946
+ implementation if you decide to use hashes.
947
+ (more examples at *test/Factories.rb*)
948
+
949
+ ```ruby
950
+
951
+ FactoryBot.define do
952
+ factory :valid_card_col, class: Hash do
953
+ holder_name 'Vicente Olmos'
954
+ expiration_month '09'
955
+ card_number '4111111111111111'
956
+ expiration_year '14'
957
+ cvv2 '111'
958
+ initialize_with { attributes }
959
+ end
960
+ ```
961
+
962
+ ### Methods design
963
+
964
+ This ruby API standardize the method names across all different resources using the **create**,**get**,**update** and **
965
+ delete** verbs.
966
+
967
+ For full method documentation take a look at:
968
+
969
+ - http://docs.openpay.mx/
970
+
971
+ The test suite at *test/spec* is a good source of reference.
972
+
973
+ ##### create
974
+
975
+ Creates the given resource
976
+
977
+ ```ruby
978
+ open_pay_resource.create(representation, customer_id = nil)
979
+ ```
980
+
981
+ ##### get
982
+
983
+ Gets an instance of a given resource
984
+
985
+ ```ruby
986
+ open_pay_resource.get(object_id, customer_id = nil)
987
+ ```
988
+
989
+ ##### update
990
+
991
+ Updates an instance of a given resource
992
+
993
+ ```ruby
994
+ open_pay_resource.update(representation, customer_id = nil)
995
+ ```
996
+
997
+ ##### delete
998
+
999
+ Deletes an instance of the given resource
1000
+
1001
+ ```ruby
1002
+ open_pay_resource.delete(object_id, customer_id = nil)
1003
+ ```
1004
+
1005
+ ##### all
1006
+
1007
+ Returns an array of all instances of a resource
1008
+
1009
+ ```ruby
1010
+ open_pay_resource.all(customer_id = nil)
1011
+ ```
1012
+
1013
+ ##### each
1014
+
1015
+ Returns a block for each instance resource
1016
+
1017
+ ```ruby
1018
+ open_pay_resource.each(customer_id = nil)
1019
+ ```
1020
+
1021
+ ##### delete_all(available only under the development environment)
1022
+
1023
+ Deletes all instances of the given resource
1024
+
1025
+ ```ruby
1026
+ #in case this method is executed under the production environment an OpenpayException will be raised.
1027
+ open_pay_resource.delete_all(customer_id = nil)
1028
+ ```
1029
+
1030
+ ### API Methods
1031
+
1032
+ #### pse
1033
+
1034
+ - creates a merchant pse
1035
+
1036
+ pse.create(pse_hash)
1037
+
1038
+ - creates a customer pse
1039
+
1040
+ pse.create(charge_hash,customer_id)
1041
+
1042
+ #### cards
1043
+
1044
+ - creates a merchant card
1045
+
1046
+ cards.create(card_json)
1047
+
1048
+ - creates a customer card
1049
+
1050
+ cards.create(card_hash, customer_id)
1051
+
1052
+ - gets merchant card
1053
+
1054
+ card=cards.get(card_id)
1055
+
1056
+ - gets customer card
1057
+
1058
+ card=cards.get(card_id, customer_id)
1059
+
1060
+ - each merchant card
1061
+
1062
+ cards.each {|merchant_card| p card}
1063
+
1064
+ - list merchant / customer cards
1065
+
1066
+ search_params = OpenpayUtils::SearchParams.new
1067
+ search_params.limit = 1
1068
+
1069
+ merchant_filtered_list = cards.list(search_params)
1070
+ customer_filtered_list = cards.list(search_params, customer_id)
1071
+
1072
+ - each customer card
1073
+
1074
+ cards.each(customer_id) {|customer_card | p customer_card }
1075
+
1076
+ - all merchant cards
1077
+
1078
+ merchant_cards=cards.all
1079
+
1080
+ - all customer cards
1081
+
1082
+ customer_cards=cards.all(customer_id)
1083
+
1084
+ - delete merchant card
1085
+
1086
+ cards.delete(card_id)
1087
+
1088
+ - delete customer card
1089
+
1090
+ cards.delete(card_id,customer_id)
1091
+
1092
+ - delete all merchant cards
1093
+
1094
+ cards.delete_all
1095
+
1096
+ - delete all customer cards
1097
+
1098
+ cards.delete_all(customer_id)
1099
+
1100
+ #### charges
1101
+
1102
+ - creates merchant charge
1103
+
1104
+ charges.create(charge_hash)
1105
+
1106
+ - creates customer charge
1107
+
1108
+ charges.create(charge_hash,customer_id)
1109
+
1110
+ - gets merchant charge
1111
+
1112
+ merchant_charge=charges.get(charge_id)
1113
+
1114
+ - gets customer charge
1115
+
1116
+ customer_charge=charges.get(charge_id,customer_id)
1117
+
1118
+ - each merchant charge
1119
+
1120
+ charges.each {|charge| p charge}
1121
+
1122
+ - list merchant / customer charges
1123
+
1124
+ search_params = OpenpayUtils::SearchParams.new
1125
+ search_params.limit = 1
1126
+
1127
+ merchant_filtered_list = charges.list(search_params)
1128
+ customer_filtered_list = charges.list(search_params, customer_id)
1129
+
1130
+ - each customer charge
1131
+
1132
+ charges.each(customer_id) {|charge| p charge}
1133
+
1134
+
1135
+ - all merchant charge
1136
+
1137
+ charges.all
1138
+
1139
+ - all customer charge
1140
+
1141
+ charges.all(customer_id)
1142
+
1143
+ - refund merchant charge
1144
+
1145
+ charges.refund(charge_id, refund_description_hash)
1146
+
1147
+ - refund merchant charge
1148
+
1149
+ charges.refund(charge_id, refund_description_hash)
1150
+
1151
+ #### customers
1152
+
1153
+ - creates customer
1154
+
1155
+ customers.create(customer_json)
1156
+
1157
+ - get customer
1158
+
1159
+ customer=customers.get(customer_id)
1160
+
1161
+ - update customer
1162
+
1163
+ customers.update(customer_hash)
1164
+
1165
+ - delete customer
1166
+
1167
+ customers.delete(customer_id)
1168
+
1169
+ - each customer
1170
+
1171
+ customers.each do {|customer| p customer }
1172
+
1173
+ - list customers
1174
+
1175
+ search_params = OpenpayUtils::SearchParams.new
1176
+ search_params.limit = 1
1177
+
1178
+ customers_filtered_list = customers.list(search_params)
1179
+
1180
+
1181
+ - all customer
1182
+
1183
+ all_customers=customers.all
1184
+
1185
+ - delete all customers (sand box mode only)
1186
+
1187
+ all_customers=customers.all
1188
+
1189
+
1190
+ #### plans
1191
+
1192
+ - create merchant plan
1193
+
1194
+ plans.create(plan_hash)
1195
+
1196
+
1197
+ - create customer plan
1198
+
1199
+ plans.create(plan_hash,customer_id)
1200
+
1201
+ - get a merchant plan
1202
+
1203
+ merchant_plan=plans.get(plan_id)
1204
+
1205
+ - get a customer plan
1206
+
1207
+ customer_plan=plans.get(plan_id,customer_id)
1208
+
1209
+
1210
+ - updates a merchant plan
1211
+
1212
+ plans.update(plan_hash,customer_id)
1213
+
1214
+ - updates a customer plan
1215
+
1216
+ plans.update(plan_hash,customer_id)
1217
+
1218
+ - each merchant plan
1219
+
1220
+ plans.each do {|plan| p plan }
1221
+
1222
+ - each customer plans
1223
+
1224
+ plans.each(customer_id) do {|plan| p plan }
1225
+
1226
+
1227
+ - list merchant /customer plan
1228
+
1229
+ search_params = OpenpayUtils::SearchParams.new
1230
+ search_params.limit = 1
1231
+
1232
+ merchant_filtered_list = plans.list(search_params)
1233
+ customer_filtered_list = plans.list(search_params, customer_id)
1234
+
1235
+
1236
+ - all merchant plans
1237
+
1238
+ plans.all
1239
+
1240
+ - all customer plans
1241
+
1242
+ plans.all(customer_id)
1243
+
1244
+ #### subscriptions
1245
+
1246
+ - create customer subscriptions
1247
+
1248
+ subscriptions.create(subscriptions_hash,customer_id)
1249
+
1250
+ - get customer subscription
1251
+
1252
+ subscriptions.get(subscriptions_hash,customer_id)
1253
+
1254
+ - update customer subscription
1255
+
1256
+ subscription_update_hash={ trial_end_date: "2016-01-12" }
1257
+ subscriptions.update(subscription_id,customer_id, subscription_update_hash )
1258
+
1259
+ - all customer subscription
1260
+
1261
+ subscriptions.all(customer_id)
1262
+
1263
+
1264
+ - each customer subscription
1265
+
1266
+ subscriptions.each(customer_id) {|subscription| p subscription }
1267
+
1268
+
1269
+ - list customer subscriptions
1270
+
1271
+ search_params = OpenpayUtils::SearchParams.new
1272
+ search_params.limit = 1
1273
+
1274
+ customer_filtered_list = subscriptions.list(search_params, customer_id)
1275
+
1276
+ - deletes customer subscription
1277
+
1278
+ subscriptions.delete(customer_id)
1279
+
1280
+ - deletes all customer subscriptions ( sandbox mode only)
1281
+
1282
+ subscriptions.delete(customer_id)
1283
+
1284
+
1285
+ #### Exceptions
1286
+
1287
+ This API generates 3 different Exception classes.
1288
+
1289
+ - **OpenpayException**: Generic base API exception class, Generic API exceptions.
1290
+
1291
+ - Internal server error (500 Internal Server Error).
1292
+ - OpenpayApi factory method, invalid resource name.
1293
+
1294
+ Examples:
1295
+
1296
+ ```ruby
1297
+ #production mode
1298
+ openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
1299
+ customers = openpay_prod.create(:customers)
1300
+ customers.delete_all # will raise an OpenpayException
1301
+ ```
1302
+
1303
+ ```ruby
1304
+ #production mode
1305
+ openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
1306
+ customers = openpay_prod.create(:non_existing_resource) # will raise an OpenpayException
1307
+ ```
1308
+
1309
+ - **OpenpayConnectionException**: Exception class for connection related issues, errors happening prior the server
1310
+ connection.
1311
+
1312
+ - Authentication Error (401 Unauthorized)
1313
+ - Connection Errors.
1314
+ - SSL Errors.
1315
+
1316
+ Example:
1317
+
1318
+ ```ruby
1319
+ #invalid id and key
1320
+ merchant_id = 'santa'
1321
+ private_key = 'invalid'
1322
+
1323
+ openpay = OpenpayApi.new(merchant_id, private_key)
1324
+ customers = openpay.create(:customers)
1325
+
1326
+ begin
1327
+ customers.get('23444422211')
1328
+ rescue OpenpayConnectionException => e
1329
+ e.http_code # => 401
1330
+ e.error_code # => 1002
1331
+ e.description # => 'The api key or merchant id are invalid.'
1332
+ e.json_body # {"category":"request","description":"The api key or merchant id are invalid.","http_code":401,"error_code":1002,"request_id":null}
1333
+ end
1334
+ ```
1335
+
1336
+ - **OpenpayTransactionException**: Errors happening after the initial connection has been initiated, errors during
1337
+ transactions.
1338
+
1339
+ - Bad Request (e.g. Malformed json,Invalid data)
1340
+ - Unprocessable Entity (e.g. invalid data)
1341
+ - Resource not found (404 Not Found)
1342
+ - Conflict (e.g. resource already exists)
1343
+ - PaymentRequired (e.g. insufficient funds)
1344
+ - UnprocessableEntity ( e.g. stolen card )
1345
+
1346
+ *Bad Request* Example:
1347
+
1348
+ ```ruby
1349
+ email = 'foo'
1350
+ customer_hash = FactoryBot.build(:customer, email: email)
1351
+ begin
1352
+ customers.create(customer_hash)
1353
+ rescue OpenpayTransactionException => e
1354
+ e.http_code # => 400
1355
+ e.error_code # => 1001
1356
+ e.description # => 'email\' not a well-formed email address'
1357
+ end
1358
+ ```
1359
+
1360
+ *Resource not found* Example:
1361
+
1362
+ ```ruby
1363
+
1364
+ begin
1365
+ #non existing customer
1366
+ customers.delete('1111')
1367
+ rescue OpenpayApiTransactionError => e
1368
+ e.http_code # => 404
1369
+ e.error_code # =>1005
1370
+ e.description # =>"The customer with id '1111' does not exist"
1371
+ end
1372
+ ```
1373
+
1374
+ ### These exceptions have the following attributes:
1375
+
1376
+ - *category*
1377
+ - *description*
1378
+ - *http_code*
1379
+ - *error_code*
1380
+ - *json_message*
1381
+
1382
+ For more information about categories, descriptions and codes take a look at:
1383
+
1384
+ - http://docs.openpay.mx/#errores
1385
+ - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
1386
+
1387
+ ## Debug
1388
+
1389
+ In the Openpay dashboard you are able to see every request and its corresponding request/response.
1390
+
1391
+ - https://sandbox-dashboard.openpay.mx
1392
+
1393
+ ## Developer Notes
1394
+
1395
+ - bank accounts for merchant cannot be created using the api. It should be done through the dashboard.
1396
+ - Is recommended to reset your account using the dashboard when running serious testing (assure clean state)
1397
+ - check openpay_api.rb for Logger configuration
1398
+ - travis https://travis-ci.org/open-pay/openpay-ruby , if a test fails it will leave some records, it may affect
1399
+ posterior tests. it is recommended to reset the console/account to assure a clean state after a failure occurs.
1400
+
1401
+ ## More information
1402
+
1403
+ For more use cases take a look at the *test/spec* folder
1404
+
1405
+ 1. http://docs.openpay.mx/
1406
+
1407
+
1408
+
1409
+ # Openpay Peru
1410
+
1411
+ ## Description
1412
+
1413
+ ruby client for *Openpay api* services (version 3.0.0)
1414
+
1415
+ This is a ruby client implementing the payment services for *Openpay* at openpay.pe
1416
+
1417
+ For more information about Openpay visit:
1418
+
1419
+ - http://openpay.pe/
1420
+
1421
+ For the full *Openpay api* documentation take a look at:
1422
+
1423
+ - https://www.openpay.pe/api-v2/
1424
+
1425
+ ## Installation
1426
+
1427
+ Add the following line to your Gem file
1428
+
1429
+ #openpay gem
1430
+ gem 'openpay'
1431
+
1432
+ Update your bundle:
1433
+
1434
+ $ bundle
1435
+
1436
+ Or install it from the command line:
1437
+
1438
+ $ gem install openpay
1439
+
1440
+ ### Requirements
1441
+
1442
+ * ruby 2.4 or higher
1443
+
1444
+ ## Usage
1445
+
1446
+ ### Initialization
1447
+
1448
+ ```ruby
1449
+ require 'openpay'
1450
+
1451
+ #merchant and private key
1452
+ merchant_id = 'mywvupjjs9xdnryxtplq'
1453
+ private_key = 'sk_92b25d3baec149e6b428d81abfe37006'
1454
+ country = 'pe'
1455
+
1456
+ #An openpay resource factory instance is created out of the OpenpayApi
1457
+ #it points to the development environment by default.
1458
+ #The country value can take 'mx' to Mexico or 'co' for Colombia or 'pe' for Peru
1459
+ openpay = OpenpayApi.new(merchant_id, private_key, country,'pe')
1460
+
1461
+ #To enable production mode you should pass a third argument as true.
1462
+ #openpay_prod=OpenpayApi.new(merchant_id,private_key,true)
1463
+
1464
+ #This ruby client manages a default timeout of 90 seconds to make the request
1465
+ # to Openpay services, if you need to modify this value, you need to explicitly
1466
+ # define the type of environment and followed by the new value for the timeout.
1467
+ #Syntax:
1468
+ # openpay_prod=OpenpayApi.new(merchant_id,private_key,isProduction,timeout)
1469
+ #Example:
1470
+ # openpay_prod=OpenpayApi.new(merchant_id,private_key,false,30)
1471
+ ```
1472
+
1473
+ The openpay factory instance is in charge to generate the required resources through a factory method (create). Resource
1474
+ classes should be initialized using the factory method as described below.
1475
+
1476
+ ```ruby
1477
+ #creating an instance for each available resource
1478
+ charges = openpay.create(:charges)
1479
+ checkouts = openpay.create(:checkouts)
1480
+ customers = openpay.create(:customers)
1481
+ cards = openpay.create(:cards)
1482
+ webhooks = openpay.create(:webhooks)
1483
+
1484
+ ```
1485
+
1486
+ According to the current version of the *Openpay api* the available resources are:
1487
+
1488
+ - *charges*
1489
+ - *checkouts*
1490
+ - *customers*
1491
+ - *cards*
1492
+ - *webhooks*
1493
+
1494
+ Each rest resource exposed in the rest *Openpay api* is represented by a class in this ruby API, being **
1495
+ OpenpayResource** the base class.
1496
+
1497
+ ### Implementation
1498
+
1499
+ Each resource depending of its structure and available methods, will have one or more of the methods described under the
1500
+ methods subsection. Below a short description about the implementation high level details. For detailed documentation
1501
+ take a look a the openpay api documentation.
1502
+
1503
+ #### Arguments
1504
+
1505
+ Given most resources belong, either to a merchant or a customer, the api was designed taking this in consideration, so:
1506
+
1507
+ The first argument represent the json/hash object, while the second argument which is optional represents the **
1508
+ customer_id**. So if just one argument is provided the action will be performed at the merchant level, but if the second
1509
+ argument is provided passing the **customer_id**, the action will be performed at the customer level.
1510
+
1511
+ The following illustrates the api design.
1512
+
1513
+ ```ruby
1514
+ #Merchant
1515
+ hash_out = open_pay_resource.create(hash_in)
1516
+ json_out = open_pay_resource.create(json_in)
1517
+
1518
+ #Customer
1519
+ hash_out = open_pay_resource.create(hash_in, customer_id)
1520
+ json_out = open_pay_resource.create(json_in, customer_id)
1521
+
1522
+ ```
1523
+
1524
+ #### Methods Inputs/Outputs
1525
+
1526
+ This api supports both ruby hashes and json strings as inputs and outputs. (See previous example)
1527
+ If a ruby hash is passed in as in input, a hash will be returned as the method output. if a json string is passed in as
1528
+ an input, a json string will be returned as the method function output.
1529
+
1530
+ This code excerpt from a specification demonstrates how you can use hashes and json strings interchangeably.
1531
+
1532
+ Methods without inputs will return a ruby hash.
1533
+
1534
+ ```ruby
1535
+ it 'creates a fee using a json message' do
1536
+ #create new customer
1537
+ customer_hash = FactoryBot.build(:customer_col)
1538
+ customer = @customers.create(customer_hash)
1539
+
1540
+ #create customer card , using factory girl to build the hash for us
1541
+ card_hash = FactoryBot.build(:valid_card_col)
1542
+ card = @cards.create(card_hash, customer['id'])
1543
+
1544
+ #create charge
1545
+ charge_hash = FactoryBot.build(:card_charge_col, source_id: card['id'], order_id: card['id'], amount: 4000)
1546
+ charge = @charges.create(charge_hash, customer['id'])
1547
+
1548
+ end
1549
+ ```
1550
+
1551
+ Here you can see how the **card_hash** representation looks like.
1552
+
1553
+ ```ruby
1554
+ require 'pp'
1555
+ pp card_hash =>
1556
+
1557
+ { :holder_name => 'Vicente Olmos',
1558
+ :card_number => '4111111111111111',
1559
+ :cvv2 => '111',
1560
+ :expiration_month => '09',
1561
+ :expiration_year => '25' }
1562
+ ```
1563
+
1564
+ Next, how we construct the preceding hash using **FactoryBot**.
1565
+ **FactoryBot** was used in our test suite to facilitate hash construction. It may help you as well at your final
1566
+ implementation if you decide to use hashes.
1567
+ (more examples at *test/Factories.rb*)
1568
+
1569
+ ```ruby
1570
+
1571
+ FactoryBot.define do
1572
+ factory :valid_card_col, class: Hash do
1573
+ holder_name 'Vicente Olmos'
1574
+ expiration_month '09'
1575
+ card_number '4111111111111111'
1576
+ expiration_year '14'
1577
+ cvv2 '111'
1578
+ initialize_with { attributes }
1579
+ end
1580
+ ```
1581
+
1582
+ ### Methods design
1583
+
1584
+ This ruby API standardize the method names across all different resources using the **create**,**get**,**update** and **
1585
+ delete** verbs.
1586
+
1587
+ For full method documentation take a look at:
1588
+
1589
+ - http://docs.openpay.pe/
1590
+
1591
+ The test suite at *test/spec* is a good source of reference.
1592
+
1593
+ ##### create
1594
+
1595
+ Creates the given resource
1596
+
1597
+ ```ruby
1598
+ open_pay_resource.create(representation, customer_id = nil)
1599
+ ```
1600
+
1601
+ ##### get
1602
+
1603
+ Gets an instance of a given resource
1604
+
1605
+ ```ruby
1606
+ open_pay_resource.get(object_id, customer_id = nil)
1607
+ ```
1608
+
1609
+ ##### update
1610
+
1611
+ Updates an instance of a given resource
1612
+
1613
+ ```ruby
1614
+ open_pay_resource.update(representation, customer_id = nil)
1615
+ ```
1616
+
1617
+ ##### delete
1618
+
1619
+ Deletes an instance of the given resource
1620
+
1621
+ ```ruby
1622
+ open_pay_resource.delete(object_id, customer_id = nil)
1623
+ ```
1624
+
1625
+ ##### all
1626
+
1627
+ Returns an array of all instances of a resource
1628
+
1629
+ ```ruby
1630
+ open_pay_resource.all(customer_id = nil)
1631
+ ```
1632
+
1633
+ ##### each
1634
+
1635
+ Returns a block for each instance resource
1636
+
1637
+ ```ruby
1638
+ open_pay_resource.each(customer_id = nil)
1639
+ ```
1640
+
1641
+ ##### delete_all(available only under the development environment)
1642
+
1643
+ Deletes all instances of the given resource
1644
+
1645
+ ```ruby
1646
+ #in case this method is executed under the production environment an OpenpayException will be raised.
1647
+ open_pay_resource.delete_all(customer_id = nil)
1648
+ ```
1649
+
1650
+ ### API Methods
1651
+
1652
+ #### charges
1653
+
1654
+ - creates merchant charge
1655
+
1656
+ charges.create(charge_hash)
1657
+
1658
+ - creates customer charge
1659
+
1660
+ charges.create(charge_hash,customer_id)
1661
+
1662
+ - gets merchant charge
1663
+
1664
+ merchant_charge=charges.get(charge_id)
1665
+
1666
+ - gets customer charge
1667
+
1668
+ customer_charge=charges.get(charge_id,customer_id)
1669
+
1670
+ - each merchant charge
1671
+
1672
+ charges.each {|charge| p charge}
1673
+
1674
+ - list merchant / customer charges
1675
+
1676
+ search_params = OpenpayUtils::SearchParams.new
1677
+ search_params.limit = 1
1678
+
1679
+ merchant_filtered_list = charges.list(search_params)
1680
+ customer_filtered_list = charges.list(search_params, customer_id)
1681
+
1682
+ - each customer charge
1683
+
1684
+ charges.each(customer_id) {|charge| p charge}
1685
+
1686
+
1687
+ - all merchant charge
1688
+
1689
+ charges.all
1690
+
1691
+ - all customer charge
1692
+
1693
+ charges.all(customer_id)
1694
+
1695
+ #### checkouts
1696
+
1697
+ - create checkout
1698
+
1699
+ checkouts.create(checkout_hash,customer_id)
1700
+
1701
+ checkouts.create(checkout_hash)
1702
+
1703
+ - get chekout
1704
+
1705
+ checkouts.get(checkout_id)
1706
+
1707
+ #### cards
1708
+
1709
+ - creates a merchant card
1710
+
1711
+ cards.create(card_json)
1712
+
1713
+ - creates a customer card
1714
+
1715
+ cards.create(card_hash, customer_id)
1716
+
1717
+ - gets merchant card
1718
+
1719
+ card=cards.get(card_id)
1720
+
1721
+ - gets customer card
1722
+
1723
+ card=cards.get(card_id, customer_id)
1724
+
1725
+ - each merchant card
1726
+
1727
+ cards.each {|merchant_card| p card}
1728
+
1729
+ - list merchant / customer cards
1730
+
1731
+ search_params = OpenpayUtils::SearchParams.new
1732
+ search_params.limit = 1
1733
+
1734
+ merchant_filtered_list = cards.list(search_params)
1735
+ customer_filtered_list = cards.list(search_params, customer_id)
1736
+
1737
+ - each customer card
1738
+
1739
+ cards.each(customer_id) {|customer_card | p customer_card }
1740
+
1741
+ - all merchant cards
1742
+
1743
+ merchant_cards=cards.all
1744
+
1745
+ - all customer cards
1746
+
1747
+ customer_cards=cards.all(customer_id)
1748
+
1749
+ - delete merchant card
1750
+
1751
+ cards.delete(card_id)
1752
+
1753
+ - delete customer card
1754
+
1755
+ cards.delete(card_id,customer_id)
1756
+
1757
+ - delete all merchant cards
1758
+
1759
+ cards.delete_all
1760
+
1761
+ - delete all customer cards
1762
+
1763
+ cards.delete_all(customer_id)
1764
+
1765
+ #### customers
1766
+
1767
+ - creates customer
1768
+
1769
+ customers.create(customer_json)
1770
+
1771
+ - get customer
1772
+
1773
+ customer=customers.get(customer_id)
1774
+
1775
+ - update customer
1776
+
1777
+ customers.update(customer_hash)
1778
+
1779
+ - delete customer
1780
+
1781
+ customers.delete(customer_id)
1782
+
1783
+ - each customer
1784
+
1785
+ customers.each do {|customer| p customer }
1786
+
1787
+ - list customers
1788
+
1789
+ search_params = OpenpayUtils::SearchParams.new
1790
+ search_params.limit = 1
1791
+
1792
+ customers_filtered_list = customers.list(search_params)
1793
+
1794
+
1795
+ - all customer
1796
+
1797
+ all_customers=customers.all
1798
+
1799
+ - delete all customers (sand box mode only)
1800
+
1801
+ all_customers=customers.all
1802
+
1803
+ #### webhooks
1804
+
1805
+ - create webhook
1806
+
1807
+ webhooks.create(webhook_hash)
1808
+
1809
+ - get webhook
1810
+
1811
+ webhook.get(webhook_id)
1812
+
1813
+ - all webhooks
1814
+
1815
+ webhooks.all()
1816
+
1817
+
1818
+ #### Exceptions
1819
+
1820
+ This API generates 3 different Exception classes.
1821
+
1822
+ - **OpenpayException**: Generic base API exception class, Generic API exceptions.
1823
+
1824
+ - Internal server error (500 Internal Server Error).
1825
+ - OpenpayApi factory method, invalid resource name.
1826
+
1827
+ Examples:
1828
+
1829
+ ```ruby
1830
+ #production mode
1831
+ openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
1832
+ customers = openpay_prod.create(:customers)
1833
+ customers.delete_all # will raise an OpenpayException
1834
+ ```
1835
+
1836
+ ```ruby
1837
+ #production mode
1838
+ openpay_prod = OpenpayApi.new(@merchant_id, @private_key, true)
1839
+ customers = openpay_prod.create(:non_existing_resource) # will raise an OpenpayException
1840
+ ```
1841
+
1842
+ - **OpenpayConnectionException**: Exception class for connection related issues, errors happening prior the server
1843
+ connection.
1844
+
1845
+ - Authentication Error (401 Unauthorized)
1846
+ - Connection Errors.
1847
+ - SSL Errors.
1848
+
1849
+ Example:
1850
+
1851
+ ```ruby
1852
+ #invalid id and key
1853
+ merchant_id = 'santa'
1854
+ private_key = 'invalid'
1855
+
1856
+ openpay = OpenpayApi.new(merchant_id, private_key)
1857
+ customers = openpay.create(:customers)
1858
+
1859
+ begin
1860
+ customers.get('23444422211')
1861
+ rescue OpenpayConnectionException => e
1862
+ e.http_code # => 401
1863
+ e.error_code # => 1002
1864
+ e.description # => 'The api key or merchant id are invalid.'
1865
+ e.json_body # {"category":"request","description":"The api key or merchant id are invalid.","http_code":401,"error_code":1002,"request_id":null}
1866
+ end
1867
+ ```
1868
+
1869
+ - **OpenpayTransactionException**: Errors happening after the initial connection has been initiated, errors during
1870
+ transactions.
1871
+
1872
+ - Bad Request (e.g. Malformed json,Invalid data)
1873
+ - Unprocessable Entity (e.g. invalid data)
1874
+ - Resource not found (404 Not Found)
1875
+ - Conflict (e.g. resource already exists)
1876
+ - PaymentRequired (e.g. insufficient funds)
1877
+ - UnprocessableEntity ( e.g. stolen card )
1878
+
1879
+ *Bad Request* Example:
1880
+
1881
+ ```ruby
1882
+ email = 'foo'
1883
+ customer_hash = FactoryBot.build(:customer, email: email)
1884
+ begin
1885
+ customers.create(customer_hash)
1886
+ rescue OpenpayTransactionException => e
1887
+ e.http_code # => 400
1888
+ e.error_code # => 1001
1889
+ e.description # => 'email\' not a well-formed email address'
1890
+ end
1891
+ ```
1892
+
1893
+ *Resource not found* Example:
1894
+
1895
+ ```ruby
1896
+
1897
+ begin
1898
+ #non existing customer
1899
+ customers.delete('1111')
1900
+ rescue OpenpayApiTransactionError => e
1901
+ e.http_code # => 404
1902
+ e.error_code # =>1005
1903
+ e.description # =>"The customer with id '1111' does not exist"
1904
+ end
1905
+ ```
1906
+
1907
+ ### These exceptions have the following attributes:
1908
+
1909
+ - *category*
1910
+ - *description*
1911
+ - *http_code*
1912
+ - *error_code*
1913
+ - *json_message*
1914
+
1915
+ For more information about categories, descriptions and codes take a look at:
1916
+
1917
+ - http://docs.openpay.mx/#errores
1918
+ - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
1919
+
1920
+ ## Debug
1921
+
1922
+ In the Openpay dashboard you are able to see every request and its corresponding request/response.
1923
+
1924
+ - https://sandbox-dashboard.openpay.mx
1925
+
1926
+ ## Developer Notes
1927
+
1928
+ - bank accounts for merchant cannot be created using the api. It should be done through the dashboard.
1929
+ - Is recommended to reset your account using the dashboard when running serious testing (assure clean state)
1930
+ - check openpay_api.rb for Logger configuration
1931
+ - travis https://travis-ci.org/open-pay/openpay-ruby , if a test fails it will leave some records, it may affect
1932
+ posterior tests. it is recommended to reset the console/account to assure a clean state after a failure occurs.
1933
+
1934
+ ## More information
1935
+
1936
+ For more use cases take a look at the *test/spec* folder
1937
+
1938
+ 1. http://docs.openpay.mx/
1939
+
1940
+
1941
+
1942
+
1943
+
1944
+
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+
1958
+
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+
1984
+