gocardless_pro 2.12.0 → 2.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +50 -0
- data/README.md +15 -1
- data/gocardless_pro.gemspec +2 -0
- data/lib/gocardless_pro.rb +3 -0
- data/lib/gocardless_pro/api_service.rb +3 -0
- data/lib/gocardless_pro/client.rb +6 -1
- data/lib/gocardless_pro/error/invalid_state_error.rb +2 -0
- data/lib/gocardless_pro/resources/creditor.rb +4 -0
- data/lib/gocardless_pro/resources/customer.rb +5 -0
- data/lib/gocardless_pro/resources/customer_notification.rb +97 -0
- data/lib/gocardless_pro/resources/event.rb +2 -0
- data/lib/gocardless_pro/resources/mandate_import.rb +1 -1
- data/lib/gocardless_pro/resources/mandate_import_entry.rb +1 -1
- data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +20 -2
- data/lib/gocardless_pro/services/creditors_service.rb +10 -1
- data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +20 -2
- data/lib/gocardless_pro/services/customer_notifications_service.rb +66 -0
- data/lib/gocardless_pro/services/customers_service.rb +10 -1
- data/lib/gocardless_pro/services/mandate_imports_service.rb +40 -6
- data/lib/gocardless_pro/services/mandates_service.rb +30 -3
- data/lib/gocardless_pro/services/payments_service.rb +30 -3
- data/lib/gocardless_pro/services/redirect_flows_service.rb +20 -2
- data/lib/gocardless_pro/services/refunds_service.rb +11 -6
- data/lib/gocardless_pro/services/subscriptions_service.rb +20 -2
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/resources/customer_notification_spec.rb +73 -0
- data/spec/resources/customer_spec.rb +13 -0
- data/spec/resources/event_spec.rb +7 -0
- data/spec/services/creditor_bank_accounts_service_spec.rb +33 -4
- data/spec/services/creditors_service_spec.rb +33 -4
- data/spec/services/customer_bank_accounts_service_spec.rb +33 -4
- data/spec/services/customer_notifications_service_spec.rb +84 -0
- data/spec/services/customers_service_spec.rb +50 -4
- data/spec/services/events_service_spec.rb +11 -0
- data/spec/services/mandate_imports_service_spec.rb +33 -4
- data/spec/services/mandates_service_spec.rb +33 -4
- data/spec/services/payments_service_spec.rb +33 -4
- data/spec/services/redirect_flows_service_spec.rb +33 -4
- data/spec/services/refunds_service_spec.rb +33 -4
- data/spec/services/subscriptions_service_spec.rb +33 -4
- metadata +23 -3
- data/circle.yml +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fd702df303218fec5c4bc90ad731762d95c78a57df3c5f4c74dd2cec45e1c61
|
4
|
+
data.tar.gz: f7de4d6744ee3c86a191b9649ca921d468ba64740031612670ee558d2d67f81d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51f15a425b95e8a38a957f4d875fbc8518c452e32f5a1d118866981aca16d7d4ebdecae96006b1cdb4adbb9d276184e2953d2991085a42004bf074019791281c
|
7
|
+
data.tar.gz: 4c39f5eb990e649758ab981b20e9b74dda3a322de0e94a51f1765551db0d33792a705bd1377b511d0f1b4e8deda500676a2abe9f45160ffe80c0a2f9ef6fc38c
|
@@ -0,0 +1,50 @@
|
|
1
|
+
version: 2
|
2
|
+
references:
|
3
|
+
test_library: &test_library
|
4
|
+
parallelism: 1
|
5
|
+
steps:
|
6
|
+
- 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
|
40
|
+
|
41
|
+
workflows:
|
42
|
+
version: 2
|
43
|
+
build:
|
44
|
+
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
|
data/README.md
CHANGED
@@ -164,7 +164,21 @@ These different types of error are fully documented in the [API documentation](h
|
|
164
164
|
- `#request_id`
|
165
165
|
- `#errors`
|
166
166
|
|
167
|
-
When the API returns an `invalid_state` error due to an `idempotent_creation_conflict`,
|
167
|
+
When the API returns an `invalid_state` error due to an `idempotent_creation_conflict`,
|
168
|
+
this library will attempt to retrieve the existing record which was created using the
|
169
|
+
idempotency key, however you can also configure the library to raise an exception instead:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
@client = GoCardlessPro::Client.new(
|
173
|
+
on_idempotency_conflict: :raise
|
174
|
+
)
|
175
|
+
|
176
|
+
begin
|
177
|
+
@client.payments.create(...)
|
178
|
+
rescue GoCardlessPro::IdempotencyConflict => e
|
179
|
+
# do something useful
|
180
|
+
end
|
181
|
+
```
|
168
182
|
|
169
183
|
If the client is unable to connect to GoCardless, an appropriate exception will be raised, for example:
|
170
184
|
|
data/gocardless_pro.gemspec
CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
20
|
spec.add_development_dependency 'rspec', '~> 3.7.0'
|
21
|
+
# Used by webmock and newer versions require ruby 2.1
|
22
|
+
spec.add_development_dependency 'public_suffix', '~> 2.0.5'
|
21
23
|
spec.add_development_dependency 'webmock', '~> 1.18'
|
22
24
|
spec.add_development_dependency 'rubocop', '~> 0.49.1'
|
23
25
|
spec.add_development_dependency 'yard', '~> 0.9.11'
|
data/lib/gocardless_pro.rb
CHANGED
@@ -53,6 +53,9 @@ require_relative 'gocardless_pro/services/customers_service'
|
|
53
53
|
require_relative 'gocardless_pro/resources/customer_bank_account'
|
54
54
|
require_relative 'gocardless_pro/services/customer_bank_accounts_service'
|
55
55
|
|
56
|
+
require_relative 'gocardless_pro/resources/customer_notification'
|
57
|
+
require_relative 'gocardless_pro/services/customer_notifications_service'
|
58
|
+
|
56
59
|
require_relative 'gocardless_pro/resources/event'
|
57
60
|
require_relative 'gocardless_pro/services/events_service'
|
58
61
|
|
@@ -11,6 +11,8 @@ require 'base64'
|
|
11
11
|
module GoCardlessPro
|
12
12
|
# GoCardless API
|
13
13
|
class ApiService
|
14
|
+
attr_reader :on_idempotency_conflict
|
15
|
+
|
14
16
|
# Initialize an APIService
|
15
17
|
#
|
16
18
|
# @param url [String] the URL to make requests to
|
@@ -31,6 +33,7 @@ module GoCardlessPro
|
|
31
33
|
|
32
34
|
@headers = options[:default_headers] || {}
|
33
35
|
@headers['Authorization'] = "Bearer #{token}"
|
36
|
+
@on_idempotency_conflict = options[:on_idempotency_conflict] || :fetch
|
34
37
|
end
|
35
38
|
|
36
39
|
# Make a request to the API
|
@@ -28,6 +28,11 @@ module GoCardlessPro
|
|
28
28
|
@customer_bank_accounts ||= Services::CustomerBankAccountsService.new(@api_service)
|
29
29
|
end
|
30
30
|
|
31
|
+
# Access to the service for customer_notification to make API calls
|
32
|
+
def customer_notifications
|
33
|
+
@customer_notifications ||= Services::CustomerNotificationsService.new(@api_service)
|
34
|
+
end
|
35
|
+
|
31
36
|
# Access to the service for event to make API calls
|
32
37
|
def events
|
33
38
|
@events ||= Services::EventsService.new(@api_service)
|
@@ -133,7 +138,7 @@ module GoCardlessPro
|
|
133
138
|
'User-Agent' => user_agent.to_s,
|
134
139
|
'Content-Type' => 'application/json',
|
135
140
|
'GoCardless-Client-Library' => 'gocardless-pro-ruby',
|
136
|
-
'GoCardless-Client-Version' => '2.
|
141
|
+
'GoCardless-Client-Version' => '2.13.0',
|
137
142
|
},
|
138
143
|
}
|
139
144
|
end
|
@@ -18,6 +18,9 @@ module GoCardlessPro
|
|
18
18
|
# several Direct Debit [mandates](#core-endpoints-mandates).
|
19
19
|
#
|
20
20
|
# Notes:
|
21
|
+
# - the `phone_number` field may only be supplied for New Zealand customers,
|
22
|
+
# and must be supplied if you intend to set up an BECS NZ mandate with the
|
23
|
+
# customer.
|
21
24
|
# - the `swedish_identity_number` field may only be supplied for Swedish
|
22
25
|
# customers, and must be supplied if you intend to set up an Autogiro
|
23
26
|
# mandate with the customer.
|
@@ -39,6 +42,7 @@ module GoCardlessPro
|
|
39
42
|
attr_reader :id
|
40
43
|
attr_reader :language
|
41
44
|
attr_reader :metadata
|
45
|
+
attr_reader :phone_number
|
42
46
|
attr_reader :postal_code
|
43
47
|
attr_reader :region
|
44
48
|
attr_reader :swedish_identity_number
|
@@ -62,6 +66,7 @@ module GoCardlessPro
|
|
62
66
|
@id = object['id']
|
63
67
|
@language = object['language']
|
64
68
|
@metadata = object['metadata']
|
69
|
+
@phone_number = object['phone_number']
|
65
70
|
@postal_code = object['postal_code']
|
66
71
|
@region = object['region']
|
67
72
|
@swedish_identity_number = object['swedish_identity_number']
|
@@ -0,0 +1,97 @@
|
|
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 customer_notification resource returned from the API
|
14
|
+
|
15
|
+
# Customer Notifications represent the notification which is due to be sent
|
16
|
+
# to a customer
|
17
|
+
# after an event has happened. The event, the resource and the customer to
|
18
|
+
# be notified
|
19
|
+
# are all identified in the `links` property.
|
20
|
+
#
|
21
|
+
# Note that these are ephemeral records - once the notification has been
|
22
|
+
# actioned in some
|
23
|
+
# way, it is no longer visible using this API.
|
24
|
+
#
|
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
|
+
#
|
31
|
+
class CustomerNotification
|
32
|
+
attr_reader :action_taken
|
33
|
+
attr_reader :action_taken_at
|
34
|
+
attr_reader :action_taken_by
|
35
|
+
attr_reader :id
|
36
|
+
attr_reader :type
|
37
|
+
|
38
|
+
# Initialize a customer_notification resource instance
|
39
|
+
# @param object [Hash] an object returned from the API
|
40
|
+
def initialize(object, response = nil)
|
41
|
+
@object = object
|
42
|
+
|
43
|
+
@action_taken = object['action_taken']
|
44
|
+
@action_taken_at = object['action_taken_at']
|
45
|
+
@action_taken_by = object['action_taken_by']
|
46
|
+
@id = object['id']
|
47
|
+
@links = object['links']
|
48
|
+
@type = object['type']
|
49
|
+
@response = response
|
50
|
+
end
|
51
|
+
|
52
|
+
def api_response
|
53
|
+
ApiResponse.new(@response)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return the links that the resource has
|
57
|
+
def links
|
58
|
+
@customer_notification_links ||= Links.new(@links)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Provides the customer_notification resource as a hash of all its readable attributes
|
62
|
+
def to_h
|
63
|
+
@object
|
64
|
+
end
|
65
|
+
|
66
|
+
class Links
|
67
|
+
def initialize(links)
|
68
|
+
@links = links || {}
|
69
|
+
end
|
70
|
+
|
71
|
+
def customer
|
72
|
+
@links['customer']
|
73
|
+
end
|
74
|
+
|
75
|
+
def event
|
76
|
+
@links['event']
|
77
|
+
end
|
78
|
+
|
79
|
+
def mandate
|
80
|
+
@links['mandate']
|
81
|
+
end
|
82
|
+
|
83
|
+
def payment
|
84
|
+
@links['payment']
|
85
|
+
end
|
86
|
+
|
87
|
+
def refund
|
88
|
+
@links['refund']
|
89
|
+
end
|
90
|
+
|
91
|
+
def subscription
|
92
|
+
@links['subscription']
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -18,6 +18,7 @@ module GoCardlessPro
|
|
18
18
|
class Event
|
19
19
|
attr_reader :action
|
20
20
|
attr_reader :created_at
|
21
|
+
attr_reader :customer_notifications
|
21
22
|
attr_reader :details
|
22
23
|
attr_reader :id
|
23
24
|
attr_reader :metadata
|
@@ -30,6 +31,7 @@ module GoCardlessPro
|
|
30
31
|
|
31
32
|
@action = object['action']
|
32
33
|
@created_at = object['created_at']
|
34
|
+
@customer_notifications = object['customer_notifications']
|
33
35
|
@details = object['details']
|
34
36
|
@id = object['id']
|
35
37
|
@links = object['links']
|
@@ -54,7 +54,7 @@ module GoCardlessPro
|
|
54
54
|
#
|
55
55
|
# <p class="restricted-notice"><strong>Restricted</strong>: This API is
|
56
56
|
# currently
|
57
|
-
# only available for approved
|
57
|
+
# only available for approved integrators - please <a
|
58
58
|
# href="mailto:help@gocardless.com">get
|
59
59
|
# in touch</a> if you would like to use this API.</p>
|
60
60
|
class MandateImport
|
@@ -40,7 +40,7 @@ module GoCardlessPro
|
|
40
40
|
#
|
41
41
|
# <p class="restricted-notice"><strong>Restricted</strong>: This API is
|
42
42
|
# currently
|
43
|
-
# only available for approved
|
43
|
+
# only available for approved integrators - please <a
|
44
44
|
# href="mailto:help@gocardless.com">get
|
45
45
|
# in touch</a> if you would like to use this API.</p>
|
46
46
|
#
|
@@ -29,7 +29,16 @@ module GoCardlessPro
|
|
29
29
|
# Response doesn't raise any errors until #body is called
|
30
30
|
response.tap(&:body)
|
31
31
|
rescue InvalidStateError => e
|
32
|
-
|
32
|
+
if e.idempotent_creation_conflict?
|
33
|
+
case @api_service.on_idempotency_conflict
|
34
|
+
when :raise
|
35
|
+
raise IdempotencyConflict, e.error
|
36
|
+
when :fetch
|
37
|
+
return get(e.conflicting_resource_id)
|
38
|
+
else
|
39
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
40
|
+
end
|
41
|
+
end
|
33
42
|
|
34
43
|
raise e
|
35
44
|
end
|
@@ -112,7 +121,16 @@ module GoCardlessPro
|
|
112
121
|
# Response doesn't raise any errors until #body is called
|
113
122
|
response.tap(&:body)
|
114
123
|
rescue InvalidStateError => e
|
115
|
-
|
124
|
+
if e.idempotent_creation_conflict?
|
125
|
+
case @api_service.on_idempotency_conflict
|
126
|
+
when :raise
|
127
|
+
raise IdempotencyConflict, e.error
|
128
|
+
when :fetch
|
129
|
+
return get(e.conflicting_resource_id)
|
130
|
+
else
|
131
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
132
|
+
end
|
133
|
+
end
|
116
134
|
|
117
135
|
raise e
|
118
136
|
end
|
@@ -29,7 +29,16 @@ module GoCardlessPro
|
|
29
29
|
# Response doesn't raise any errors until #body is called
|
30
30
|
response.tap(&:body)
|
31
31
|
rescue InvalidStateError => e
|
32
|
-
|
32
|
+
if e.idempotent_creation_conflict?
|
33
|
+
case @api_service.on_idempotency_conflict
|
34
|
+
when :raise
|
35
|
+
raise IdempotencyConflict, e.error
|
36
|
+
when :fetch
|
37
|
+
return get(e.conflicting_resource_id)
|
38
|
+
else
|
39
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
40
|
+
end
|
41
|
+
end
|
33
42
|
|
34
43
|
raise e
|
35
44
|
end
|
@@ -41,7 +41,16 @@ module GoCardlessPro
|
|
41
41
|
# Response doesn't raise any errors until #body is called
|
42
42
|
response.tap(&:body)
|
43
43
|
rescue InvalidStateError => e
|
44
|
-
|
44
|
+
if e.idempotent_creation_conflict?
|
45
|
+
case @api_service.on_idempotency_conflict
|
46
|
+
when :raise
|
47
|
+
raise IdempotencyConflict, e.error
|
48
|
+
when :fetch
|
49
|
+
return get(e.conflicting_resource_id)
|
50
|
+
else
|
51
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
52
|
+
end
|
53
|
+
end
|
45
54
|
|
46
55
|
raise e
|
47
56
|
end
|
@@ -145,7 +154,16 @@ module GoCardlessPro
|
|
145
154
|
# Response doesn't raise any errors until #body is called
|
146
155
|
response.tap(&:body)
|
147
156
|
rescue InvalidStateError => e
|
148
|
-
|
157
|
+
if e.idempotent_creation_conflict?
|
158
|
+
case @api_service.on_idempotency_conflict
|
159
|
+
when :raise
|
160
|
+
raise IdempotencyConflict, e.error
|
161
|
+
when :fetch
|
162
|
+
return get(e.conflicting_resource_id)
|
163
|
+
else
|
164
|
+
raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
|
165
|
+
end
|
166
|
+
end
|
149
167
|
|
150
168
|
raise e
|
151
169
|
end
|
@@ -0,0 +1,66 @@
|
|
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 CustomerNotification endpoints
|
13
|
+
class CustomerNotificationsService < BaseService
|
14
|
+
# "Handling" a notification means that you have sent the notification yourself
|
15
|
+
# (and
|
16
|
+
# don't want GoCardless to send it).
|
17
|
+
# If the notification has already been actioned, or the deadline to notify has
|
18
|
+
# passed,
|
19
|
+
# this endpoint will return an `already_actioned` error and you should not take
|
20
|
+
# further action.
|
21
|
+
#
|
22
|
+
# Example URL: /customer_notifications/:identity/actions/handle
|
23
|
+
#
|
24
|
+
# @param identity # The id of the notification.
|
25
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
26
|
+
def handle(identity, options = {})
|
27
|
+
path = sub_url('/customer_notifications/:identity/actions/handle', 'identity' => identity)
|
28
|
+
|
29
|
+
params = options.delete(:params) || {}
|
30
|
+
options[:params] = {}
|
31
|
+
options[:params]['data'] = params
|
32
|
+
|
33
|
+
options[:retry_failures] = false
|
34
|
+
|
35
|
+
response = make_request(:post, path, options)
|
36
|
+
|
37
|
+
return if response.body.nil?
|
38
|
+
|
39
|
+
Resources::CustomerNotification.new(unenvelope_body(response.body), response)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
45
|
+
#
|
46
|
+
# @param body [Hash]
|
47
|
+
def unenvelope_body(body)
|
48
|
+
body[envelope_key] || body['data']
|
49
|
+
end
|
50
|
+
|
51
|
+
# return the key which API responses will envelope data under
|
52
|
+
def envelope_key
|
53
|
+
'customer_notifications'
|
54
|
+
end
|
55
|
+
|
56
|
+
# take a URL with placeholder params and substitute them out for the actual value
|
57
|
+
# @param url [String] the URL with placeholders in
|
58
|
+
# @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
|
59
|
+
def sub_url(url, param_map)
|
60
|
+
param_map.reduce(url) do |new_url, (param, value)|
|
61
|
+
new_url.gsub(":#{param}", URI.escape(value))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|