gocardless_pro 2.17.1 → 2.21.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.
- checksums.yaml +4 -4
- data/lib/gocardless_pro.rb +3 -0
- data/lib/gocardless_pro/client.rb +6 -1
- data/lib/gocardless_pro/resources/creditor_bank_account.rb +1 -2
- data/lib/gocardless_pro/resources/currency_exchange_rate.rb +44 -0
- data/lib/gocardless_pro/resources/customer_notification.rb +3 -5
- data/lib/gocardless_pro/resources/event.rb +2 -1
- data/lib/gocardless_pro/resources/mandate_import.rb +5 -8
- data/lib/gocardless_pro/resources/mandate_import_entry.rb +3 -5
- data/lib/gocardless_pro/resources/payout.rb +2 -0
- data/lib/gocardless_pro/resources/redirect_flow.rb +2 -0
- data/lib/gocardless_pro/resources/subscription.rb +38 -29
- data/lib/gocardless_pro/services/currency_exchange_rates_service.rb +67 -0
- data/lib/gocardless_pro/services/customers_service.rb +1 -2
- data/lib/gocardless_pro/services/instalment_schedules_service.rb +81 -5
- data/lib/gocardless_pro/services/mandates_service.rb +1 -1
- data/lib/gocardless_pro/services/payouts_service.rb +21 -0
- data/lib/gocardless_pro/services/subscriptions_service.rb +129 -0
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/resources/currency_exchange_rate_spec.rb +103 -0
- data/spec/resources/instalment_schedule_spec.rb +193 -1
- data/spec/resources/payout_spec.rb +45 -0
- data/spec/resources/redirect_flow_spec.rb +9 -0
- data/spec/resources/subscription_spec.rb +210 -0
- data/spec/services/currency_exchange_rates_service_spec.rb +223 -0
- data/spec/services/instalment_schedules_service_spec.rb +270 -1
- data/spec/services/payouts_service_spec.rb +74 -0
- data/spec/services/redirect_flows_service_spec.rb +9 -0
- data/spec/services/subscriptions_service_spec.rb +240 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c285e5a1284e099a2840ea4dfb7a8282a73a38aa0def7e81f522654b4be5922
|
4
|
+
data.tar.gz: 0443f073f12c0c6d69029a4a79d28634978274e73b6d1bc0a1517066c44b66e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf2401b3823b41bd1d562a80f0e7a8b0847a86f04e1ec29ad2e55b3caf814e39ea379f0686c6108b91de81701b8cebc697e0bd1f7cd4741c44176785c01bcc27
|
7
|
+
data.tar.gz: f8aa9bd7ff1c8f969d54ae654b324395572459ec065e603601dbe5eb9a38ec61852724820dc8423bc7407e47004434dcee4b880b3a4d2678086b0f0729dece07
|
data/lib/gocardless_pro.rb
CHANGED
@@ -47,6 +47,9 @@ require_relative 'gocardless_pro/services/creditors_service'
|
|
47
47
|
require_relative 'gocardless_pro/resources/creditor_bank_account'
|
48
48
|
require_relative 'gocardless_pro/services/creditor_bank_accounts_service'
|
49
49
|
|
50
|
+
require_relative 'gocardless_pro/resources/currency_exchange_rate'
|
51
|
+
require_relative 'gocardless_pro/services/currency_exchange_rates_service'
|
52
|
+
|
50
53
|
require_relative 'gocardless_pro/resources/customer'
|
51
54
|
require_relative 'gocardless_pro/services/customers_service'
|
52
55
|
|
@@ -18,6 +18,11 @@ module GoCardlessPro
|
|
18
18
|
@creditor_bank_accounts ||= Services::CreditorBankAccountsService.new(@api_service)
|
19
19
|
end
|
20
20
|
|
21
|
+
# Access to the service for currency_exchange_rate to make API calls
|
22
|
+
def currency_exchange_rates
|
23
|
+
@currency_exchange_rates ||= Services::CurrencyExchangeRatesService.new(@api_service)
|
24
|
+
end
|
25
|
+
|
21
26
|
# Access to the service for customer to make API calls
|
22
27
|
def customers
|
23
28
|
@customers ||= Services::CustomersService.new(@api_service)
|
@@ -143,7 +148,7 @@ module GoCardlessPro
|
|
143
148
|
'User-Agent' => user_agent.to_s,
|
144
149
|
'Content-Type' => 'application/json',
|
145
150
|
'GoCardless-Client-Library' => 'gocardless-pro-ruby',
|
146
|
-
'GoCardless-Client-Version' => '2.
|
151
|
+
'GoCardless-Client-Version' => '2.21.0',
|
147
152
|
},
|
148
153
|
}
|
149
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
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#
|
4
|
+
# This client is automatically generated from a template and JSON schema definition.
|
5
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module GoCardlessPro
|
11
|
+
# A module containing classes for each of the resources in the GC Api
|
12
|
+
module Resources
|
13
|
+
# Represents an instance of a currency_exchange_rate resource returned from the API
|
14
|
+
|
15
|
+
# Currency exchange rates from our foreign exchange provider.
|
16
|
+
class CurrencyExchangeRate
|
17
|
+
attr_reader :rate
|
18
|
+
attr_reader :source
|
19
|
+
attr_reader :target
|
20
|
+
attr_reader :time
|
21
|
+
|
22
|
+
# Initialize a currency_exchange_rate resource instance
|
23
|
+
# @param object [Hash] an object returned from the API
|
24
|
+
def initialize(object, response = nil)
|
25
|
+
@object = object
|
26
|
+
|
27
|
+
@rate = object['rate']
|
28
|
+
@source = object['source']
|
29
|
+
@target = object['target']
|
30
|
+
@time = object['time']
|
31
|
+
@response = response
|
32
|
+
end
|
33
|
+
|
34
|
+
def api_response
|
35
|
+
ApiResponse.new(@response)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Provides the currency_exchange_rate resource as a hash of all its readable attributes
|
39
|
+
def to_h
|
40
|
+
@object
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -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
|
-
#
|
28
|
-
#
|
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
|
-
#
|
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
|
-
#
|
58
|
-
#
|
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
|
-
#
|
44
|
-
#
|
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
|
-
# -
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
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
|
-
# |
|
29
|
-
#
|
30
|
-
# |
|
31
|
-
#
|
32
|
-
# | yearly
|
33
|
-
# optional (
|
34
|
-
# | monthly
|
35
|
-
#
|
36
|
-
# | weekly
|
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
|
-
# |
|
42
|
-
#
|
43
|
-
# |
|
42
|
+
# | __interval_unit__ | __interval__ | __month__ | __day_of_month__ | valid?
|
43
|
+
# |
|
44
|
+
# | :---------------- | :----------- | :-------- | :--------------- |
|
44
45
|
# :------------------------------------------------- |
|
45
|
-
# | yearly
|
46
|
-
#
|
47
|
-
# |
|
48
|
-
#
|
49
|
-
# | monthly
|
50
|
-
#
|
51
|
-
# |
|
52
|
-
#
|
53
|
-
# |
|
54
|
-
#
|
55
|
-
# |
|
56
|
-
#
|
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
|
#
|
@@ -69,9 +74,11 @@ module GoCardlessPro
|
|
69
74
|
class Subscription
|
70
75
|
attr_reader :amount
|
71
76
|
attr_reader :app_fee
|
77
|
+
attr_reader :count
|
72
78
|
attr_reader :created_at
|
73
79
|
attr_reader :currency
|
74
80
|
attr_reader :day_of_month
|
81
|
+
attr_reader :earliest_charge_date_after_resume
|
75
82
|
attr_reader :end_date
|
76
83
|
attr_reader :id
|
77
84
|
attr_reader :interval
|
@@ -92,9 +99,11 @@ module GoCardlessPro
|
|
92
99
|
|
93
100
|
@amount = object['amount']
|
94
101
|
@app_fee = object['app_fee']
|
102
|
+
@count = object['count']
|
95
103
|
@created_at = object['created_at']
|
96
104
|
@currency = object['currency']
|
97
105
|
@day_of_month = object['day_of_month']
|
106
|
+
@earliest_charge_date_after_resume = object['earliest_charge_date_after_resume']
|
98
107
|
@end_date = object['end_date']
|
99
108
|
@id = object['id']
|
100
109
|
@interval = object['interval']
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require_relative './base_service'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
# encoding: utf-8
|
5
|
+
#
|
6
|
+
# This client is automatically generated from a template and JSON schema definition.
|
7
|
+
# See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
|
8
|
+
#
|
9
|
+
|
10
|
+
module GoCardlessPro
|
11
|
+
module Services
|
12
|
+
# Service for making requests to the CurrencyExchangeRate endpoints
|
13
|
+
class CurrencyExchangeRatesService < BaseService
|
14
|
+
# Returns a [cursor-paginated](#api-usage-cursor-pagination) list of all
|
15
|
+
# exchange rates.
|
16
|
+
# Example URL: /currency_exchange_rates
|
17
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
18
|
+
def list(options = {})
|
19
|
+
path = '/currency_exchange_rates'
|
20
|
+
|
21
|
+
options[:retry_failures] = true
|
22
|
+
|
23
|
+
response = make_request(:get, path, options)
|
24
|
+
|
25
|
+
ListResponse.new(
|
26
|
+
response: response,
|
27
|
+
unenveloped_body: unenvelope_body(response.body),
|
28
|
+
resource_class: Resources::CurrencyExchangeRate
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
|
33
|
+
#
|
34
|
+
# @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
|
35
|
+
# Otherwise they will be the body of the request.
|
36
|
+
def all(options = {})
|
37
|
+
Paginator.new(
|
38
|
+
service: self,
|
39
|
+
options: options
|
40
|
+
).enumerator
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
46
|
+
#
|
47
|
+
# @param body [Hash]
|
48
|
+
def unenvelope_body(body)
|
49
|
+
body[envelope_key] || body['data']
|
50
|
+
end
|
51
|
+
|
52
|
+
# return the key which API responses will envelope data under
|
53
|
+
def envelope_key
|
54
|
+
'currency_exchange_rates'
|
55
|
+
end
|
56
|
+
|
57
|
+
# take a URL with placeholder params and substitute them out for the actual value
|
58
|
+
# @param url [String] the URL with placeholders in
|
59
|
+
# @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
|
60
|
+
def sub_url(url, param_map)
|
61
|
+
param_map.reduce(url) do |new_url, (param, value)|
|
62
|
+
new_url.gsub(":#{param}", URI.escape(value))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -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".
|
@@ -12,11 +12,66 @@ module GoCardlessPro
|
|
12
12
|
# Service for making requests to the InstalmentSchedule endpoints
|
13
13
|
class InstalmentSchedulesService < BaseService
|
14
14
|
# Creates a new instalment schedule object, along with the associated payments.
|
15
|
+
# This
|
16
|
+
# API is recommended if you know the specific dates you wish to charge.
|
17
|
+
# Otherwise,
|
18
|
+
# please check out the [scheduling
|
19
|
+
# version](#instalment-schedules-create-with-schedule).
|
15
20
|
#
|
16
|
-
# The `instalments` property
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
21
|
+
# The `instalments` property is an array of payment properties (`amount` and
|
22
|
+
# `charge_date`).
|
23
|
+
#
|
24
|
+
# It can take quite a while to create the associated payments, so the API will
|
25
|
+
# return
|
26
|
+
# the status as `pending` initially. When processing has completed, a subsequent
|
27
|
+
# GET
|
28
|
+
# request for the instalment schedule will either have the status `success` and
|
29
|
+
# link
|
30
|
+
# to the created payments, or the status `error` and detailed information about
|
31
|
+
# the
|
32
|
+
# failures.
|
33
|
+
# Example URL: /instalment_schedules
|
34
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
35
|
+
def create_with_dates(options = {})
|
36
|
+
path = '/instalment_schedules'
|
37
|
+
|
38
|
+
params = options.delete(:params) || {}
|
39
|
+
options[:params] = {}
|
40
|
+
options[:params][envelope_key] = params
|
41
|
+
|
42
|
+
options[:retry_failures] = true
|
43
|
+
|
44
|
+
begin
|
45
|
+
response = make_request(:post, path, options)
|
46
|
+
|
47
|
+
# Response doesn't raise any errors until #body is called
|
48
|
+
response.tap(&:body)
|
49
|
+
rescue InvalidStateError => e
|
50
|
+
if e.idempotent_creation_conflict?
|
51
|
+
case @api_service.on_idempotency_conflict
|
52
|
+
when :raise
|
53
|
+
raise IdempotencyConflict, e.error
|
54
|
+
when :fetch
|
55
|
+
return get(e.conflicting_resource_id)
|
56
|
+
else
|
57
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
raise e
|
62
|
+
end
|
63
|
+
|
64
|
+
return if response.body.nil?
|
65
|
+
|
66
|
+
Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Creates a new instalment schedule object, along with the associated payments.
|
70
|
+
# This
|
71
|
+
# API is recommended if you wish to use the GoCardless scheduling logic. For
|
72
|
+
# finer
|
73
|
+
# control over the individual dates, please check out the [alternative
|
74
|
+
# version](#instalment-schedules-create-with-dates).
|
20
75
|
#
|
21
76
|
# It can take quite a while to create the associated payments, so the API will
|
22
77
|
# return
|
@@ -27,7 +82,7 @@ module GoCardlessPro
|
|
27
82
|
# failures.
|
28
83
|
# Example URL: /instalment_schedules
|
29
84
|
# @param options [Hash] parameters as a hash, under a params key.
|
30
|
-
def
|
85
|
+
def create_with_schedule(options = {})
|
31
86
|
path = '/instalment_schedules'
|
32
87
|
|
33
88
|
params = options.delete(:params) || {}
|
@@ -107,6 +162,27 @@ module GoCardlessPro
|
|
107
162
|
Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
|
108
163
|
end
|
109
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
|
+
|
110
186
|
# Immediately cancels an instalment schedule; no further payments will be
|
111
187
|
# collected for it.
|
112
188
|
#
|