gocardless_pro 2.18.0 → 2.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) 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/creditor_bank_account.rb +1 -2
  8. data/lib/gocardless_pro/resources/customer_notification.rb +3 -5
  9. data/lib/gocardless_pro/resources/event.rb +2 -1
  10. data/lib/gocardless_pro/resources/mandate_import.rb +5 -8
  11. data/lib/gocardless_pro/resources/mandate_import_entry.rb +3 -5
  12. data/lib/gocardless_pro/resources/payout.rb +2 -0
  13. data/lib/gocardless_pro/resources/redirect_flow.rb +2 -0
  14. data/lib/gocardless_pro/resources/subscription.rb +36 -29
  15. data/lib/gocardless_pro/services/customers_service.rb +1 -2
  16. data/lib/gocardless_pro/services/instalment_schedules_service.rb +21 -0
  17. data/lib/gocardless_pro/services/mandates_service.rb +1 -1
  18. data/lib/gocardless_pro/services/payouts_service.rb +21 -0
  19. data/lib/gocardless_pro/services/subscriptions_service.rb +129 -0
  20. data/lib/gocardless_pro/version.rb +1 -1
  21. data/spec/resources/instalment_schedule_spec.rb +35 -0
  22. data/spec/resources/payout_spec.rb +45 -0
  23. data/spec/resources/redirect_flow_spec.rb +9 -0
  24. data/spec/resources/subscription_spec.rb +195 -0
  25. data/spec/services/creditor_bank_accounts_service_spec.rb +1 -1
  26. data/spec/services/customer_bank_accounts_service_spec.rb +1 -1
  27. data/spec/services/customer_notifications_service_spec.rb +1 -1
  28. data/spec/services/customers_service_spec.rb +1 -1
  29. data/spec/services/instalment_schedules_service_spec.rb +61 -1
  30. data/spec/services/mandate_imports_service_spec.rb +2 -2
  31. data/spec/services/mandates_service_spec.rb +2 -2
  32. data/spec/services/payments_service_spec.rb +2 -2
  33. data/spec/services/payouts_service_spec.rb +74 -0
  34. data/spec/services/redirect_flows_service_spec.rb +10 -1
  35. data/spec/services/subscriptions_service_spec.rb +222 -1
  36. metadata +7 -8
  37. data/gocardless_pro-2.17.1.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 250fed25fc74cb084ad988286e20f8dd2c679fcb62e0de5a1fc3bfca71b67c43
4
- data.tar.gz: af02087f4d85aafa9337d51219c467bc195c6c9eff6d03b2f9c5dbf209956680
3
+ metadata.gz: 3bb8531d374a6fe482eaaccbc49cd9cbf1575f880cb9633c0b0848ca09157b76
4
+ data.tar.gz: 24e1f269a875c46dd8a2165f856ba18a4acea648aed82a600de26425bb32bd3d
5
5
  SHA512:
6
- metadata.gz: a3bd1149c2936dfd1ba6d8b60e7183c279d105046c4c02ab497e2d11da3c3f93c363a56ce5a2c1133138ad9acd421bbfb4c479c1da3970afb4c6b650a0197965
7
- data.tar.gz: '07951005f59ae4328b34342bb24c9b06bfb9f0221a87630751d21b9755354fb3daaf7f0b34bb51d98811f2e1199479be08745afdb66c888953bfad50fc8bc099'
6
+ metadata.gz: b93423658f351048e9dd31cb216a86d2c389638d2079647457f68a521eaa4f749844c199cc2cfbb44904dcc18ed9608f94698d1e2e3201341e833714c8a6e6bc
7
+ data.tar.gz: a2836a224de279066f96d8fa28238368271cbfe967bda9015655ce68cca8262466821d6a923b87db2a050f85e99f14758de9c8214f61fd0089ae127a0cb229d2
@@ -1,50 +1,32 @@
1
- version: 2
2
- references:
3
- test_library: &test_library
1
+ version: 2.1
2
+
3
+ jobs:
4
+ test: &test
4
5
  parallelism: 1
