gocardless_pro 2.18.1 → 2.22.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +25 -43
  3. data/Gemfile +7 -0
  4. data/gocardless_pro.gemspec +2 -2
  5. data/lib/gocardless_pro/api_service.rb +1 -1
  6. data/lib/gocardless_pro/client.rb +1 -1
  7. data/lib/gocardless_pro/resources/payout.rb +2 -0
  8. data/lib/gocardless_pro/services/bank_details_lookups_service.rb +0 -10
  9. data/lib/gocardless_pro/services/base_service.rb +11 -0
  10. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +0 -10
  11. data/lib/gocardless_pro/services/creditors_service.rb +0 -10
  12. data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +0 -10
  13. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +0 -10
  14. data/lib/gocardless_pro/services/customer_notifications_service.rb +0 -10
  15. data/lib/gocardless_pro/services/customers_service.rb +0 -10
  16. data/lib/gocardless_pro/services/events_service.rb +0 -10
  17. data/lib/gocardless_pro/services/instalment_schedules_service.rb +21 -10
  18. data/lib/gocardless_pro/services/mandate_import_entries_service.rb +0 -10
  19. data/lib/gocardless_pro/services/mandate_imports_service.rb +0 -10
  20. data/lib/gocardless_pro/services/mandate_pdfs_service.rb +0 -10
  21. data/lib/gocardless_pro/services/mandates_service.rb +0 -10
  22. data/lib/gocardless_pro/services/payments_service.rb +0 -10
  23. data/lib/gocardless_pro/services/payout_items_service.rb +0 -10
  24. data/lib/gocardless_pro/services/payouts_service.rb +21 -10
  25. data/lib/gocardless_pro/services/redirect_flows_service.rb +0 -10
  26. data/lib/gocardless_pro/services/refunds_service.rb +6 -11
  27. data/lib/gocardless_pro/services/subscriptions_service.rb +21 -16
  28. data/lib/gocardless_pro/version.rb +1 -1
  29. data/spec/resources/instalment_schedule_spec.rb +35 -0
  30. data/spec/resources/payout_spec.rb +45 -0
  31. data/spec/services/creditor_bank_accounts_service_spec.rb +1 -1
  32. data/spec/services/customer_bank_accounts_service_spec.rb +1 -1
  33. data/spec/services/customer_notifications_service_spec.rb +1 -1
  34. data/spec/services/customers_service_spec.rb +1 -1
  35. data/spec/services/instalment_schedules_service_spec.rb +61 -1
  36. data/spec/services/mandate_imports_service_spec.rb +2 -2
  37. data/spec/services/mandates_service_spec.rb +2 -2
  38. data/spec/services/payments_service_spec.rb +2 -2
  39. data/spec/services/payouts_service_spec.rb +74 -0
  40. data/spec/services/redirect_flows_service_spec.rb +1 -1
  41. data/spec/services/subscriptions_service_spec.rb +3 -3
  42. metadata +7 -7
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -225,15 +224,6 @@ module GoCardlessPro
225
224
  def envelope_key
226
225
  'mandates'
227
226
  end
228
-
229
- # take a URL with placeholder params and substitute them out for the actual value
230
- # @param url [String] the URL with placeholders in
231
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
232
- def sub_url(url, param_map)
233
- param_map.reduce(url) do |new_url, (param, value)|
234
- new_url.gsub(":#{param}", URI.escape(value))
235
- end
236
- end
237
227
  end
238
228
  end
239
229
  end
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -225,15 +224,6 @@ module GoCardlessPro
225
224
  def envelope_key
226
225
  'payments'
227
226
  end
228
-
229
- # take a URL with placeholder params and substitute them out for the actual value
230
- # @param url [String] the URL with placeholders in
231
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
232
- def sub_url(url, param_map)
233
- param_map.reduce(url) do |new_url, (param, value)|
234
- new_url.gsub(":#{param}", URI.escape(value))
235
- end
236
- end
237
227
  end
238
228
  end
239
229
  end
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -54,15 +53,6 @@ module GoCardlessPro
54
53
  def envelope_key
55
54
  'payout_items'
56
55
  end
57
-
58
- # take a URL with placeholder params and substitute them out for the actual value
59
- # @param url [String] the URL with placeholders in
60
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
61
- def sub_url(url, param_map)
62
- param_map.reduce(url) do |new_url, (param, value)|
63
- new_url.gsub(":#{param}", URI.escape(value))
64
- end
65
- end
66
56
  end
67
57
  end
