gocardless_pro 4.2.0 → 4.4.1

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 (101) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -12
  3. data/lib/gocardless_pro/client.rb +33 -3
  4. data/lib/gocardless_pro/error.rb +3 -3
  5. data/lib/gocardless_pro/list_response.rb +2 -2
  6. data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +11 -3
  7. data/lib/gocardless_pro/paginator.rb +3 -2
  8. data/lib/gocardless_pro/resources/balance.rb +4 -1
  9. data/lib/gocardless_pro/resources/bank_account_detail.rb +5 -1
  10. data/lib/gocardless_pro/resources/bank_account_holder_verification.rb +44 -0
  11. data/lib/gocardless_pro/resources/bank_authorisation.rb +9 -2
  12. data/lib/gocardless_pro/resources/bank_details_lookup.rb +3 -1
  13. data/lib/gocardless_pro/resources/billing_request.rb +24 -10
  14. data/lib/gocardless_pro/resources/billing_request_flow.rb +18 -2
  15. data/lib/gocardless_pro/resources/billing_request_template.rb +18 -2
  16. data/lib/gocardless_pro/resources/billing_request_with_action.rb +6 -5
  17. data/lib/gocardless_pro/resources/block.rb +12 -8
  18. data/lib/gocardless_pro/resources/creditor.rb +26 -6
  19. data/lib/gocardless_pro/resources/creditor_bank_account.rb +17 -7
  20. data/lib/gocardless_pro/resources/currency_exchange_rate.rb +4 -1
  21. data/lib/gocardless_pro/resources/customer.rb +22 -5
  22. data/lib/gocardless_pro/resources/customer_bank_account.rb +24 -10
  23. data/lib/gocardless_pro/resources/customer_notification.rb +8 -5
  24. data/lib/gocardless_pro/resources/event.rb +31 -4
  25. data/lib/gocardless_pro/resources/export.rb +7 -1
  26. data/lib/gocardless_pro/resources/funds_availability.rb +38 -0
  27. data/lib/gocardless_pro/resources/instalment_schedule.rb +8 -2
  28. data/lib/gocardless_pro/resources/institution.rb +11 -4
  29. data/lib/gocardless_pro/resources/logo.rb +2 -1
  30. data/lib/gocardless_pro/resources/mandate.rb +21 -6
  31. data/lib/gocardless_pro/resources/mandate_import.rb +29 -22
  32. data/lib/gocardless_pro/resources/mandate_import_entry.rb +16 -17
  33. data/lib/gocardless_pro/resources/mandate_pdf.rb +5 -4
  34. data/lib/gocardless_pro/resources/negative_balance_limit.rb +4 -2
  35. data/lib/gocardless_pro/resources/outbound_payment.rb +33 -12
  36. data/lib/gocardless_pro/resources/outbound_payment_import.rb +81 -0
  37. data/lib/gocardless_pro/resources/outbound_payment_import_entry.rb +77 -0
  38. data/lib/gocardless_pro/resources/payer_authorisation.rb +34 -32
  39. data/lib/gocardless_pro/resources/payment.rb +24 -8
  40. data/lib/gocardless_pro/resources/payment_account.rb +64 -0
  41. data/lib/gocardless_pro/resources/payment_account_transaction.rb +79 -0
  42. data/lib/gocardless_pro/resources/payout.rb +19 -8
  43. data/lib/gocardless_pro/resources/payout_item.rb +4 -3
  44. data/lib/gocardless_pro/resources/redirect_flow.rb +44 -25
  45. data/lib/gocardless_pro/resources/refund.rb +16 -7
  46. data/lib/gocardless_pro/resources/scheme_identifier.rb +18 -3
  47. data/lib/gocardless_pro/resources/subscription.rb +37 -16
  48. data/lib/gocardless_pro/resources/tax_rate.rb +8 -3
  49. data/lib/gocardless_pro/resources/transferred_mandate.rb +3 -1
  50. data/lib/gocardless_pro/resources/verification_detail.rb +19 -8
  51. data/lib/gocardless_pro/resources/webhook.rb +13 -2
  52. data/lib/gocardless_pro/services/balances_service.rb +11 -3
  53. data/lib/gocardless_pro/services/bank_account_details_service.rb +14 -3
  54. data/lib/gocardless_pro/services/bank_account_holder_verifications_service.rb +92 -0
  55. data/lib/gocardless_pro/services/bank_authorisations_service.rb +9 -3
  56. data/lib/gocardless_pro/services/bank_details_lookups_service.rb +14 -6
  57. data/lib/gocardless_pro/services/billing_request_flows_service.rb +8 -2
  58. data/lib/gocardless_pro/services/billing_request_templates_service.rb +14 -7
  59. data/lib/gocardless_pro/services/billing_request_with_actions_service.rb +7 -1
  60. data/lib/gocardless_pro/services/billing_requests_service.rb +38 -33
  61. data/lib/gocardless_pro/services/blocks_service.rb +17 -10
  62. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +14 -7
  63. data/lib/gocardless_pro/services/creditors_service.rb +13 -6
  64. data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +10 -3
  65. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +25 -15
  66. data/lib/gocardless_pro/services/customer_notifications_service.rb +8 -3
  67. data/lib/gocardless_pro/services/customers_service.rb +15 -9
  68. data/lib/gocardless_pro/services/events_service.rb +16 -4
  69. data/lib/gocardless_pro/services/exports_service.rb +8 -2
  70. data/lib/gocardless_pro/services/funds_availabilities_service.rb +56 -0
  71. data/lib/gocardless_pro/services/instalment_schedules_service.rb +21 -13
  72. data/lib/gocardless_pro/services/institutions_service.rb +8 -2
  73. data/lib/gocardless_pro/services/logos_service.rb +9 -3
  74. data/lib/gocardless_pro/services/mandate_import_entries_service.rb +10 -4
  75. data/lib/gocardless_pro/services/mandate_imports_service.rb +16 -8
  76. data/lib/gocardless_pro/services/mandate_pdfs_service.rb +11 -5
  77. data/lib/gocardless_pro/services/mandates_service.rb +23 -16
  78. data/lib/gocardless_pro/services/negative_balance_limits_service.rb +10 -3
  79. data/lib/gocardless_pro/services/outbound_payment_import_entries_service.rb +64 -0
  80. data/lib/gocardless_pro/services/outbound_payment_imports_service.rb +118 -0
  81. data/lib/gocardless_pro/services/outbound_payments_service.rb +34 -12
  82. data/lib/gocardless_pro/services/payer_authorisations_service.rb +18 -15
  83. data/lib/gocardless_pro/services/payer_themes_service.rb +7 -1
  84. data/lib/gocardless_pro/services/payment_account_transactions_service.rb +93 -0
  85. data/lib/gocardless_pro/services/payment_accounts_service.rb +83 -0
  86. data/lib/gocardless_pro/services/payments_service.rb +29 -21
  87. data/lib/gocardless_pro/services/payout_items_service.rb +12 -7
  88. data/lib/gocardless_pro/services/payouts_service.rb +14 -7
  89. data/lib/gocardless_pro/services/redirect_flows_service.rb +19 -9
  90. data/lib/gocardless_pro/services/refunds_service.rb +18 -13
  91. data/lib/gocardless_pro/services/scenario_simulators_service.rb +90 -81
  92. data/lib/gocardless_pro/services/scheme_identifiers_service.rb +15 -9
  93. data/lib/gocardless_pro/services/subscriptions_service.rb +57 -47
  94. data/lib/gocardless_pro/services/tax_rates_service.rb +11 -4
  95. data/lib/gocardless_pro/services/transferred_mandates_service.rb +8 -2
  96. data/lib/gocardless_pro/services/verification_details_service.rb +7 -1
  97. data/lib/gocardless_pro/services/webhooks_service.rb +13 -6
  98. data/lib/gocardless_pro/version.rb +1 -1
  99. data/lib/gocardless_pro/webhook.rb +45 -0
  100. data/lib/gocardless_pro.rb +18 -0
  101. metadata +38 -16
