starling-ruby 0.1.0 → 0.2.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 +4 -4
- data/.circleci/config.yml +8 -0
- data/.gitignore +1 -0
- data/.reek +27 -0
- data/.rubocop.yml +6 -4
- data/CHANGELOG.md +17 -0
- data/Gemfile.lock +37 -2
- data/README.md +102 -17
- data/bin/console +2 -6
- data/lib/starling.rb +40 -7
- data/lib/starling/api_service.rb +45 -37
- data/lib/starling/client.rb +165 -6
- data/lib/starling/errors/api_error.rb +35 -2
- data/lib/starling/errors/base_error.rb +6 -24
- data/lib/starling/middlewares/raise_starling_errors.rb +11 -10
- data/lib/starling/request.rb +17 -19
- data/lib/starling/resources/account_balance_resource.rb +14 -6
- data/lib/starling/resources/account_resource.rb +10 -0
- data/lib/starling/resources/address_resource.rb +26 -0
- data/lib/starling/resources/addresses_resource.rb +18 -0
- data/lib/starling/resources/base_resource.rb +34 -9
- data/lib/starling/resources/card_resource.rb +46 -0
- data/lib/starling/resources/contact_account_resource.rb +31 -0
- data/lib/starling/resources/contact_resource.rb +16 -0
- data/lib/starling/resources/customer_resource.rb +36 -0
- data/lib/starling/resources/direct_debit_mandate_resource.rb +43 -0
- data/lib/starling/resources/direct_debit_transaction_resource.rb +54 -0
- data/lib/starling/resources/inbound_faster_payments_transaction_resource.rb +56 -0
- data/lib/starling/resources/mastercard_transaction_resource.rb +73 -0
- data/lib/starling/resources/me_resource.rb +26 -0
- data/lib/starling/resources/merchant_location_resource.rb +33 -0
- data/lib/starling/resources/merchant_resource.rb +34 -0
- data/lib/starling/resources/outbound_faster_payments_transaction_resource.rb +56 -0
- data/lib/starling/resources/payment_resource.rb +78 -0
- data/lib/starling/resources/transaction_resource.rb +42 -0
- data/lib/starling/services/account_balance_service.rb +11 -2
- data/lib/starling/services/account_service.rb +16 -3
- data/lib/starling/services/addresses_service.rb +26 -0
- data/lib/starling/services/base_service.rb +22 -1
- data/lib/starling/services/card_service.rb +26 -0
- data/lib/starling/services/contact_accounts_service.rb +54 -0
- data/lib/starling/services/contacts_service.rb +73 -0
- data/lib/starling/services/customer_service.rb +25 -0
- data/lib/starling/services/direct_debit_mandates_service.rb +61 -0
- data/lib/starling/services/direct_debit_transactions_service.rb +46 -0
- data/lib/starling/services/inbound_faster_payments_transactions_service.rb +46 -0
- data/lib/starling/services/mastercard_transactions_service.rb +30 -0
- data/lib/starling/services/me_service.rb +26 -0
- data/lib/starling/services/merchant_locations_service.rb +34 -0
- data/lib/starling/services/merchants_service.rb +26 -0
- data/lib/starling/services/outbound_faster_payments_transactions_service.rb +46 -0
- data/lib/starling/services/payments_service.rb +30 -0
- data/lib/starling/services/transactions_service.rb +44 -0
- data/lib/starling/utils.rb +30 -0
- data/lib/starling/version.rb +1 -1
- data/starling-ruby.gemspec +2 -0
- metadata +63 -2
@@ -0,0 +1,26 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing an address in the response from the Addresses API
|
4
|
+
class AddressResource < BaseResource
|
5
|
+
# @return [String] the city where the address is located
|
6
|
+
def city
|
7
|
+
parsed_data['city']
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the country where the addresses is located (e.g. "GBR")
|
11
|
+
def country
|
12
|
+
parsed_data['country']
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] the postcode of the address
|
16
|
+
def postcode
|
17
|
+
parsed_data['postcode']
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] the street address of the address
|
21
|
+
def street_address
|
22
|
+
parsed_data['streetAddress']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a response from the Addresses API
|
4
|
+
class AddressesResource < BaseResource
|
5
|
+
# @return [AddressResource] the user's current address
|
6
|
+
def current
|
7
|
+
AddressResource.new(parsed_data: parsed_data['current'])
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Array<AddressResource>] a list of the user's previous addresses
|
11
|
+
def previous
|
12
|
+
parsed_data['previous'].map do |address|
|
13
|
+
AddressResource.new(parsed_data: address)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,38 +1,63 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'time'
|
3
|
+
require 'date'
|
3
4
|
|
4
5
|
module Starling
|
5
6
|
module Resources
|
7
|
+
# A basic implementation of a resource representing a response from the Starling Bank
|
8
|
+
# API
|
6
9
|
class BaseResource
|
7
|
-
# A resource can be instantiated with either a Faraday::Response
|
8
|
-
# #body, or with a Hash pre-parsed from JSON
|
10
|
+
# A resource can be instantiated with either a Faraday::Response (including a
|
11
|
+
# #body), or with a Hash pre-parsed from JSON.
|
12
|
+
#
|
13
|
+
# An alternative possible approach to our resources would be to parse out the
|
14
|
+
# attributes we care about at initialisation, and then just add `attr_reader`s,
|
15
|
+
# rather than looking into the parsed JSON hash. The current solution is probably
|
16
|
+
# preferable, since it defers delving into the hash until a parameter is actually
|
17
|
+
# wanted, and keeps instance variables to a minimum.
|
18
|
+
#
|
19
|
+
# @param response [Faraday::Response] The complete HTTP response, returned by
|
20
|
+
# {Request#make_request}
|
21
|
+
# @param parsed_data [Hash] The pre-parsed data for the resource, useful for
|
22
|
+
# building resources from list resources we've already
|
23
|
+
# parsed
|
9
24
|
def initialize(response: nil, parsed_data: nil)
|
10
|
-
|
25
|
+
unless response || parsed_data
|
11
26
|
raise ArgumentError, 'Either response or parsed_data must be provided to ' \
|
12
27
|
'instantiate a resource'
|
13
28
|
end
|
14
29
|
|
15
30
|
@response = response
|
16
|
-
@parsed_data = parsed_data
|
31
|
+
@parsed_data = parsed_data || JSON.parse(response.body)
|
17
32
|
end
|
18
33
|
|
19
34
|
private
|
20
35
|
|
36
|
+
attr_reader :parsed_data
|
37
|
+
|
21
38
|
def present_datetime(iso8601_string)
|
22
39
|
Time.parse(iso8601_string)
|
23
40
|
end
|
24
41
|
|
42
|
+
def present_date(string)
|
43
|
+
Date.parse(string)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Many fields returned in the API (e.g. transaction amounts) can be either integers
|
47
|
+
# or more complex values with decimal places. The JSON parser will turn these into
|
48
|
+
# Integer (Fixnum in Ruby versions before 2.4) and Float objects respectively. For
|
49
|
+
# consistency, we will convert anything that *could* be a Float into a Float.
|
50
|
+
def present_float(number)
|
51
|
+
Float(number)
|
52
|
+
end
|
53
|
+
|
25
54
|
# Some strings returned by the API are specified as Enum types, with a specified
|
26
55
|
# set of possible values. These are best represented in Ruby as symbols (e.g.
|
27
56
|
# the Transaction API's `source` can have the value MASTER_CARD, which will become
|
28
57
|
# :master_card.
|
29
|
-
def
|
58
|
+
def present_enum(enum_string)
|
30
59
|
enum_string.downcase.to_sym
|
31
60
|
end
|
32
|
-
|
33
|
-
def parsed_data
|
34
|
-
@parsed_data ||= JSON.parse(@response.body)
|
35
|
-
end
|
36
61
|
end
|
37
62
|
end
|
38
63
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a response from the Card API
|
4
|
+
class CardResource < BaseResource
|
5
|
+
# @return [String] the Starling internal ID of the card
|
6
|
+
def id
|
7
|
+
parsed_data['id']
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the name on the front of the card
|
11
|
+
def name_on_card
|
12
|
+
parsed_data['nameOnCard']
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] the type of the card (e.g. "ContactlessDebitMastercard")
|
16
|
+
def type
|
17
|
+
parsed_data['type']
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [true, false] whether the card is enabled
|
21
|
+
def enabled
|
22
|
+
parsed_data['enabled']
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [true, false] whether the card has been cancelled
|
26
|
+
def cancelled
|
27
|
+
parsed_data['cancelled']
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [true, false] whether the card's activation has been requested
|
31
|
+
def activation_requested
|
32
|
+
parsed_data['activationRequested']
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [true, false] whether the card has been activated
|
36
|
+
def activated
|
37
|
+
parsed_data['activated']
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Date] when the card was dispatched by post to the user
|
41
|
+
def dispatch_date
|
42
|
+
present_date(parsed_data['dispatchDate'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a Contact Account returned from the Contact Accounts API
|
4
|
+
class ContactAccountResource < BaseResource
|
5
|
+
# @return [String] the Starling internal ID of the contact account
|
6
|
+
def id
|
7
|
+
parsed_data['id']
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the name of the contact account
|
11
|
+
def name
|
12
|
+
parsed_data['name']
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Symbol] the type of the contact account (e.g. `:domestic`)
|
16
|
+
def type
|
17
|
+
present_enum(parsed_data['type'])
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] the account number of the contact account
|
21
|
+
def account_number
|
22
|
+
parsed_data['accountNumber']
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String] the sort code of the contact account
|
26
|
+
def sort_code
|
27
|
+
parsed_data['sortCode']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a Contact returned from the Contacts API
|
4
|
+
class ContactResource < BaseResource
|
5
|
+
# @return [String] the Starling internal ID of the contact
|
6
|
+
def id
|
7
|
+
parsed_data['id']
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the name of the contact
|
11
|
+
def name
|
12
|
+
parsed_data['name']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing the response returned from the Customer API
|
4
|
+
class CustomerResource < BaseResource
|
5
|
+
# @return [String] the Starling internal ID of the customer
|
6
|
+
def customer_uid
|
7
|
+
parsed_data['customerUid']
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the first name of the customer
|
11
|
+
def first_name
|
12
|
+
parsed_data['firstName']
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] the last name of the customer
|
16
|
+
def last_name
|
17
|
+
parsed_data['lastName']
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Date] the date of birth of the customer
|
21
|
+
def date_of_birth
|
22
|
+
present_date(parsed_data['dateOfBirth'])
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String] the email address of the customer
|
26
|
+
def email
|
27
|
+
parsed_data['email']
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] the phone number of the customer
|
31
|
+
def phone
|
32
|
+
parsed_data['phone']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a Direct Debit mandate returned from the Direct Debit
|
4
|
+
# Mandates API
|
5
|
+
class DirectDebitMandateResource < BaseResource
|
6
|
+
# @return [String] the Starling internal ID of the Direct Debit mandate
|
7
|
+
def uid
|
8
|
+
parsed_data['uid']
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String] the reference of the Direct Debit mandate
|
12
|
+
def reference
|
13
|
+
parsed_data['reference']
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Symbol] the status of the mandate (e.g. `:live`)
|
17
|
+
def status
|
18
|
+
present_enum(parsed_data['status'])
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Symbol] the source of the mandate (e.g. `:electronic` or `paper)
|
22
|
+
def source
|
23
|
+
present_enum(parsed_data['source'])
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Time] the date when the mandate was created
|
27
|
+
def created
|
28
|
+
present_datetime(parsed_data['created'])
|
29
|
+
end
|
30
|
+
alias created_at created
|
31
|
+
|
32
|
+
# @return [String] the name of the Direct Debit mandate's originator
|
33
|
+
def originator_name
|
34
|
+
parsed_data['originatorName']
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String] the Starling internal ID of the Direct Debit mandate's originator
|
38
|
+
def originator_uid
|
39
|
+
parsed_data['originatorUid']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a Transaction returned from the Transaction Direct Debit
|
4
|
+
# API
|
5
|
+
class DirectDebitTransactionResource < BaseResource
|
6
|
+
# @return [String] the Starling internal ID of the transaction
|
7
|
+
def id
|
8
|
+
parsed_data['id']
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String] the currency of the transaction (e.g. "GBP" or "UAH")
|
12
|
+
def currency
|
13
|
+
parsed_data['currency']
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Float] the amount of the transaction
|
17
|
+
def amount
|
18
|
+
present_float(parsed_data['amount'])
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Symbol] the direction of the transaction (e.g. `:outbound`)
|
22
|
+
def direction
|
23
|
+
present_enum(parsed_data['direction'])
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Time] the date and time when the transaction was recorded
|
27
|
+
def created
|
28
|
+
present_datetime(parsed_data['created'])
|
29
|
+
end
|
30
|
+
alias created_at created
|
31
|
+
|
32
|
+
# @return [String] the narrative of the transaction
|
33
|
+
def narrative
|
34
|
+
parsed_data['narrative']
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Symbol] the source of the transaction (e.g. `:master_card`)
|
38
|
+
def source
|
39
|
+
present_enum(parsed_data['source'])
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [String] the Starling internal ID of the Direct Debit mandate
|
43
|
+
def mandate_id
|
44
|
+
parsed_data['mandateId']
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Symbol] the type of the transaction
|
48
|
+
# (e.g. `:first_payment_of_direct_debit` or `:direct_debit`)
|
49
|
+
def type
|
50
|
+
present_enum(parsed_data['type'])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a Transaction returned from the Transactions Faster
|
4
|
+
# Payments In API
|
5
|
+
class InboundFasterPaymentsTransactionResource < BaseResource
|
6
|
+
# @return [String] the Starling internal ID of the transaction
|
7
|
+
def id
|
8
|
+
parsed_data['id']
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String] the currency of the transaction (e.g. "GBP" or "UAH")
|
12
|
+
def currency
|
13
|
+
parsed_data['currency']
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Float] the amount of the transaction
|
17
|
+
def amount
|
18
|
+
present_float(parsed_data['amount'])
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Symbol] the direction of the transaction (e.g. `:outbound`)
|
22
|
+
def direction
|
23
|
+
present_enum(parsed_data['direction'])
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Time] the date and time when the transaction was recorded
|
27
|
+
def created
|
28
|
+
present_datetime(parsed_data['created'])
|
29
|
+
end
|
30
|
+
alias created_at created
|
31
|
+
|
32
|
+
# @return [String] the narrative of the transaction
|
33
|
+
def narrative
|
34
|
+
parsed_data['narrative']
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Symbol] the source of the transaction (e.g. `:master_card`)
|
38
|
+
def source
|
39
|
+
present_enum(parsed_data['source'])
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [String, nil] the Starling internal ID of the contact who sent the
|
43
|
+
# payment, or nil if they are not one of the user's contacts
|
44
|
+
def sending_contact_id
|
45
|
+
parsed_data['sendingContactId']
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String, nil] the Starling internal ID of the contact account which sent
|
49
|
+
# the payment, or nil if they are not one of the user's
|
50
|
+
# contacts
|
51
|
+
def sending_contact_account_id
|
52
|
+
parsed_data['sendingContactAccountId']
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Starling
|
2
|
+
module Resources
|
3
|
+
# A resource representing a Transaction returned from the Transactions Mastercard API
|
4
|
+
class MastercardTransactionResource < BaseResource
|
5
|
+
# @return [String] the Starling internal ID of the transaction
|
6
|
+
def id
|
7
|
+
parsed_data['id']
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [String] the currency of the transaction (e.g. "GBP" or "UAH")
|
11
|
+
def currency
|
12
|
+
parsed_data['currency']
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Float] the amount of the transaction
|
16
|
+
def amount
|
17
|
+
present_float(parsed_data['amount'])
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Symbol] the direction of the transaction (e.g. `:outbound`)
|
21
|
+
def direction
|
22
|
+
present_enum(parsed_data['direction'])
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Time] the date and time when the transaction was recorded
|
26
|
+
def created
|
27
|
+
present_datetime(parsed_data['created'])
|
28
|
+
end
|
29
|
+
alias created_at created
|
30
|
+
|
31
|
+
# @return [String] the narrative of the transaction
|
32
|
+
def narrative
|
33
|
+
parsed_data['narrative']
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Symbol] the source of the transaction (e.g. `:master_card`)
|
37
|
+
def source
|
38
|
+
present_enum(parsed_data['source'])
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Symbol] the MasterCard transaction method of the transaction (e.g.
|
42
|
+
# `:contactless`)
|
43
|
+
def mastercard_transaction_method
|
44
|
+
present_enum(parsed_data['mastercardTransactionMethod'])
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Symbol] the status of the transaction (e.g. `:settled`)
|
48
|
+
def status
|
49
|
+
present_enum(parsed_data['status'])
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [String] the source currency of the transaction (e.g. "GBP" or "UAH")
|
53
|
+
def source_currency
|
54
|
+
parsed_data['sourceCurrency']
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Float] the source amount of the transaction
|
58
|
+
def source_amount
|
59
|
+
present_float(parsed_data['sourceAmount'])
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [String] the Starling internal ID of the merchant
|
63
|
+
def merchant_id
|
64
|
+
parsed_data['merchantId']
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String] the Starling internal ID of the merchant location
|
68
|
+
def merchant_location_id
|
69
|
+
parsed_data['merchantLocationId']
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|