gocardless_pro 2.7.0 → 2.8.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 +6 -0
- data/lib/gocardless_pro/client.rb +11 -1
- data/lib/gocardless_pro/resources/mandate_import.rb +88 -0
- data/lib/gocardless_pro/resources/mandate_import_entry.rb +99 -0
- data/lib/gocardless_pro/services/mandate_import_entries_service.rb +99 -0
- data/lib/gocardless_pro/services/mandate_imports_service.rb +156 -0
- data/lib/gocardless_pro/version.rb +1 -1
- data/spec/resources/mandate_import_entry_spec.rb +206 -0
- data/spec/resources/mandate_import_spec.rb +340 -0
- data/spec/services/mandate_import_entries_service_spec.rb +345 -0
- data/spec/services/mandate_imports_service_spec.rb +412 -0
- metadata +15 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0dcc61e6ad974bee34243805fb1a45bec38c51db4ebf9bbdc6ee240ca96e782
|
4
|
+
data.tar.gz: 9ef2aabea6263516ba9cee0e1bb1efa682f59f9ede69c880a20d9d73a2b8c820
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 116e36fef2b4f6bec63d06f1a792fb240537bd2c1ed23b6684409367c24cb6148f21d7f52a14a7710642ba0e01cc5011c4f72d9cbc1c83918fc128759997cf96
|
7
|
+
data.tar.gz: cc8ad6e8119952e90cecc405a82a38d5631e06f42c2ea48cf03127526e644927c5f316be27968f9b3b466622c57b87a9c2842cd6fca9da7ecff06dae4d453bed
|
data/lib/gocardless_pro.rb
CHANGED
@@ -58,6 +58,12 @@ require_relative 'gocardless_pro/services/events_service'
|
|
58
58
|
require_relative 'gocardless_pro/resources/mandate'
|
59
59
|
require_relative 'gocardless_pro/services/mandates_service'
|
60
60
|
|
61
|
+
require_relative 'gocardless_pro/resources/mandate_import'
|
62
|
+
require_relative 'gocardless_pro/services/mandate_imports_service'
|
63
|
+
|
64
|
+
require_relative 'gocardless_pro/resources/mandate_import_entry'
|
65
|
+
require_relative 'gocardless_pro/services/mandate_import_entries_service'
|
66
|
+
|
61
67
|
require_relative 'gocardless_pro/resources/mandate_pdf'
|
62
68
|
require_relative 'gocardless_pro/services/mandate_pdfs_service'
|
63
69
|
|
@@ -38,6 +38,16 @@ module GoCardlessPro
|
|
38
38
|
@mandates ||= Services::MandatesService.new(@api_service)
|
39
39
|
end
|
40
40
|
|
41
|
+
# Access to the service for mandate_import to make API calls
|
42
|
+
def mandate_imports
|
43
|
+
@mandate_imports ||= Services::MandateImportsService.new(@api_service)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Access to the service for mandate_import_entry to make API calls
|
47
|
+
def mandate_import_entries
|
48
|
+
@mandate_import_entries ||= Services::MandateImportEntriesService.new(@api_service)
|
49
|
+
end
|
50
|
+
|
41
51
|
# Access to the service for mandate_pdf to make API calls
|
42
52
|
def mandate_pdfs
|
43
53
|
@mandate_pdfs ||= Services::MandatePdfsService.new(@api_service)
|
@@ -123,7 +133,7 @@ module GoCardlessPro
|
|
123
133
|
'User-Agent' => user_agent.to_s,
|
124
134
|
'Content-Type' => 'application/json',
|
125
135
|
'GoCardless-Client-Library' => 'gocardless-pro-ruby',
|
126
|
-
'GoCardless-Client-Version' => '2.
|
136
|
+
'GoCardless-Client-Version' => '2.8.0',
|
127
137
|
},
|
128
138
|
}
|
129
139
|
end
|
@@ -0,0 +1,88 @@
|
|
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 mandate_import resource returned from the API
|
14
|
+
|
15
|
+
# Mandate Imports allow you to migrate existing mandates from other
|
16
|
+
# providers into the
|
17
|
+
# GoCardless platform.
|
18
|
+
#
|
19
|
+
# The process is as follows:
|
20
|
+
#
|
21
|
+
# 1. [Create a mandate
|
22
|
+
# import](#mandate-imports-create-a-new-mandate-import)
|
23
|
+
# 2. [Add entries](#mandate-import-entries-add-a-mandate-import-entry) to
|
24
|
+
# the import
|
25
|
+
# 3. [Submit](#mandate-imports-submit-a-mandate-import) the import
|
26
|
+
# 4. Wait until a member of the GoCardless team approves the import, at
|
27
|
+
# which point the mandates will be created
|
28
|
+
# 5. [Link up the
|
29
|
+
# mandates](#mandate-import-entries-list-all-mandate-import-entries) in your
|
30
|
+
# system
|
31
|
+
#
|
32
|
+
# When you add entries to your mandate import, they are not turned into
|
33
|
+
# actual mandates
|
34
|
+
# until the mandate import is submitted by you via the API, and then
|
35
|
+
# processed by a member
|
36
|
+
# of the GoCardless team. When that happens, a mandate will be created for
|
37
|
+
# each entry in the import.
|
38
|
+
#
|
39
|
+
# We will issue a `mandate_created` webhook for each entry, which will be
|
40
|
+
# the same as the webhooks
|
41
|
+
# triggered when [ creating a mandate ](#mandates-create-a-mandate) using
|
42
|
+
# the mandates API. Once these
|
43
|
+
# webhooks start arriving, any reconciliation can now be accomplished by
|
44
|
+
# [checking the current status](#mandate-imports-get-a-mandate-import) of
|
45
|
+
# the mandate import and
|
46
|
+
# [linking up the mandates to your
|
47
|
+
# system](#mandate-import-entries-list-all-mandate-import-entries).
|
48
|
+
#
|
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>
|
54
|
+
#
|
55
|
+
# <p class="restricted-notice"><strong>Restricted</strong>: This API is
|
56
|
+
# currently
|
57
|
+
# only available for approved partners - please <a
|
58
|
+
# href="mailto:help@gocardless.com">get
|
59
|
+
# in touch</a> if you would like to use this API.</p>
|
60
|
+
class MandateImport
|
61
|
+
attr_reader :created_at
|
62
|
+
attr_reader :id
|
63
|
+
attr_reader :scheme
|
64
|
+
attr_reader :status
|
65
|
+
|
66
|
+
# Initialize a mandate_import resource instance
|
67
|
+
# @param object [Hash] an object returned from the API
|
68
|
+
def initialize(object, response = nil)
|
69
|
+
@object = object
|
70
|
+
|
71
|
+
@created_at = object['created_at']
|
72
|
+
@id = object['id']
|
73
|
+
@scheme = object['scheme']
|
74
|
+
@status = object['status']
|
75
|
+
@response = response
|
76
|
+
end
|
77
|
+
|
78
|
+
def api_response
|
79
|
+
ApiResponse.new(@response)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Provides the mandate_import resource as a hash of all its readable attributes
|
83
|
+
def to_h
|
84
|
+
@object
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,99 @@
|
|
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 mandate_import_entry resource returned from the API
|
14
|
+
|
15
|
+
# Mandate Import Entries are added to a [Mandate
|
16
|
+
# Import](#core-endpoints-mandate-imports).
|
17
|
+
# Each entry corresponds to one mandate to be imported into GoCardless.
|
18
|
+
#
|
19
|
+
# To import a mandate you will need:
|
20
|
+
# <ol>
|
21
|
+
# <li>Identifying information about the customer (name/company and
|
22
|
+
# address)</li>
|
23
|
+
# <li>Bank account details, consisting of an account holder name and
|
24
|
+
# either an IBAN or <a href="#appendix-local-bank-details">local bank
|
25
|
+
# details</a></li>
|
26
|
+
# <li>Amendment details (SEPA only)</li>
|
27
|
+
# </ol>
|
28
|
+
#
|
29
|
+
# We suggest you provide a `record_identifier` (which is unique within the
|
30
|
+
# context of a
|
31
|
+
# single mandate import) to help you to identify mandates that have been
|
32
|
+
# created once the
|
33
|
+
# import has been processed by GoCardless. You can
|
34
|
+
# [list the mandate import
|
35
|
+
# entries](#mandate-import-entries-list-all-mandate-import-entries),
|
36
|
+
# match them up in your system using the `record_identifier`, and look at
|
37
|
+
# the `links`
|
38
|
+
# fields to find the mandate, customer and customer bank account that have
|
39
|
+
# been imported.
|
40
|
+
#
|
41
|
+
# <p class="restricted-notice"><strong>Restricted</strong>: This API is
|
42
|
+
# currently
|
43
|
+
# only available for approved partners - please <a
|
44
|
+
# href="mailto:help@gocardless.com">get
|
45
|
+
# in touch</a> if you would like to use this API.</p>
|
46
|
+
#
|
47
|
+
class MandateImportEntry
|
48
|
+
attr_reader :created_at
|
49
|
+
attr_reader :record_identifier
|
50
|
+
|
51
|
+
# Initialize a mandate_import_entry resource instance
|
52
|
+
# @param object [Hash] an object returned from the API
|
53
|
+
def initialize(object, response = nil)
|
54
|
+
@object = object
|
55
|
+
|
56
|
+
@created_at = object['created_at']
|
57
|
+
@links = object['links']
|
58
|
+
@record_identifier = object['record_identifier']
|
59
|
+
@response = response
|
60
|
+
end
|
61
|
+
|
62
|
+
def api_response
|
63
|
+
ApiResponse.new(@response)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return the links that the resource has
|
67
|
+
def links
|
68
|
+
@mandate_import_entry_links ||= Links.new(@links)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Provides the mandate_import_entry resource as a hash of all its readable attributes
|
72
|
+
def to_h
|
73
|
+
@object
|
74
|
+
end
|
75
|
+
|
76
|
+
class Links
|
77
|
+
def initialize(links)
|
78
|
+
@links = links || {}
|
79
|
+
end
|
80
|
+
|
81
|
+
def customer
|
82
|
+
@links['customer']
|
83
|
+
end
|
84
|
+
|
85
|
+
def customer_bank_account
|
86
|
+
@links['customer_bank_account']
|
87
|
+
end
|
88
|
+
|
89
|
+
def mandate
|
90
|
+
@links['mandate']
|
91
|
+
end
|
92
|
+
|
93
|
+
def mandate_import
|
94
|
+
@links['mandate_import']
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,99 @@
|
|
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 MandateImportEntry endpoints
|
13
|
+
class MandateImportEntriesService < BaseService
|
14
|
+
# For an existing [mandate import](#core-endpoints-mandate-imports), this
|
15
|
+
# endpoint can
|
16
|
+
# be used to add individual mandates to be imported into GoCardless.
|
17
|
+
#
|
18
|
+
# You can add no more than 30,000 rows to a single mandate import.
|
19
|
+
# If you attempt to go over this limit, the API will return a
|
20
|
+
# `record_limit_exceeded` error.
|
21
|
+
# Example URL: /mandate_import_entries
|
22
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
23
|
+
def create(options = {})
|
24
|
+
path = '/mandate_import_entries'
|
25
|
+
|
26
|
+
params = options.delete(:params) || {}
|
27
|
+
options[:params] = {}
|
28
|
+
options[:params][envelope_key] = params
|
29
|
+
|
30
|
+
options[:retry_failures] = true
|
31
|
+
|
32
|
+
response = make_request(:post, path, options)
|
33
|
+
|
34
|
+
return if response.body.nil?
|
35
|
+
|
36
|
+
Resources::MandateImportEntry.new(unenvelope_body(response.body), response)
|
37
|
+
end
|
38
|
+
|
39
|
+
# For an existing mandate import, this endpoint lists all of the entries
|
40
|
+
# attached.
|
41
|
+
#
|
42
|
+
# After a mandate import has been submitted, you can use this endpoint to
|
43
|
+
# associate records
|
44
|
+
# in your system (using the `record_identifier` that you provided when creating
|
45
|
+
# the
|
46
|
+
# mandate import).
|
47
|
+
#
|
48
|
+
# Example URL: /mandate_import_entries
|
49
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
50
|
+
def list(options = {})
|
51
|
+
path = '/mandate_import_entries'
|
52
|
+
|
53
|
+
options[:retry_failures] = true
|
54
|
+
|
55
|
+
response = make_request(:get, path, options)
|
56
|
+
|
57
|
+
ListResponse.new(
|
58
|
+
response: response,
|
59
|
+
unenveloped_body: unenvelope_body(response.body),
|
60
|
+
resource_class: Resources::MandateImportEntry
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
|
65
|
+
#
|
66
|
+
# @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
|
67
|
+
# Otherwise they will be the body of the request.
|
68
|
+
def all(options = {})
|
69
|
+
Paginator.new(
|
70
|
+
service: self,
|
71
|
+
options: options
|
72
|
+
).enumerator
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
78
|
+
#
|
79
|
+
# @param body [Hash]
|
80
|
+
def unenvelope_body(body)
|
81
|
+
body[envelope_key] || body['data']
|
82
|
+
end
|
83
|
+
|
84
|
+
# return the key which API responses will envelope data under
|
85
|
+
def envelope_key
|
86
|
+
'mandate_import_entries'
|
87
|
+
end
|
88
|
+
|
89
|
+
# take a URL with placeholder params and substitute them out for the actual value
|
90
|
+
# @param url [String] the URL with placeholders in
|
91
|
+
# @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
|
92
|
+
def sub_url(url, param_map)
|
93
|
+
param_map.reduce(url) do |new_url, (param, value)|
|
94
|
+
new_url.gsub(":#{param}", URI.escape(value))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,156 @@
|
|
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 MandateImport endpoints
|
13
|
+
class MandateImportsService < BaseService
|
14
|
+
# Mandate imports are first created, before mandates are added one-at-a-time, so
|
15
|
+
# this endpoint merely signals the start of the import process. Once you've
|
16
|
+
# finished
|
17
|
+
# adding entries to an import, you should
|
18
|
+
# [submit](#mandate-imports-submit-a-mandate-import) it.
|
19
|
+
# Example URL: /mandate_imports
|
20
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
21
|
+
def create(options = {})
|
22
|
+
path = '/mandate_imports'
|
23
|
+
|
24
|
+
params = options.delete(:params) || {}
|
25
|
+
options[:params] = {}
|
26
|
+
options[:params][envelope_key] = params
|
27
|
+
|
28
|
+
options[:retry_failures] = true
|
29
|
+
|
30
|
+
begin
|
31
|
+
response = make_request(:post, path, options)
|
32
|
+
|
33
|
+
# Response doesn't raise any errors until #body is called
|
34
|
+
response.tap(&:body)
|
35
|
+
rescue InvalidStateError => e
|
36
|
+
return get(e.conflicting_resource_id) if e.idempotent_creation_conflict?
|
37
|
+
|
38
|
+
raise e
|
39
|
+
end
|
40
|
+
|
41
|
+
return if response.body.nil?
|
42
|
+
|
43
|
+
Resources::MandateImport.new(unenvelope_body(response.body), response)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a single mandate import.
|
47
|
+
# Example URL: /mandate_imports/:identity
|
48
|
+
#
|
49
|
+
# @param identity # Unique identifier, beginning with "IM".
|
50
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
51
|
+
def get(identity, options = {})
|
52
|
+
path = sub_url('/mandate_imports/:identity', 'identity' => identity)
|
53
|
+
|
54
|
+
options[:retry_failures] = true
|
55
|
+
|
56
|
+
response = make_request(:get, path, options)
|
57
|
+
|
58
|
+
return if response.body.nil?
|
59
|
+
|
60
|
+
Resources::MandateImport.new(unenvelope_body(response.body), response)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Submits the mandate import, which allows it to be processed by a member of the
|
64
|
+
# GoCardless team. Once the import has been submitted, it can no longer have
|
65
|
+
# entries
|
66
|
+
# added to it.
|
67
|
+
# Example URL: /mandate_imports/:identity/actions/submit
|
68
|
+
#
|
69
|
+
# @param identity # Unique identifier, beginning with "IM".
|
70
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
71
|
+
def submit(identity, options = {})
|
72
|
+
path = sub_url('/mandate_imports/:identity/actions/submit', 'identity' => identity)
|
73
|
+
|
74
|
+
params = options.delete(:params) || {}
|
75
|
+
options[:params] = {}
|
76
|
+
options[:params]['data'] = params
|
77
|
+
|
78
|
+
options[:retry_failures] = false
|
79
|
+
|
80
|
+
begin
|
81
|
+
response = make_request(:post, path, options)
|
82
|
+
|
83
|
+
# Response doesn't raise any errors until #body is called
|
84
|
+
response.tap(&:body)
|
85
|
+
rescue InvalidStateError => e
|
86
|
+
return get(e.conflicting_resource_id) if e.idempotent_creation_conflict?
|
87
|
+
|
88
|
+
raise e
|
89
|
+
end
|
90
|
+
|
91
|
+
return if response.body.nil?
|
92
|
+
|
93
|
+
Resources::MandateImport.new(unenvelope_body(response.body), response)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Cancels the mandate import, which aborts the import process and stops the
|
97
|
+
# mandates
|
98
|
+
# being set up in GoCardless. Once the import has been cancelled, it can no
|
99
|
+
# longer have
|
100
|
+
# entries added to it. Mandate imports which have already been submitted cannot
|
101
|
+
# be
|
102
|
+
# cancelled.
|
103
|
+
# Example URL: /mandate_imports/:identity/actions/cancel
|
104
|
+
#
|
105
|
+
# @param identity # Unique identifier, beginning with "IM".
|
106
|
+
# @param options [Hash] parameters as a hash, under a params key.
|
107
|
+
def cancel(identity, options = {})
|
108
|
+
path = sub_url('/mandate_imports/:identity/actions/cancel', 'identity' => identity)
|
109
|
+
|
110
|
+
params = options.delete(:params) || {}
|
111
|
+
options[:params] = {}
|
112
|
+
options[:params]['data'] = params
|
113
|
+
|
114
|
+
options[:retry_failures] = false
|
115
|
+
|
116
|
+
begin
|
117
|
+
response = make_request(:post, path, options)
|
118
|
+
|
119
|
+
# Response doesn't raise any errors until #body is called
|
120
|
+
response.tap(&:body)
|
121
|
+
rescue InvalidStateError => e
|
122
|
+
return get(e.conflicting_resource_id) if e.idempotent_creation_conflict?
|
123
|
+
|
124
|
+
raise e
|
125
|
+
end
|
126
|
+
|
127
|
+
return if response.body.nil?
|
128
|
+
|
129
|
+
Resources::MandateImport.new(unenvelope_body(response.body), response)
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
# Unenvelope the response of the body using the service's `envelope_key`
|
135
|
+
#
|
136
|
+
# @param body [Hash]
|
137
|
+
def unenvelope_body(body)
|
138
|
+
body[envelope_key] || body['data']
|
139
|
+
end
|
140
|
+
|
141
|
+
# return the key which API responses will envelope data under
|
142
|
+
def envelope_key
|
143
|
+
'mandate_imports'
|
144
|
+
end
|
145
|
+
|
146
|
+
# take a URL with placeholder params and substitute them out for the actual value
|
147
|
+
# @param url [String] the URL with placeholders in
|
148
|
+
# @param param_map [Hash] a hash of placeholders and their actual values (which will be escaped)
|
149
|
+
def sub_url(url, param_map)
|
150
|
+
param_map.reduce(url) do |new_url, (param, value)|
|
151
|
+
new_url.gsub(":#{param}", URI.escape(value))
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|