@@ -20,7 +20,7 @@ module GoCardlessPro
20
20
  # become active. On other schemes, including SEPA,
21
21
  # this happens instantly.
22
22
  #
23
- # #### Scheme identifier name validations
23
+ # Scheme identifier name validations
24
24
  #
25
25
  # The `name` field of a scheme identifier can contain alphanumeric characters,
26
26
  # spaces and
@@ -29,8 +29,8 @@ module GoCardlessPro
29
29
  # Its maximum length and the special characters it supports depend on the
30
30
  # scheme:
31
31
  #
32
- # | __scheme__ | __maximum length__ | __special characters allowed__
33
- # |
32
+ # | scheme | maximum length | special characters allowed
33
+ # |
34
34
  # | :---------------- | :----------------- |
35
35
  # :-------------------------------------------------- |
36
36
  # | `bacs` | 18 characters | `/` `.` `&` `-`
@@ -49,7 +49,6 @@ module GoCardlessPro
49
49
  # You should ensure that the name you set matches the legal name or the trading
50
50
  # name of
51
51
  # the creditor, otherwise, there is an increased risk of chargeback.
52
- #
53
52
  # Example URL: /scheme_identifiers
54
53
  # @param options [Hash] parameters as a hash, under a params key.
55
54
  def create(options = {})