68
58
  end
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -59,6 +58,27 @@ module GoCardlessPro
59
58
  Resources::Payout.new(unenvelope_body(response.body), response)
60
59
  end
61
60
 
61
+ # Updates a payout object. This accepts only the metadata parameter.
62
+ # Example URL: /payouts/:identity
63
+ #
64
+ # @param identity # Unique identifier, beginning with "PO".
65
+ # @param options [Hash] parameters as a hash, under a params key.
66
+ def update(identity, options = {})
67
+ path = sub_url('/payouts/:identity', 'identity' => identity)
68
+
69
+ params = options.delete(:params) || {}
70
+ options[:params] = {}
71
+ options[:params][envelope_key] = params
72
+
73
+ options[:retry_failures] = true
74
+
75
+ response = make_request(:put, path, options)
76
+
77
+ return if response.body.nil?
78
+
79
+ Resources::Payout.new(unenvelope_body(response.body), response)
80
+ end
81
+
62
82
  private
63
83
 
64
84
  # Unenvelope the response of the body using the service's `envelope_key`
@@ -72,15 +92,6 @@ module GoCardlessPro
72
92
  def envelope_key
73
93
  'payouts'
74
94
  end
75
-
76
- # take a URL with placeholder params and substitute them out for the actual value
77
- # @param url [String] the URL with placeholders in
78
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
79
- def sub_url(url, param_map)
80
- param_map.reduce(url) do |new_url, (param, value)|
81
- new_url.gsub(":#{param}", URI.escape(value))
82
- end
83
- end
84
95
  end
85
96
  end
86
97
  end
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -127,15 +126,6 @@ module GoCardlessPro
127
126
  def envelope_key
128
127
  'redirect_flows'
129
128
  end
130
-
131
- # take a URL with placeholder params and substitute them out for the actual value
132
- # @param url [String] the URL with placeholders in
133
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
134
- def sub_url(url, param_map)
135
- param_map.reduce(url) do |new_url, (param, value)|
136
- new_url.gsub(":#{param}", URI.escape(value))
137
- end
138
- end
139
129
  end
140
130
  end
141
131
  end
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -14,7 +13,8 @@ module GoCardlessPro
14
13
  # Creates a new refund object.
15
14
  #
16
15
  # This fails with:<a name="total_amount_confirmation_invalid"></a><a
17
- # name="number_of_refunds_exceeded"></a>
16
+ # name="number_of_refunds_exceeded"></a><a
17
+ # name="available_refund_amount_insufficient"></a>
18
18
  #
19
19
  # - `total_amount_confirmation_invalid` if the confirmation amount doesn't match
20
20
  # the total amount refunded for the payment. This safeguard is there to prevent
@@ -23,6 +23,10 @@ module GoCardlessPro
23
23
  # - `number_of_refunds_exceeded` if five or more refunds have already been
24
24
  # created against the payment.
25
25
  #
26
+ # - `available_refund_amount_insufficient` if the creditor does not have
27
+ # sufficient balance for refunds available to cover the cost of the requested
28
+ # refund.
29
+ #
26
30
  # Example URL: /refunds
27
31
  # @param options [Hash] parameters as a hash, under a params key.
28
32
  def create(options = {})
@@ -139,15 +143,6 @@ module GoCardlessPro
139
143
  def envelope_key
140
144
  'refunds'
141
145
  end
142
-
143
- # take a URL with placeholder params and substitute them out for the actual value
144
- # @param url [String] the URL with placeholders in
145
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
146
- def sub_url(url, param_map)
147
- param_map.reduce(url) do |new_url, (param, value)|
148
- new_url.gsub(":#{param}", URI.escape(value))
149
- end
150
- end
151
146
  end
152
147
  end
153
148
  end
@@ -1,5 +1,4 @@
1
1
  require_relative './base_service'
2
- require 'uri'
3
2
 
4
3
  # encoding: utf-8
5
4
  #
@@ -141,9 +140,22 @@ module GoCardlessPro
141
140
  # Pause a subscription object.
142
141
  # No payments will be created until it is resumed.
143
142
  #
