revolut-api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +64 -0
- data/LICENSE.txt +21 -0
- data/README.md +238 -0
- data/Rakefile +6 -0
- data/bin/console +38 -0
- data/bin/setup +8 -0
- data/credentials.yml.example +7 -0
- data/lib/revolut/api.rb +55 -0
- data/lib/revolut/api/base.rb +124 -0
- data/lib/revolut/api/client.rb +29 -0
- data/lib/revolut/api/configuration.rb +26 -0
- data/lib/revolut/api/constants.rb +26 -0
- data/lib/revolut/api/errors.rb +20 -0
- data/lib/revolut/api/private/auth.rb +49 -0
- data/lib/revolut/api/private/exchange.rb +91 -0
- data/lib/revolut/api/private/transactions.rb +77 -0
- data/lib/revolut/api/private/user.rb +40 -0
- data/lib/revolut/api/public/client.rb +24 -0
- data/lib/revolut/api/railtie.rb +14 -0
- data/lib/revolut/api/response/address.rb +36 -0
- data/lib/revolut/api/response/card.rb +54 -0
- data/lib/revolut/api/response/card_issuer.rb +29 -0
- data/lib/revolut/api/response/merchant.rb +30 -0
- data/lib/revolut/api/response/pocket.rb +33 -0
- data/lib/revolut/api/response/quote.rb +52 -0
- data/lib/revolut/api/response/transaction.rb +67 -0
- data/lib/revolut/api/response/user.rb +50 -0
- data/lib/revolut/api/response/wallet.rb +42 -0
- data/lib/revolut/api/utilities.rb +28 -0
- data/lib/revolut/api/version.rb +5 -0
- data/revolut-api.gemspec +35 -0
- metadata +207 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Private
|
4
|
+
module Transactions
|
5
|
+
|
6
|
+
def transactions(from: Time.new(Time.now.year, Time.now.month, 1, 0, 0, 0, 0), type: nil, phrase: nil, completed: nil, pending: nil, fetch_all: true, memoize: true)
|
7
|
+
current = Time.now.utc
|
8
|
+
txs = {}
|
9
|
+
|
10
|
+
if fetch_all && memoize && memoized.fetch(:transactions, []).any?
|
11
|
+
txs = memoized.fetch(:transactions, [])
|
12
|
+
else
|
13
|
+
while from < current
|
14
|
+
params = {from: ::Revolut::Api::Utilities.utc_to_epoch(from)}
|
15
|
+
data = request_transactions(params: params)
|
16
|
+
|
17
|
+
data.each do |item|
|
18
|
+
tx = ::Revolut::Api::Response::Transaction.new(item)
|
19
|
+
txs[tx.id] = tx if tx && !tx.id.to_s.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
from = from + ::Revolut::Api::Constants::TIME[:one_month]
|
23
|
+
break unless fetch_all
|
24
|
+
end
|
25
|
+
|
26
|
+
txs = txs.values
|
27
|
+
memoized[:transactions] = txs if fetch_all
|
28
|
+
end
|
29
|
+
|
30
|
+
if !type.to_s.empty?
|
31
|
+
txs = txs.select { |tx| tx.type.to_s.upcase.strip == type.to_s.upcase.strip }
|
32
|
+
end
|
33
|
+
|
34
|
+
if completed.eql?(true)
|
35
|
+
txs = txs.select { |tx| tx.completed? }
|
36
|
+
end
|
37
|
+
|
38
|
+
if pending.eql?(true)
|
39
|
+
txs = txs.select { |tx| tx.pending? }
|
40
|
+
end
|
41
|
+
|
42
|
+
if !phrase.to_s.empty?
|
43
|
+
txs = txs.select { |tx| !(tx.description =~ /#{phrase}/i).nil? }
|
44
|
+
end
|
45
|
+
|
46
|
+
txs = txs.sort_by { |tx| tx.started_date }
|
47
|
+
|
48
|
+
return txs
|
49
|
+
end
|
50
|
+
|
51
|
+
def request_transactions(params: {}, retries: 3)
|
52
|
+
data = nil
|
53
|
+
|
54
|
+
begin
|
55
|
+
data = get("user/current/transactions", params: params)
|
56
|
+
rescue Faraday::ParsingError => e
|
57
|
+
retries -= 1
|
58
|
+
retry if retries > 0
|
59
|
+
end
|
60
|
+
|
61
|
+
return data
|
62
|
+
end
|
63
|
+
|
64
|
+
def transaction(id)
|
65
|
+
response = get("transaction/#{id}")
|
66
|
+
|
67
|
+
if response.is_a?(Hash)
|
68
|
+
log "#{response["message"]}"
|
69
|
+
elsif response.is_a?(Array)
|
70
|
+
return ::Revolut::Api::Response::Transaction.new(response&.first)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Private
|
4
|
+
module User
|
5
|
+
|
6
|
+
def user
|
7
|
+
::Revolut::Api::Response::User.new(get("user/current"))
|
8
|
+
end
|
9
|
+
|
10
|
+
def wallet
|
11
|
+
::Revolut::Api::Response::Wallet.new(get("user/current/wallet"))
|
12
|
+
end
|
13
|
+
|
14
|
+
def cards
|
15
|
+
get("user/current/cards")&.collect { |response| ::Revolut::Api::Response::Card.new(response) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_address(city: nil, country: nil, postcode: nil, region: nil, street_line_one: nil, street_line_two: nil)
|
19
|
+
response = nil
|
20
|
+
address = user.address
|
21
|
+
|
22
|
+
if address
|
23
|
+
address.city = city unless city.nil?
|
24
|
+
address.country = country unless country.nil?
|
25
|
+
address.postcode = postcode unless postcode.nil?
|
26
|
+
address.region = region unless region.nil?
|
27
|
+
address.street_line_one = street_line_one unless street_line_one.nil?
|
28
|
+
address.street_line_two = street_line_two unless street_line_two.nil?
|
29
|
+
|
30
|
+
payload = {"address" => address.to_api_hash}
|
31
|
+
response = patch("user/current", data: payload)
|
32
|
+
end
|
33
|
+
|
34
|
+
return response
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Public
|
4
|
+
|
5
|
+
class Client < ::Revolut::Api::Base
|
6
|
+
def initialize(host: "www.revolut.com")
|
7
|
+
super(host: host)
|
8
|
+
end
|
9
|
+
|
10
|
+
def quotes(from: [], to: [], endpoint: "api/quote/internal")
|
11
|
+
options = {
|
12
|
+
user_agent: ::Revolut::Api::Constants::PUBLIC_USER_AGENT,
|
13
|
+
authenticate: false,
|
14
|
+
check_configuration: false
|
15
|
+
}
|
16
|
+
|
17
|
+
super(from: from, to: to, endpoint: endpoint, options: options)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class Address
|
5
|
+
attr_accessor :mapping
|
6
|
+
attr_accessor :country, :city, :postcode, :region, :street_line_one, :street_line_two
|
7
|
+
|
8
|
+
MAPPING = {
|
9
|
+
"country" => :country,
|
10
|
+
"city" => :city,
|
11
|
+
"postcode" => :postcode,
|
12
|
+
"region" => :region,
|
13
|
+
"streetLine1" => :street_line_one,
|
14
|
+
"streetLine2" => :street_line_two
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize(hash = {})
|
18
|
+
::Revolut::Api::Response::Address::MAPPING.each do |revolut_key, accessor|
|
19
|
+
self.send("#{accessor}=", hash.fetch(revolut_key, nil))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_api_hash
|
24
|
+
hash = {}
|
25
|
+
|
26
|
+
::Revolut::Api::Response::Address::MAPPING.each do |revolut_key, accessor|
|
27
|
+
hash[revolut_key] = self.send(accessor)
|
28
|
+
end
|
29
|
+
|
30
|
+
return hash
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class Card
|
5
|
+
attr_accessor :id, :owner_id
|
6
|
+
attr_accessor :last_four, :brand
|
7
|
+
attr_accessor :expiry_date, :expired
|
8
|
+
attr_accessor :three_d_verified, :address, :issuer
|
9
|
+
attr_accessor :currency, :confirmed, :confirmation_attempts, :auto_topup
|
10
|
+
attr_accessor :created_date, :updated_date, :last_used_date
|
11
|
+
attr_accessor :topup_limit, :current_topup
|
12
|
+
|
13
|
+
def initialize(hash = {})
|
14
|
+
self.id = hash.fetch("id", nil)
|
15
|
+
self.owner_id = hash.fetch("ownerId", nil)
|
16
|
+
self.last_four = hash.fetch("lastFour", nil)&.to_i
|
17
|
+
self.brand = hash.fetch("brand", nil)
|
18
|
+
|
19
|
+
self.expiry_date = {
|
20
|
+
month: hash.fetch("expiryDate", {}).fetch("month", nil),
|
21
|
+
year: hash.fetch("expiryDate", {}).fetch("year", nil),
|
22
|
+
}
|
23
|
+
|
24
|
+
self.three_d_verified = hash.fetch("threeDVerified", false)
|
25
|
+
|
26
|
+
address_data = hash.fetch("address", {})
|
27
|
+
self.address = ::Revolut::Api::Response::Address.new(address_data)
|
28
|
+
|
29
|
+
issuer_data = hash.fetch("issuer", {})
|
30
|
+
self.issuer = ::Revolut::Api::Response::CardIssuer.new(issuer_data)
|
31
|
+
|
32
|
+
self.currency = hash.fetch("currency", nil)
|
33
|
+
self.confirmed = hash.fetch("confirmed", false)
|
34
|
+
self.confirmation_attempts = hash.fetch("confirmationAttempts", 0)
|
35
|
+
self.auto_topup = hash.fetch("autoTopup", nil)
|
36
|
+
|
37
|
+
self.created_date = hash.fetch("createdDate", nil)
|
38
|
+
self.created_date = ::Revolut::Api::Utilities.epoch_to_utc(self.created_date) unless self.created_date.nil?
|
39
|
+
self.updated_date = hash.fetch("updatedDate", nil)
|
40
|
+
self.updated_date = ::Revolut::Api::Utilities.epoch_to_utc(self.updated_date) unless self.updated_date.nil?
|
41
|
+
self.last_used_date = hash.fetch("lastUsedDate", nil)
|
42
|
+
self.last_used_date = ::Revolut::Api::Utilities.epoch_to_utc(self.last_used_date) unless self.last_used_date.nil?
|
43
|
+
|
44
|
+
self.topup_limit = hash.fetch("topupLimit", nil)
|
45
|
+
self.topup_limit = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.topup_limit) if !self.currency.to_s.empty? && !self.topup_limit.nil?
|
46
|
+
|
47
|
+
self.current_topup = hash.fetch("currentTopup", nil)
|
48
|
+
self.current_topup = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.current_topup) if !self.currency.to_s.empty? && !self.current_topup.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class CardIssuer
|
5
|
+
attr_accessor :mapping
|
6
|
+
attr_accessor :bin, :name, :logo_url
|
7
|
+
attr_accessor :card_type, :card_brand
|
8
|
+
attr_accessor :currency, :supported
|
9
|
+
|
10
|
+
MAPPING = {
|
11
|
+
"bin" => :bin,
|
12
|
+
"name" => :name,
|
13
|
+
"logoUrl" => :logo_url,
|
14
|
+
"cardType" => :card_type,
|
15
|
+
"cardBrand" => :card_brand,
|
16
|
+
"currency" => :currency,
|
17
|
+
"supported" => :supported
|
18
|
+
}
|
19
|
+
|
20
|
+
def initialize(hash = {})
|
21
|
+
::Revolut::Api::Response::CardIssuer::MAPPING.each do |revolut_key, accessor|
|
22
|
+
self.send("#{accessor}=", hash.fetch(revolut_key, nil))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class Merchant
|
5
|
+
attr_accessor :mapping
|
6
|
+
attr_accessor :id, :scheme, :name, :mcc, :country, :state, :city, :postcode, :address, :category
|
7
|
+
|
8
|
+
MAPPING = {
|
9
|
+
"id" => :id,
|
10
|
+
"scheme" => :scheme,
|
11
|
+
"name" => :name,
|
12
|
+
"mcc" => :mcc,
|
13
|
+
"country" => :country,
|
14
|
+
"state" => :state,
|
15
|
+
"city" => :city,
|
16
|
+
"postcode" => :postcode,
|
17
|
+
"address" => :address,
|
18
|
+
"category" => :category,
|
19
|
+
}
|
20
|
+
|
21
|
+
def initialize(hash = {})
|
22
|
+
::Revolut::Api::Response::Merchant::MAPPING.each do |revolut_key, accessor|
|
23
|
+
self.send("#{accessor}=", hash.fetch(revolut_key, nil))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class Pocket
|
5
|
+
attr_accessor :id, :state
|
6
|
+
attr_accessor :currency
|
7
|
+
attr_accessor :balance, :blocked_amount
|
8
|
+
|
9
|
+
def initialize(hash = {})
|
10
|
+
self.id = hash.fetch("id", nil)
|
11
|
+
self.state = hash.fetch("state", nil)
|
12
|
+
|
13
|
+
self.currency = hash.fetch("currency", nil)
|
14
|
+
|
15
|
+
self.balance = hash.fetch("balance", nil)
|
16
|
+
self.balance = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.balance) if !self.currency.to_s.empty? && !self.balance.nil?
|
17
|
+
|
18
|
+
self.blocked_amount = hash.fetch("blockedAmount", nil)
|
19
|
+
self.blocked_amount = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.blocked_amount) if !self.currency.to_s.empty? && !self.blocked_amount.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def active?
|
23
|
+
in_state?(:active)
|
24
|
+
end
|
25
|
+
|
26
|
+
def in_state?(state)
|
27
|
+
self.state.downcase.strip.to_sym.eql?(state)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class Quote
|
5
|
+
attr_accessor :from, :to
|
6
|
+
attr_accessor :fee, :rate, :markup
|
7
|
+
attr_accessor :epoch, :timestamp
|
8
|
+
attr_accessor :success, :message
|
9
|
+
|
10
|
+
def initialize(hash = {})
|
11
|
+
if hash.has_key?("message")
|
12
|
+
self.message = hash.fetch("message")
|
13
|
+
self.success = false
|
14
|
+
|
15
|
+
else
|
16
|
+
self.from = {}
|
17
|
+
self.to = {}
|
18
|
+
self.fee = {}
|
19
|
+
|
20
|
+
set_amount_hash("from", hash)
|
21
|
+
set_amount_hash("to", hash)
|
22
|
+
set_amount_hash("fee", hash)
|
23
|
+
|
24
|
+
self.rate = hash.fetch("rate", nil)
|
25
|
+
self.markup = hash.fetch("markup", nil)
|
26
|
+
|
27
|
+
self.epoch = hash.fetch("timestamp", nil)
|
28
|
+
self.timestamp = ::Revolut::Api::Utilities.epoch_to_utc(self.epoch)
|
29
|
+
|
30
|
+
self.success = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_amount_hash(key, hash)
|
35
|
+
if hash.has_key?(key)
|
36
|
+
sub_item = hash.fetch(key, {})
|
37
|
+
|
38
|
+
if sub_item.is_a?(Hash)
|
39
|
+
self.send(key)[:currency] = sub_item.fetch("currency", nil)
|
40
|
+
self.send(key)[:base_amount] = sub_item.fetch("amount", nil)
|
41
|
+
self.send(key)[:amount] = ::Revolut::Api::Utilities.convert_from_integer_amount(self.send(key)[:currency], self.send(key)[:base_amount]) if !self.send(key)[:currency].to_s.empty? && !self.send(key)[:base_amount].nil?
|
42
|
+
|
43
|
+
elsif sub_item.is_a?(String)
|
44
|
+
self.send("#{key}=", sub_item)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Revolut
|
2
|
+
module Api
|
3
|
+
module Response
|
4
|
+
class Transaction
|
5
|
+
attr_accessor :id, :leg_id
|
6
|
+
attr_accessor :type, :state
|
7
|
+
attr_accessor :started_date, :updated_date, :completed_date
|
8
|
+
attr_accessor :currency, :amount, :fee, :balance, :description, :rate
|
9
|
+
attr_accessor :direction, :counterpart
|
10
|
+
attr_accessor :merchant, :card
|
11
|
+
|
12
|
+
def initialize(hash = {})
|
13
|
+
self.id = hash.fetch("id", nil)
|
14
|
+
self.leg_id = hash.fetch("legId", nil)
|
15
|
+
self.type = hash.fetch("type", nil)
|
16
|
+
self.state = hash.fetch("state", nil)
|
17
|
+
|
18
|
+
self.started_date = hash.fetch("startedDate", nil)
|
19
|
+
self.started_date = ::Revolut::Api::Utilities.epoch_to_utc(self.started_date) unless self.started_date.nil?
|
20
|
+
self.updated_date = hash.fetch("updatedDate", nil)
|
21
|
+
self.updated_date = ::Revolut::Api::Utilities.epoch_to_utc(self.updated_date) unless self.updated_date.nil?
|
22
|
+
self.completed_date = hash.fetch("completedDate", nil)
|
23
|
+
self.completed_date = ::Revolut::Api::Utilities.epoch_to_utc(self.completed_date) unless self.completed_date.nil?
|
24
|
+
|
25
|
+
self.currency = hash.fetch("currency", nil)
|
26
|
+
self.amount = hash.fetch("amount", nil)
|
27
|
+
self.amount = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.amount) if !self.currency.to_s.empty? && !self.amount.nil?
|
28
|
+
|
29
|
+
self.fee = hash.fetch("fee", nil)
|
30
|
+
self.fee = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.fee) if !self.currency.to_s.empty? && !self.fee.nil?
|
31
|
+
|
32
|
+
self.balance = hash.fetch("balance", nil)
|
33
|
+
self.balance = ::Revolut::Api::Utilities.convert_from_integer_amount(self.currency, self.balance) if !self.currency.to_s.empty? && !self.balance.nil?
|
34
|
+
|
35
|
+
self.description = hash.fetch("description", nil)
|
36
|
+
|
37
|
+
self.rate = hash.fetch("rate", nil)
|
38
|
+
self.direction = hash.fetch("direction", nil)
|
39
|
+
|
40
|
+
self.counterpart = {}
|
41
|
+
self.counterpart[:currency] = hash.fetch("counterpart", {}).fetch("currency", nil)
|
42
|
+
self.counterpart[:amount] = hash.fetch("counterpart", {}).fetch("amount", nil)
|
43
|
+
self.counterpart[:amount] = ::Revolut::Api::Utilities.convert_from_integer_amount(self.counterpart[:currency], self.counterpart[:amount]) if !self.counterpart[:currency].to_s.empty? && !self.counterpart[:amount].nil?
|
44
|
+
|
45
|
+
merchant_data = hash.fetch("merchant", {})
|
46
|
+
self.merchant = ::Revolut::Api::Response::Merchant.new(merchant_data) if !merchant_data.empty?
|
47
|
+
|
48
|
+
self.card = {}
|
49
|
+
self.card[:last_four] = hash.fetch("card", {}).fetch("lastFour", nil)
|
50
|
+
end
|
51
|
+
|
52
|
+
def completed?
|
53
|
+
in_state?(:completed)
|
54
|
+
end
|
55
|
+
|
56
|
+
def pending?
|
57
|
+
in_state?(:pending)
|
58
|
+
end
|
59
|
+
|
60
|
+
def in_state?(state)
|
61
|
+
self.state.downcase.strip.to_sym.eql?(state)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|