@@ -70,7 +69,7 @@ module GoCardlessPro
70
69
  if e.idempotent_creation_conflict?
71
70
  case @api_service.on_idempotency_conflict
72
71
  when :raise
73
- raise IdempotencyConflict, e.error
72
+ raise IdempotencyConflict.new(e.error)
74
73
  when :fetch
75
74
  return get(e.conflicting_resource_id)
76
75
  end
@@ -84,8 +83,9 @@ module GoCardlessPro
84
83
  Resources::SchemeIdentifier.new(unenvelope_body(response.body), response)
85
84
  end
86
85
 
87
- # Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your scheme
88
- # identifiers.
86
+ # Returns a cursor-paginated
87
+ # (https://developer.gocardless.com/api-reference/#api-usage-cursor-pagination)
88
+ # list of your scheme identifiers.
89
89
  # Example URL: /scheme_identifiers
90
90
  # @param options [Hash] parameters as a hash, under a params key.
91
91
  def list(options = {})
@@ -120,7 +120,7 @@ module GoCardlessPro
120
120
  # @param options [Hash] parameters as a hash, under a params key.
121
121
  def get(identity, options = {})
122
122
  path = sub_url('/scheme_identifiers/:identity', {
123
- 'identity' => identity
123
+ 'identity' => identity,
124
124
  })
125
125
 
126
126
  options[:retry_failures] = true
@@ -138,7 +138,13 @@ module GoCardlessPro
138
138
  #
139
139
  # @param body [Hash]
140
140
  def unenvelope_body(body)
141
- body[envelope_key] || body['data']
141
+ if body.key?(envelope_key)
142
+ body[envelope_key]
143
+ elsif body.key?('data')
144
+ body['data']
145
+ else
146
+ body
147
+ end
142
148
  end
143
149
 
144
150
  # return the key which API responses will envelope data under
@@ -31,7 +31,7 @@ module GoCardlessPro
31
31
  if e.idempotent_creation_conflict?
32
32
  case @api_service.on_idempotency_conflict
33
33
  when :raise
34
- raise IdempotencyConflict, e.error
34
+ raise IdempotencyConflict.new(e.error)
35
35
  when :fetch
36
36
  return get(e.conflicting_resource_id)
37
37
  end
@@ -45,9 +45,10 @@ module GoCardlessPro
45
45
  Resources::Subscription.new(unenvelope_body(response.body), response)
46
46
  end
47
47
 
