gocardless-pro 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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +132 -0
  6. data/circle.yml +18 -0
  7. data/demo.rb +10 -0
  8. data/gocardless-pro.gemspec +27 -0
  9. data/lib/gocardless-pro.rb +243 -0
  10. data/lib/gocardless-pro/api_service.rb +57 -0
  11. data/lib/gocardless-pro/error.rb +42 -0
  12. data/lib/gocardless-pro/error/gocardless_error.rb +5 -0
  13. data/lib/gocardless-pro/error/invalid_api_usage_error.rb +5 -0
  14. data/lib/gocardless-pro/error/invalid_state_error.rb +5 -0
  15. data/lib/gocardless-pro/error/validation_error.rb +5 -0
  16. data/lib/gocardless-pro/list_response.rb +34 -0
  17. data/lib/gocardless-pro/paginator.rb +37 -0
  18. data/lib/gocardless-pro/request.rb +69 -0
  19. data/lib/gocardless-pro/resources/api_key.rb +62 -0
  20. data/lib/gocardless-pro/resources/creditor.rb +83 -0
  21. data/lib/gocardless-pro/resources/creditor_bank_account.rb +78 -0
  22. data/lib/gocardless-pro/resources/customer.rb +72 -0
  23. data/lib/gocardless-pro/resources/customer_bank_account.rb +80 -0
  24. data/lib/gocardless-pro/resources/event.rb +75 -0
  25. data/lib/gocardless-pro/resources/helper.rb +29 -0
  26. data/lib/gocardless-pro/resources/mandate.rb +70 -0
  27. data/lib/gocardless-pro/resources/payment.rb +86 -0
  28. data/lib/gocardless-pro/resources/payout.rb +66 -0
  29. data/lib/gocardless-pro/resources/publishable_api_key.rb +51 -0
  30. data/lib/gocardless-pro/resources/redirect_flow.rb +104 -0
  31. data/lib/gocardless-pro/resources/refund.rb +70 -0
  32. data/lib/gocardless-pro/resources/role.rb +101 -0
  33. data/lib/gocardless-pro/resources/subscription.rb +152 -0
  34. data/lib/gocardless-pro/resources/user.rb +60 -0
  35. data/lib/gocardless-pro/response.rb +77 -0
  36. data/lib/gocardless-pro/services/api_key_service.rb +130 -0
  37. data/lib/gocardless-pro/services/base_service.rb +29 -0
  38. data/lib/gocardless-pro/services/creditor_bank_account_service.rb +122 -0
  39. data/lib/gocardless-pro/services/creditor_service.rb +112 -0
  40. data/lib/gocardless-pro/services/customer_bank_account_service.rb +153 -0
  41. data/lib/gocardless-pro/services/customer_service.rb +112 -0
  42. data/lib/gocardless-pro/services/event_service.rb +80 -0
  43. data/lib/gocardless-pro/services/helper_service.rb +97 -0
  44. data/lib/gocardless-pro/services/mandate_service.rb +170 -0
  45. data/lib/gocardless-pro/services/payment_service.rb +164 -0
  46. data/lib/gocardless-pro/services/payout_service.rb +80 -0
  47. data/lib/gocardless-pro/services/publishable_api_key_service.rb +130 -0
  48. data/lib/gocardless-pro/services/redirect_flow_service.rb +96 -0
  49. data/lib/gocardless-pro/services/refund_service.rb +126 -0
  50. data/lib/gocardless-pro/services/role_service.rb +127 -0
  51. data/lib/gocardless-pro/services/subscription_service.rb +133 -0
  52. data/lib/gocardless-pro/services/user_service.rb +148 -0
  53. data/lib/gocardless-pro/version.rb +8 -0
  54. data/spec/api_service_spec.rb +69 -0
  55. data/spec/client_spec.rb +29 -0
  56. data/spec/error_spec.rb +44 -0
  57. data/spec/resources/api_key_spec.rb +85 -0
  58. data/spec/resources/creditor_bank_account_spec.rb +109 -0
  59. data/spec/resources/creditor_spec.rb +125 -0
  60. data/spec/resources/customer_bank_account_spec.rb +109 -0
  61. data/spec/resources/customer_spec.rb +127 -0
  62. data/spec/resources/event_spec.rb +113 -0
  63. data/spec/resources/helper_spec.rb +23 -0
  64. data/spec/resources/mandate_spec.rb +97 -0
  65. data/spec/resources/payment_spec.rb +129 -0
  66. data/spec/resources/payout_spec.rb +89 -0
  67. data/spec/resources/publishable_api_key_spec.rb +63 -0
  68. data/spec/resources/redirect_flow_spec.rb +97 -0
  69. data/spec/resources/refund_spec.rb +77 -0
  70. data/spec/resources/role_spec.rb +63 -0
  71. data/spec/resources/subscription_spec.rb +157 -0
  72. data/spec/resources/user_spec.rb +85 -0
  73. data/spec/response_spec.rb +79 -0
  74. data/spec/services/api_key_service_spec.rb +362 -0
  75. data/spec/services/creditor_bank_account_service_spec.rb +365 -0
  76. data/spec/services/creditor_service_spec.rb +339 -0
  77. data/spec/services/customer_bank_account_service_spec.rb +404 -0
  78. data/spec/services/customer_service_spec.rb +365 -0
  79. data/spec/services/event_service_spec.rb +172 -0
  80. data/spec/services/helper_service_spec.rb +123 -0
  81. data/spec/services/mandate_service_spec.rb +449 -0
  82. data/spec/services/payment_service_spec.rb +497 -0
  83. data/spec/services/payout_service_spec.rb +172 -0
  84. data/spec/services/publishable_api_key_service_spec.rb +336 -0
  85. data/spec/services/redirect_flow_service_spec.rb +208 -0
  86. data/spec/services/refund_service_spec.rb +279 -0
  87. data/spec/services/role_service_spec.rb +336 -0
  88. data/spec/services/subscription_service_spec.rb +488 -0
  89. data/spec/services/user_service_spec.rb +433 -0
  90. data/spec/spec_helper.rb +91 -0
  91. metadata +255 -0