6
+ parameters:
7
+ faraday-version: { type: string }
8
+ ruby-version: { type: string }
9
+ docker:
10
+ - image: ruby:<<parameters.ruby-version>>
11
+ environment:
12
+ - FARADAY_VERSION=<<parameters.faraday-version>>
5
13
  steps:
6
14
  - checkout
7
- - run: |
8
- bundle install
9
- bundle exec rspec
10
- jobs:
11
- test_ruby_2_5:
12
- <<: *test_library
13
- docker:
14
- - image: ruby:2.5
15
-
16
- test_ruby_2_4:
17
- <<: *test_library
18
- docker:
19
- - image: ruby:2.4
20
-
21
- test_ruby_2_3:
22
- <<: *test_library
23
- docker:
24
- - image: ruby:2.3
25
-
26
- test_ruby_2_2:
27
- <<: *test_library
28
- docker:
29
- - image: ruby:2.2
30
-
31
- test_ruby_2_1:
32
- <<: *test_library
33
- docker:
34
- - image: ruby:2.1
35
-
36
- test_ruby_2_0:
37
- <<: *test_library
38
- docker:
39
- - image: ruby:2.0
15
+ - run: bundle install && bundle exec rspec
40
16
 
41
17
  workflows:
42
18
  version: 2
43
- build:
19
+ tests:
44
20
  jobs:
45
- - test_ruby_2_5
46
- - test_ruby_2_4
47
- - test_ruby_2_3
48
- - test_ruby_2_2
49
- - test_ruby_2_1
50
- - test_ruby_2_0
21
+ - test:
22
+ matrix:
23
+ parameters:
24
+ faraday-version: ["0.9.2", "1.0"]
25
+ ruby-version: ["2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7"]
26
+ exclude:
27
+ - faraday-version: "1.0"
28
+ ruby-version: "2.0"
29
+ - faraday-version: "1.0"
30
+ ruby-version: "2.1"
31
+ - faraday-version: "1.0"
32
+ ruby-version: "2.2"
data/Gemfile CHANGED
@@ -1,2 +1,9 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ # We support both pre-1.x and post-1.x Faraday versions, but to ensure compatibility we
5
+ # pin this gem against each in separate runs of CI, using the FARADAY_VERSION env var. For
6
+ # more details on the values, see .circleci/config.yml.
7
+ if ENV.key?("FARADAY_VERSION")
8
+ gem 'faraday', "~> #{ENV["FARADAY_VERSION"]}"
9
+ end
@@ -17,10 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
- spec.add_dependency 'faraday', ['>= 0.9.2', '< 1.0']
20
+ spec.add_dependency 'faraday', ['>= 0.9.2', '< 2']
21
21
 
22
22
  spec.add_development_dependency 'rspec', '~> 3.7.0'
23
- spec.add_development_dependency 'webmock', '~> 1.18'
23
+ spec.add_development_dependency 'webmock', '~> 3.8.3'
24
24
  spec.add_development_dependency 'rubocop', '~> 0.49.1'
25
25
  spec.add_development_dependency 'yard', '~> 0.9.11'
26
26
 
@@ -23,7 +23,7 @@ module GoCardlessPro
23
23
  @url = url
24
24
  root_url, @path_prefix = unpack_url(url)
25
25
  http_adapter = options[:http_adapter] || [:net_http]
26
- connection_options = options[:connection_options]
26
+ connection_options = options.fetch(:connection_options, {})
27
27
 
28
28
  @connection = Faraday.new(root_url, connection_options) do |faraday|
29
29
  faraday.response :raise_gocardless_errors
@@ -148,7 +148,7 @@ module GoCardlessPro
148
148
  'User-Agent' => user_agent.to_s,
149
149
  'Content-Type' => 'application/json',
150
150
  'GoCardless-Client-Library' => 'gocardless-pro-ruby',
151
- 'GoCardless-Client-Version' => '2.18.0',
151
+ 'GoCardless-Client-Version' => '2.22.0',
152
152
  },
153
153
  }
154
154
  end
@@ -23,8 +23,7 @@ module GoCardlessPro
23
23
  # `links[creditor_bank_account]` in the error response.
24
24
  #
25
25
  # <p class="restricted-notice"><strong>Restricted</strong>: This API is not