48
- # Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your
49
- # subscriptions. Please note if the subscriptions are related to customers who
50
- # have been removed, they will not be shown in the response.
48
+ # Returns a cursor-paginated
49
+ # (https://developer.gocardless.com/api-reference/#api-usage-cursor-pagination)
50
+ # list of your subscriptions. Please note if the subscriptions are related to
51
+ # customers who have been removed, they will not be shown in the response.
51
52
  # Example URL: /subscriptions
52
53
  # @param options [Hash] parameters as a hash, under a params key.
53
54
  def list(options = {})
@@ -82,7 +83,7 @@ module GoCardlessPro
82
83
  # @param options [Hash] parameters as a hash, under a params key.
83
84
  def get(identity, options = {})
84
85
  path = sub_url('/subscriptions/:identity', {
85
- 'identity' => identity
86
+ 'identity' => identity,
86
87
  })
87
88
 
88
89
  options[:retry_failures] = true
@@ -98,33 +99,33 @@ module GoCardlessPro
98
99
  #
99
100
  # This fails with:
100
101
  #
101
- # - `validation_failed` if invalid data is provided when attempting to update a
102
+ # -
103
+ # `validation_failed` if invalid data is provided when attempting to update a
102
104
  # subscription.
103
- #
104
- # - `subscription_not_active` if the subscription is no longer active.
105
- #
106
- # - `subscription_already_ended` if the subscription has taken all payments.
107
- #
108
- # - `mandate_payments_require_approval` if the amount is being changed and the
105
+ # -
106
+ # `subscription_not_active` if the subscription is no longer active.
107
+ # -
108
+ # `subscription_already_ended` if the subscription has taken all payments.
109
+ # -
110
+ # `mandate_payments_require_approval` if the amount is being changed and the
109
111
  # mandate requires approval.
110
- #
111
- # - `number_of_subscription_amendments_exceeded` error if the subscription
112
- # amount has already been changed 10 times.
113
- #
114
- # - `forbidden` if the amount is being changed, and the subscription was created
112
+ # -
113
+ # `number_of_subscription_amendments_exceeded` error if the subscription amount
114
+ # has already been changed 10 times.
115
+ # -
116
+ # `forbidden` if the amount is being changed, and the subscription was created
115
117
  # by an app and you are not authenticated as that app, or if the subscription
116
118
  # was not created by an app and you are authenticated as an app
117
- #
118
- # - `resource_created_by_another_app` if the app fee is being changed, and the
119
+ # -
120
+ # `resource_created_by_another_app` if the app fee is being changed, and the
119
121
  # subscription was created by an app other than the app you are authenticated as
120
- #
121
122
  # Example URL: /subscriptions/:identity
122
123
  #
123
124
  # @param identity # Unique identifier, beginning with "SB".
124
125
  # @param options [Hash] parameters as a hash, under a params key.
125
126
  def update(identity, options = {})
126
127
  path = sub_url('/subscriptions/:identity', {
127
- 'identity' => identity
128
+ 'identity' => identity,
128
129
  })
129
130
 
130
131
  params = options.delete(:params) || {}
@@ -148,8 +149,10 @@ module GoCardlessPro
148
149
  # when they continue forever (created without `count` or `end_date`) or
149
150
  # the subscription is already paused for a number of cycles.
150
151
  #
151
- # When `pause_cycles` is omitted the subscription is paused until the [resume
152
- # endpoint](#subscriptions-resume-a-subscription) is called.
152
+ # When `pause_cycles` is omitted the subscription is paused until the resume
153
+ # endpoint
154
+ # (https://developer.gocardless.com/api-reference/#subscriptions-resume-a-subscription)
155
+ # is called.
153
156
  # If the subscription is collecting a fixed number of payments, `end_date` will
154
157
  # be set to `null`.
155
158
  # When paused indefinitely, `upcoming_payments` will be empty.
@@ -163,22 +166,23 @@ module GoCardlessPro
163
166
  #
164
167
  # This fails with:
165
168
  #