144
- # This can only be used with subscriptions created with `count` or
145
- # subscriptions without `count` and `end_date`
146
- # If the subscription has `count` its `end_date` will be `null` after pausing.
143
+ # This can only be used when a subscription collecting a fixed number of
144
+ # payments (created using `count`)
145
+ # or when they continue forever (created without `count` or `end_date`)
146
+ #
147
+ # When `pause_cycles` is omitted the subscription is paused until the [resume
148
+ # endpoint](#subscriptions-resume-a-subscription) is called.
149
+ # If the subscription is collecting a fixed number of payments, `end_date` will
150
+ # be set to `nil`.
151
+ # When paused indefinitely, `upcoming_payments` will be empty.
152
+ #
153
+ # When `pause_cycles` is provided the subscription will be paused for the number
154
+ # of cycles requested.
155
+ # If the subscription is collecting a fixed number of payments, `end_date` will
156
+ # be set to a new value.
157
+ # When paused for a number of cycles, `upcoming_payments` will still contain the
158
+ # upcoming charge dates.
147
159
  #
148
160
  # This fails with:
149
161
  #
@@ -158,6 +170,9 @@ module GoCardlessPro
158
170
  #
159
171
  # - `subscription_already_ended` if the subscription has taken all payments.
160
172
  #
173
+ # - `pause_cycles_must_be_greater_than_or_equal_to` if the provided value for
174
+ # `pause_cycles` cannot be satisfied.
175
+ #
161
176
  # Example URL: /subscriptions/:identity/actions/pause
162
177
  #
163
178
  # @param identity # Unique identifier, beginning with "SB".
@@ -199,6 +214,8 @@ module GoCardlessPro
199
214
  # Resume a subscription object.
200
215
  # Payments will start to be created again based on the subscriptions recurrence
201
216
  # rules.
217
+ # The `charge_date` on the next payment will be the same as the subscriptions
218
+ # `earliest_charge_date_after_resume`
202
219
  #
203
220
  # This fails with:
204
221
  #
@@ -211,9 +228,6 @@ module GoCardlessPro
211
228
  #
212
229
  # - `subscription_not_paused` if the subscription is not paused.
213
230
  #
214
- # - `subscription_already_scheduled_to_resume` if a subscription already has a
215
- # scheduled resume date.
216
- #
217
231
  # Example URL: /subscriptions/:identity/actions/resume
218
232
  #
219
233
  # @param identity # Unique identifier, beginning with "SB".
@@ -309,15 +323,6 @@ module GoCardlessPro
309
323
  def envelope_key
310
324
  'subscriptions'
311
325
  end
312
-
313
- # take a URL with placeholder params and substitute them out for the actual value
314
- # @param url [String] the URL with placeholders in
315
- # @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
316
- def sub_url(url, param_map)
317
- param_map.reduce(url) do |new_url, (param, value)|
318
- new_url.gsub(":#{param}", URI.escape(value))
319
- end
320
- end
321
326
  end
322
327
  end
323
328
  end
@@ -4,5 +4,5 @@ end
4
4
 
5
5
  module GoCardlessPro
6
6
  # Current version of the GC gem
7
- VERSION = '2.18.1'.freeze
7
+ VERSION = '2.22.1'.freeze
8
8
  end
@@ -529,6 +529,41 @@ describe GoCardlessPro::Resources::InstalmentSchedule do
529
529
  end
530
530
  end
531
531
 
532
+ describe '#update' do
533
+ subject(:put_update_response) { client.instalment_schedules.update(id, params: update_params) }
534
+ let(:id) { 'ABC123' }
535
+
536
+ context 'with a valid request' do
537
+ let(:update_params) { { 'hello' => 'world' } }
538
+
539
+ let!(:stub) do
540
+ stub_url = '/instalment_schedules/:identity'.gsub(':identity', id)
541
+ stub_request(:put, /.*api.gocardless.com#{stub_url}/).to_return(
542
+ body: {
543
+ 'instalment_schedules' => {
544
+
545
+ 'created_at' => 'created_at-input',
546
+ 'currency' => 'currency-input',
547
+ 'id' => 'id-input',
548
+ 'links' => 'links-input',
549
+ 'metadata' => 'metadata-input',
550
+ 'name' => 'name-input',
551
+ 'payment_errors' => 'payment_errors-input',
552
+ 'status' => 'status-input',
553
+ 'total_amount' => 'total_amount-input',
554
+ },
555
+ }.to_json,
556
+ headers: response_headers
557
+ )
558
+ end
559
+
560
+ it 'updates and returns the resource' do
561
+ expect(put_update_response).to be_a(GoCardlessPro::Resources::InstalmentSchedule)
562
+ expect(stub).to have_been_requested
563
+ end
564
+ end
565
+ end
566
+
532
567
  describe '#cancel' do
533
568
  subject(:post_response) { client.instalment_schedules.cancel(resource_id) }
