gocardless_pro 0.3.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 (76) 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 +146 -0
  6. data/circle.yml +3 -0
  7. data/demo.rb +9 -0
  8. data/gocardless_pro.gemspec +26 -0
  9. data/lib/gocardless_pro.rb +73 -0
  10. data/lib/gocardless_pro/api_service.rb +58 -0
  11. data/lib/gocardless_pro/client.rb +135 -0
  12. data/lib/gocardless_pro/error.rb +42 -0
  13. data/lib/gocardless_pro/error/gocardless_error.rb +5 -0
  14. data/lib/gocardless_pro/error/invalid_api_usage_error.rb +5 -0
  15. data/lib/gocardless_pro/error/invalid_state_error.rb +5 -0
  16. data/lib/gocardless_pro/error/validation_error.rb +5 -0
  17. data/lib/gocardless_pro/list_response.rb +29 -0
  18. data/lib/gocardless_pro/paginator.rb +43 -0
  19. data/lib/gocardless_pro/request.rb +69 -0
  20. data/lib/gocardless_pro/resources/creditor.rb +84 -0
  21. data/lib/gocardless_pro/resources/creditor_bank_account.rb +78 -0
  22. data/lib/gocardless_pro/resources/customer.rb +75 -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 +87 -0
  28. data/lib/gocardless_pro/resources/payout.rb +66 -0
  29. data/lib/gocardless_pro/resources/redirect_flow.rb +106 -0
  30. data/lib/gocardless_pro/resources/refund.rb +71 -0
  31. data/lib/gocardless_pro/resources/subscription.rb +155 -0
  32. data/lib/gocardless_pro/response.rb +77 -0
  33. data/lib/gocardless_pro/services/base_service.rb +28 -0
  34. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +119 -0
  35. data/lib/gocardless_pro/services/creditors_service.rb +113 -0
  36. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +154 -0
  37. data/lib/gocardless_pro/services/customers_service.rb +113 -0
  38. data/lib/gocardless_pro/services/events_service.rb +80 -0
  39. data/lib/gocardless_pro/services/helpers_service.rb +99 -0
  40. data/lib/gocardless_pro/services/mandates_service.rb +173 -0
  41. data/lib/gocardless_pro/services/payments_service.rb +168 -0
  42. data/lib/gocardless_pro/services/payouts_service.rb +82 -0
  43. data/lib/gocardless_pro/services/redirect_flows_service.rb +98 -0
  44. data/lib/gocardless_pro/services/refunds_service.rb +132 -0
  45. data/lib/gocardless_pro/services/subscriptions_service.rb +134 -0
  46. data/lib/gocardless_pro/version.rb +8 -0
  47. data/spec/api_service_spec.rb +73 -0
  48. data/spec/client_spec.rb +19 -0
  49. data/spec/error_spec.rb +44 -0
  50. data/spec/resources/creditor_bank_account_spec.rb +109 -0
  51. data/spec/resources/creditor_spec.rb +125 -0
  52. data/spec/resources/customer_bank_account_spec.rb +109 -0
  53. data/spec/resources/customer_spec.rb +135 -0
  54. data/spec/resources/event_spec.rb +113 -0
  55. data/spec/resources/helper_spec.rb +23 -0
  56. data/spec/resources/mandate_spec.rb +97 -0
  57. data/spec/resources/payment_spec.rb +129 -0
  58. data/spec/resources/payout_spec.rb +89 -0
  59. data/spec/resources/redirect_flow_spec.rb +97 -0
  60. data/spec/resources/refund_spec.rb +77 -0
  61. data/spec/resources/subscription_spec.rb +165 -0
  62. data/spec/response_spec.rb +89 -0
  63. data/spec/services/creditor_bank_accounts_service_spec.rb +413 -0
  64. data/spec/services/creditors_service_spec.rb +388 -0
  65. data/spec/services/customer_bank_accounts_service_spec.rb +452 -0
  66. data/spec/services/customers_service_spec.rb +429 -0
  67. data/spec/services/events_service_spec.rb +217 -0
  68. data/spec/services/helpers_service_spec.rb +122 -0
  69. data/spec/services/mandates_service_spec.rb +495 -0
  70. data/spec/services/payments_service_spec.rb +546 -0
  71. data/spec/services/payouts_service_spec.rb +217 -0
  72. data/spec/services/redirect_flows_service_spec.rb +254 -0
  73. data/spec/services/refunds_service_spec.rb +323 -0
  74. data/spec/services/subscriptions_service_spec.rb +557 -0
  75. data/spec/spec_helper.rb +91 -0
  76. metadata +224 -0