166
- # - `forbidden` if the subscription was created by an app and you are not
169
+ # -
170
+ # `forbidden` if the subscription was created by an app and you are not
167
171
  # authenticated as that app, or if the subscription was not created by an app
168
172
  # and you are authenticated as an app
169
- #
170
- # - `validation_failed` if invalid data is provided when attempting to pause a
173
+ # -
174
+ # `validation_failed` if invalid data is provided when attempting to pause a
171
175
  # subscription.
172
- #
173
- # - `subscription_paused_cannot_update_cycles` if the subscription is already
176
+ # -
177
+ # `subscription_paused_cannot_update_cycles` if the subscription is already
174
178
  # paused for a number of cycles and the request provides a value for
175
179
  # `pause_cycle`.
176
- #
177
- # - `subscription_cannot_be_paused` if the subscription cannot be paused.
178
- #
179
- # - `subscription_already_ended` if the subscription has taken all payments.
180
- #
181
- # - `pause_cycles_must_be_greater_than_or_equal_to` if the provided value for
180
+ # -
181
+ # `subscription_cannot_be_paused` if the subscription cannot be paused.
182
+ # -
183
+ # `subscription_already_ended` if the subscription has taken all payments.
184
+ # -
185
+ # `pause_cycles_must_be_greater_than_or_equal_to` if the provided value for
182
186
  # `pause_cycles` cannot be satisfied.
183
187
  # Example URL: /subscriptions/:identity/actions/pause
184
188
  #
@@ -186,7 +190,7 @@ module GoCardlessPro
186
190
  # @param options [Hash] parameters as a hash, under a params key.
187
191
  def pause(identity, options = {})
188
192
  path = sub_url('/subscriptions/:identity/actions/pause', {
189
- 'identity' => identity
193
+ 'identity' => identity,
190
194
  })
191
195
 
192
196
  params = options.delete(:params) || {}
@@ -204,7 +208,7 @@ module GoCardlessPro
204
208
  if e.idempotent_creation_conflict?
205
209
  case @api_service.on_idempotency_conflict
206
210
  when :raise
207
- raise IdempotencyConflict, e.error
211
+ raise IdempotencyConflict.new(e.error)
208
212
  when :fetch
209
213
  return get(e.conflicting_resource_id)
210
214
  end
@@ -226,22 +230,22 @@ module GoCardlessPro
226
230
  #
227
231
  # This fails with:
228
232
  #
229
- # - `forbidden` if the subscription was created by an app and you are not
233
+ # -
234
+ # `forbidden` if the subscription was created by an app and you are not
230
235
  # authenticated as that app, or if the subscription was not created by an app
231
236
  # and you are authenticated as an app
232
- #
233
- # - `validation_failed` if invalid data is provided when attempting to resume a
237
+ # -
238
+ # `validation_failed` if invalid data is provided when attempting to resume a
234
239
  # subscription.
235
- #
236
- # - `subscription_not_paused` if the subscription is not paused.
237
- #
240
+ # -
241
+ # `subscription_not_paused` if the subscription is not paused.
238
242
  # Example URL: /subscriptions/:identity/actions/resume
239
243
  #
240
244
  # @param identity # Unique identifier, beginning with "SB".
241
245
  # @param options [Hash] parameters as a hash, under a params key.
242
246
  def resume(identity, options = {})
243
247
  path = sub_url('/subscriptions/:identity/actions/resume', {
244
- 'identity' => identity
248
+ 'identity' => identity,
245
249
  })
246
250
 
247
251
  params = options.delete(:params) || {}
@@ -259,7 +263,7 @@ module GoCardlessPro
259
263
  if e.idempotent_creation_conflict?
260
264
  case @api_service.on_idempotency_conflict
261
265
  when :raise
262
- raise IdempotencyConflict, e.error
266
+ raise IdempotencyConflict.new(e.error)
263
267
  when :fetch
264
268
  return get(e.conflicting_resource_id)
265
269
  end