534
569
 
@@ -26,6 +26,7 @@ describe GoCardlessPro::Resources::Payout do
26
26
  'fx' => 'fx-input',
27
27
  'id' => 'id-input',
28
28
  'links' => 'links-input',
29
+ 'metadata' => 'metadata-input',
29
30
  'payout_type' => 'payout_type-input',
30
31
  'reference' => 'reference-input',
31
32
  'status' => 'status-input',
@@ -58,6 +59,8 @@ describe GoCardlessPro::Resources::Payout do
58
59
 
59
60
  expect(get_list_response.records.first.id).to eq('id-input')
60
61
 
62
+ expect(get_list_response.records.first.metadata).to eq('metadata-input')
63
+
61
64
  expect(get_list_response.records.first.payout_type).to eq('payout_type-input')
62
65
 
63
66
  expect(get_list_response.records.first.reference).to eq('reference-input')
@@ -88,6 +91,7 @@ describe GoCardlessPro::Resources::Payout do
88
91
  'fx' => 'fx-input',
89
92
  'id' => 'id-input',
90
93
  'links' => 'links-input',
94
+ 'metadata' => 'metadata-input',
91
95
  'payout_type' => 'payout_type-input',
92
96
  'reference' => 'reference-input',
93
97
  'status' => 'status-input',
@@ -114,6 +118,7 @@ describe GoCardlessPro::Resources::Payout do
114
118
  'fx' => 'fx-input',
115
119
  'id' => 'id-input',
116
120
  'links' => 'links-input',
121
+ 'metadata' => 'metadata-input',
117
122
  'payout_type' => 'payout_type-input',
118
123
  'reference' => 'reference-input',
119
124
  'status' => 'status-input',
@@ -156,6 +161,7 @@ describe GoCardlessPro::Resources::Payout do
156
161
  'fx' => 'fx-input',
157
162
  'id' => 'id-input',
158
163
  'links' => 'links-input',
164
+ 'metadata' => 'metadata-input',
159
165
  'payout_type' => 'payout_type-input',
160
166
  'reference' => 'reference-input',
161
167
  'status' => 'status-input',
@@ -192,6 +198,7 @@ describe GoCardlessPro::Resources::Payout do
192
198
  'fx' => 'fx-input',
193
199
  'id' => 'id-input',
194
200
  'links' => 'links-input',
201
+ 'metadata' => 'metadata-input',
195
202
  'payout_type' => 'payout_type-input',
196
203
  'reference' => 'reference-input',
197
204
  'status' => 'status-input',
@@ -228,4 +235,42 @@ describe GoCardlessPro::Resources::Payout do
228
235
  end
229
236
  end
230
237
  end
238
+
239
+ describe '#update' do
240
+ subject(:put_update_response) { client.payouts.update(id, params: update_params) }
241
+ let(:id) { 'ABC123' }
242
+
243
+ context 'with a valid request' do
244
+ let(:update_params) { { 'hello' => 'world' } }
245
+
246
+ let!(:stub) do
247
+ stub_url = '/payouts/:identity'.gsub(':identity', id)
248
+ stub_request(:put, /.*api.gocardless.com#{stub_url}/).to_return(
249
+ body: {
250
+ 'payouts' => {
251
+
252
+ 'amount' => 'amount-input',
253
+ 'arrival_date' => 'arrival_date-input',
254
+ 'created_at' => 'created_at-input',
255
+ 'currency' => 'currency-input',
256
+ 'deducted_fees' => 'deducted_fees-input',
257
+ 'fx' => 'fx-input',
258
+ 'id' => 'id-input',
259
+ 'links' => 'links-input',
260
+ 'metadata' => 'metadata-input',
261
+ 'payout_type' => 'payout_type-input',
262
+ 'reference' => 'reference-input',
263
+ 'status' => 'status-input',
264
+ },
265
+ }.to_json,
266
+ headers: response_headers
267
+ )
268
+ end
269
+
270
+ it 'updates and returns the resource' do
271
+ expect(put_update_response).to be_a(GoCardlessPro::Resources::Payout)
272
+ expect(stub).to have_been_requested
273
+ end
274
+ end
275
+ end
231
276
  end
@@ -692,7 +692,7 @@ describe GoCardlessPro::Services::CreditorBankAccountsService do
692
692
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
693
693
  to_timeout
694
694
 
695
- expect { post_response }.to raise_error(Faraday::TimeoutError)
695
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
696
696
  expect(stub).to have_been_requested