26
- # available for
27
- # partner integrations.</p>
26
+ # available for partner integrations.</p>
28
27
  class CreditorBankAccount
29
28
  attr_reader :account_holder_name
30
29
  attr_reader :account_number_ending
@@ -23,11 +23,9 @@ module GoCardlessPro
23
23
  # way, it is no longer visible using this API.
24
24
  #
25
25
  # <p class="restricted-notice"><strong>Restricted</strong>: This API is
26
- # currently
27
- # only available for approved integrators - please <a
28
- # href="mailto:help@gocardless.com">get
29
- # in touch</a> if you would like to use this API.</p>
30
- #
26
+ # currently only available for approved integrators - please <a
27
+ # href="mailto:help@gocardless.com">get in touch</a> if you would like to
28
+ # use this API.</p>
31
29
  class CustomerNotification
32
30
  attr_reader :action_taken
33
31
  attr_reader :action_taken_at
@@ -14,7 +14,8 @@ module GoCardlessPro
14
14
 
15
15
  # Events are stored for all webhooks. An event refers to a resource which
16
16
  # has been updated, for example a payment which has been collected, or a
17
- # mandate which has been transferred.
17
+ # mandate which has been transferred. See [here](#event-actions) for a
18
+ # complete list of event types.
18
19
  class Event
19
20
  attr_reader :action
20
21
  attr_reader :created_at
@@ -47,16 +47,13 @@ module GoCardlessPro
47
47
  # system](#mandate-import-entries-list-all-mandate-import-entries).
48
48
  #
49
49
  # <p class="notice">Note that all Mandate Imports have an upper limit of
50
- # 30,000 entries, so
51
- # we recommend you split your import into several smaller imports if you're
52
- # planning to
53
- # exceed this threshold.</p>
50
+ # 30,000 entries, so we recommend you split your import into several smaller
51
+ # imports if you're planning to exceed this threshold.</p>
54
52
  #
55
53
  # <p class="restricted-notice"><strong>Restricted</strong>: This API is
56
- # currently
57
- # only available for approved integrators - please <a
58
- # href="mailto:help@gocardless.com">get
59
- # in touch</a> if you would like to use this API.</p>
54
+ # currently only available for approved integrators - please <a
55
+ # href="mailto:help@gocardless.com">get in touch</a> if you would like to
56
+ # use this API.</p>
60
57
  class MandateImport
61
58
  attr_reader :created_at
62
59
  attr_reader :id
@@ -39,11 +39,9 @@ module GoCardlessPro
39
39
  # been imported.
40
40
  #
41
41
  # <p class="restricted-notice"><strong>Restricted</strong>: This API is
42
- # currently
43
- # only available for approved integrators - please <a
44
- # href="mailto:help@gocardless.com">get
45
- # in touch</a> if you would like to use this API.</p>
46
- #
42
+ # currently only available for approved integrators - please <a
43
+ # href="mailto:help@gocardless.com">get in touch</a> if you would like to
44
+ # use this API.</p>
47
45
  class MandateImportEntry
48
46
  attr_reader :created_at
49
47
  attr_reader :record_identifier
@@ -26,6 +26,7 @@ module GoCardlessPro
26
26
  attr_reader :deducted_fees
27
27
  attr_reader :fx
28
28
  attr_reader :id
29
+ attr_reader :metadata
29
30
  attr_reader :payout_type
30
31
  attr_reader :reference
31
32
  attr_reader :status
@@ -43,6 +44,7 @@ module GoCardlessPro
43
44
  @fx = object['fx']
44
45
  @id = object['id']
45
46
  @links = object['links']
47
+ @metadata = object['metadata']
46
48
  @payout_type = object['payout_type']
47
49
  @reference = object['reference']
48
50
  @status = object['status']
@@ -49,6 +49,7 @@ module GoCardlessPro
49
49
  attr_reader :created_at
50
50
  attr_reader :description
51
51
  attr_reader :id
52
+ attr_reader :metadata
52
53
  attr_reader :redirect_url
53
54
  attr_reader :scheme
54
55
  attr_reader :session_token
@@ -64,6 +65,7 @@ module GoCardlessPro
64
65
  @description = object['description']
65
66
  @id = object['id']