@@ -285,7 +289,7 @@ module GoCardlessPro
285
289
  # @param options [Hash] parameters as a hash, under a params key.
286
290
  def cancel(identity, options = {})
287
291
  path = sub_url('/subscriptions/:identity/actions/cancel', {
288
- 'identity' => identity
292
+ 'identity' => identity,
289
293
  })
290
294
 
291
295
  params = options.delete(:params) || {}
@@ -303,7 +307,7 @@ module GoCardlessPro
303
307
  if e.idempotent_creation_conflict?
304
308
  case @api_service.on_idempotency_conflict
305
309
  when :raise
306
- raise IdempotencyConflict, e.error
310
+ raise IdempotencyConflict.new(e.error)
307
311
  when :fetch
308
312
  return get(e.conflicting_resource_id)
309
313
  end
@@ -323,7 +327,13 @@ module GoCardlessPro
323
327
  #
324
328
  # @param body [Hash]
325
329
  def unenvelope_body(body)
326
- body[envelope_key] || body['data']
330
+ if body.key?(envelope_key)
331
+ body[envelope_key]
332
+ elsif body.key?('data')
333
+ body['data']
334
+ else
335
+ body
336
+ end
327
337
  end
328
338
 
329
339
  # return the key which API responses will envelope data under
@@ -10,8 +10,9 @@ module GoCardlessPro
10
10
  module Services
11
11
  # Service for making requests to the TaxRate endpoints
12
12
  class TaxRatesService < BaseService
13
- # Returns a [cursor-paginated](#api-usage-cursor-pagination) list of all tax
14
- # rates.
13
+ # Returns a cursor-paginated
14
+ # (https://developer.gocardless.com/api-reference/#api-usage-cursor-pagination)
15
+ # list of all tax rates.
15
16
  # Example URL: /tax_rates
16
17
  # @param options [Hash] parameters as a hash, under a params key.
17
18
  def list(options = {})
@@ -46,7 +47,7 @@ module GoCardlessPro
46
47
  # @param options [Hash] parameters as a hash, under a params key.
47
48
  def get(identity, options = {})
48
49
  path = sub_url('/tax_rates/:identity', {
49
- 'identity' => identity
50
+ 'identity' => identity,
50
51
  })
51
52
 
52
53
  options[:retry_failures] = true
@@ -64,7 +65,13 @@ module GoCardlessPro
64
65
  #
65
66
  # @param body [Hash]
66
67
  def unenvelope_body(body)
67
- body[envelope_key] || body['data']
68
+ if body.key?(envelope_key)
69
+ body[envelope_key]
70
+ elsif body.key?('data')
71
+ body['data']
72
+ else
73
+ body
74
+ end
68
75
  end
69
76
 
70
77
  # return the key which API responses will envelope data under
@@ -19,7 +19,7 @@ module GoCardlessPro
19
19
  # @param options [Hash] parameters as a hash, under a params key.
20
20
  def transferred_mandates(identity, options = {})
21
21
  path = sub_url('/transferred_mandates/:identity', {
22
- 'identity' => identity
22
+ 'identity' => identity,
23
23
  })
24
24
 
25
25
  options[:retry_failures] = false
@@ -37,7 +37,13 @@ module GoCardlessPro
37
37
  #
38
38
  # @param body [Hash]
39
39
  def unenvelope_body(body)
40
- body[envelope_key] || body['data']
40
+ if body.key?(envelope_key)
41
+ body[envelope_key]
42
+ elsif body.key?('data')
43
+ body['data']
44
+ else
45
+ body
46
+ end
41
47
  end
42
48
 
43
49
  # return the key which API responses will envelope data under
@@ -63,7 +63,13 @@ module GoCardlessPro
63
63
  #
64
64
  # @param body [Hash]
65
65
  def unenvelope_body(body)
66
- body[envelope_key] || body['data']
66
+ if body.key?(envelope_key)
67
+ body[envelope_key]
68
+ elsif body.key?('data')
69
+ body['data']
70
+ else
71
+ body
72
+ end
67
73
  end