@@ -0,0 +1,99 @@
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 GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the Helper endpoints
12
+ class HelpersService < BaseService
13
+ # Returns a PDF mandate form with a signature field, ready to be signed by your
14
+ # customer. May be fully or partially pre-filled.
15
+ #
16
+ # You must specify `Accept:
17
+ # application/pdf` on requests to this endpoint.
18
+ #
19
+ # Bank account details may
20
+ # either be supplied using the IBAN (international bank account number), or
21
+ # [local
22
+ # details](https://developer.gocardless.com/pro/2015-04-29/#ui-local-bank-details).
23
+ # For more information on the different fields required in each country, please
24
+ # see the [local bank
25
+ # details](https://developer.gocardless.com/pro/2015-04-29/#ui-local-bank-details)
26
+ # section.
27
+ #
28
+ # To generate a mandate in a foreign language, set your
29
+ # `Accept-Language` header to the relevant [ISO
30
+ # 639-1](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes#Partial_ISO_639_table)
31
+ # language code. Currently Dutch, English, French, German, Italian, Portuguese
32
+ # and Spanish are supported.
33
+ #
34
+ # _Note:_ If you want to render a PDF of an
35
+ # existing mandate you can also do so using the [mandate show
36
+ # endpoint](https://developer.gocardless.com/pro/2015-04-29/#mandates-get-a-single-mandate).
37
+ # Example URL: /helpers/mandate
38
+ # @param options [Hash] parameters as a hash, under a params key.
39
+ def mandate(options = {})
40
+ path = '/helpers/mandate'
41
+
42
+ params = options.delete(:params) || {}
43
+ options[:params] = {}
44
+ options[:params]['data'] = params
45
+ response = make_request(:post, path, options)
46
+
47
+ return if response.body.nil?
48
+ Resources::Helper.new(unenvelope_body(response.body))
49
+ end
50
+
51
+ # Check whether an account number and bank / branch code combination are
52
+ # compatible.
53
+ #
54
+ # Bank account details may either be supplied using the IBAN
55
+ # (international bank account number), or [local
56
+ # details](https://developer.gocardless.com/pro/2015-04-29/#ui-local-bank-details).
57
+ # For more information on the different fields required in each country, please
58
+ # see the [local bank
59
+ # details](https://developer.gocardless.com/pro/2015-04-29/#ui-local-bank-details)
60
+ # section.
61
+ # Example URL: /helpers/modulus_check
62
+ # @param options [Hash] parameters as a hash, under a params key.
63
+ def modulus_check(options = {})
64
+ path = '/helpers/modulus_check'
65
+
66
+ params = options.delete(:params) || {}
67
+ options[:params] = {}
68
+ options[:params]['data'] = params
69
+ response = make_request(:post, path, options)
70
+
71
+ return if response.body.nil?
72
+ Resources::Helper.new(unenvelope_body(response.body))
73
+ end
74
+
75
+ # Unenvelope the response of the body using the service's `envelope_key`
76
+ #
77
+ # @param body [Hash]
78
+ def unenvelope_body(body)
79
+ body[envelope_key] || body['data']
80
+ end
81
+
82
+ private
83
+
84
+ # return the key which API responses will envelope data under
85
+ def envelope_key
86
+ 'helpers'
87
+ end
88
+
89
+ # take a URL with placeholder params and substitute them out for the acutal value
90
+ # @param url [String] the URL with placeholders in
91
+ # @param param_map [Hash] a hash of placeholders and their actual values
92
+ def sub_url(url, param_map)
93
+ param_map.reduce(url) do |new_url, (param, value)|
94
+ new_url.gsub(":#{param}", value)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,173 @@
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 GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the Mandate endpoints
12
+ class MandatesService < BaseService
13
+ # Creates a new mandate object.
14
+ # Example URL: /mandates
15
+ # @param options [Hash] parameters as a hash, under a params key.
16
+ def create(options = {})
17
+ path = '/mandates'
18
+
19
+ params = options.delete(:params) || {}
20
+ options[:params] = {}
21
+ options[:params][envelope_key] = params
22
+ response = make_request(:post, path, options)
23
+
24
+ return if response.body.nil?
25
+ Resources::Mandate.new(unenvelope_body(response.body))
26
+ end
27
+
28
+ # Returns a
29
+ # [cursor-paginated](https://developer.gocardless.com/pro/2015-04-29/#overview-cursor-pagination)
30
+ # list of your mandates. Except where stated, these filters can only be used one
31
+ # at a time.
32
+ # Example URL: /mandates
33
+ # @param options [Hash] parameters as a hash, under a params key.
34
+ def list(options = {})
35
+ path = '/mandates'
36
+
37
+ response = make_request(:get, path, options)
38
+ ListResponse.new(
39
+ raw_response: response,
40
+ unenveloped_body: unenvelope_body(response.body),
41
+ resource_class: Resources::Mandate
42
+ )
43
+ end
44
+
45
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
46
+ #
47
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
48
+ # Otherwise they will be the body of the request.
49
+ def all(options = {})
50
+ Paginator.new(
51
+ service: self,
52
+ path: '/mandates',
53
+ options: options,
54
+ resource_class: Resources::Mandate
55
+ ).enumerator
56
+ end
57
+
58
+ # Retrieves the details of an existing mandate.
59
+ #
60
+ # If you specify `Accept:
61
+ # application/pdf` on a request to this endpoint it will return a PDF complying
62
+ # to the relevant scheme rules, which you can present to your customer.
63
+ #
64
+ # PDF
65
+ # mandates can be retrieved in Dutch, English, French, German, Italian,
66
+ # Portuguese and Spanish by specifying the [ISO
67
+ # 639-1](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes#Partial_ISO_639_table)
68
+ # language code as an `Accept-Language` header.
69
+ # Example URL: /mandates/:identity
70
+ #
71
+ # @param identity # Unique identifier, beginning with "MD"
72
+ # @param options [Hash] parameters as a hash, under a params key.
73
+ def get(identity, options = {})
74
+ path = sub_url('/mandates/:identity', 'identity' => identity)
75
+
76
+ response = make_request(:get, path, options)
77
+
78
+ return if response.body.nil?
79
+ Resources::Mandate.new(unenvelope_body(response.body))
80
+ end
81
+
82
+ # Updates a mandate object. This accepts only the metadata parameter.
83
+ # Example URL: /mandates/:identity
84
+ #
85
+ # @param identity # Unique identifier, beginning with "MD"
86
+ # @param options [Hash] parameters as a hash, under a params key.
87
+ def update(identity, options = {})
88
+ path = sub_url('/mandates/:identity', 'identity' => identity)
89
+
90
+ params = options.delete(:params) || {}
91
+ options[:params] = {}
92
+ options[:params][envelope_key] = params
93
+ response = make_request(:put, path, options)
94
+
95
+ return if response.body.nil?
96
+ Resources::Mandate.new(unenvelope_body(response.body))
97
+ end
98
+
99
+ # Immediately cancels a mandate and all associated cancellable payments. Any
100
+ # metadata supplied to this endpoint will be stored on the mandate cancellation
101
+ # event it causes.
102
+ #
103
+ # This will fail with a `cancellation_failed` error if the
104
+ # mandate is already cancelled.
105
+ # Example URL: /mandates/:identity/actions/cancel
106
+ #
107
+ # @param identity # Unique identifier, beginning with "MD"
108
+ # @param options [Hash] parameters as a hash, under a params key.
109
+ def cancel(identity, options = {})
110
+ path = sub_url('/mandates/:identity/actions/cancel', 'identity' => identity)
111
+
112
+ params = options.delete(:params) || {}
113
+ options[:params] = {}
114
+ options[:params]['data'] = params
115
+ response = make_request(:post, path, options)
116
+
117
+ return if response.body.nil?
118
+ Resources::Mandate.new(unenvelope_body(response.body))
119
+ end
120
+
121
+ # <a name="mandate_not_inactive"></a>Reinstates a cancelled or expired mandate
122
+ # to the banks. You will receive a `resubmission_requested` webhook, but after
123
+ # that reinstating the mandate follows the same process as its initial creation,
124
+ # so you will receive a `submitted` webhook, followed by a `reinstated` or
125
+ # `failed` webhook up to two working days later. Any metadata supplied to this
126
+ # endpoint will be stored on the `resubmission_requested` event it causes.
127
+ #
128
+ #
129
+ # This will fail with a `mandate_not_inactive` error if the mandate is already
130
+ # being submitted, or is active.
131
+ #
132
+ # Mandates can be resubmitted up to 3 times.
133
+ # Example URL: /mandates/:identity/actions/reinstate
134
+ #
135
+ # @param identity # Unique identifier, beginning with "MD"
136
+ # @param options [Hash] parameters as a hash, under a params key.
137
+ def reinstate(identity, options = {})
138
+ path = sub_url('/mandates/:identity/actions/reinstate', 'identity' => identity)
139
+
140
+ params = options.delete(:params) || {}
141
+ options[:params] = {}
142
+ options[:params]['data'] = params
143
+ response = make_request(:post, path, options)
144
+
145
+ return if response.body.nil?
146
+ Resources::Mandate.new(unenvelope_body(response.body))
147
+ end
148
+
149
+ # Unenvelope the response of the body using the service's `envelope_key`
150
+ #
151
+ # @param body [Hash]
152
+ def unenvelope_body(body)
153
+ body[envelope_key] || body['data']
154
+ end
155
+
156
+ private
157
+
158
+ # return the key which API responses will envelope data under
159
+ def envelope_key
160
+ 'mandates'
161
+ end
162
+
163
+ # take a URL with placeholder params and substitute them out for the acutal value
164
+ # @param url [String] the URL with placeholders in
165
+ # @param param_map [Hash] a hash of placeholders and their actual values
166
+ def sub_url(url, param_map)
167
+ param_map.reduce(url) do |new_url, (param, value)|
168
+ new_url.gsub(":#{param}", value)
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,168 @@
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 GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the Payment endpoints
12
+ class PaymentsService < BaseService
13
+ # <a name="mandate_is_inactive"></a>Creates a new payment object.
14
+ #
15
+ # This
16
+ # fails with a `mandate_is_inactive` error if the linked
17
+ # [mandate](https://developer.gocardless.com/pro/2015-04-29/#api-endpoints-mandates)
18
+ # is cancelled. Payments can be created against `pending_submission` mandates,
19
+ # but they will not be submitted until the mandate becomes active.
20
+ # Example URL: /payments
21
+ # @param options [Hash] parameters as a hash, under a params key.
22
+ def create(options = {})
23
+ path = '/payments'
24
+
25
+ params = options.delete(:params) || {}
26
+ options[:params] = {}
27
+ options[:params][envelope_key] = params
28
+ response = make_request(:post, path, options)
29
+
30
+ return if response.body.nil?
31
+ Resources::Payment.new(unenvelope_body(response.body))
32
+ end
33
+
34
+ # Returns a
35
+ # [cursor-paginated](https://developer.gocardless.com/pro/2015-04-29/#overview-cursor-pagination)
36
+ # list of your payments.
37
+ # Example URL: /payments
38
+ # @param options [Hash] parameters as a hash, under a params key.
39
+ def list(options = {})
40
+ path = '/payments'
41
+
42
+ response = make_request(:get, path, options)
43
+ ListResponse.new(
44
+ raw_response: response,
45
+ unenveloped_body: unenvelope_body(response.body),
46
+ resource_class: Resources::Payment
47
+ )
48
+ end
49
+
50
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
51
+ #
52
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
53
+ # Otherwise they will be the body of the request.
54
+ def all(options = {})
55
+ Paginator.new(
56
+ service: self,
57
+ path: '/payments',
58
+ options: options,
59
+ resource_class: Resources::Payment
60
+ ).enumerator
61
+ end
62
+
63
+ # Retrieves the details of a single existing payment.
64
+ # Example URL: /payments/:identity
65
+ #
66
+ # @param identity # Unique identifier, beginning with "PM"
67
+ # @param options [Hash] parameters as a hash, under a params key.
68
+ def get(identity, options = {})
69
+ path = sub_url('/payments/:identity', 'identity' => identity)
70
+
71
+ response = make_request(:get, path, options)
72
+
73
+ return if response.body.nil?
74
+ Resources::Payment.new(unenvelope_body(response.body))
75
+ end
76
+
77
+ # Updates a payment object. This accepts only the metadata parameter.
78
+ # Example URL: /payments/:identity
79
+ #
80
+ # @param identity # Unique identifier, beginning with "PM"
81
+ # @param options [Hash] parameters as a hash, under a params key.
82
+ def update(identity, options = {})
83
+ path = sub_url('/payments/:identity', 'identity' => identity)
84
+
85
+ params = options.delete(:params) || {}
86
+ options[:params] = {}
87
+ options[:params][envelope_key] = params
88
+ response = make_request(:put, path, options)
89
+
90
+ return if response.body.nil?
91
+ Resources::Payment.new(unenvelope_body(response.body))
92
+ end
93
+
94
+ # Cancels the payment if it has not already been submitted to the banks. Any
95
+ # metadata supplied to this endpoint will be stored on the payment cancellation
96
+ # event it causes.
97
+ #
98
+ # This will fail with a `cancellation_failed` error unless
99
+ # the payment's status is `pending_submission`.
100
+ # Example URL: /payments/:identity/actions/cancel
101
+ #
102
+ # @param identity # Unique identifier, beginning with "PM"
103
+ # @param options [Hash] parameters as a hash, under a params key.
104
+ def cancel(identity, options = {})
105
+ path = sub_url('/payments/:identity/actions/cancel', 'identity' => identity)
106
+
107
+ params = options.delete(:params) || {}
108
+ options[:params] = {}
109
+ options[:params]['data'] = params
110
+ response = make_request(:post, path, options)
111
+
112
+ return if response.body.nil?
113
+ Resources::Payment.new(unenvelope_body(response.body))
114
+ end
115
+
116
+ # <a name="retry_failed"></a>Retries a failed payment if the underlying mandate
117
+ # is active. You will receive a `resubmission_requested` webhook, but after that
118
+ # retrying the payment follows the same process as its initial creation, so you
119
+ # will receive a `submitted` webhook, followed by a `confirmed` or `failed`
120
+ # event. Any metadata supplied to this endpoint will be stored against the
121
+ # payment submission event it causes.
122
+ #
123
+ # This will return a `retry_failed`
124
+ # error if the payment has not failed.
125
+ #
126
+ # Payments can be retried up to 3
127
+ # times.
128
+ # Example URL: /payments/:identity/actions/retry
129
+ #
130
+ # @param identity # Unique identifier, beginning with "PM"
131
+ # @param options [Hash] parameters as a hash, under a params key.
132
+ def retry(identity, options = {})
133
+ path = sub_url('/payments/:identity/actions/retry', 'identity' => identity)
134
+
135
+ params = options.delete(:params) || {}
136
+ options[:params] = {}
137
+ options[:params]['data'] = params
138
+ response = make_request(:post, path, options)
139
+
140
+ return if response.body.nil?
141
+ Resources::Payment.new(unenvelope_body(response.body))
142
+ end
143
+
144
+ # Unenvelope the response of the body using the service's `envelope_key`
145
+ #
146
+ # @param body [Hash]
147
+ def unenvelope_body(body)
148
+ body[envelope_key] || body['data']
149
+ end
150
+
151
+ private
152
+
153
+ # return the key which API responses will envelope data under
154
+ def envelope_key
155
+ 'payments'
156
+ end
157
+
158
+ # take a URL with placeholder params and substitute them out for the acutal value
159
+ # @param url [String] the URL with placeholders in
160
+ # @param param_map [Hash] a hash of placeholders and their actual values
161
+ def sub_url(url, param_map)
162
+ param_map.reduce(url) do |new_url, (param, value)|
163
+ new_url.gsub(":#{param}", value)
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,82 @@
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 GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the Payout endpoints
12
+ class PayoutsService < BaseService
13
+ # Returns a
14
+ # [cursor-paginated](https://developer.gocardless.com/pro/2015-04-29/#overview-cursor-pagination)
15
+ # list of your payouts.
16
+ # Example URL: /payouts
17
+ # @param options [Hash] parameters as a hash, under a params key.
18
+ def list(options = {})
19
+ path = '/payouts'
20
+
21
+ response = make_request(:get, path, options)
22
+ ListResponse.new(
23
+ raw_response: response,
24
+ unenveloped_body: unenvelope_body(response.body),
25
+ resource_class: Resources::Payout
26
+ )
27
+ end
28
+
29
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
30
+ #
31
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
32
+ # Otherwise they will be the body of the request.
33
+ def all(options = {})
34
+ Paginator.new(
35
+ service: self,
36
+ path: '/payouts',
37
+ options: options,
38
+ resource_class: Resources::Payout
39
+ ).enumerator
40
+ end
41
+
42
+ # Retrieves the details of a single payout. For an example of how to reconcile
43
+ # the transactions in a payout, see [this
44
+ # guide](#events-fetching-events-for-a-payout).
45
+ # Example URL: /payouts/:identity
46
+ #
47
+ # @param identity # Unique identifier, beginning with "PO"
48
+ # @param options [Hash] parameters as a hash, under a params key.
49
+ def get(identity, options = {})
50
+ path = sub_url('/payouts/:identity', 'identity' => identity)
51
+
52
+ response = make_request(:get, path, options)
53
+
54
+ return if response.body.nil?
55
+ Resources::Payout.new(unenvelope_body(response.body))
56
+ end
57
+
58
+ # Unenvelope the response of the body using the service's `envelope_key`
59
+ #
60
+ # @param body [Hash]
61
+ def unenvelope_body(body)
62
+ body[envelope_key] || body['data']
63
+ end
64
+
65
+ private
66
+
67
+ # return the key which API responses will envelope data under
68
+ def envelope_key
69
+ 'payouts'
70
+ end
71
+
72
+ # take a URL with placeholder params and substitute them out for the acutal value
73
+ # @param url [String] the URL with placeholders in
74
+ # @param param_map [Hash] a hash of placeholders and their actual values
75
+ def sub_url(url, param_map)
76
+ param_map.reduce(url) do |new_url, (param, value)|
77
+ new_url.gsub(":#{param}", value)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end