66
67
  @links = object['links']
68
+ @metadata = object['metadata']
67
69
  @redirect_url = object['redirect_url']
68
70
  @scheme = object['scheme']
69
71
  @session_token = object['session_token']
@@ -20,40 +20,45 @@ module GoCardlessPro
20
20
  # The following rules apply when specifying recurrence:
21
21
  #
22
22
  # - The first payment must be charged within 1 year.
23
- # - When neither `month` nor `day_of_month` are present, the subscription
24
- # will recur from the `start_date` based on the `interval_unit`.
25
- # - If `month` or `day_of_month` are present, the recurrence rules will be
26
- # applied from the `start_date`, and the following validations apply:
23
+ # - If `day_of_month` and `start_date` are not provided `start_date` will be
24
+ # the [mandate](#core-endpoints-mandates)'s `next_possible_charge_date` and
25
+ # the subscription will then recur based on the `interval` & `interval_unit`
26
+ # - If `month` or `day_of_month` are present the following validations
27
+ # apply:
27
28
  #
28
- # | interval_unit | month |
29
- # day_of_month |
30
- # | :-------------- | :--------------------------------------------- |
31
- # :-------------------------------------- |
32
- # | yearly | optional (required if `day_of_month` provided) |
33
- # optional (required if `month` provided) |
34
- # | monthly | invalid |
35
- # required |
36
- # | weekly | invalid |
37
- # invalid |
29
+ # | __interval_unit__ | __month__ |
30
+ # __day_of_month__ |
31
+ # | :---------------- | :--------------------------------------------- |
32
+ # :----------------------------------------- |
33
+ # | yearly | optional (required if `day_of_month` provided) |
34
+ # optional (invalid if `month` not provided) |
35
+ # | monthly | invalid |
36
+ # optional |
37
+ # | weekly | invalid |
38
+ # invalid |
38
39
  #
39
40
  # Examples:
40
41
  #
41
- # | interval_unit | interval | month | day_of_month | valid?
42
- # |
43
- # | :-------------- | :--------- | :------ | :------------- |
42
+ # | __interval_unit__ | __interval__ | __month__ | __day_of_month__ | valid?
43
+ # |
44
+ # | :---------------- | :----------- | :-------- | :--------------- |
44
45
  # :------------------------------------------------- |
45
- # | yearly | 1 | january | -1 | valid
46
- # |
47
- # | yearly | 1 | march | | invalid -
48
- # missing `day_of_month` |
49
- # | monthly | 6 | | 12 | valid
50
- # |
51
- # | monthly | 6 | august | 12 | invalid -
52
- # `month` must be blank |
53
- # | weekly | 2 | | | valid
54
- # |
55
- # | weekly | 2 | october | 10 | invalid -
56
- # `month` and `day_of_month` must be blank |
46
+ # | yearly | 1 | january | -1 | valid
47
+ # |
48
+ # | monthly | 6 | | | valid
49
+ # |
50
+ # | monthly | 6 | | 12 | valid
51
+ # |
52
+ # | weekly | 2 | | | valid
53
+ # |
54
+ # | yearly | 1 | march | |
55
+ # invalid - missing `day_of_month` |
56
+ # | yearly | 1 | | 2 |
57
+ # invalid - missing `month` |
58
+ # | monthly | 6 | august | 12 |
59
+ # invalid - `month` must be blank |
60
+ # | weekly | 2 | october | 10 |
61
+ # invalid - `month` and `day_of_month` must be blank |
57
62
  #
58
63
  # ### Rolling dates
59
64
  #
@@ -73,6 +78,7 @@ module GoCardlessPro
73
78
  attr_reader :created_at
74
79
  attr_reader :currency
75
80
  attr_reader :day_of_month
81
+ attr_reader :earliest_charge_date_after_resume
76
82
  attr_reader :end_date
77
83
  attr_reader :id
78
84
  attr_reader :interval
@@ -97,6 +103,7 @@ module GoCardlessPro
97
103
  @created_at = object['created_at']
98
104
  @currency = object['currency']
99
105
  @day_of_month = object['day_of_month']
106
+ @earliest_charge_date_after_resume = object['earliest_charge_date_after_resume']
100
107
  @end_date = object['end_date']