68
74
 
69
75
  # return the key which API responses will envelope data under
@@ -10,8 +10,9 @@ module GoCardlessPro
10
10
  module Services
11
11
  # Service for making requests to the Webhook endpoints
12
12
  class WebhooksService < BaseService
13
- # Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your
14
- # webhooks.
13
+ # Returns a cursor-paginated
14
+ # (https://developer.gocardless.com/api-reference/#api-usage-cursor-pagination)
15
+ # list of your webhooks.
15
16
  # Example URL: /webhooks
16
17
  # @param options [Hash] parameters as a hash, under a params key.
17
18
  def list(options = {})
@@ -46,7 +47,7 @@ module GoCardlessPro
46
47
  # @param options [Hash] parameters as a hash, under a params key.
47
48
  def get(identity, options = {})
48
49
  path = sub_url('/webhooks/:identity', {
49
- 'identity' => identity
50
+ 'identity' => identity,
50
51
  })
51
52
 
52
53
  options[:retry_failures] = true
@@ -65,7 +66,7 @@ module GoCardlessPro
65
66
  # @param options [Hash] parameters as a hash, under a params key.
66
67
  def retry(identity, options = {})
67
68
  path = sub_url('/webhooks/:identity/actions/retry', {
68
- 'identity' => identity
69
+ 'identity' => identity,
69
70
  })
70
71
 
71
72
  params = options.delete(:params) || {}
@@ -83,7 +84,7 @@ module GoCardlessPro
83
84
  if e.idempotent_creation_conflict?
84
85
  case @api_service.on_idempotency_conflict
85
86
  when :raise
86
- raise IdempotencyConflict, e.error
87
+ raise IdempotencyConflict.new(e.error)
87
88
  when :fetch
88
89
  return get(e.conflicting_resource_id)
89
90
  end
@@ -103,7 +104,13 @@ module GoCardlessPro
103
104
  #
104
105
  # @param body [Hash]
105
106
  def unenvelope_body(body)
106
- body[envelope_key] || body['data']
107
+ if body.key?(envelope_key)
108
+ body[envelope_key]
109
+ elsif body.key?('data')
110
+ body['data']
111
+ else
112
+ body
113
+ end
107
114
  end
108
115
 
109
116
  # return the key which API responses will envelope data under
@@ -3,5 +3,5 @@ end
3
3
 
4
4
  module GoCardlessPro
5
5
  # Current version of the GC gem
6
- VERSION = '4.2.0'
6
+ VERSION = '4.4.1'
7
7
  end
@@ -1,6 +1,18 @@
1
1
  require 'openssl'
2
2
 
3
3
  module GoCardlessPro
4
+ # Represents the result of parsing a webhook, containing both the events
5
+ # and the webhook metadata.
6
+ class WebhookParseResult
7
+ attr_reader :events
8
+ attr_reader :webhook_id
9
+
10
+ def initialize(events, webhook_id)
11
+ @events = events
12
+ @webhook_id = webhook_id
13
+ end
14
+ end
15
+
4
16
  class Webhook
5
17
  class InvalidSignatureError < StandardError; end
6
18
 
@@ -38,6 +50,39 @@ module GoCardlessPro
38
50
  events.map { |event| Resources::Event.new(event) }
39
51
  end
40
52
 
