gocardless_pro 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -4
- data/lib/gocardless_pro.rb +1 -0
- data/lib/gocardless_pro/api_service.rb +2 -0
- data/lib/gocardless_pro/client.rb +4 -3
- data/lib/gocardless_pro/error/invalid_state_error.rb +17 -0
- data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +50 -0
- data/lib/gocardless_pro/request.rb +38 -1
- data/lib/gocardless_pro/resources/creditor.rb +2 -2
- data/lib/gocardless_pro/resources/creditor_bank_account.rb +11 -11
- data/lib/gocardless_pro/resources/customer_bank_account.rb +2 -2
- data/lib/gocardless_pro/resources/event.rb +2 -2
- data/lib/gocardless_pro/resources/mandate.rb +2 -2
- data/lib/gocardless_pro/resources/payment.rb +7 -7
- data/lib/gocardless_pro/resources/payout.rb +7 -6
- data/lib/gocardless_pro/resources/redirect_flow.rb +2 -2
- data/lib/gocardless_pro/resources/refund.rb +2 -2
- data/lib/gocardless_pro/resources/subscription.rb +2 -2
- data/lib/gocardless_pro/response.rb +2 -54
- data/lib/gocardless_pro/services/bank_details_lookups_service.rb +3 -0
- data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +31 -2
- data/lib/gocardless_pro/services/creditors_service.rb +21 -1
- data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +34 -2
- data/lib/gocardless_pro/services/customers_service.rb +21 -1
- data/lib/gocardless_pro/services/events_service.rb +5 -0
- data/lib/gocardless_pro/services/mandate_pdfs_service.rb +3 -0
- data/lib/gocardless_pro/services/mandates_service.rb +47 -3
- data/lib/gocardless_pro/services/payments_service.rb +47 -3
- data/lib/gocardless_pro/services/payouts_service.rb +5 -0
- data/lib/gocardless_pro/services/redirect_flows_service.rb +28 -2
- data/lib/gocardless_pro/services/refunds_service.rb +21 -1
- data/lib/gocardless_pro/services/subscriptions_service.rb +34 -2
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/api_service_spec.rb +106 -0
- data/spec/middlewares/raise_gocardless_errors_spec.rb +98 -0
- data/spec/resources/bank_details_lookup_spec.rb +102 -19
- data/spec/resources/creditor_bank_account_spec.rb +416 -40
- data/spec/resources/creditor_spec.rb +414 -53
- data/spec/resources/customer_bank_account_spec.rb +452 -40
- data/spec/resources/customer_spec.rb +457 -45
- data/spec/resources/event_spec.rb +171 -72
- data/spec/resources/mandate_pdf_spec.rb +100 -17
- data/spec/resources/mandate_spec.rb +501 -44
- data/spec/resources/payment_spec.rb +531 -48
- data/spec/resources/payout_spec.rb +189 -45
- data/spec/resources/redirect_flow_spec.rb +277 -43
- data/spec/resources/refund_spec.rb +349 -34
- data/spec/resources/subscription_spec.rb +531 -53
- data/spec/response_spec.rb +12 -79
- data/spec/services/bank_details_lookups_service_spec.rb +67 -2
- data/spec/services/creditor_bank_accounts_service_spec.rb +309 -31
- data/spec/services/creditors_service_spec.rb +343 -33
- data/spec/services/customer_bank_accounts_service_spec.rb +335 -32
- data/spec/services/customers_service_spec.rb +364 -36
- data/spec/services/events_service_spec.rb +185 -24
- data/spec/services/mandate_pdfs_service_spec.rb +66 -2
- data/spec/services/mandates_service_spec.rb +341 -33
- data/spec/services/payments_service_spec.rb +355 -35
- data/spec/services/payouts_service_spec.rb +206 -26
- data/spec/services/redirect_flows_service_spec.rb +137 -7
- data/spec/services/refunds_service_spec.rb +301 -27
- data/spec/services/subscriptions_service_spec.rb +377 -38
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b558be54b18a323263272b8629c8f7f57c5b034b
|
4
|
+
data.tar.gz: b7f920a9a2c6861183603d02bd19c803c245108f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df5272b94fa8d97a0945fcc393e69a97558ce9dd4701c54049e6d4e66aea4b0521e3c3f2dc5783a3aebedb6f19a791e85fe40f016487e41726688f3341a72ac4
|
7
|
+
data.tar.gz: 42cc33ed47c7e8fa42f23d7e1b3e99bc7f19e7de0891adb82b9c62de102945982ceec33e7a2c5e111c9eabc9268c4a772d1d221bbd8938b4030f168c82a6ba9f
|
data/README.md
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
A Ruby client for the GoCardless API. For full details of the GoCardless API, see the [API docs](https://developer.gocardless.com/pro/).
|
4
4
|
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/gocardless_pro.svg)](http://badge.fury.io/rb/gocardless_pro)
|
6
6
|
[![Build Status](https://travis-ci.org/gocardless/gocardless-pro-ruby.svg?branch=master)](https://travis-ci.org/gocardless/gocardless-pro-ruby)
|
7
7
|
|
8
8
|
- ["Getting started" guide](https://developer.gocardless.com/getting-started/api/introduction/?lang=ruby) with copy and paste Ruby code samples
|
9
|
-
- [API Reference](https://developer.gocardless.com/api-reference
|
9
|
+
- [API Reference](https://developer.gocardless.com/api-reference)
|
10
10
|
|
11
11
|
## Usage Examples
|
12
12
|
|
@@ -115,6 +115,11 @@ For POST and PUT requests you need to pass in the body in under the `params` key
|
|
115
115
|
)
|
116
116
|
```
|
117
117
|
|
118
|
+
When creating a resource, the library will automatically include a randomly-generated
|
119
|
+
[idempotency key](https://developer.gocardless.com/api-reference/#making-requests-idempotency-keys)
|
120
|
+
- this means that if a request appears to fail but is in fact successful (for example due
|
121
|
+
to a timeout), you will not end up creating multiple duplicates of the resource.
|
122
|
+
|
118
123
|
If any parameters are required they come first:
|
119
124
|
|
120
125
|
```rb
|
@@ -125,7 +130,7 @@ If any parameters are required they come first:
|
|
125
130
|
|
126
131
|
Custom headers can be provided for a POST request under the `headers` key.
|
127
132
|
|
128
|
-
The most common use of a custom header would be to set
|
133
|
+
The most common use of a custom header would be to set a custom [idempotency key](https://developer.gocardless.com/pro/#making-requests-idempotency-keys) when making a request:
|
129
134
|
|
130
135
|
```rb
|
131
136
|
@client.customers.create(
|
@@ -142,7 +147,7 @@ The most common use of a custom header would be to set an [idempotency key](http
|
|
142
147
|
|
143
148
|
### Handling failures
|
144
149
|
|
145
|
-
When the API returns an error, the client will raise a corresponding one. There are four classes of error which could be thrown,
|
150
|
+
When the API returns an error, the client will raise a corresponding one. There are four classes of error which could be thrown, all of which subclass `GoCardlessPro::Error`:
|
146
151
|
|
147
152
|
- `GoCardlessPro::GoCardlessError`
|
148
153
|
- `GoCardlessPro::InvalidApiUsageError`
|
@@ -151,6 +156,8 @@ When the API returns an error, the client will raise a corresponding one. There
|
|
151
156
|
|
152
157
|
These errors are fully documented in the [API documentation](https://developer.gocardless.com/api-reference/#overview-errors).
|
153
158
|
|
159
|
+
When the API returns an `invalid_state` error due to an `idempotent_creation_conflict`, where possible, the library will automatically retrieve the existing record which was created using the idempotency key.
|
160
|
+
|
154
161
|
All errors have the following methods to facilitate access to information in the API response:
|
155
162
|
|
156
163
|
- `#documentation_url`
|
@@ -160,6 +167,8 @@ All errors have the following methods to facilitate access to information in the
|
|
160
167
|
- `#request_id`
|
161
168
|
- `#errors`
|
162
169
|
|
170
|
+
If a timeout occurs, and the request being made is idempotent, the library will automatically retry the request up to 3 times before giving up and raising a `Faraday::TimeoutError` error.
|
171
|
+
|
163
172
|
### Using the OAuth API
|
164
173
|
|
165
174
|
The API includes [OAuth](https://developer.gocardless.com/pro/2015-07-06/#guides-oauth) functionality, which allows you to work with other users' GoCardless accounts. Once a user approves you, you can use the GoCardless API on their behalf and receive their webhooks.
|
data/lib/gocardless_pro.rb
CHANGED
@@ -24,6 +24,7 @@ end
|
|
24
24
|
|
25
25
|
require_relative 'gocardless_pro/api_service'
|
26
26
|
require_relative 'gocardless_pro/list_response'
|
27
|
+
require_relative 'gocardless_pro/middlewares/raise_gocardless_errors'
|
27
28
|
require_relative 'gocardless_pro/error'
|
28
29
|
require_relative 'gocardless_pro/error/validation_error'
|
29
30
|
require_relative 'gocardless_pro/error/gocardless_error'
|
@@ -116,7 +116,9 @@ module GoCardlessPro
|
|
116
116
|
default_headers: {
|
117
117
|
'GoCardless-Version' => '2015-07-06',
|
118
118
|
'User-Agent' => "#{user_agent}",
|
119
|
-
'Content-Type' => 'application/json'
|
119
|
+
'Content-Type' => 'application/json',
|
120
|
+
'GoCardless-Client-Library' => 'gocardless-pro-ruby',
|
121
|
+
'GoCardless-Client-Version' => '2.0.0'
|
120
122
|
}
|
121
123
|
}
|
122
124
|
end
|
@@ -124,8 +126,7 @@ module GoCardlessPro
|
|
124
126
|
def user_agent
|
125
127
|
@user_agent ||=
|
126
128
|
begin
|
127
|
-
|
128
|
-
gem_info = "#{gem_name}"
|
129
|
+
gem_info = 'gocardless-pro-ruby'
|
129
130
|
gem_info += "/v#{GoCardlessPro::VERSION}" if defined?(GoCardlessPro::VERSION)
|
130
131
|
|
131
132
|
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
@@ -1,5 +1,22 @@
|
|
1
1
|
module GoCardlessPro
|
2
2
|
# Thrown when the API returns an invalid state error
|
3
3
|
class InvalidStateError < Error
|
4
|
+
IDEMPOTENT_CREATION_CONFLICT = 'idempotent_creation_conflict'.freeze
|
5
|
+
CONFLICTING_RESOURCE_ID = 'conflicting_resource_id'.freeze
|
6
|
+
|
7
|
+
def idempotent_creation_conflict?
|
8
|
+
!idempotent_creation_conflict_error.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
def conflicting_resource_id
|
12
|
+
return unless idempotent_creation_conflict?
|
13
|
+
idempotent_creation_conflict_error['links'][CONFLICTING_RESOURCE_ID]
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def idempotent_creation_conflict_error
|
19
|
+
errors.find { |error| error['reason'] == IDEMPOTENT_CREATION_CONFLICT }
|
20
|
+
end
|
4
21
|
end
|
5
22
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module GoCardlessPro
|
2
|
+
module Middlewares
|
3
|
+
class RaiseGoCardlessErrors < Faraday::Response::Middleware
|
4
|
+
API_ERROR_STATUSES = 501..599
|
5
|
+
CLIENT_ERROR_STATUSES = 400..500
|
6
|
+
|
7
|
+
def on_complete(env)
|
8
|
+
if !json?(env) || API_ERROR_STATUSES.include?(env.status)
|
9
|
+
fail ApiError, generate_error_data(env)
|
10
|
+
end
|
11
|
+
|
12
|
+
if CLIENT_ERROR_STATUSES.include?(env.status)
|
13
|
+
json_body ||= JSON.parse(env.body) unless env.body.empty?
|
14
|
+
error_type = json_body['error']['type']
|
15
|
+
fail(error_class_for_type(error_type), json_body['error'])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def error_class_for_type(type)
|
22
|
+
{
|
23
|
+
validation_failed: GoCardlessPro::ValidationError,
|
24
|
+
gocardless: GoCardlessPro::GoCardlessError,
|
25
|
+
invalid_api_usage: GoCardlessPro::InvalidApiUsageError,
|
26
|
+
invalid_state: GoCardlessPro::InvalidStateError
|
27
|
+
}.fetch(type.to_sym)
|
28
|
+
end
|
29
|
+
|
30
|
+
def generate_error_data(env)
|
31
|
+
{
|
32
|
+
'message' => "Something went wrong with this request\n" \
|
33
|
+
"code: #{env.status}\n" \
|
34
|
+
"headers: #{env.response_headers}\n" \
|
35
|
+
"body: #{env.body}",
|
36
|
+
'code' => env.status
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def json?(env)
|
41
|
+
content_type = env.response_headers['Content-Type'] ||
|
42
|
+
env.response_headers['content-type'] || ''
|
43
|
+
|
44
|
+
content_type.include?('application/json')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Faraday::Response.register_middleware raise_gocardless_errors: GoCardlessPro::Middlewares::RaiseGoCardlessErrors
|
@@ -1,6 +1,11 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module GoCardlessPro
|
2
4
|
# A class that wraps an API request
|
3
5
|
class Request
|
6
|
+
MAX_NETWORK_RETRIES = 3
|
7
|
+
RETRY_DELAY = 0.5
|
8
|
+
|
4
9
|
# Initialize a request class, which makes calls to the API
|
5
10
|
# @param connection
|
6
11
|
# @param method [Symbol] the method to make the request with
|
@@ -13,6 +18,7 @@ module GoCardlessPro
|
|
13
18
|
@path = path
|
14
19
|
@headers = options.delete(:headers) || {}
|
15
20
|
@envelope_name = options.delete(:envelope_key)
|
21
|
+
@retry_failures = options.delete(:retry_failures) { true }
|
16
22
|
@given_options = options
|
17
23
|
|
18
24
|
@request_body = request_body
|
@@ -21,11 +27,34 @@ module GoCardlessPro
|
|
21
27
|
@request_body = @request_body.to_json
|
22
28
|
@headers['Content-Type'] ||= 'application/json'
|
23
29
|
end
|
30
|
+
|
31
|
+
@headers['Idempotency-Key'] ||= SecureRandom.uuid if @method == :post
|
24
32
|
end
|
25
33
|
|
26
34
|
# Make the request and wrap it in a Response object
|
27
35
|
def request
|
28
|
-
|
36
|
+
if @retry_failures
|
37
|
+
with_retries { Response.new(make_request) }
|
38
|
+
else
|
39
|
+
Response.new(make_request)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def with_retries
|
44
|
+
requests_attempted = 0
|
45
|
+
total_requests_allowed = MAX_NETWORK_RETRIES + 1
|
46
|
+
|
47
|
+
begin
|
48
|
+
yield
|
49
|
+
rescue => exception
|
50
|
+
if requests_attempted < total_requests_allowed && should_retry?(exception)
|
51
|
+
requests_attempted += 1
|
52
|
+
sleep(RETRY_DELAY)
|
53
|
+
retry
|
54
|
+
else
|
55
|
+
raise exception
|
56
|
+
end
|
57
|
+
end
|
29
58
|
end
|
30
59
|
|
31
60
|
# Make the API request
|
@@ -57,5 +86,13 @@ module GoCardlessPro
|
|
57
86
|
{}
|
58
87
|
end
|
59
88
|
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def should_retry?(exception)
|
93
|
+
return true if exception.is_a?(Faraday::TimeoutError)
|
94
|
+
return true if exception.is_a?(Faraday::ConnectionFailed)
|
95
|
+
return true if exception.is_a?(GoCardlessPro::ApiError)
|
96
|
+
end
|
60
97
|
end
|
61
98
|
end
|
@@ -61,7 +61,7 @@ module GoCardlessPro
|
|
61
61
|
|
62
62
|
# Return the links that the resource has
|
63
63
|
def links
|
64
|
-
@
|
64
|
+
@creditor_links ||= Links.new(@links)
|
65
65
|
end
|
66
66
|
|
67
67
|
# Provides the creditor resource as a hash of all its readable attributes
|
@@ -71,7 +71,7 @@ module GoCardlessPro
|
|
71
71
|
|
72
72
|
class Links
|
73
73
|
def initialize(links)
|
74
|
-
@links = links
|
74
|
+
@links = links || {}
|
75
75
|
end
|
76
76
|
|
77
77
|
def default_eur_payout_account
|
@@ -12,15 +12,15 @@ module GoCardlessPro
|
|
12
12
|
# Represents an instance of a creditor_bank_account resource returned from the API
|
13
13
|
|
14
14
|
# Creditor Bank Accounts hold the bank details of a
|
15
|
-
# [creditor](#
|
16
|
-
#
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
15
|
+
# [creditor](#core-endpoints-creditors). These are the bank accounts which
|
16
|
+
# your [payouts](#core-endpoints-payouts) will be sent to.
|
17
|
+
#
|
18
|
+
# Note
|
19
|
+
# that creditor bank accounts must be unique, and so you will encounter a
|
20
|
+
# `bank_account_exists` error if you try to create a duplicate bank account.
|
21
|
+
# You may wish to handle this by updating the existing record instead, the
|
22
|
+
# ID of which will be provided as `links[creditor_bank_account]` in the
|
23
|
+
# error response.
|
24
24
|
class CreditorBankAccount
|
25
25
|
attr_reader :account_holder_name
|
26
26
|
attr_reader :account_number_ending
|
@@ -56,7 +56,7 @@ module GoCardlessPro
|
|
56
56
|
|
57
57
|
# Return the links that the resource has
|
58
58
|
def links
|
59
|
-
@
|
59
|
+
@creditor_bank_account_links ||= Links.new(@links)
|
60
60
|
end
|
61
61
|
|
62
62
|
# Provides the creditor_bank_account resource as a hash of all its readable attributes
|
@@ -66,7 +66,7 @@ module GoCardlessPro
|
|
66
66
|
|
67
67
|
class Links
|
68
68
|
def initialize(links)
|
69
|
-
@links = links
|
69
|
+
@links = links || {}
|
70
70
|
end
|
71
71
|
|
72
72
|
def creditor
|
@@ -57,7 +57,7 @@ module GoCardlessPro
|
|
57
57
|
|
58
58
|
# Return the links that the resource has
|
59
59
|
def links
|
60
|
-
@
|
60
|
+
@customer_bank_account_links ||= Links.new(@links)
|
61
61
|
end
|
62
62
|
|
63
63
|
# Provides the customer_bank_account resource as a hash of all its readable attributes
|
@@ -67,7 +67,7 @@ module GoCardlessPro
|
|
67
67
|
|
68
68
|
class Links
|
69
69
|
def initialize(links)
|
70
|
-
@links = links
|
70
|
+
@links = links || {}
|
71
71
|
end
|
72
72
|
|
73
73
|
def customer
|
@@ -43,7 +43,7 @@ module GoCardlessPro
|
|
43
43
|
|
44
44
|
# Return the links that the resource has
|
45
45
|
def links
|
46
|
-
@
|
46
|
+
@event_links ||= Links.new(@links)
|
47
47
|
end
|
48
48
|
|
49
49
|
# Provides the event resource as a hash of all its readable attributes
|
@@ -53,7 +53,7 @@ module GoCardlessPro
|
|
53
53
|
|
54
54
|
class Links
|
55
55
|
def initialize(links)
|
56
|
-
@links = links
|
56
|
+
@links = links || {}
|
57
57
|
end
|
58
58
|
|
59
59
|
def mandate
|
@@ -50,7 +50,7 @@ module GoCardlessPro
|
|
50
50
|
|
51
51
|
# Return the links that the resource has
|
52
52
|
def links
|
53
|
-
@
|
53
|
+
@mandate_links ||= Links.new(@links)
|
54
54
|
end
|
55
55
|
|
56
56
|
# Provides the mandate resource as a hash of all its readable attributes
|
@@ -60,7 +60,7 @@ module GoCardlessPro
|
|
60
60
|
|
61
61
|
class Links
|
62
62
|
def initialize(links)
|
63
|
-
@links = links
|
63
|
+
@links = links || {}
|
64
64
|
end
|
65
65
|
|
66
66
|
def creditor
|
@@ -13,12 +13,12 @@ module GoCardlessPro
|
|
13
13
|
|
14
14
|
# Payment objects represent payments from a
|
15
15
|
# [customer](#core-endpoints-customers) to a
|
16
|
-
# [creditor](#
|
17
|
-
#
|
16
|
+
# [creditor](#core-endpoints-creditors), taken against a Direct Debit
|
17
|
+
# [mandate](#core-endpoints-mandates).
|
18
18
|
#
|
19
|
-
# GoCardless
|
20
|
-
#
|
21
|
-
#
|
19
|
+
# GoCardless will notify
|
20
|
+
# you via a [webhook](#appendix-webhooks) whenever the state of a payment
|
21
|
+
# changes.
|
22
22
|
class Payment
|
23
23
|
attr_reader :amount
|
24
24
|
attr_reader :amount_refunded
|
@@ -56,7 +56,7 @@ module GoCardlessPro
|
|
56
56
|
|
57
57
|
# Return the links that the resource has
|
58
58
|
def links
|
59
|
-
@
|
59
|
+
@payment_links ||= Links.new(@links)
|
60
60
|
end
|
61
61
|
|
62
62
|
# Provides the payment resource as a hash of all its readable attributes
|
@@ -66,7 +66,7 @@ module GoCardlessPro
|
|
66
66
|
|
67
67
|
class Links
|
68
68
|
def initialize(links)
|
69
|
-
@links = links
|
69
|
+
@links = links || {}
|
70
70
|
end
|
71
71
|
|
72
72
|
def creditor
|
@@ -12,10 +12,9 @@ module GoCardlessPro
|
|
12
12
|
# Represents an instance of a payout resource returned from the API
|
13
13
|
|
14
14
|
# Payouts represent transfers from GoCardless to a
|
15
|
-
# [creditor](#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# collected.
|
15
|
+
# [creditor](#core-endpoints-creditors). Each payout contains the funds
|
16
|
+
# collected from one or many [payments](#core-endpoints-payments). Payouts
|
17
|
+
# are created automatically after a payment has been successfully collected.
|
19
18
|
class Payout
|
20
19
|
attr_reader :amount
|
21
20
|
attr_reader :arrival_date
|
@@ -23,6 +22,7 @@ module GoCardlessPro
|
|
23
22
|
attr_reader :currency
|
24
23
|
attr_reader :deducted_fees
|
25
24
|
attr_reader :id
|
25
|
+
attr_reader :payout_type
|
26
26
|
attr_reader :reference
|
27
27
|
attr_reader :status
|
28
28
|
|
@@ -38,6 +38,7 @@ module GoCardlessPro
|
|
38
38
|
@deducted_fees = object['deducted_fees']
|
39
39
|
@id = object['id']
|
40
40
|
@links = object['links']
|
41
|
+
@payout_type = object['payout_type']
|
41
42
|
@reference = object['reference']
|
42
43
|
@status = object['status']
|
43
44
|
@response = response
|
@@ -49,7 +50,7 @@ module GoCardlessPro
|
|
49
50
|
|
50
51
|
# Return the links that the resource has
|
51
52
|
def links
|
52
|
-
@
|
53
|
+
@payout_links ||= Links.new(@links)
|
53
54
|
end
|
54
55
|
|
55
56
|
# Provides the payout resource as a hash of all its readable attributes
|
@@ -59,7 +60,7 @@ module GoCardlessPro
|
|
59
60
|
|
60
61
|
class Links
|
61
62
|
def initialize(links)
|
62
|
-
@links = links
|
63
|
+
@links = links || {}
|
63
64
|
end
|
64
65
|
|
65
66
|
def creditor
|