101
108
  @id = object['id']
102
109
  @interval = object['interval']
@@ -123,8 +123,7 @@ module GoCardlessPro
123
123
  # ID.
124
124
  #
125
125
  # <p class="restricted-notice"><strong>The action of removing a customer cannot
126
- # be
127
- # reversed, so please use with care.</strong></p>
126
+ # be reversed, so please use with care.</strong></p>
128
127
  # Example URL: /customers/:identity
129
128
  #
130
129
  # @param identity # Unique identifier, beginning with "CU".
@@ -162,6 +162,27 @@ module GoCardlessPro
162
162
  Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
163
163
  end
164
164
 
165
+ # Updates an instalment schedule. This accepts only the metadata parameter.
166
+ # Example URL: /instalment_schedules/:identity
167
+ #
168
+ # @param identity # Unique identifier, beginning with "IS".
169
+ # @param options [Hash] parameters as a hash, under a params key.
170
+ def update(identity, options = {})
171
+ path = sub_url('/instalment_schedules/:identity', 'identity' => identity)
172
+
173
+ params = options.delete(:params) || {}
174
+ options[:params] = {}
175
+ options[:params][envelope_key] = params
176
+
177
+ options[:retry_failures] = true
178
+
179
+ response = make_request(:put, path, options)
180
+
181
+ return if response.body.nil?
182
+
183
+ Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
184
+ end
185
+
165
186
  # Immediately cancels an instalment schedule; no further payments will be
166
187
  # collected for it.
167
188
  #
@@ -172,7 +172,7 @@ module GoCardlessPro
172
172
  # This will fail with a `mandate_not_inactive` error if the mandate is already
173
173
  # being submitted, or is active.
174
174
  #
175
- # Mandates can be resubmitted up to 3 times.
175
+ # Mandates can be resubmitted up to 10 times.
176
176
  # Example URL: /mandates/:identity/actions/reinstate
177
177
  #
178
178
  # @param identity # Unique identifier, beginning with "MD". Note that this prefix may not
@@ -59,6 +59,27 @@ module GoCardlessPro
59
59
  Resources::Payout.new(unenvelope_body(response.body), response)
60
60
  end
61
61
 
62
+ # Updates a payout object. This accepts only the metadata parameter.
63
+ # Example URL: /payouts/:identity
64
+ #
65
+ # @param identity # Unique identifier, beginning with "PO".
66
+ # @param options [Hash] parameters as a hash, under a params key.
67
+ def update(identity, options = {})
68
+ path = sub_url('/payouts/:identity', 'identity' => identity)
69
+
70
+ params = options.delete(:params) || {}
71
+ options[:params] = {}
72
+ options[:params][envelope_key] = params
73
+
74
+ options[:retry_failures] = true
75
+
76
+ response = make_request(:put, path, options)
77
+
78
+ return if response.body.nil?
79
+
80
+ Resources::Payout.new(unenvelope_body(response.body), response)
81
+ end
82
+
62
83
  private
63
84
 
64
85
  # Unenvelope the response of the body using the service's `envelope_key`
@@ -138,6 +138,135 @@ module GoCardlessPro
138
138
  Resources::Subscription.new(unenvelope_body(response.body), response)
139
139
  end
140
140
 
