gocardless_pro 2.15.1 → 2.16.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/README.md +10 -0
- data/lib/gocardless_pro/client.rb +6 -1
- data/lib/gocardless_pro/resources/event.rb +4 -0
- data/lib/gocardless_pro/resources/instalment_schedule.rb +92 -0
- data/lib/gocardless_pro/resources/payment.rb +4 -0
- data/lib/gocardless_pro/resources/refund.rb +2 -0
- data/lib/gocardless_pro/services/instalment_schedules_service.rb +177 -0
- data/lib/gocardless_pro/version.rb +1 -1
- data/lib/gocardless_pro.rb +3 -0
- data/spec/resources/instalment_schedule_spec.rb +442 -0
- data/spec/resources/refund_spec.rb +13 -0
- data/spec/services/instalment_schedules_service_spec.rb +700 -0
- data/spec/services/refunds_service_spec.rb +17 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 396dcbfc132b43e7d8d8a29bed742fe7eea6a097b143182761f68847a2ab0879
|
4
|
+
data.tar.gz: c3b2f53f38baf4a182eefec78be40e55ad21d9ec45b0a6a3169824859fe7a1af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8077e0c81cb8c2c2c51aca0d9d76d855be60aede0ef86bc87ea3d6be03bb13fda37002f4913621919478b07e9c2eabf491e6d551d5e59bc6cf80d7e7288955f8
|
7
|
+
data.tar.gz: e33ffac591f5657eb93172d866ecdda2105a452e066e7eabc0fc1b9d14dc59241f5f8b6b2a3e090d38afae4023cb3a280699307e332f4b4bd342d0f38715604c
|
data/README.md
CHANGED
@@ -120,6 +120,16 @@ When creating a resource, the library will automatically include a randomly-gene
|
|
120
120
|
[idempotency key](https://developer.gocardless.com/api-reference/#making-requests-idempotency-keys)
|
121
121
|
- this means that if a request appears to fail but is in fact successful (for example due
|
122
122
|
to a timeout), you will not end up creating multiple duplicates of the resource.
|
123
|
+
- By default if a request results in an Idempotency Key conflict
|
124
|
+
the library will make a second request and return the object that was
|
125
|
+
originally created with the Idempotency Key. If you wish, you can instead configure
|
126
|
+
the client to raise the conflict for you to handle. e.g
|
127
|
+
```
|
128
|
+
@client = GoCardlessPro::Client.new(
|
129
|
+
access_token: ENV["GOCARDLESS_TOKEN"],
|
130
|
+
on_idempotency_conflict: :raise,
|
131
|
+
)
|
132
|
+
```
|
123
133
|
|
124
134
|
If any parameters are required they come first:
|
125
135
|
|
@@ -38,6 +38,11 @@ module GoCardlessPro
|
|
38
38
|
@events ||= Services::EventsService.new(@api_service)
|
39
39
|
end
|
40
40
|
|
41
|
+
# Access to the service for instalment_schedule to make API calls
|
42
|
+
def instalment_schedules
|
43
|
+
@instalment_schedules ||= Services::InstalmentSchedulesService.new(@api_service)
|
44
|
+
end
|
45
|
+
|
41
46
|
# Access to the service for mandate to make API calls
|
42
47
|
def mandates
|
43
48
|
@mandates ||= Services::MandatesService.new(@api_service)
|
@@ -138,7 +143,7 @@ module GoCardlessPro
|
|
138
143
|
'User-Agent' => user_agent.to_s,
|
139
144
|
'Content-Type' => 'application/json',
|
140
145
|
'GoCardless-Client-Library' => 'gocardless-pro-ruby',
|
141
|
-
'GoCardless-Client-Version' => '2.
|
146
|
+
'GoCardless-Client-Version' => '2.16.0',
|
142
147
|
},
|
143
148
|
}
|
144
149
|
end
|
@@ -0,0 +1,92 @@
|
|
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 instalment_schedule resource returned from the API
|
14
|
+
|
15
|
+
# Instalment schedules are objects which represent a collection of related
|
16
|
+
# payments, with the
|
17
|
+
# intention to collect the `total_amount` specified. The API supports both
|
18
|
+
# schedule-based
|
19
|
+
# creation (similar to subscriptions) as well as explicit selection of
|
20
|
+
# differing payment
|
21
|
+
# amounts and charge dates.
|
22
|
+
#
|
23
|
+
# Unlike subscriptions, the payments are created immediately, so the
|
24
|
+
# instalment schedule
|
25
|
+
# cannot be modified once submitted and instead can only be cancelled (which
|
26
|
+
# will cancel
|
27
|
+
# any of the payments which have not yet been submitted).
|
28
|
+
#
|
29
|
+
# Customers will receive a single notification about the complete schedule
|
30
|
+
# of collection.
|
31
|
+
#
|
32
|
+
class InstalmentSchedule
|
33
|
+
attr_reader :created_at
|
34
|
+
attr_reader :currency
|
35
|
+
attr_reader :id
|
36
|
+
attr_reader :metadata
|
37
|
+
attr_reader :name
|
38
|
+
attr_reader :payment_errors
|
39
|
+
attr_reader :status
|
40
|
+
attr_reader :total_amount
|
41
|
+
|
42
|
+
# Initialize a instalment_schedule resource instance
|
43
|
+
# @param object [Hash] an object returned from the API
|
44
|
+
def initialize(object, response = nil)
|
45
|
+
@object = object
|
46
|
+
|
47
|
+
@created_at = object['created_at']
|
48
|
+
@currency = object['currency']
|
49
|
+
@id = object['id']
|
50
|
+
@links = object['links']
|
51
|
+
@metadata = object['metadata']
|
52
|
+
@name = object['name']
|
53
|
+
@payment_errors = object['payment_errors']
|
54
|
+
@status = object['status']
|
55
|
+
@total_amount = object['total_amount']
|
56
|
+
@response = response
|
57
|
+
end
|
58
|
+
|
59
|
+
def api_response
|
60
|
+
ApiResponse.new(@response)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return the links that the resource has
|
64
|
+
def links
|
65
|
+
@instalment_schedule_links ||= Links.new(@links)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Provides the instalment_schedule resource as a hash of all its readable attributes
|
69
|
+
def to_h
|
70
|
+
@object
|
71
|
+
end
|
72
|
+
|
73
|
+
class Links
|
74
|
+
def initialize(links)
|
75
|
+
@links = links || {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def customer
|
79
|
+
@links['customer']
|
80
|
+
end
|
81
|
+
|
82
|
+
def mandate
|
83
|
+
@links['mandate']
|
84
|
+
end
|
85
|
+
|
86
|
+
def payments
|
87
|
+
@links['payments']
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -27,6 +27,7 @@ module GoCardlessPro
|
|
27
27
|
attr_reader :id
|
28
28
|
attr_reader :metadata
|
29
29
|
attr_reader :reference
|
30
|
+
attr_reader :status
|
30
31
|
|
31
32
|
# Initialize a refund resource instance
|
32
33
|
# @param object [Hash] an object returned from the API
|
@@ -41,6 +42,7 @@ module GoCardlessPro
|
|
41
42
|
@links = object['links']
|
42
43
|
@metadata = object['metadata']
|
43
44
|
@reference = object['reference']
|
45
|
+
@status = object['status']
|
44
46
|
@response = response
|
45
47
|
end
|
46
48
|
|
@@ -0,0 +1,177 @@
|
|
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 InstalmentSchedule endpoints
|
13
|
+
class InstalmentSchedulesService < BaseService
|
14
|
+
# Creates a new instalment schedule object, along with the associated payments.
|
15
|
+
#
|
16
|
+
# The `instalments` property can either be an array of payment properties
|
17
|
+
# (`amount`
|
18
|
+
# and `charge_date`) or a schedule object with `interval`, `interval_unit` and
|
19
|
+
# `amounts`.
|
20
|
+
#
|
21
|
+
# It can take quite a while to create the associated payments, so the API will
|
22
|
+
# return
|
23
|
+
# the status as `pending` initially. When processing has completed, a subsequent
|
24
|
+
# GET request for the instalment schedule will either have the status `success`
|
25
|
+
# and link to
|
26
|
+
# the created payments, or the status `error` and detailed information about the
|
27
|
+
# failures.
|
28
|
+
# Example URL: /instalment_schedules
|
29
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
30
|
+
def create(options = {})
|
31
|
+
path = '/instalment_schedules'
|
32
|
+
|
33
|
+
params = options.delete(:params) || {}
|
34
|
+
options[:params] = {}
|
35
|
+
options[:params][envelope_key] = params
|
36
|
+
|
37
|
+
options[:retry_failures] = true
|
38
|
+
|
39
|
+
begin
|
40
|
+
response = make_request(:post, path, options)
|
41
|
+
|
42
|
+
# Response doesn't raise any errors until #body is called
|
43
|
+
response.tap(&:body)
|
44
|
+
rescue InvalidStateError => e
|
45
|
+
if e.idempotent_creation_conflict?
|
46
|
+
case @api_service.on_idempotency_conflict
|
47
|
+
when :raise
|
48
|
+
raise IdempotencyConflict, e.error
|
49
|
+
when :fetch
|
50
|
+
return get(e.conflicting_resource_id)
|
51
|
+
else
|
52
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
raise e
|
57
|
+
end
|
58
|
+
|
59
|
+
return if response.body.nil?
|
60
|
+
|
61
|
+
Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your
|
65
|
+
# instalment schedules.
|
66
|
+
# Example URL: /instalment_schedules
|
67
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
68
|
+
def list(options = {})
|
69
|
+
path = '/instalment_schedules'
|
70
|
+
|
71
|
+
options[:retry_failures] = true
|
72
|
+
|
73
|
+
response = make_request(:get, path, options)
|
74
|
+
|
75
|
+
ListResponse.new(
|
76
|
+
response: response,
|
77
|
+
unenveloped_body: unenvelope_body(response.body),
|
78
|
+
resource_class: Resources::InstalmentSchedule
|
79
|
+
)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
|
83
|
+
#
|
84
|
+
# @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
|
85
|
+
# Otherwise they will be the body of the request.
|
86
|
+
def all(options = {})
|
87
|
+
Paginator.new(
|
88
|
+
service: self,
|
89
|
+
options: options
|
90
|
+
).enumerator
|
91
|
+
end
|
92
|
+
|
93
|
+
# Retrieves the details of an existing instalment schedule.
|
94
|
+
# Example URL: /instalment_schedules/:identity
|
95
|
+
#
|
96
|
+
# @param identity # Unique identifier, beginning with "IS".
|
97
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
98
|
+
def get(identity, options = {})
|
99
|
+
path = sub_url('/instalment_schedules/:identity', 'identity' => identity)
|
100
|
+
|
101
|
+
options[:retry_failures] = true
|
102
|
+
|
103
|
+
response = make_request(:get, path, options)
|
104
|
+
|
105
|
+
return if response.body.nil?
|
106
|
+
|
107
|
+
Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Immediately cancels an instalment schedule; no further payments will be
|
111
|
+
# collected for it.
|
112
|
+
#
|
113
|
+
# This will fail with a `cancellation_failed` error if the instalment schedule
|
114
|
+
# is already cancelled or has completed.
|
115
|
+
# Example URL: /instalment_schedules/:identity/actions/cancel
|
116
|
+
#
|
117
|
+
# @param identity # Unique identifier, beginning with "IS".
|
118
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
119
|
+
def cancel(identity, options = {})
|
120
|
+
path = sub_url('/instalment_schedules/:identity/actions/cancel', 'identity' => identity)
|
121
|
+
|
122
|
+
params = options.delete(:params) || {}
|
123
|
+
options[:params] = {}
|
124
|
+
options[:params]['data'] = params
|
125
|
+
|
126
|
+
options[:retry_failures] = false
|
127
|
+
|
128
|
+
begin
|
129
|
+
response = make_request(:post, path, options)
|
130
|
+
|
131
|
+
# Response doesn't raise any errors until #body is called
|
132
|
+
response.tap(&:body)
|
133
|
+
rescue InvalidStateError => e
|
134
|
+
if e.idempotent_creation_conflict?
|
135
|
+
case @api_service.on_idempotency_conflict
|
136
|
+
when :raise
|
137
|
+
raise IdempotencyConflict, e.error
|
138
|
+
when :fetch
|
139
|
+
return get(e.conflicting_resource_id)
|
140
|
+
else
|
141
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
raise e
|
146
|
+
end
|
147
|
+
|
148
|
+
return if response.body.nil?
|
149
|
+
|
150
|
+
Resources::InstalmentSchedule.new(unenvelope_body(response.body), response)
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
156
|
+
#
|
157
|
+
# @param body [Hash]
|
158
|
+
def unenvelope_body(body)
|
159
|
+
body[envelope_key] || body['data']
|
160
|
+
end
|
161
|
+
|
162
|
+
# return the key which API responses will envelope data under
|
163
|
+
def envelope_key
|
164
|
+
'instalment_schedules'
|
165
|
+
end
|
166
|
+
|
167
|
+
# take a URL with placeholder params and substitute them out for the actual value
|
168
|
+
# @param url [String] the URL with placeholders in
|
169
|
+
# @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
|
170
|
+
def sub_url(url, param_map)
|
171
|
+
param_map.reduce(url) do |new_url, (param, value)|
|
172
|
+
new_url.gsub(":#{param}", URI.escape(value))
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/lib/gocardless_pro.rb
CHANGED
@@ -59,6 +59,9 @@ require_relative 'gocardless_pro/services/customer_notifications_service'
|
|
59
59
|
require_relative 'gocardless_pro/resources/event'
|
60
60
|
require_relative 'gocardless_pro/services/events_service'
|
61
61
|
|
62
|
+
require_relative 'gocardless_pro/resources/instalment_schedule'
|
63
|
+
require_relative 'gocardless_pro/services/instalment_schedules_service'
|
64
|
+
|
62
65
|
require_relative 'gocardless_pro/resources/mandate'
|
63
66
|
require_relative 'gocardless_pro/services/mandates_service'
|
64
67
|
|