mercadopago 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +8 -0
- data/README.md +55 -11
- data/fixtures/vcr_cassettes/cancel_preapproval.yml +65 -0
- data/fixtures/vcr_cassettes/create_preapproval.yml +68 -0
- data/fixtures/vcr_cassettes/create_preference.yml +102 -0
- data/fixtures/vcr_cassettes/get_preference.yml +97 -0
- data/fixtures/vcr_cassettes/login.yml +63 -0
- data/fixtures/vcr_cassettes/wrong_login.yml +63 -0
- data/fixtures/vcr_cassettes/wrong_token.yml +63 -0
- data/lib/mercadopago/authentication.rb +15 -8
- data/lib/mercadopago/checkout.rb +22 -8
- data/lib/mercadopago/client.rb +47 -7
- data/lib/mercadopago/request.rb +22 -3
- data/lib/mercadopago/version.rb +1 -1
- data/mercadopago.gemspec +4 -1
- data/test/test_mercado_pago.rb +176 -58
- metadata +54 -3
@@ -0,0 +1,63 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.mercadopago.com/oauth/token
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: client_id=<CLIENT-ID>&client_secret=<CLIENT-SECRET>&grant_type=client_credentials
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/x-www-form-urlencoded
|
12
|
+
Accept:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
User-Agent:
|
17
|
+
- Ruby
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Date:
|
24
|
+
- Mon, 25 Apr 2016 18:27:43 GMT
|
25
|
+
Content-Type:
|
26
|
+
- application/json;charset=UTF-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
Vary:
|
32
|
+
- Accept,Accept-Encoding
|
33
|
+
Cache-Control:
|
34
|
+
- max-age=0
|
35
|
+
Etag:
|
36
|
+
- ea81c1fa59f6b789c1d7811bb3497072
|
37
|
+
X-Content-Type-Options:
|
38
|
+
- nosniff
|
39
|
+
X-Frame-Options:
|
40
|
+
- DENY
|
41
|
+
X-Request-Id:
|
42
|
+
- 29adeddd-6421-45c5-a855-0d3bfbb05878
|
43
|
+
X-Xss-Protection:
|
44
|
+
- 1; mode=block
|
45
|
+
Strict-Transport-Security:
|
46
|
+
- max-age=15724800
|
47
|
+
Access-Control-Allow-Origin:
|
48
|
+
- "*"
|
49
|
+
Access-Control-Allow-Headers:
|
50
|
+
- Content-Type
|
51
|
+
Access-Control-Allow-Methods:
|
52
|
+
- PUT, GET, POST, DELETE, OPTIONS
|
53
|
+
Access-Control-Max-Age:
|
54
|
+
- '86400'
|
55
|
+
X-Libra-Upstreamhost:
|
56
|
+
- 172.16.161.224
|
57
|
+
body:
|
58
|
+
encoding: UTF-8
|
59
|
+
string: '{"access_token":"APP_USR-<CLIENT-ID>-1234567","refresh_token":"TG-2345e6rtyughj7city8d3-1234567","live_mode":true,"user_id":1234567,"token_type":"bearer","expires_in":21600,"scope":"offline_access
|
60
|
+
read write"}'
|
61
|
+
http_version:
|
62
|
+
recorded_at: Mon, 25 Apr 2016 18:27:43 GMT
|
63
|
+
recorded_with: VCR 3.0.1
|
@@ -0,0 +1,63 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.mercadopago.com/oauth/token
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: client_id=fake_client_id&client_secret=fake_client_secret&grant_type=client_credentials
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/x-www-form-urlencoded
|
12
|
+
Accept:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
User-Agent:
|
17
|
+
- Ruby
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 400
|
21
|
+
message: Bad Request
|
22
|
+
headers:
|
23
|
+
Date:
|
24
|
+
- Mon, 25 Apr 2016 18:27:42 GMT
|
25
|
+
Content-Type:
|
26
|
+
- application/json;charset=UTF-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
Vary:
|
32
|
+
- Accept,Accept-Encoding
|
33
|
+
Cache-Control:
|
34
|
+
- max-age=0
|
35
|
+
X-Content-Type-Option:
|
36
|
+
- nosniff
|
37
|
+
X-Frame-Options:
|
38
|
+
- DENY
|
39
|
+
X-Request-Id:
|
40
|
+
- 9e31afa8-3bef-4c21-93ab-0c43a7510d97
|
41
|
+
X-Xss-Protection:
|
42
|
+
- 1; mode=block
|
43
|
+
X-Content-Type-Options:
|
44
|
+
- nosniff
|
45
|
+
Strict-Transport-Security:
|
46
|
+
- max-age=15724800
|
47
|
+
Access-Control-Allow-Origin:
|
48
|
+
- "*"
|
49
|
+
Access-Control-Allow-Headers:
|
50
|
+
- Content-Type
|
51
|
+
Access-Control-Allow-Methods:
|
52
|
+
- PUT, GET, POST, DELETE, OPTIONS
|
53
|
+
Access-Control-Max-Age:
|
54
|
+
- '86400'
|
55
|
+
X-Libra-Upstreamhost:
|
56
|
+
- 172.16.149.113
|
57
|
+
body:
|
58
|
+
encoding: UTF-8
|
59
|
+
string: '{"message":"Invalid client_id","error":"bad_request","status":400,"cause":{"code":11,"description":"Invalid
|
60
|
+
client_id","data":null}}'
|
61
|
+
http_version:
|
62
|
+
recorded_at: Mon, 25 Apr 2016 18:27:42 GMT
|
63
|
+
recorded_with: VCR 3.0.1
|
@@ -0,0 +1,63 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.mercadopago.com/checkout/preferences?access_token=fake_token
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: "{}"
|
9
|
+
headers:
|
10
|
+
Content-Type:
|
11
|
+
- application/json
|
12
|
+
Accept:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
User-Agent:
|
17
|
+
- Ruby
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 400
|
21
|
+
message: Bad Request
|
22
|
+
headers:
|
23
|
+
Date:
|
24
|
+
- Mon, 25 Apr 2016 18:27:48 GMT
|
25
|
+
Content-Type:
|
26
|
+
- application/json;charset=UTF-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
Cache-Control:
|
32
|
+
- max-age=60, stale-while-revalidate=30, stale-if-error=120
|
33
|
+
Vary:
|
34
|
+
- Accept,Accept-Encoding
|
35
|
+
X-Content-Type-Options:
|
36
|
+
- nosniff
|
37
|
+
- nosniff
|
38
|
+
X-Request-Id:
|
39
|
+
- 0aac4aff-d8c1-44d5-9b56-9770bdb9b923
|
40
|
+
Access-Control-Allow-Origin:
|
41
|
+
- "*"
|
42
|
+
Access-Control-Allow-Headers:
|
43
|
+
- Content-Type
|
44
|
+
Access-Control-Allow-Methods:
|
45
|
+
- PUT, GET, POST, DELETE, OPTIONS
|
46
|
+
Access-Control-Max-Age:
|
47
|
+
- '86400'
|
48
|
+
X-Frame-Options:
|
49
|
+
- DENY
|
50
|
+
X-Xss-Protection:
|
51
|
+
- 1; mode=block
|
52
|
+
- 1; mode=block
|
53
|
+
Strict-Transport-Security:
|
54
|
+
- max-age=15724800
|
55
|
+
- max-age=16070400
|
56
|
+
X-Libra-Upstreamhost:
|
57
|
+
- 172.16.161.224
|
58
|
+
body:
|
59
|
+
encoding: UTF-8
|
60
|
+
string: '{"message":"Malformed access_token: null","error":"bad_request","status":400,"cause":[]}'
|
61
|
+
http_version:
|
62
|
+
recorded_at: Mon, 25 Apr 2016 18:27:48 GMT
|
63
|
+
recorded_with: VCR 3.0.1
|
@@ -2,6 +2,10 @@ module MercadoPago
|
|
2
2
|
|
3
3
|
module Authentication
|
4
4
|
|
5
|
+
CONTENT_HEADERS = {
|
6
|
+
content_type: 'application/x-www-form-urlencoded',
|
7
|
+
accept: 'application/json'
|
8
|
+
}.freeze
|
5
9
|
#
|
6
10
|
# Receives the client credentials and makes a request to oAuth API.
|
7
11
|
# On success, returns a hash with the access data; on failure, returns nil.
|
@@ -13,10 +17,12 @@ module MercadoPago
|
|
13
17
|
# - client_secret
|
14
18
|
#
|
15
19
|
def self.access_token(client_id, client_secret)
|
16
|
-
payload = {
|
17
|
-
|
20
|
+
payload = {
|
21
|
+
grant_type: 'client_credentials',
|
22
|
+
client_id: client_id,
|
23
|
+
client_secret: client_secret }
|
18
24
|
|
19
|
-
MercadoPago::Request.wrap_post('/oauth/token', payload,
|
25
|
+
MercadoPago::Request.wrap_post('/oauth/token', payload, CONTENT_HEADERS)
|
20
26
|
end
|
21
27
|
|
22
28
|
#
|
@@ -27,12 +33,13 @@ module MercadoPago
|
|
27
33
|
# - refresh_token
|
28
34
|
#
|
29
35
|
def self.refresh_access_token(client_id, client_secret, refresh_token)
|
30
|
-
payload = {
|
31
|
-
|
36
|
+
payload = {
|
37
|
+
grant_type: 'refresh_token',
|
38
|
+
client_id: client_id,
|
39
|
+
client_secret: client_secret,
|
40
|
+
refresh_token: refresh_token }
|
32
41
|
|
33
|
-
MercadoPago::Request.wrap_post('/oauth/token', payload,
|
42
|
+
MercadoPago::Request.wrap_post('/oauth/token', payload, CONTENT_HEADERS)
|
34
43
|
end
|
35
|
-
|
36
44
|
end
|
37
|
-
|
38
45
|
end
|
data/lib/mercadopago/checkout.rb
CHANGED
@@ -14,9 +14,10 @@ module MercadoPago
|
|
14
14
|
#
|
15
15
|
def self.create_preference(access_token, data)
|
16
16
|
payload = JSON.generate(data)
|
17
|
-
headers = { content_type: 'application/json', accept: 'application/json' }
|
18
17
|
|
19
|
-
MercadoPago::Request
|
18
|
+
MercadoPago::Request
|
19
|
+
.wrap_post("/checkout/preferences?access_token=#{access_token}",
|
20
|
+
payload)
|
20
21
|
end
|
21
22
|
|
22
23
|
#
|
@@ -33,7 +34,6 @@ module MercadoPago
|
|
33
34
|
# - preference_id: the payment preference ID
|
34
35
|
#
|
35
36
|
def self.get_preference(access_token, preference_id)
|
36
|
-
headers = { accept: 'application/json' }
|
37
37
|
MercadoPago::Request.wrap_get("/checkout/preferences/#{preference_id}?access_token=#{access_token}")
|
38
38
|
end
|
39
39
|
|
@@ -44,9 +44,10 @@ module MercadoPago
|
|
44
44
|
#
|
45
45
|
def self.create_preapproval_payment(access_token, data)
|
46
46
|
payload = JSON.generate(data)
|
47
|
-
headers = { content_type: 'application/json', accept: 'application/json' }
|
48
47
|
|
49
|
-
MercadoPago::Request
|
48
|
+
MercadoPago::Request
|
49
|
+
.wrap_post("/preapproval?access_token=#{access_token}",
|
50
|
+
payload)
|
50
51
|
end
|
51
52
|
|
52
53
|
#
|
@@ -56,10 +57,23 @@ module MercadoPago
|
|
56
57
|
# - preapproval_id: the preapproval payment ID
|
57
58
|
#
|
58
59
|
def self.get_preapproval_payment(access_token, preapproval_id)
|
59
|
-
|
60
|
-
|
60
|
+
MercadoPago::Request
|
61
|
+
.wrap_get("/preapproval/#{preapproval_id}?access_token=#{access_token}")
|
61
62
|
end
|
62
63
|
|
63
|
-
|
64
|
+
#
|
65
|
+
# - access_token: the MercadoPago account associated with this access_token will
|
66
|
+
# receive the money from the payment of preapproval payment.
|
67
|
+
# - preapproval_id: the preapproval payment ID
|
68
|
+
#
|
69
|
+
def self.cancel_preapproval_payment(access_token, preapproval_id)
|
70
|
+
payload = JSON.generate(status: :cancelled)
|
71
|
+
headers = { content_type: 'application/json', accept: 'application/json' }
|
64
72
|
|
73
|
+
MercadoPago::Request
|
74
|
+
.wrap_put("/preapproval/#{preapproval_id}?access_token=#{access_token}",
|
75
|
+
payload,
|
76
|
+
headers)
|
77
|
+
end
|
78
|
+
end
|
65
79
|
end
|
data/lib/mercadopago/client.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'json'
|
3
|
+
require 'uri'
|
4
|
+
|
2
5
|
module MercadoPago
|
3
6
|
|
4
7
|
class AccessError < Exception
|
@@ -34,7 +37,8 @@ module MercadoPago
|
|
34
37
|
# - client_secret
|
35
38
|
#
|
36
39
|
def initialize(client_id, client_secret)
|
37
|
-
load_tokens MercadoPago::Authentication.access_token(client_id,
|
40
|
+
load_tokens MercadoPago::Authentication.access_token(client_id,
|
41
|
+
client_secret)
|
38
42
|
end
|
39
43
|
|
40
44
|
#
|
@@ -56,7 +60,8 @@ module MercadoPago
|
|
56
60
|
# - client_secret
|
57
61
|
#
|
58
62
|
def refresh_access_token(client_id, client_secret)
|
59
|
-
load_tokens
|
63
|
+
load_tokens(MercadoPago::Authentication
|
64
|
+
.refresh_access_token(client_id, client_secret, @refresh_token))
|
60
65
|
end
|
61
66
|
|
62
67
|
#
|
@@ -92,7 +97,18 @@ module MercadoPago
|
|
92
97
|
# - preapproval_id: the id of the preapproval payment preference that will be retrieved.
|
93
98
|
#
|
94
99
|
def get_preapproval_payment(preapproval_id)
|
95
|
-
MercadoPago::Checkout.get_preapproval_payment(@access_token,
|
100
|
+
MercadoPago::Checkout.get_preapproval_payment(@access_token,
|
101
|
+
preapproval_id)
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Cancels a recurring payment.
|
106
|
+
#
|
107
|
+
# - preapproval_id: the id of the preapproval payment preference that will be canceled.
|
108
|
+
#
|
109
|
+
def cancel_preapproval_payment(preapproval_id)
|
110
|
+
MercadoPago::Checkout.cancel_preapproval_payment(@access_token,
|
111
|
+
preapproval_id)
|
96
112
|
end
|
97
113
|
|
98
114
|
#
|
@@ -115,7 +131,8 @@ module MercadoPago
|
|
115
131
|
# - authorized_id: the id of the recurring payment authorized to be checked.
|
116
132
|
#
|
117
133
|
def notification_authorized(authorized_id)
|
118
|
-
MercadoPago::Collection.notification_authorized(@access_token,
|
134
|
+
MercadoPago::Collection.notification_authorized(@access_token,
|
135
|
+
authorized_id)
|
119
136
|
end
|
120
137
|
|
121
138
|
#
|
@@ -124,7 +141,8 @@ module MercadoPago
|
|
124
141
|
# - preapproval_id: the id of the recurring payment to be checked.
|
125
142
|
#
|
126
143
|
def notification_preapproval(preapproval_id)
|
127
|
-
MercadoPago::Collection.notification_preapproval(@access_token,
|
144
|
+
MercadoPago::Collection.notification_preapproval(@access_token,
|
145
|
+
preapproval_id)
|
128
146
|
end
|
129
147
|
|
130
148
|
#
|
@@ -136,6 +154,30 @@ module MercadoPago
|
|
136
154
|
MercadoPago::Collection.search(@access_token, search_hash, @sandbox)
|
137
155
|
end
|
138
156
|
|
157
|
+
#
|
158
|
+
# Performs a generic GET to the given URL
|
159
|
+
#
|
160
|
+
# - url: the URL to request
|
161
|
+
#
|
162
|
+
def get(url, data = {}, headers = nil)
|
163
|
+
data[:access_token] = @access_token
|
164
|
+
query = URI.encode_www_form data
|
165
|
+
|
166
|
+
MercadoPago::Request.wrap_get("#{url}?{query}", headers)
|
167
|
+
end
|
168
|
+
|
169
|
+
#
|
170
|
+
# Performs a generic POST to the given URL
|
171
|
+
#
|
172
|
+
# - url: the URL to request
|
173
|
+
# - data: the data to send along the request
|
174
|
+
#
|
175
|
+
def post(url, data, headers = nil)
|
176
|
+
payload = JSON.generate(data)
|
177
|
+
|
178
|
+
MercadoPago::Request.wrap_post("#{url}?access_token=#{@access_token}", payload, headers)
|
179
|
+
end
|
180
|
+
|
139
181
|
#
|
140
182
|
# Private methods.
|
141
183
|
#
|
@@ -156,7 +198,5 @@ module MercadoPago
|
|
156
198
|
raise AccessError, auth['message']
|
157
199
|
end
|
158
200
|
end
|
159
|
-
|
160
201
|
end
|
161
|
-
|
162
202
|
end
|
data/lib/mercadopago/request.rb
CHANGED
@@ -8,10 +8,15 @@ module MercadoPago
|
|
8
8
|
class ClientError < Exception
|
9
9
|
end
|
10
10
|
|
11
|
+
CONTENT_HEADERS = {
|
12
|
+
content_type: 'application/json',
|
13
|
+
accept: 'application/json'
|
14
|
+
}.freeze
|
15
|
+
|
11
16
|
#
|
12
17
|
# This URL is the base for all API calls.
|
13
18
|
#
|
14
|
-
MERCADOPAGO_URL = 'https://api.mercadopago.com'
|
19
|
+
MERCADOPAGO_URL = 'https://api.mercadopago.com'.freeze
|
15
20
|
|
16
21
|
#
|
17
22
|
# Makes a POST request to a MercadoPago API.
|
@@ -20,18 +25,32 @@ module MercadoPago
|
|
20
25
|
# - payload: the data to be trasmitted to the API.
|
21
26
|
# - headers: the headers to be transmitted over the HTTP request.
|
22
27
|
#
|
23
|
-
def self.wrap_post(path, payload, headers =
|
28
|
+
def self.wrap_post(path, payload, headers = nil)
|
24
29
|
raise ClientError('No data given') if payload.nil? or payload.empty?
|
30
|
+
headers ||= CONTENT_HEADERS
|
25
31
|
make_request(:post, path, payload, headers)
|
26
32
|
end
|
27
33
|
|
34
|
+
#
|
35
|
+
# Makes a PUT request to a MercadoPago API.
|
36
|
+
#
|
37
|
+
# - path: the path of the API to be called.
|
38
|
+
# - payload: the data to be trasmitted to the API.
|
39
|
+
# - headers: the headers to be transmitted over the HTTP request.
|
40
|
+
#
|
41
|
+
def self.wrap_put(path, payload, headers = {})
|
42
|
+
raise ClientError('No data given') if payload.nil? or payload.empty?
|
43
|
+
make_request(:put, path, payload, headers)
|
44
|
+
end
|
45
|
+
|
28
46
|
#
|
29
47
|
# Makes a GET request to a MercadoPago API.
|
30
48
|
#
|
31
49
|
# - path: the path of the API to be called, including any query string parameters.
|
32
50
|
# - headers: the headers to be transmitted over the HTTP request.
|
33
51
|
#
|
34
|
-
def self.wrap_get(path, headers =
|
52
|
+
def self.wrap_get(path, headers = nil)
|
53
|
+
headers ||= CONTENT_HEADERS
|
35
54
|
make_request(:get, path, nil, headers)
|
36
55
|
end
|
37
56
|
|