141
+ # Pause a subscription object.
142
+ # No payments will be created until it is resumed.
143
+ #
144
+ # This can only be used when a subscription collecting a fixed number of
145
+ # payments (created using `count`)
146
+ # or when they continue forever (created without `count` or `end_date`)
147
+ #
148
+ # When `pause_cycles` is omitted the subscription is paused until the [resume
149
+ # endpoint](#subscriptions-resume-a-subscription) is called.
150
+ # If the subscription is collecting a fixed number of payments, `end_date` will
151
+ # be set to `nil`.
152
+ # When paused indefinitely, `upcoming_payments` will be empty.
153
+ #
154
+ # When `pause_cycles` is provided the subscription will be paused for the number
155
+ # of cycles requested.
156
+ # If the subscription is collecting a fixed number of payments, `end_date` will
157
+ # be set to a new value.
158
+ # When paused for a number of cycles, `upcoming_payments` will still contain the
159
+ # upcoming charge dates.
160
+ #
161
+ # This fails with:
162
+ #
163
+ # - `forbidden` if the subscription was created by an app and you are not
164
+ # authenticated as that app, or if the subscription was not created by an app
165
+ # and you are authenticated as an app
166
+ #
167
+ # - `validation_failed` if invalid data is provided when attempting to pause a
168
+ # subscription.
169
+ #
170
+ # - `subscription_not_active` if the subscription is no longer active.
171
+ #
172
+ # - `subscription_already_ended` if the subscription has taken all payments.
173
+ #
174
+ # - `pause_cycles_must_be_greater_than_or_equal_to` if the provided value for
175
+ # `pause_cycles` cannot be satisfied.
176
+ #
177
+ # Example URL: /subscriptions/:identity/actions/pause
178
+ #
179
+ # @param identity # Unique identifier, beginning with "SB".
180
+ # @param options [Hash] parameters as a hash, under a params key.
181
+ def pause(identity, options = {})
182
+ path = sub_url('/subscriptions/:identity/actions/pause', 'identity' => identity)
183
+
184
+ params = options.delete(:params) || {}
185
+ options[:params] = {}
186
+ options[:params]['data'] = params
187
+
188
+ options[:retry_failures] = false
189
+
190
+ begin
191
+ response = make_request(:post, path, options)
192
+
193
+ # Response doesn't raise any errors until #body is called
194
+ response.tap(&:body)
195
+ rescue InvalidStateError => e
196
+ if e.idempotent_creation_conflict?
197
+ case @api_service.on_idempotency_conflict
198
+ when :raise
199
+ raise IdempotencyConflict, e.error
200
+ when :fetch
201
+ return get(e.conflicting_resource_id)
202
+ else
203
+ raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
204
+ end
205
+ end
206
+
207
+ raise e
208
+ end
209
+
210
+ return if response.body.nil?
211
+
212
+ Resources::Subscription.new(unenvelope_body(response.body), response)
213
+ end
214
+
215
+ # Resume a subscription object.
216
+ # Payments will start to be created again based on the subscriptions recurrence
217
+ # rules.
218
+ # The `charge_date` on the next payment will be the same as the subscriptions
219
+ # `earliest_charge_date_after_resume`
220
+ #
221
+ # This fails with:
222
+ #
223
+ # - `forbidden` if the subscription was created by an app and you are not
224
+ # authenticated as that app, or if the subscription was not created by an app
225
+ # and you are authenticated as an app
226
+ #
227
+ # - `validation_failed` if invalid data is provided when attempting to resume a
228
+ # subscription.
229
+ #
230
+ # - `subscription_not_paused` if the subscription is not paused.
231
+ #
232
+ # Example URL: /subscriptions/:identity/actions/resume
233
+ #
234
+ # @param identity # Unique identifier, beginning with "SB".
235
+ # @param options [Hash] parameters as a hash, under a params key.
236
+ def resume(identity, options = {})
237
+ path = sub_url('/subscriptions/:identity/actions/resume', 'identity' => identity)
238
+
239
+ params = options.delete(:params) || {}
240
+ options[:params] = {}
241
+ options[:params]['data'] = params
242
+
243
+ options[:retry_failures] = false
244
+
245
+ begin
246
+ response = make_request(:post, path, options)
247
+
248
+ # Response doesn't raise any errors until #body is called
249
+ response.tap(&:body)
250
+ rescue InvalidStateError => e
251
+ if e.idempotent_creation_conflict?
252
+ case @api_service.on_idempotency_conflict
253
+ when :raise
254
+ raise IdempotencyConflict, e.error
255
+ when :fetch
256
+ return get(e.conflicting_resource_id)
257
+ else
258
+ raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
259
+ end
260
+ end
261
+
262
+ raise e
263
+ end
264
+
265
+ return if response.body.nil?
266
+
267
+ Resources::Subscription.new(unenvelope_body(response.body), response)
268
+ end
269
+
141
270
  # Immediately cancels a subscription; no more payments will be created under it.
142
271
  # Any metadata supplied to this endpoint will be stored on the payment
143
272
  # cancellation event it causes.