697
697
  end
698
698
  end
@@ -754,7 +754,7 @@ describe GoCardlessPro::Services::CustomerBankAccountsService do
754
754
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
755
755
  to_timeout
756
756
 
757
- expect { post_response }.to raise_error(Faraday::TimeoutError)
757
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
758
758
  expect(stub).to have_been_requested
759
759
  end
760
760
  end
@@ -45,7 +45,7 @@ describe GoCardlessPro::Services::CustomerNotificationsService do
45
45
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
46
46
  to_timeout
47
47
 
48
- expect { post_response }.to raise_error(Faraday::TimeoutError)
48
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
49
49
  expect(stub).to have_been_requested
50
50
  end
51
51
  end
@@ -882,7 +882,7 @@ describe GoCardlessPro::Services::CustomersService do
882
882
  stub = stub_request(:delete, /.*api.gocardless.com#{stub_url}/).
883
883
  to_timeout
884
884
 
885
- expect { delete_response }.to raise_error(Faraday::TimeoutError)
885
+ expect { delete_response }.to raise_error(Faraday::ConnectionFailed)
886
886
  expect(stub).to have_been_requested
887
887
  end
888
888
  end
@@ -828,6 +828,66 @@ describe GoCardlessPro::Services::InstalmentSchedulesService do
828
828
  end
829
829
  end
830
830
 
831
+ describe '#update' do
832
+ subject(:put_update_response) { client.instalment_schedules.update(id, params: update_params) }
833
+ let(:id) { 'ABC123' }
834
+
835
+ context 'with a valid request' do
836
+ let(:update_params) { { 'hello' => 'world' } }
837
+
838
+ let!(:stub) do
839
+ stub_url = '/instalment_schedules/:identity'.gsub(':identity', id)
840
+ stub_request(:put, /.*api.gocardless.com#{stub_url}/).to_return(
841
+ body: {
842
+ 'instalment_schedules' => {
843
+
844
+ 'created_at' => 'created_at-input',
845
+ 'currency' => 'currency-input',
846
+ 'id' => 'id-input',
847
+ 'links' => 'links-input',
848
+ 'metadata' => 'metadata-input',
849
+ 'name' => 'name-input',
850
+ 'payment_errors' => 'payment_errors-input',
851
+ 'status' => 'status-input',
852
+ 'total_amount' => 'total_amount-input',
853
+ },
854
+ }.to_json,
855
+ headers: response_headers
856
+ )
857
+ end
858
+
859
+ it 'updates and returns the resource' do
860
+ expect(put_update_response).to be_a(GoCardlessPro::Resources::InstalmentSchedule)
861
+ expect(stub).to have_been_requested
862
+ end
863
+
864
+ describe 'retry behaviour' do
865
+ before { allow_any_instance_of(GoCardlessPro::Request).to receive(:sleep) }
866
+
867
+ it 'retries timeouts' do
868
+ stub_url = '/instalment_schedules/:identity'.gsub(':identity', id)
869
+ stub = stub_request(:put, /.*api.gocardless.com#{stub_url}/).
870
+ to_timeout.then.to_return(status: 200, headers: response_headers)
871
+
872
+ put_update_response
873
+ expect(stub).to have_been_requested.twice
874
+ end
875
+
876
+ it 'retries 5XX errors' do
877
+ stub_url = '/instalment_schedules/:identity'.gsub(':identity', id)
878
+ stub = stub_request(:put, /.*api.gocardless.com#{stub_url}/).
879
+ to_return(status: 502,
880
+ headers: { 'Content-Type' => 'text/html' },
881
+ body: '<html><body>Response from Cloudflare</body></html>').
882
+ then.to_return(status: 200, headers: response_headers)
883
+
884
+ put_update_response
885
+ expect(stub).to have_been_requested.twice
886
+ end
887
+ end
888
+ end
889
+ end
890
+
831
891
  describe '#cancel' do
832
892
  subject(:post_response) { client.instalment_schedules.cancel(resource_id) }
833
893
 
@@ -867,7 +927,7 @@ describe GoCardlessPro::Services::InstalmentSchedulesService do
867
927
  stub = stub_request(:post, /.*api.gocardless.com#{stub_url}/).
868
928
  to_timeout
869
929
 
870
- expect { post_response }.to raise_error(Faraday::TimeoutError)
930
+ expect { post_response }.to raise_error(Faraday::ConnectionFailed)
871
931
  expect(stub).to have_been_requested
872
932
  end
873
933
  end