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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +13 -0
- data/README.md +1984 -0
- data/Rakefile +16 -0
- data/lib/openpay/bankaccounts.rb +58 -0
- data/lib/openpay/cards.rb +73 -0
- data/lib/openpay/charges.rb +101 -0
- data/lib/openpay/colombia/cards_co.rb +73 -0
- data/lib/openpay/colombia/charges_co.rb +76 -0
- data/lib/openpay/colombia/customers_co.rb +166 -0
- data/lib/openpay/colombia/plans_co.rb +17 -0
- data/lib/openpay/colombia/pse_co.rb +17 -0
- data/lib/openpay/colombia/subscriptions_co.rb +50 -0
- data/lib/openpay/colombia/tokens_co.rb +5 -0
- data/lib/openpay/colombia/webhooks_co.rb +5 -0
- data/lib/openpay/customers.rb +200 -0
- data/lib/openpay/errors/openpay_connection_exception.rb +3 -0
- data/lib/openpay/errors/openpay_exception.rb +29 -0
- data/lib/openpay/errors/openpay_exception_factory.rb +56 -0
- data/lib/openpay/errors/openpay_transaction_exception.rb +5 -0
- data/lib/openpay/fees.rb +5 -0
- data/lib/openpay/open_pay_resource.rb +295 -0
- data/lib/openpay/open_pay_resource_factory.rb +17 -0
- data/lib/openpay/openpay_api.rb +72 -0
- data/lib/openpay/payouts.rb +55 -0
- data/lib/openpay/peru/cards_pe.rb +73 -0
- data/lib/openpay/peru/charges_pe.rb +76 -0
- data/lib/openpay/peru/checkouts_pe.rb +51 -0
- data/lib/openpay/peru/customers_pe.rb +79 -0
- data/lib/openpay/peru/tokens_pe.rb +5 -0
- data/lib/openpay/peru/webhooks_pe.rb +5 -0
- data/lib/openpay/plans.rb +17 -0
- data/lib/openpay/points.rb +10 -0
- data/lib/openpay/subscriptions.rb +50 -0
- data/lib/openpay/tokens.rb +7 -0
- data/lib/openpay/transfers.rb +39 -0
- data/lib/openpay/utils/country.rb +3 -0
- data/lib/openpay/utils/search_params.rb +24 -0
- data/lib/openpay/webhooks.rb +9 -0
- data/lib/openpay.rb +55 -0
- data/lib/version.rb +3 -0
- data/openpay.gemspec +30 -0
- data/test/Factories.rb +524 -0
- data/test/spec/bankaccounts_spec.rb +52 -0
- data/test/spec/cards_spec.rb +437 -0
- data/test/spec/charges_spec.rb +382 -0
- data/test/spec/colombia/cards_col_spec.rb +364 -0
- data/test/spec/colombia/charges_col_spec.rb +258 -0
- data/test/spec/colombia/customers_co_spec.rb +151 -0
- data/test/spec/colombia/plans_col_spec.rb +133 -0
- data/test/spec/colombia/pse_col_spec.rb +49 -0
- data/test/spec/colombia/subscriptions_col_spec.rb +230 -0
- data/test/spec/colombia/tokens_col_spec.rb +38 -0
- data/test/spec/customers_spec.rb +172 -0
- data/test/spec/exceptions_spec.rb +105 -0
- data/test/spec/fees_spec.rb +166 -0
- data/test/spec/openpayresource_spec.rb +54 -0
- data/test/spec/payouts_spec.rb +231 -0
- data/test/spec/peru/cards_pe_spec.rb +363 -0
- data/test/spec/peru/charges_pe_spec.rb +218 -0
- data/test/spec/peru/checkouts_pe_spec.rb +71 -0
- data/test/spec/peru/customers_pe_spec.rb +151 -0
- data/test/spec/peru/tokens_pe_spec.rb +38 -0
- data/test/spec/peru/webhook_pe_spec.rb +50 -0
- data/test/spec/plans_spec.rb +158 -0
- data/test/spec/points_spec.rb +26 -0
- data/test/spec/requesttimeout_spec.rb +22 -0
- data/test/spec/subscriptions_spec.rb +294 -0
- data/test/spec/transfers_spec.rb +219 -0
- data/test/spec/utils/search_params_spec.rb +36 -0
- data/test/spec_helper.rb +24 -0
- metadata +219 -0
data/README.md
ADDED
@@ -0,0 +1,1984 @@
|
|
1
|
+

|
2
|
+
|
3
|
+
[](https://travis-ci.org/open-pay/openpay-ruby)
|
4
|
+
|
5
|
+
[](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
|
+
|