recurrente 0.1.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 +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +97 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/recurrente/version.rb +3 -0
- data/lib/recurrente.rb +917 -0
- data/recurrente.gemspec +28 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 716ce762602e9f49f4b374526b10bec58c0c792c
|
4
|
+
data.tar.gz: 6a5d4fc2d65dceb23234190ee5cf0aab2c47c039
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c23c626585fac94966144472e3935ebd2eac7a7e220f5a3bf6a9c622f3f183eccf23846c7995039645a6321b5129a17efe19dd8d2fd21d03afbd5b63564e97f5
|
7
|
+
data.tar.gz: f56e9a9196fb92763aba00020866b07fa95c75e0c4998fb6c5555e230b68d58710042c90f1c10fe7a55f95cd4aa3840d8c99b397bc8fc9e36bfa623e8fb227a5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 gabosarmiento
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# Recurrente
|
2
|
+
|
3
|
+
This is a work in progress that seeks to explore the Payulatam's recurring payments api.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'recurrente'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install recurrente
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
This is divided into 5 sections in the same way that is explained in Payu's website.
|
24
|
+
|
25
|
+
1. Plans
|
26
|
+
2. Suscriptors
|
27
|
+
3. Credit Cards
|
28
|
+
4. Suscriptions
|
29
|
+
5. Extra charges
|
30
|
+
|
31
|
+
Before anything you'll need to change the test data within an initializer in the config folder in order to replace these constants:
|
32
|
+
|
33
|
+
# TEST DATA
|
34
|
+
API_URL = "http://stg.api.payulatam.com/payments-api/rest/v4.3"
|
35
|
+
API_KEY = "6u39nqhq8ftd0hlvnjfs66eh8c"
|
36
|
+
API_LOGIN = "11959c415b33d0c"
|
37
|
+
MERCHANT_ID = "500238"
|
38
|
+
ACCOUNT = "500538"
|
39
|
+
|
40
|
+
Notice that the API_URL is pointing to http instead of using a secure protocol. This is just for testing purposes.
|
41
|
+
|
42
|
+
## COVERED ENDPOINTS
|
43
|
+
|
44
|
+
Everything is contained in the same ruby file because I wanted to see every method in one place. Clearly this needs improvement but so far this is what I got.
|
45
|
+
|
46
|
+
### PLANS
|
47
|
+
#### 1.1 GET - Mostrar todos los planes
|
48
|
+
#### 1.2 POST - Crear un nuevo Plan
|
49
|
+
#### 1.3 GET - Consultar un plan existente
|
50
|
+
#### 1.4 PUT - Actualizar un plan existente
|
51
|
+
#### 1.5 DELETE - Borrar un Plan existente
|
52
|
+
|
53
|
+
### SUSCRIPTORS
|
54
|
+
#### 2.1 POST - Crear un Suscriptor
|
55
|
+
#### 2.2 GET - Buscar un Suscriptor
|
56
|
+
#### 2.3 PUT - Actualizar un Suscriptor
|
57
|
+
#### 2.4 DELETE - Borrar un Suscriptor
|
58
|
+
|
59
|
+
### CREDIT CARDS
|
60
|
+
#### 3.1 POST - Crear una Tarjeta de Credito a un Suscriptor
|
61
|
+
#### 3.2 GET - Buscar una tarjeta de crédito
|
62
|
+
#### 3.3 GET - Buscar tarjetas de crédito de un usuario
|
63
|
+
#### 3.4 DELETE - Eliminar una tarjeta de crédito
|
64
|
+
|
65
|
+
### SUSCRIPTIONS
|
66
|
+
#### 4.1 POST - Crear suscripción
|
67
|
+
##### 4.1.1 CON TODOS LOS ELEMENTOS NUEVOS
|
68
|
+
##### 4.1.2 CON TODOS LOS ELEMENTOS EXISTENTES
|
69
|
+
##### 4.1.3 PLAN Y SUSCRIPTOR YA CREADOS Y UNA TARJETA NUEVA
|
70
|
+
##### 4.1.4 CLIENTE Y TARJETA YA CREADOS, CON PLAN NUEVO
|
71
|
+
#### 4.2 PUT - Update Suscription Credit Card
|
72
|
+
#### 4.3 GET - Buscar una Suscripción
|
73
|
+
#### 4.4 GET - Buscar las suscripciones de un Cliente
|
74
|
+
#### 4.5 POST - Cancelar una Suscripción. Status CANCELLED
|
75
|
+
|
76
|
+
### CHARGES
|
77
|
+
#### 5.1 POST - Crear un cargo adicional
|
78
|
+
#### 5.2 PUT - Actualizar un cargo adicional
|
79
|
+
#### 5.3 GET - Buscar un Cargo Extra por ID
|
80
|
+
#### 5.4 GET - Buscar un Cargo Extra por Suscripcion
|
81
|
+
#### 5.5 POST - Borrar un cargo de la suscripción
|
82
|
+
|
83
|
+
## Development
|
84
|
+
|
85
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
86
|
+
|
87
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
88
|
+
|
89
|
+
## Contributing
|
90
|
+
|
91
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gabosarmiento/recurrente.
|
92
|
+
|
93
|
+
|
94
|
+
## License
|
95
|
+
|
96
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
97
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "recurrente"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/recurrente.rb
ADDED
@@ -0,0 +1,917 @@
|
|
1
|
+
require "recurrente/version"
|
2
|
+
require "httparty"
|
3
|
+
require 'json'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
# TEST DATA
|
7
|
+
API_URL = "http://stg.api.payulatam.com/payments-api/rest/v4.3"
|
8
|
+
API_KEY = "6u39nqhq8ftd0hlvnjfs66eh8c"
|
9
|
+
API_LOGIN = "11959c415b33d0c"
|
10
|
+
MERCHANT_ID = "500238"
|
11
|
+
ACCOUNT = "500538"
|
12
|
+
|
13
|
+
|
14
|
+
module Recurrente
|
15
|
+
include HTTParty
|
16
|
+
base_uri API_URL
|
17
|
+
headers = {
|
18
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
19
|
+
'Accept' => 'application/json',
|
20
|
+
'Accept-language' => 'es'
|
21
|
+
}
|
22
|
+
# No es necesario encodear con base64 ya que httparty lo hace por debajo
|
23
|
+
basic_auth API_LOGIN, API_KEY
|
24
|
+
default_timeout 4 # hard timeout after 4 seconds
|
25
|
+
|
26
|
+
attr_accessor :auth
|
27
|
+
@auth = "Basic " + Base64.encode64("#{API_LOGIN}:#{API_KEY}")
|
28
|
+
# Una buena practica de consumir una API es definir los timeouts que podrían
|
29
|
+
# acumularse y tumbar la pagina al tener los servidores atentidendo las peticiones
|
30
|
+
# HTTParty sacará un Net::OpenTimeout si no puede conectarse al servidor y un
|
31
|
+
# Net::ReadTimeout si al leer la respuesta del servidor se cuelga.
|
32
|
+
|
33
|
+
def self.handle_timeouts
|
34
|
+
begin
|
35
|
+
yield
|
36
|
+
rescue Net::OpenTimeout, Net::ReadTimeout
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
########################################################################
|
42
|
+
# ****** 1 - PLANES ****** #
|
43
|
+
#########################################################################
|
44
|
+
# Mediante esta funcionalidad puedes crear el plan de pagos de una #
|
45
|
+
# una suscripción con las debidas restricciones y su recurrencia #
|
46
|
+
#########################################################################
|
47
|
+
|
48
|
+
# 1.1 GET - Mostrar todos los planes
|
49
|
+
def self.find_plans
|
50
|
+
handle_timeouts do
|
51
|
+
response = get("/plans")
|
52
|
+
JSON.pretty_generate(response.parsed_response)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# 1.2 POST - Crear un nuevo Plan
|
57
|
+
def self.create_plan(codigo, descripcion, intervalo, cantidad_intervalos, moneda, valor, impuesto, base_impuesto, reintentos, dias_entre_reintentos, cobros,periodo_de_gracia)
|
58
|
+
#######################################################################################################################
|
59
|
+
# Recurrente.create_plan("Netflix-001", "Plan semanal", "WEEK", "1", "COP", "14000", "0", "0", "2", "2", "12", "2") #
|
60
|
+
# codigo Es el nombre con el que se manipula el plan. #
|
61
|
+
# descripcion Es la descripción del Plan #
|
62
|
+
# intervalo Es la frecuencia con la que se repite el cobro: DAY, WEEK, MONTH, YEAR. #
|
63
|
+
# cantidad_intervalos Es lo que define cada cuanto se realiza el cobro de la suscripción #
|
64
|
+
# moneda Es el código para definir las divisas según el estándar internacional ISO 4217 #
|
65
|
+
# valor Es el valor del plan #
|
66
|
+
# base_impuesto Es el valor para calcular la devolución del impuesto #
|
67
|
+
# impuesto Es el valor del impuesto #
|
68
|
+
# reintentos Es la cantidad de intentos antes de ser rechazado el pago #
|
69
|
+
# cobros Es la cantidad máxima de pagos que espera el plan #
|
70
|
+
# periodo de gracia Es la cantidad máxima de pagos pendientes antes de cancelada #
|
71
|
+
# dias_entre_reintentos Es la cantidad de días de espera entre los reintentos. #
|
72
|
+
#######################################################################################################################
|
73
|
+
|
74
|
+
handle_timeouts do
|
75
|
+
headers = {
|
76
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
77
|
+
'Accept' => 'application/json',
|
78
|
+
'Accept-language' => 'es',
|
79
|
+
'Authorization' => @auth
|
80
|
+
}
|
81
|
+
params = {
|
82
|
+
"accountId": ACCOUNT,
|
83
|
+
"planCode": codigo,
|
84
|
+
"description": descripcion,
|
85
|
+
"interval": intervalo,
|
86
|
+
"intervalCount": cantidad_intervalos ,
|
87
|
+
"maxPaymentsAllowed": cobros,
|
88
|
+
"paymentAttemptsDelay": dias_entre_reintentos,
|
89
|
+
"maxPaymentAttempts": reintentos,
|
90
|
+
"maxPendingPayments": periodo_de_gracia,
|
91
|
+
"additionalValues": [
|
92
|
+
{
|
93
|
+
"name": "PLAN_VALUE",
|
94
|
+
"value": valor,
|
95
|
+
"currency": moneda
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"name": "PLAN_TAX",
|
99
|
+
"value": impuesto,
|
100
|
+
"currency": moneda
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"name": "PLAN_TAX_RETURN_BASE",
|
104
|
+
"value": base_impuesto,
|
105
|
+
"currency": moneda
|
106
|
+
}
|
107
|
+
]
|
108
|
+
}
|
109
|
+
# Es necesario incluir los encabezados de otra forma lo identifica de otro typo distinto a json
|
110
|
+
|
111
|
+
|
112
|
+
response = post("/plans", body: params.to_json, headers: headers)
|
113
|
+
|
114
|
+
case response.code
|
115
|
+
when 200..202
|
116
|
+
puts JSON.pretty_generate(response.parsed_response)
|
117
|
+
retrieve_plan response
|
118
|
+
when 404
|
119
|
+
response.message
|
120
|
+
when 500..600
|
121
|
+
puts "OMG ERROR #{response.code}"
|
122
|
+
else
|
123
|
+
response
|
124
|
+
end
|
125
|
+
end # <-- Timeout Block
|
126
|
+
end
|
127
|
+
|
128
|
+
# 1.3 GET - Consultar un plan existente
|
129
|
+
def self.find_plan(plan_code)
|
130
|
+
handle_timeouts do
|
131
|
+
response = get("/plans" + "/#{plan_code}")
|
132
|
+
puts JSON.pretty_generate(response.parsed_response)
|
133
|
+
response
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# 1.4 PUT - Actualizar un plan existente
|
138
|
+
|
139
|
+
def self.update_plan(plan_code, codigo, descripcion, valor, impuesto, base_impuesto, reintentos, periodo_de_gracia, dias_entre_reintentos)
|
140
|
+
# Atributos eliminados cuenta, intervalo, cantidad de intervalos, cobros, moneda
|
141
|
+
handle_timeouts do
|
142
|
+
headers = {
|
143
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
144
|
+
'Accept' => 'application/json',
|
145
|
+
'Accept-language' => 'es',
|
146
|
+
'Authorization' => @auth
|
147
|
+
}
|
148
|
+
params = {
|
149
|
+
"planCode": codigo,
|
150
|
+
"description": descripcion,
|
151
|
+
"paymentAttemptsDelay": dias_entre_reintentos,
|
152
|
+
"maxPaymentAttempts": reintentos,
|
153
|
+
"maxPendingPayments": periodo_de_gracia,
|
154
|
+
"additionalValues": [
|
155
|
+
{
|
156
|
+
"name": "PLAN_VALUE",
|
157
|
+
"value": valor
|
158
|
+
},
|
159
|
+
{
|
160
|
+
"name": "PLAN_TAX",
|
161
|
+
"value": impuesto
|
162
|
+
},
|
163
|
+
{
|
164
|
+
"name": "PLAN_TAX_RETURN_BASE",
|
165
|
+
"value": base_impuesto
|
166
|
+
}
|
167
|
+
]
|
168
|
+
}
|
169
|
+
# Es necesario incluir los encabezados de otra forma lo identifica de otro typo distinto a json
|
170
|
+
|
171
|
+
|
172
|
+
response = put("/plans" + "/#{plan_code}", body: params.to_json, headers: headers)
|
173
|
+
|
174
|
+
|
175
|
+
case response.code
|
176
|
+
when 200..202
|
177
|
+
puts JSON.pretty_generate(response.parsed_response)
|
178
|
+
retrieve_plan response
|
179
|
+
when 404
|
180
|
+
response.message
|
181
|
+
when 500..600
|
182
|
+
puts "OMG ERROR #{response.code}"
|
183
|
+
else
|
184
|
+
response
|
185
|
+
end
|
186
|
+
end # <-- Timeout block
|
187
|
+
end
|
188
|
+
|
189
|
+
# 1.5 DELETE - Borrar un Plan existente
|
190
|
+
|
191
|
+
def self.delete_plan(plan_code)
|
192
|
+
handle_timeouts do
|
193
|
+
response = delete("/plans" + "/#{plan_code}")
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
#####################################################################
|
198
|
+
# ****** 2 - SUSCRIPTORES ****** #
|
199
|
+
#####################################################################
|
200
|
+
# Un cliente es la unidad que identifica quien será el beneficiario #
|
201
|
+
# de un producto o servicio prestado y que se encuentra asociado a #
|
202
|
+
# un plan de pagos recurrentes. #
|
203
|
+
#####################################################################
|
204
|
+
|
205
|
+
# 2.1 POST - Crear un Suscriptor
|
206
|
+
def self.create_suscriptor(name,email)
|
207
|
+
handle_timeouts do
|
208
|
+
headers = {
|
209
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
210
|
+
'Accept' => 'application/json',
|
211
|
+
'Accept-language' => 'es',
|
212
|
+
'Authorization' => @auth
|
213
|
+
}
|
214
|
+
|
215
|
+
params = {
|
216
|
+
"fullName": name,
|
217
|
+
"email": email
|
218
|
+
}
|
219
|
+
|
220
|
+
response = post('/customers', body: params.to_json, headers: headers)
|
221
|
+
|
222
|
+
case response.code
|
223
|
+
when 200..202
|
224
|
+
puts response
|
225
|
+
puts JSON.pretty_generate(response.parsed_response)
|
226
|
+
retrieve_customer response
|
227
|
+
when 404
|
228
|
+
response.message
|
229
|
+
when 500..600
|
230
|
+
puts "OMG ERROR #{response.code}"
|
231
|
+
else
|
232
|
+
response
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# 2.2 GET - Buscar un Suscriptor
|
238
|
+
def self.find_suscriptor(customer_id)
|
239
|
+
handle_timeouts do
|
240
|
+
response = get("/customers" + "/#{customer_id}")
|
241
|
+
|
242
|
+
case response.code
|
243
|
+
when 200..202
|
244
|
+
puts JSON.pretty_generate(response.parsed_response)
|
245
|
+
response.parsed_response["customer"] # Retorna el hash del suscriptor
|
246
|
+
when 404
|
247
|
+
response.message
|
248
|
+
when 500..600
|
249
|
+
puts "OMG ERROR #{response.code}"
|
250
|
+
else
|
251
|
+
response
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# 2.3 PUT - Actualizar un Suscriptor
|
257
|
+
def self.update_suscriptor(customer_id,name,email)
|
258
|
+
handle_timeouts do
|
259
|
+
headers = {
|
260
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
261
|
+
'Accept' => 'application/json',
|
262
|
+
'Accept-language' => 'es',
|
263
|
+
'Authorization' => @auth
|
264
|
+
}
|
265
|
+
|
266
|
+
params = {
|
267
|
+
"fullName": name,
|
268
|
+
"email": email
|
269
|
+
}
|
270
|
+
|
271
|
+
response = put('/customers'+ "/#{customer_id}", body: params.to_json, headers: headers)
|
272
|
+
|
273
|
+
|
274
|
+
case response.code
|
275
|
+
when 200..202
|
276
|
+
puts JSON.pretty_generate(response.parsed_response)
|
277
|
+
retrieve_customer response
|
278
|
+
when 404
|
279
|
+
response.message
|
280
|
+
when 500..600
|
281
|
+
puts "OMG ERROR #{response.code}"
|
282
|
+
else
|
283
|
+
response
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
# 2.4 DELETE - Borrar un Suscriptor
|
288
|
+
def self.delete_suscriptor(customer_id)
|
289
|
+
handle_timeouts do
|
290
|
+
response = delete("/customers" + "/#{customer_id}")
|
291
|
+
case response.code
|
292
|
+
when 200..202
|
293
|
+
puts response
|
294
|
+
response.parsed_response["response"]["description"]
|
295
|
+
when 404
|
296
|
+
response.message
|
297
|
+
when 500..600
|
298
|
+
puts "OMG ERROR #{response.code}"
|
299
|
+
else
|
300
|
+
response
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
#########################################################################
|
306
|
+
# ****** 3 - TARJETAS DE CREDITO ****** #
|
307
|
+
#########################################################################
|
308
|
+
# Es el medio de pago con el cual se relaciona un Plan y un Pagador, #
|
309
|
+
# se encuentra compuesto por el número de tarjeta de crédito #
|
310
|
+
# (el cual será tokenizado para almacenar los datos de forma segura), #
|
311
|
+
# la fecha de vencimiento de la tarjeta y algunos datos adicionales #
|
312
|
+
# de dirección. #
|
313
|
+
#########################################################################
|
314
|
+
|
315
|
+
# 3.1 POST - Crear una Tarjeta de Credito a un Suscriptor
|
316
|
+
|
317
|
+
def self.create_card(customer_id, numero , exp_mes, exp_ano ,tipo, nombre, documento, dir_linea1, dir_linea2 , dir_linea3 , departamento, ciudad, pais, codigo_postal, telefono)
|
318
|
+
# Recurrente.add_customer_card(cliente, "371449635398431","01", "2018","AMEX","Pablo Picasso","1020304050","Calle Falsa","123","Patio 1","Bogotá","Bogotá D.C.", "CO", "110221", "3103456789")
|
319
|
+
|
320
|
+
#############################################################################################################
|
321
|
+
# customer_id Campo para la URL no va en la petición. Código de identificación del cliente. #
|
322
|
+
# numero Número de la tarjeta Ej: "4242424242424242" #
|
323
|
+
# exp_mes Mes de expiración - Mínimo 1 máximo 12. Ej: "01" #
|
324
|
+
# exp_ano Año de expiración de la tarjeta. Ej: "2018" #
|
325
|
+
# tipo Franquicia de la tarjeta VISA, AMEX, DINERS, MASTERCARD. Ej: "VISA" #
|
326
|
+
# nombre Nombre del tarjeta habiente: Ej: "Pedrito Fernandez" #
|
327
|
+
# documento Documento de identificación. Ej: "1020304050" #
|
328
|
+
# dir_linea1 Línea 1 de dirección opcional de correspondencia. Ej: "Calle Falsa" #
|
329
|
+
# dir_linea2 Línea 2 de dirección opcional de correspondencia. Ej: "123" #
|
330
|
+
# dir_linea3 Línea 3 de dirección opcional de correspondencia. Ej: "Patio trasero" #
|
331
|
+
# departamento Nombre de departamento. Ej: "Bogotá" #
|
332
|
+
# ciudad Nombre de ciudad. Ej: "Bogotá D.C." #
|
333
|
+
# pais Dos letras del país según el Código ISO 3166. Ej: "CO" #
|
334
|
+
# codigo_postal Código de la dirección #
|
335
|
+
# telefono Teléfono asociado con la dirección #
|
336
|
+
#############################################################################################################
|
337
|
+
handle_timeouts do
|
338
|
+
headers = {
|
339
|
+
'Content-Type' => 'application/json; charset=UTF-8',
|
340
|
+
'Accept' => "application/json",
|
341
|
+
'Accept-language' => 'es',
|
342
|
+
'Authorization' => @auth
|
343
|
+
}
|
344
|
+
params = {
|
345
|
+
"name": nombre,
|
346
|
+
"document": documento,
|
347
|
+
"number": numero,
|
348
|
+
"expMonth": exp_mes,
|
349
|
+
"expYear": exp_ano,
|
350
|
+
"type": tipo,
|
351
|
+
"address": {
|
352
|
+
"line1": dir_linea1,
|
353
|
+
"line2": dir_linea2,
|
354
|
+
"line3": dir_linea3,
|
355
|
+
"postalCode": codigo_postal,
|
356
|
+
"city": ciudad,
|
357
|
+
"state": departamento,
|
358
|
+
"country": pais,
|
359
|
+
"phone": telefono
|
360
|
+
}
|
361
|
+
}
|
362
|
+
|
363
|
+
response = post('/customers' + "/#{customer_id}/creditCards", body: JSON.generate(params), headers: headers)
|
364
|
+
case response.code
|
365
|
+
when 200
|
366
|
+
response
|
367
|
+
when 201
|
368
|
+
puts JSON.pretty_generate(response.parsed_response)
|
369
|
+
retrieve_credit_card response
|
370
|
+
when 404
|
371
|
+
response.message
|
372
|
+
when 500..600
|
373
|
+
puts "OMG ERROR #{response.code}"
|
374
|
+
else
|
375
|
+
response
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
# 3.2 GET - Buscar una tarjeta de crédito
|
381
|
+
def self.find_card(token)
|
382
|
+
handle_timeouts do
|
383
|
+
response = get("/creditCards" + "/#{token}")
|
384
|
+
puts JSON.pretty_generate(response.parsed_response)
|
385
|
+
case response.code
|
386
|
+
when 200
|
387
|
+
response.parsed_response["creditCard"]
|
388
|
+
else
|
389
|
+
response
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
# 3.3 GET - Buscar tarjetas de crédito de un usuario
|
395
|
+
|
396
|
+
def self.find_cards_by_suscriptor(customer_id)
|
397
|
+
handle_timeouts do
|
398
|
+
response = get("/customers"+ "/#{customer_id}/creditCards")
|
399
|
+
case response.code
|
400
|
+
when 200
|
401
|
+
puts JSON.pretty_generate(response.parsed_response)
|
402
|
+
response.parsed_response["creditCardListResponse"]["creditCards"]["creditCard"]
|
403
|
+
# Retorna el hash de las tarjetas de crédito
|
404
|
+
when 404
|
405
|
+
response.message
|
406
|
+
when 500..600
|
407
|
+
puts "OMG ERROR #{response.code}"
|
408
|
+
else
|
409
|
+
response
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
# 3.4 DELETE - Eliminar una tarjeta de crédito
|
415
|
+
|
416
|
+
def self.delete_card(customer_id, token)
|
417
|
+
handle_timeouts do
|
418
|
+
response = delete("/customers" + "/#{customer_id}" + '/creditCards' + "/#{token}")
|
419
|
+
|
420
|
+
case response.code
|
421
|
+
when 200..202
|
422
|
+
puts response
|
423
|
+
response.parsed_response["response"]["description"]
|
424
|
+
# Retorna la descripción
|
425
|
+
when 404
|
426
|
+
response.message
|
427
|
+
when 500..600
|
428
|
+
puts "OMG ERROR #{response.code}"
|
429
|
+
else
|
430
|
+
response
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
###########################################################
|
436
|
+
# ****** 4 - SUSCRIPCIONES ****** #
|
437
|
+
# Una suscripción es la relación entre un plan de pagos, #
|
438
|
+
# un pagador y una tarjeta de crédito y es el elemento #
|
439
|
+
# con el que se controla la ejecución de los cobros #
|
440
|
+
# correspondientes. #
|
441
|
+
###########################################################
|
442
|
+
|
443
|
+
# 4.1 POST - Crear suscripción
|
444
|
+
|
445
|
+
# quantity Es la cantidad de Planes que adquiere con la suscripción
|
446
|
+
# installments Es el número de cuotas en las que diferira cada pago
|
447
|
+
# trial_days Son los días de prueba
|
448
|
+
#
|
449
|
+
|
450
|
+
# 4.1.1 CON TODOS LOS ELEMENTOS NUEVOS
|
451
|
+
def self.create_suscription(params = {})
|
452
|
+
handle_timeouts do
|
453
|
+
|
454
|
+
headers = {
|
455
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
456
|
+
'Accept' => 'application/json',
|
457
|
+
'Accept-language' => 'es',
|
458
|
+
'Authorization' => @auth
|
459
|
+
}
|
460
|
+
response = post('/subscriptions', body: params.to_json, headers: headers)
|
461
|
+
case response.code
|
462
|
+
when 200..202
|
463
|
+
puts response
|
464
|
+
retrieve_suscription response
|
465
|
+
when 404
|
466
|
+
response.message
|
467
|
+
when 500..600
|
468
|
+
puts "OMG ERROR #{response.code}"
|
469
|
+
else
|
470
|
+
response
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
|
476
|
+
|
477
|
+
# 4.1.2 CON TODOS LOS ELEMENTOS EXISTENTES
|
478
|
+
|
479
|
+
def self.create_suscription_all_existent(customer_id, plan_code, token, quantity, installments, trial_days)
|
480
|
+
#Recurrente.add_new_suscription(cliente,plan,token,1,1,0)
|
481
|
+
handle_timeouts do
|
482
|
+
params = {
|
483
|
+
"quantity": quantity,
|
484
|
+
"installments": installments,
|
485
|
+
"trialDays": trial_days,
|
486
|
+
"customer": {
|
487
|
+
"id": customer_id,
|
488
|
+
"creditCards": [
|
489
|
+
{
|
490
|
+
"token": token
|
491
|
+
}
|
492
|
+
]
|
493
|
+
},
|
494
|
+
"plan": {
|
495
|
+
"planCode": plan_code
|
496
|
+
}
|
497
|
+
}
|
498
|
+
headers = {
|
499
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
500
|
+
'Accept' => 'application/json',
|
501
|
+
'Accept-language' => 'es',
|
502
|
+
'Authorization' => @auth
|
503
|
+
}
|
504
|
+
response = post('/subscriptions', body: params.to_json, headers: headers)
|
505
|
+
case response.code
|
506
|
+
when 200..202
|
507
|
+
puts response
|
508
|
+
retrieve_suscription response
|
509
|
+
when 404
|
510
|
+
response.message
|
511
|
+
response
|
512
|
+
when 500..600
|
513
|
+
puts "OMG ERROR #{response.code}"
|
514
|
+
else
|
515
|
+
response
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
# 4.1.3 PLAN Y SUSCRIPTOR YA CREADOS Y UNA TARJETA NUEVA
|
521
|
+
def self.create_suscription_alternative_1(customer_id, plan_code, quantity, installments, trial_days, numero , exp_mes, exp_ano ,tipo, nombre, documento, dir_linea1, dir_linea2 , dir_linea3 , departamento, ciudad, pais, codigo_postal, telefono )
|
522
|
+
handle_timeouts do
|
523
|
+
params = {
|
524
|
+
"quantity": quantity,
|
525
|
+
"installments": installments,
|
526
|
+
"trialDays": trial_days,
|
527
|
+
"customer": {
|
528
|
+
"id": customer_id,
|
529
|
+
"creditCards": [
|
530
|
+
{
|
531
|
+
"name": nombre,
|
532
|
+
"document": documento,
|
533
|
+
"number": numero,
|
534
|
+
"expMonth": exp_mes,
|
535
|
+
"expYear": exp_ano,
|
536
|
+
"type": tipo,
|
537
|
+
"address": {
|
538
|
+
"line1": dir_linea1,
|
539
|
+
"line2": dir_linea2,
|
540
|
+
"line3": dir_linea3,
|
541
|
+
"postalCode": codigo_postal,
|
542
|
+
"city": ciudad,
|
543
|
+
"state": departamento,
|
544
|
+
"country": pais,
|
545
|
+
"phone": telefono
|
546
|
+
}
|
547
|
+
}
|
548
|
+
]
|
549
|
+
},
|
550
|
+
"plan": {
|
551
|
+
"planCode": plan_code
|
552
|
+
}
|
553
|
+
}
|
554
|
+
headers = {
|
555
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
556
|
+
'Accept' => 'application/json',
|
557
|
+
'Accept-language' => 'es',
|
558
|
+
'Authorization' => @auth
|
559
|
+
}
|
560
|
+
response = post('/subscriptions', body: params.to_json, headers: headers)
|
561
|
+
case response.code
|
562
|
+
when 200..202
|
563
|
+
puts response
|
564
|
+
retrieve_suscription response
|
565
|
+
when 404
|
566
|
+
response.message
|
567
|
+
when 500..600
|
568
|
+
puts "OMG ERROR #{response.code}"
|
569
|
+
else
|
570
|
+
response
|
571
|
+
end
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
# 4.1.4 CLIENTE Y TARJETA YA CREADOS, CON PLAN NUEVO
|
576
|
+
def self.create_suscription_alternative_2(customer_id, plan_code, token, quantity, installments, trial_days, codigo, descripcion, intervalo, cantidad_intervalos, moneda, valor, impuesto, base_impuesto, reintentos, dias_entre_reintentos, cobros,periodo_de_gracia)
|
577
|
+
handle_timeouts do
|
578
|
+
params = {
|
579
|
+
"installments": installments,
|
580
|
+
"trialDays": trial_days,
|
581
|
+
"customer": {
|
582
|
+
"id": customer_id,
|
583
|
+
"creditCards": [
|
584
|
+
{
|
585
|
+
"token": token
|
586
|
+
}
|
587
|
+
]
|
588
|
+
},
|
589
|
+
"plan": {
|
590
|
+
"accountId": ACCOUNT,
|
591
|
+
"planCode": codigo,
|
592
|
+
"description": descripcion,
|
593
|
+
"interval": intervalo,
|
594
|
+
"intervalCount": cantidad_intervalos ,
|
595
|
+
"maxPaymentsAllowed": cobros,
|
596
|
+
"paymentAttemptsDelay": dias_entre_reintentos,
|
597
|
+
"maxPaymentAttempts": reintentos,
|
598
|
+
"maxPendingPayments": periodo_de_gracia,
|
599
|
+
"additionalValues": [
|
600
|
+
{
|
601
|
+
"name": "PLAN_VALUE",
|
602
|
+
"value": valor,
|
603
|
+
"currency": moneda
|
604
|
+
},
|
605
|
+
{
|
606
|
+
"name": "PLAN_TAX",
|
607
|
+
"value": impuesto,
|
608
|
+
"currency": moneda
|
609
|
+
},
|
610
|
+
{
|
611
|
+
"name": "PLAN_TAX_RETURN_BASE",
|
612
|
+
"value": base_impuesto,
|
613
|
+
"currency": moneda
|
614
|
+
}
|
615
|
+
]
|
616
|
+
}
|
617
|
+
}
|
618
|
+
headers = {
|
619
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
620
|
+
'Accept' => 'application/json',
|
621
|
+
'Accept-language' => 'es',
|
622
|
+
'Authorization' => @auth
|
623
|
+
}
|
624
|
+
response = post('/subscriptions', body: params.to_json, headers: headers)
|
625
|
+
case response.code
|
626
|
+
when 200..202
|
627
|
+
puts response
|
628
|
+
retrieve_suscription response
|
629
|
+
when 404
|
630
|
+
response.message
|
631
|
+
when 500..600
|
632
|
+
puts "OMG ERROR #{response.code}"
|
633
|
+
else
|
634
|
+
response
|
635
|
+
end
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
# 4.2 PUT - Update Suscription Credit Card
|
640
|
+
|
641
|
+
def self.update_suscription_card(suscription_id, token)
|
642
|
+
handle_timeouts do
|
643
|
+
headers = {
|
644
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
645
|
+
'Accept' => 'application/json',
|
646
|
+
'Accept-language' => 'es',
|
647
|
+
'Authorization' => @auth
|
648
|
+
}
|
649
|
+
params = {
|
650
|
+
"creditCardToken": token
|
651
|
+
}
|
652
|
+
response = put('/subscriptions'+ "/#{suscription_id}", body: params.to_json, headers: headers)
|
653
|
+
|
654
|
+
case response.code
|
655
|
+
when 200..202
|
656
|
+
puts JSON.pretty_generate(response.parsed_response)
|
657
|
+
puts response.code.to_s + " " + response.message
|
658
|
+
response
|
659
|
+
when 404
|
660
|
+
response.message
|
661
|
+
when 500..600
|
662
|
+
puts "OMG ERROR #{response.code}"
|
663
|
+
else
|
664
|
+
response
|
665
|
+
end
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
# 4.3 GET - Buscar una Suscripción
|
670
|
+
def self.find_suscription(suscription_id)
|
671
|
+
handle_timeouts do
|
672
|
+
response = get("/subscriptions" + "/#{suscription_id}")
|
673
|
+
|
674
|
+
case response.code
|
675
|
+
when 200..202
|
676
|
+
puts JSON.pretty_generate(response.parsed_response)
|
677
|
+
puts response.code.to_s + " " + response.message
|
678
|
+
response
|
679
|
+
when 404
|
680
|
+
response.code.to_s + " " + response.message
|
681
|
+
when 500..600
|
682
|
+
puts "OMG ERROR #{response.code}"
|
683
|
+
else
|
684
|
+
response
|
685
|
+
end
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
# 4.4 GET - Buscar las suscripciones de un Cliente
|
690
|
+
def self.find_suscriptions_by_suscriptor(customer_id)
|
691
|
+
handle_timeouts do
|
692
|
+
response = get("/subscriptions" + "/?customerId=#{customer_id}")
|
693
|
+
|
694
|
+
case response.code
|
695
|
+
when 200..202
|
696
|
+
puts JSON.pretty_generate(response.parsed_response)
|
697
|
+
puts response.code.to_s + " " + response.message
|
698
|
+
response.parsed_response["subscriptionsListResponse"]["subscriptions"]
|
699
|
+
when 404
|
700
|
+
response.message
|
701
|
+
when 500..600
|
702
|
+
puts "OMG ERROR #{response.code}"
|
703
|
+
else
|
704
|
+
response
|
705
|
+
end
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
709
|
+
# 4.5 POST - Cancelar una Suscripción. Status CANCELLED
|
710
|
+
|
711
|
+
def self.cancel_suscription(suscription_id)
|
712
|
+
handle_timeouts do
|
713
|
+
response = delete("/subscriptions" + "/#{suscription_id}")
|
714
|
+
|
715
|
+
case response.code
|
716
|
+
when 200..202
|
717
|
+
puts response
|
718
|
+
response.parsed_response["response"]["description"]
|
719
|
+
when 404
|
720
|
+
response.message
|
721
|
+
when 500..600
|
722
|
+
puts "OMG ERROR #{response.code}"
|
723
|
+
else
|
724
|
+
response
|
725
|
+
end
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
|
730
|
+
########################################################################
|
731
|
+
# ****** 5 - CARGOS ADICIONALES ****** #
|
732
|
+
# Un cargo puede ser un cobro adicional o un descuento realizado #
|
733
|
+
# sobre el valor de uno de los pagos que conforman el plan de #
|
734
|
+
# pagos recurrentes. Estos solo afectan el siguiente cobro pendiente #
|
735
|
+
# y se ejecutan una única vez. #
|
736
|
+
########################################################################
|
737
|
+
|
738
|
+
# 5.1 POST - Crear un cargo adicional
|
739
|
+
|
740
|
+
def self.create_charge(suscription_id, descripcion, valor, moneda, impuesto, base_impuesto )
|
741
|
+
handle_timeouts do
|
742
|
+
headers = {
|
743
|
+
'Content-type' => 'application/json; charset=UTF-8',
|
744
|
+
'Accept' => 'application/json',
|
745
|
+
'Accept-language' => 'es',
|
746
|
+
'Authorization' => @auth
|
747
|
+
}
|
748
|
+
params = {
|
749
|
+
"description": descripcion,
|
750
|
+
"additionalValues": [
|
751
|
+
{
|
752
|
+
"name": "ITEM_VALUE",
|
753
|
+
"value": valor,
|
754
|
+
"currency": moneda
|
755
|
+
},
|
756
|
+
{
|
757
|
+
"name": "ITEM_TAX",
|
758
|
+
"value": impuesto,
|
759
|
+
"currency": moneda
|
760
|
+
},
|
761
|
+
{
|
762
|
+
"name": "ITEM_TAX_RETURN_BASE",
|
763
|
+
"value": base_impuesto,
|
764
|
+
"currency": moneda
|
765
|
+
}
|
766
|
+
]
|
767
|
+
}
|
768
|
+
response = post("/subscriptions" + "/#{suscription_id}" + "/recurringBillItems", body: params.to_json, headers: headers)
|
769
|
+
case response.code
|
770
|
+
when 200..202
|
771
|
+
puts JSON.pretty_generate(response.parsed_response)
|
772
|
+
retrieve_extra_charge response
|
773
|
+
when 404
|
774
|
+
response.message
|
775
|
+
when 500..600
|
776
|
+
puts "OMG ERROR #{response.code}"
|
777
|
+
else
|
778
|
+
response
|
779
|
+
end
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
# 5.2 PUT - Actualizar un cargo adicional
|
784
|
+
|
785
|
+
def self.update_charge(extra_charge_id, descripcion, valor, moneda, impuesto, base_impuesto )
|
786
|
+
handle_timeouts do
|
787
|
+
params = {
|
788
|
+
"description": descripcion,
|
789
|
+
"additionalValues": [
|
790
|
+
{
|
791
|
+
"name": "ITEM_VALUE",
|
792
|
+
"value": valor,
|
793
|
+
"currency": moneda
|
794
|
+
},
|
795
|
+
{
|
796
|
+
"name": "ITEM_TAX",
|
797
|
+
"value": impuesto,
|
798
|
+
"currency": moneda
|
799
|
+
},
|
800
|
+
{
|
801
|
+
"name": "ITEM_TAX_RETURN_BASE",
|
802
|
+
"value": base_impuesto,
|
803
|
+
"currency": moneda
|
804
|
+
}
|
805
|
+
]
|
806
|
+
}
|
807
|
+
|
808
|
+
headers = {
|
809
|
+
'Content-type' => 'application/json;charset=UTF-8',
|
810
|
+
'Accept' => 'application/json',
|
811
|
+
'Accept-language' => 'es',
|
812
|
+
'Authorization' => @auth
|
813
|
+
}
|
814
|
+
put("/recurringBillItems" + "/#{extra_charge_id}", body: params.to_json, headers: headers)
|
815
|
+
case response.code
|
816
|
+
when 200..202
|
817
|
+
puts JSON.pretty_generate(response.parsed_response)
|
818
|
+
puts response.code.to_s + " " + response.message
|
819
|
+
response
|
820
|
+
when 404
|
821
|
+
response.message
|
822
|
+
when 500..600
|
823
|
+
puts "OMG ERROR #{response.code}"
|
824
|
+
else
|
825
|
+
response
|
826
|
+
end
|
827
|
+
end
|
828
|
+
end
|
829
|
+
|
830
|
+
# 5.3 GET - Buscar un Cargo Extra por ID
|
831
|
+
def self.find_charge_by_id(charge_id)
|
832
|
+
handle_timeouts do
|
833
|
+
response = get("/recurringBillItems" + "/#{charge_id}")
|
834
|
+
|
835
|
+
case response.code
|
836
|
+
when 200
|
837
|
+
puts JSON.pretty_generate(response.parsed_response)
|
838
|
+
puts response.code.to_s + " " + response.message
|
839
|
+
response.parsed_response["recurringBillItem"]
|
840
|
+
# Retorna el cargo extra
|
841
|
+
when 404
|
842
|
+
response.message
|
843
|
+
response
|
844
|
+
when 500..600
|
845
|
+
puts "OMG ERROR #{response.code}"
|
846
|
+
response
|
847
|
+
else
|
848
|
+
response
|
849
|
+
end
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
# 5.4 GET - Buscar un Cargo Extra por Suscripcion
|
854
|
+
def self.find_charge_by_suscription(suscription_id)
|
855
|
+
handle_timeouts do
|
856
|
+
response = get("/recurringBillItems" + "/?subscriptionId=#{suscription_id}")
|
857
|
+
|
858
|
+
case response.code
|
859
|
+
when 200
|
860
|
+
puts JSON.pretty_generate(response.parsed_response)
|
861
|
+
puts response.code.to_s + " " + response.message
|
862
|
+
response.parsed_response["recurringBillItemListResponse"]["recurringBillItems"]["recurringBillItem"]
|
863
|
+
# Retorna los cargos extra de la suscripción
|
864
|
+
when 404
|
865
|
+
response.message
|
866
|
+
when 500..600
|
867
|
+
puts "OMG ERROR #{response.code}"
|
868
|
+
else
|
869
|
+
response
|
870
|
+
end
|
871
|
+
end
|
872
|
+
end
|
873
|
+
|
874
|
+
# 5.5 POST - Borrar un cargo de la suscripción
|
875
|
+
|
876
|
+
def self.delete_charge(extra_charge_id)
|
877
|
+
handle_timeouts do
|
878
|
+
response = delete("/recurringBillItems" + "/#{extra_charge_id}")
|
879
|
+
|
880
|
+
case response.code
|
881
|
+
when 200..202
|
882
|
+
puts response
|
883
|
+
puts response.code.to_s + " " + response.message
|
884
|
+
response.parsed_response["response"]["description"]
|
885
|
+
when 404
|
886
|
+
response.message
|
887
|
+
when 500..600
|
888
|
+
puts "OMG ERROR #{response.code}"
|
889
|
+
else
|
890
|
+
response
|
891
|
+
end
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
private
|
896
|
+
def self.retrieve_plan(response)
|
897
|
+
response.parsed_response["planCode"]
|
898
|
+
end
|
899
|
+
|
900
|
+
def self.retrieve_customer(response)
|
901
|
+
response.parsed_response["id"]
|
902
|
+
end
|
903
|
+
|
904
|
+
def self.retrieve_credit_card(response)
|
905
|
+
response.parsed_response["token"]
|
906
|
+
end
|
907
|
+
|
908
|
+
def self.retrieve_suscription(response)
|
909
|
+
response.parsed_response["id"]
|
910
|
+
end
|
911
|
+
|
912
|
+
def self.retrieve_extra_charge(response)
|
913
|
+
response.parsed_response["id"]
|
914
|
+
end
|
915
|
+
end
|
916
|
+
|
917
|
+
|
data/recurrente.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'recurrente/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "recurrente"
|
8
|
+
spec.version = Recurrente::VERSION
|
9
|
+
spec.authors = ["gabosarmiento"]
|
10
|
+
spec.email = ["gabrielsarmiento@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Un wrapper para el API de pagos recurrentes de Payulatam}
|
13
|
+
spec.description = %q{Una Gem de Ruby para consumir la API de payulatam.com api y manejar los pagos recurrentes}
|
14
|
+
spec.homepage = "https://github.com/gabosarmiento/recurrente.git"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
|
25
|
+
# Dependency
|
26
|
+
spec.add_dependency "httparty"
|
27
|
+
spec.add_dependency "json"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: recurrente
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- gabosarmiento
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: httparty
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: json
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Una Gem de Ruby para consumir la API de payulatam.com api y manejar los
|
70
|
+
pagos recurrentes
|
71
|
+
email:
|
72
|
+
- gabrielsarmiento@gmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/console
|
83
|
+
- bin/setup
|
84
|
+
- lib/recurrente.rb
|
85
|
+
- lib/recurrente/version.rb
|
86
|
+
- recurrente.gemspec
|
87
|
+
homepage: https://github.com/gabosarmiento/recurrente.git
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.4.6
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: Un wrapper para el API de pagos recurrentes de Payulatam
|
111
|
+
test_files: []
|