53
+ # Validates that a webhook was genuinely sent by GoCardless using
54
+ # `.signature_valid?`, and then parses it into a WebhookParseResult containing
55
+ # both the events and the webhook ID from the meta field
56
+ #
57
+ # @option options [String] :request_body the request body
58
+ # @option options [String] :signature_header the signature included in the request,
59
+ # found in the `Webhook-Signature` header
60
+ # @option options [String] :webhook_endpoint_secret the webhook endpoint secret for
61
+ # your webhook endpoint, as configured in your GoCardless Dashboard
62
+ # @return [WebhookParseResult] containing the events and webhook ID
63
+ # @raise [InvalidSignatureError] if the signature header specified does not match
64
+ # the signature computed using the request body and webhook endpoint secret
65
+ # @raise [ArgumentError] if a required keyword argument is not provided or is not
66
+ # of the required type
67
+ def parse_with_meta(options = {})
68
+ validate_options!(options)
69
+
70
+ unless signature_valid?(request_body: options[:request_body],
71
+ signature_header: options[:signature_header],
72
+ webhook_endpoint_secret: options[:webhook_endpoint_secret])
73
+ raise InvalidSignatureError, "This webhook doesn't appear to be a genuine " \
74
+ 'webhook from GoCardless, because the signature ' \
75
+ "header doesn't match the signature computed" \
76
+ ' with your webhook endpoint secret.'
77
+ end
78
+
79
+ parsed = JSON.parse(options[:request_body])
80
+ events = parsed['events'].map { |event| Resources::Event.new(event) }
81
+ webhook_id = parsed.dig('meta', 'webhook_id')
82
+
83
+ WebhookParseResult.new(events, webhook_id)
84
+ end
85
+
41
86
  # Validates that a webhook was genuinely sent by GoCardless by computing its
42
87
  # signature using the body and your webhook endpoint secret, and comparing that with
43
88
  # the signature included in the `Webhook-Signature` header
@@ -45,6 +45,9 @@ require_relative 'gocardless_pro/services/balances_service'
45
45
  require_relative 'gocardless_pro/resources/bank_account_detail'
46
46
  require_relative 'gocardless_pro/services/bank_account_details_service'
47
47
 
48
+ require_relative 'gocardless_pro/resources/bank_account_holder_verification'
49
+ require_relative 'gocardless_pro/services/bank_account_holder_verifications_service'
50
+
48
51
  require_relative 'gocardless_pro/resources/bank_authorisation'
49
52
  require_relative 'gocardless_pro/services/bank_authorisations_service'
50
53
 
@@ -90,6 +93,9 @@ require_relative 'gocardless_pro/services/events_service'
90
93
  require_relative 'gocardless_pro/resources/export'
91
94
  require_relative 'gocardless_pro/services/exports_service'
92
95
 
96
+ require_relative 'gocardless_pro/resources/funds_availability'
97
+ require_relative 'gocardless_pro/services/funds_availabilities_service'
98
+
93
99
  require_relative 'gocardless_pro/resources/instalment_schedule'
94
100
  require_relative 'gocardless_pro/services/instalment_schedules_service'
95
101
 
@@ -117,6 +123,12 @@ require_relative 'gocardless_pro/services/negative_balance_limits_service'
117
123
  require_relative 'gocardless_pro/resources/outbound_payment'
118
124
  require_relative 'gocardless_pro/services/outbound_payments_service'
119
125
 
126
+ require_relative 'gocardless_pro/resources/outbound_payment_import'
127
+ require_relative 'gocardless_pro/services/outbound_payment_imports_service'
128
+
129
+ require_relative 'gocardless_pro/resources/outbound_payment_import_entry'
130
+ require_relative 'gocardless_pro/services/outbound_payment_import_entries_service'
131
+
120
132
  require_relative 'gocardless_pro/resources/payer_authorisation'
121
133
  require_relative 'gocardless_pro/services/payer_authorisations_service'
122
134
 
@@ -126,6 +138,12 @@ require_relative 'gocardless_pro/services/payer_themes_service'
126
138
  require_relative 'gocardless_pro/resources/payment'
127
139
  require_relative 'gocardless_pro/services/payments_service'
128
140
 
141
+ require_relative 'gocardless_pro/resources/payment_account'
142
+ require_relative 'gocardless_pro/services/payment_accounts_service'
143
+
144
+ require_relative 'gocardless_pro/resources/payment_account_transaction'
145
+ require_relative 'gocardless_pro/services/payment_account_transactions_service'
146
+
129
147
  require_relative 'gocardless_pro/resources/payout'
130
148
  require_relative 'gocardless_pro/services/payouts_service'
131
149