@@ -0,0 +1,60 @@
1
+
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+ #
9
+ require 'uri'
10
+
11
+ module GoCardless
12
+ # A module containing classes for each of the resources in the GC Api
13
+ module Resources
14
+ #
15
+ # Represents an instance of a user resource returned from the API
16
+ class User
17
+ attr_reader :created_at
18
+
19
+ attr_reader :email
20
+
21
+ attr_reader :enabled
22
+
23
+ attr_reader :family_name
24
+
25
+ attr_reader :given_name
26
+
27
+ attr_reader :id
28
+
29
+ # initialize a resource instance
30
+ # @param object [Hash] an object returned from the API
31
+ def initialize(object)
32
+ @object = object
33
+
34
+ @created_at = object['created_at']
35
+ @email = object['email']
36
+ @enabled = object['enabled']
37
+ @family_name = object['family_name']
38
+ @given_name = object['given_name']
39
+ @id = object['id']
40
+ @links = object['links']
41
+ end
42
+
43
+ # return the links that the resource has
44
+ def links
45
+ Struct.new(
46
+ *{
47
+
48
+ role: ''
49
+
50
+ }.keys.sort
51
+ ).new(*@links.sort.map(&:last))
52
+ end
53
+
54
+ # Provides the resource as a hash of all it's readable attributes
55
+ def to_h
56
+ @object
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,77 @@
1
+ module GoCardless
2
+ # A class to wrap an API response
3
+ class Response
4
+ # Initialize a response instance
5
+ # @param response an API response
6
+ def initialize(response)
7
+ @response = response
8
+ end
9
+
10
+ # Return the body of the API response
11
+ def body
12
+ json? ? handle_json : handle_raw
13
+ end
14
+
15
+ # Returns true if the response is JSON
16
+ def json?
17
+ content_type = @response.headers['Content-Type'] ||
18
+ @response.headers['content-type'] || ''
19
+ content_type.include?('application/json')
20
+ end
21
+
22
+ # Returns true if the response is an error
23
+ def error?
24
+ @response.status >= 400
25
+ end
26
+
27
+ # Returns the meta hash of the response
28
+ def meta
29
+ fail ResponseError, 'Cannot fetch meta for non JSON response' unless json?
30
+
31
+ json_body.fetch('meta', {})
32
+ end
33
+
34
+ # Returns the limit parameter from the response
35
+ def limit
36
+ meta.fetch('limit', nil)
37
+ end
38
+
39
+ private
40
+
41
+ def json_body
42
+ @json_body ||= JSON.parse(@response.body).with_indifferent_access
43
+ end
44
+
45
+ def raw_body
46
+ @response.body
47
+ end
48
+
49
+ def handle_json
50
+ if error?
51
+ type = json_body['error']['type']
52
+ fail(error_class_for_type(type), json_body['error'])
53
+ else
54
+ json_body
55
+ end
56
+ end
57
+
58
+ def error_class_for_type(type)
59
+ {
60
+ validation_failed: GoCardless::ValidationError,
61
+ gocardless: GoCardless::GoCardlessError,
62
+ invalid_api_usage: GoCardless::InvalidApiUsageError,
63
+ invalid_state: GoCardless::InvalidStateError
64
+ }.fetch(type.to_sym)
65
+ end
66
+
67
+ def handle_raw
68
+ default_raw_message = {
69
+ 'message' => "Something went wrong with this raw request\n" \
70
+ "status: #{@response.status}\n" \
71
+ "headers: #{@response.headers}\n" \
72
+ "body: #{@response.body}"
73
+ }
74
+ error? ? fail(ApiError, default_raw_message) : raw_body
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,130 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+
9
+ module GoCardless
10
+ module Services
11
+ # Service for making requests to the ApiKey endpoints
12
+ class ApiKeyService < BaseService
13
+ # Creates a new API key.
14
+ # Example URL: /api_keys
15
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
16
+ # Else, they will be the body of the request.
17
+ def create(options = {}, custom_headers = {})
18
+ path = '/api_keys'
19
+ new_options = {}
20
+ new_options[envelope_key] = options
21
+ options = new_options
22
+ response = make_request(:post, path, options, custom_headers)
23
+
24
+ Resources::ApiKey.new(unenvelope_body(response.body))
25
+ end
26
+
27
+ # Returns a
28
+ # [cursor-paginated](https://developer.gocardless.com/pro/#overview-cursor-pagination)
29
+ # list of your API keys.
30
+ # Example URL: /api_keys
31
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
32
+ # Else, they will be the body of the request.
33
+ def list(options = {}, custom_headers = {})
34
+ path = '/api_keys'
35
+
36
+ response = make_request(:get, path, options, custom_headers)
37
+ ListResponse.new(
38
+ raw_response: response,
39
+ unenveloped_body: unenvelope_body(response.body),
40
+ resource_class: Resources::ApiKey
41
+ )
42
+ end
43
+
44
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
45
+ #
46
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
47
+ # Otherwise they will be the body of the request.
48
+ def all(options = {})
49
+ Paginator.new(
50
+ service: self,
51
+ path: '/api_keys',
52
+ options: options
53
+ ).enumerator
54
+ end
55
+
56
+ # Retrieves the details of an existing API key.
57
+ # Example URL: /api_keys/:identity
58
+ #
59
+ # @param identity # Unique identifier, beginning with "AK"
60
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
61
+ # Else, they will be the body of the request.
62
+ def get(identity, options = {}, custom_headers = {})
63
+ path = sub_url('/api_keys/:identity', 'identity' => identity)
64
+
65
+ response = make_request(:get, path, options, custom_headers)
66
+
67
+ Resources::ApiKey.new(unenvelope_body(response.body))
68
+ end
69
+
70
+ # Updates an API key. Only the `name` and `webhook_url` fields are supported.
71
+ # Example URL: /api_keys/:identity
72
+ #
73
+ # @param identity # Unique identifier, beginning with "AK"
74
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
75
+ # Else, they will be the body of the request.
76
+ def update(identity, options = {}, custom_headers = {})
77
+ path = sub_url('/api_keys/:identity', 'identity' => identity)
78
+
79
+ new_options = {}
80
+ new_options[envelope_key] = options
81
+ options = new_options
82
+ response = make_request(:put, path, options, custom_headers)
83
+
84
+ Resources::ApiKey.new(unenvelope_body(response.body))
85
+ end
86
+
87
+ # Disables an API key. Once disabled, the API key will not be usable to
88
+ # authenticate any requests, and its `webhook_url` will not receive any more
89
+ # events.
90
+ # Example URL: /api_keys/:identity/actions/disable
91
+ #
92
+ # @param identity # Unique identifier, beginning with "AK"
93
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
94
+ # Else, they will be the body of the request.
95
+ def disable(identity, options = {}, custom_headers = {})
96
+ path = sub_url('/api_keys/:identity/actions/disable', 'identity' => identity)
97
+
98
+ new_options = {}
99
+ new_options['data'] = options
100
+ options = new_options
101
+ response = make_request(:post, path, options, custom_headers)
102
+
103
+ Resources::ApiKey.new(unenvelope_body(response.body))
104
+ end
105
+
106
+ # Unenvelope the response of the body using the service's `envelope_key`
107
+ #
108
+ # @param body [Hash]
109
+ def unenvelope_body(body)
110
+ body[envelope_key] || body['data']
111
+ end
112
+
113
+ private
114
+
115
+ # return the key which API responses will envelope data under
116
+ def envelope_key
117
+ 'api_keys'
118
+ end
119
+
120
+ # take a URL with placeholder params and substitute them out for the acutal value
121
+ # @param url [String] the URL with placeholders in
122
+ # @param param_map [Hash] a hash of placeholders and their actual values
123
+ def sub_url(url, param_map)
124
+ param_map.reduce(url) do |new_url, (param, value)|
125
+ new_url.gsub(":#{param}", value)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,29 @@
1
+ module GoCardless
2
+ # Module that contains all services for making requests to the API.
3
+ module Services
4
+ # Base Service that all services inherit from.
5
+ class BaseService
6
+ # Create a new service instance to make requests against
7
+ #
8
+ # @param api_service [GoCardless::ApiService}}] an instance of the ApiService
9
+ def initialize(api_service)
10
+ @api_service = api_service
11
+ end
12
+
13
+ # Make a request to the API using the API service instance
14
+ #
15
+ # @param method [Symbol] the method to use to make the request
16
+ # @param path [String] the URL (without the base domain) to make the request to
17
+ # @param options [Hash] the options hash - either the query parameters for a GET, or the body if POST/PUT
18
+ # @param custom_headers [Hash] a hash of custom headers to use in the request
19
+ def make_request(method, path, options = {}, custom_headers = {})
20
+ @api_service.make_request(method, path, options.merge(envelope_key: envelope_key), custom_headers)
21
+ end
22
+
23
+ # Get the envelope key for the given service. Children are expected to implement this method.
24
+ def envelope_key
25
+ fail NotImplementedError
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,122 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+
9
+ module GoCardless
10
+ module Services
11
+ # Service for making requests to the CreditorBankAccount endpoints
12
+ class CreditorBankAccountService < BaseService
13
+ # Creates a new creditor bank account object.
14
+ #
15
+ # Bank account details may be
16
+ # supplied using the IBAN (international bank account number) or [local
17
+ # details](#ui-compliance-local-bank-details).
18
+ # Example URL: /creditor_bank_accounts
19
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
20
+ # Else, they will be the body of the request.
21
+ def create(options = {}, custom_headers = {})
22
+ path = '/creditor_bank_accounts'
23
+ new_options = {}
24
+ new_options[envelope_key] = options
25
+ options = new_options
26
+ response = make_request(:post, path, options, custom_headers)
27
+
28
+ Resources::CreditorBankAccount.new(unenvelope_body(response.body))
29
+ end
30
+
31
+ # Returns a
32
+ # [cursor-paginated](https://developer.gocardless.com/pro/#overview-cursor-pagination)
33
+ # list of your creditor bank accounts.
34
+ # Example URL: /creditor_bank_accounts
35
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
36
+ # Else, they will be the body of the request.
37
+ def list(options = {}, custom_headers = {})
38
+ path = '/creditor_bank_accounts'
39
+
40
+ response = make_request(:get, path, options, custom_headers)
41
+ ListResponse.new(
42
+ raw_response: response,
43
+ unenveloped_body: unenvelope_body(response.body),
44
+ resource_class: Resources::CreditorBankAccount
45
+ )
46
+ end
47
+
48
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
49
+ #
50
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
51
+ # Otherwise they will be the body of the request.
52
+ def all(options = {})
53
+ Paginator.new(
54
+ service: self,
55
+ path: '/creditor_bank_accounts',
56
+ options: options
57
+ ).enumerator
58
+ end
59
+
60
+ # Retrieves the details of an existing creditor bank account.
61
+ # Example URL: /creditor_bank_accounts/:identity
62
+ #
63
+ # @param identity # Unique identifier, beginning with "BA"
64
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
65
+ # Else, they will be the body of the request.
66
+ def get(identity, options = {}, custom_headers = {})
67
+ path = sub_url('/creditor_bank_accounts/:identity', 'identity' => identity)
68
+
69
+ response = make_request(:get, path, options, custom_headers)
70
+
71
+ Resources::CreditorBankAccount.new(unenvelope_body(response.body))
72
+ end
73
+
74
+ # Immediately disables the bank account, no money can be paid out to a disabled
75
+ # account.
76
+ #
77
+ # This will return a `disable_failed` error if the bank account
78
+ # has already been disabled.
79
+ #
80
+ # A disabled bank account can be re-enabled by
81
+ # creating a new bank account resource with the same details.
82
+ # Example URL: /creditor_bank_accounts/:identity/actions/disable
83
+ #
84
+ # @param identity # Unique identifier, beginning with "BA"
85
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
86
+ # Else, they will be the body of the request.
87
+ def disable(identity, options = {}, custom_headers = {})
88
+ path = sub_url('/creditor_bank_accounts/:identity/actions/disable', 'identity' => identity)
89
+
90
+ new_options = {}
91
+ new_options['data'] = options
92
+ options = new_options
93
+ response = make_request(:post, path, options, custom_headers)
94
+
95
+ Resources::CreditorBankAccount.new(unenvelope_body(response.body))
96
+ end
97
+
98
+ # Unenvelope the response of the body using the service's `envelope_key`
99
+ #
100
+ # @param body [Hash]
101
+ def unenvelope_body(body)
102
+ body[envelope_key] || body['data']
103
+ end
104
+
105
+ private
106
+
107
+ # return the key which API responses will envelope data under
108
+ def envelope_key
109
+ 'creditor_bank_accounts'
110
+ end
111
+
112
+ # take a URL with placeholder params and substitute them out for the acutal value
113
+ # @param url [String] the URL with placeholders in
114
+ # @param param_map [Hash] a hash of placeholders and their actual values
115
+ def sub_url(url, param_map)
116
+ param_map.reduce(url) do |new_url, (param, value)|
117
+ new_url.gsub(":#{param}", value)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,112 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+
9
+ module GoCardless
10
+ module Services
11
+ # Service for making requests to the Creditor endpoints
12
+ class CreditorService < BaseService
13
+ # Creates a new creditor.
14
+ # Example URL: /creditors
15
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
16
+ # Else, they will be the body of the request.
17
+ def create(options = {}, custom_headers = {})
18
+ path = '/creditors'
19
+ new_options = {}
20
+ new_options[envelope_key] = options
21
+ options = new_options
22
+ response = make_request(:post, path, options, custom_headers)
23
+
24
+ Resources::Creditor.new(unenvelope_body(response.body))
25
+ end
26
+
27
+ # Returns a
28
+ # [cursor-paginated](https://developer.gocardless.com/pro/#overview-cursor-pagination)
29
+ # list of your creditors.
30
+ # Example URL: /creditors
31
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
32
+ # Else, they will be the body of the request.
33
+ def list(options = {}, custom_headers = {})
34
+ path = '/creditors'
35
+
36
+ response = make_request(:get, path, options, custom_headers)
37
+ ListResponse.new(
38
+ raw_response: response,
39
+ unenveloped_body: unenvelope_body(response.body),
40
+ resource_class: Resources::Creditor
41
+ )
42
+ end
43
+
44
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
45
+ #
46
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
47
+ # Otherwise they will be the body of the request.
48
+ def all(options = {})
49
+ Paginator.new(
50
+ service: self,
51
+ path: '/creditors',
52
+ options: options
53
+ ).enumerator
54
+ end
55
+
56
+ # Retrieves the details of an existing creditor.
57
+ # Example URL: /creditors/:identity
58
+ #
59
+ # @param identity # Unique identifier, beginning with "CR".
60
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
61
+ # Else, they will be the body of the request.
62
+ def get(identity, options = {}, custom_headers = {})
63
+ path = sub_url('/creditors/:identity', 'identity' => identity)
64
+
65
+ response = make_request(:get, path, options, custom_headers)
66
+
67
+ Resources::Creditor.new(unenvelope_body(response.body))
68
+ end
69
+
70
+ # Updates a creditor object. Supports all of the fields supported when creating
71
+ # a creditor.
72
+ # Example URL: /creditors/:identity
73
+ #
74
+ # @param identity # Unique identifier, beginning with "CR".
75
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
76
+ # Else, they will be the body of the request.
77
+ def update(identity, options = {}, custom_headers = {})
78
+ path = sub_url('/creditors/:identity', 'identity' => identity)
79
+
80
+ new_options = {}
81
+ new_options[envelope_key] = options
82
+ options = new_options
83
+ response = make_request(:put, path, options, custom_headers)
84
+
85
+ Resources::Creditor.new(unenvelope_body(response.body))
86
+ end
87
+
88
+ # Unenvelope the response of the body using the service's `envelope_key`
89
+ #
90
+ # @param body [Hash]
91
+ def unenvelope_body(body)
92
+ body[envelope_key] || body['data']
93
+ end
94
+
95
+ private
96
+
97
+ # return the key which API responses will envelope data under
98
+ def envelope_key
99
+ 'creditors'
100
+ end
101
+
102
+ # take a URL with placeholder params and substitute them out for the acutal value
103
+ # @param url [String] the URL with placeholders in
104
+ # @param param_map [Hash] a hash of placeholders and their actual values
105
+ def sub_url(url, param_map)
106
+ param_map.reduce(url) do |new_url, (param, value)|
107
+ new_url.gsub(":#{param}", value)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end