gocardless_pro 2.27.0 → 2.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +20 -1
  3. data/lib/gocardless_pro.rb +6 -0
  4. data/lib/gocardless_pro/api_service.rb +4 -0
  5. data/lib/gocardless_pro/client.rb +6 -1
  6. data/lib/gocardless_pro/error/authentication_error.rb +4 -0
  7. data/lib/gocardless_pro/error/permission_error.rb +4 -0
  8. data/lib/gocardless_pro/error/rate_limit_error.rb +4 -0
  9. data/lib/gocardless_pro/middlewares/raise_gocardless_errors.rb +12 -1
  10. data/lib/gocardless_pro/resources/bank_authorisation.rb +3 -5
  11. data/lib/gocardless_pro/resources/billing_request.rb +29 -7
  12. data/lib/gocardless_pro/resources/billing_request_flow.rb +10 -0
  13. data/lib/gocardless_pro/resources/billing_request_template.rb +68 -0
  14. data/lib/gocardless_pro/resources/payer_authorisation.rb +9 -0
  15. data/lib/gocardless_pro/services/bank_authorisations_service.rb +0 -2
  16. data/lib/gocardless_pro/services/billing_request_flows_service.rb +23 -0
  17. data/lib/gocardless_pro/services/billing_request_templates_service.rb +131 -0
  18. data/lib/gocardless_pro/services/billing_requests_service.rb +49 -22
  19. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +0 -4
  20. data/lib/gocardless_pro/services/creditors_service.rb +0 -2
  21. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +0 -4
  22. data/lib/gocardless_pro/services/customers_service.rb +0 -2
  23. data/lib/gocardless_pro/services/instalment_schedules_service.rb +0 -6
  24. data/lib/gocardless_pro/services/mandate_imports_service.rb +0 -6
  25. data/lib/gocardless_pro/services/mandates_service.rb +0 -6
  26. data/lib/gocardless_pro/services/payer_authorisations_service.rb +0 -6
  27. data/lib/gocardless_pro/services/payments_service.rb +0 -6
  28. data/lib/gocardless_pro/services/redirect_flows_service.rb +0 -4
  29. data/lib/gocardless_pro/services/refunds_service.rb +0 -2
  30. data/lib/gocardless_pro/services/scenario_simulators_service.rb +28 -6
  31. data/lib/gocardless_pro/services/subscriptions_service.rb +2 -10
  32. data/lib/gocardless_pro/services/webhooks_service.rb +0 -2
  33. data/lib/gocardless_pro/version.rb +1 -1
  34. data/spec/api_service_spec.rb +12 -1
  35. data/spec/middlewares/raise_gocardless_errors_spec.rb +30 -0
  36. data/spec/resources/bank_authorisation_spec.rb +7 -7
  37. data/spec/resources/billing_request_flow_spec.rb +90 -0
  38. data/spec/resources/billing_request_spec.rb +75 -29
  39. data/spec/resources/billing_request_template_spec.rb +502 -0
  40. data/spec/services/bank_authorisations_service_spec.rb +7 -20
  41. data/spec/services/billing_request_flows_service_spec.rb +101 -0
  42. data/spec/services/billing_request_templates_service_spec.rb +789 -0
  43. data/spec/services/billing_requests_service_spec.rb +87 -47
  44. data/spec/services/creditor_bank_accounts_service_spec.rb +0 -13
  45. data/spec/services/creditors_service_spec.rb +0 -13
  46. data/spec/services/customer_bank_accounts_service_spec.rb +0 -13
  47. data/spec/services/customers_service_spec.rb +0 -13
  48. data/spec/services/instalment_schedules_service_spec.rb +0 -26
  49. data/spec/services/mandate_imports_service_spec.rb +0 -13
  50. data/spec/services/mandates_service_spec.rb +0 -13
  51. data/spec/services/payer_authorisations_service_spec.rb +0 -13
  52. data/spec/services/payments_service_spec.rb +0 -13
  53. data/spec/services/redirect_flows_service_spec.rb +0 -13
  54. data/spec/services/refunds_service_spec.rb +0 -13
  55. data/spec/services/subscriptions_service_spec.rb +0 -13
  56. metadata +16 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36f326b7d949867117fd93ecbe9074fcdb54ee3b690f046c2e48e16ce92281dc
4
- data.tar.gz: dba0ba60c85f16a5d3c87f311ea6b4b73d93a438441a2ff96c962669c56f7630
3
+ metadata.gz: ed30309cc0e32f7ec8fe6136447f06a06b7f6b42fea7ccadd35313cd2a5ca0a1
4
+ data.tar.gz: cd88fcef318324644a91336c487e2704283e12120c938bc48bfbba5cbaa36919
5
5
  SHA512:
6
- metadata.gz: 5e5939895e083285066011907aad6a992fbb1f65b86392482964a4c856f64bf2834d9a63bb20faf2e7d3c00d5fa27e32ec0c2a9c4770f805ef2db2ba2983c79f
7
- data.tar.gz: da519896309a48029ff7d5fb47f2747234b119fb7b539a8701892fe19ea2c921d3606cd66dc9ed4ce70f891a408a979176de5806881a44ce6a82b600aa8cb91b
6
+ metadata.gz: af3903ffe4dc7425072a286abc535fa379fd8d293307112d6f26b66d1ed283b7f8a440cddf833f255b13507b09ed5671d43e30773b1b50305c736ae30c84520b
7
+ data.tar.gz: c1f579f53780f7c1f96464810e2a5186fddf1d041af62f7cf975fa6d7e4304c1d149b74ff9fdf3d07985e41bb1ee46eb71ac67d556aab49343e85650e02f06b7
data/.circleci/config.yml CHANGED
@@ -13,7 +13,19 @@ jobs:
13
13
  steps:
14
14
  - checkout
15
15
  - run: bundle install && bundle exec rspec
16
-
16
+ publish: &publish
17
+ docker:
18
+ - image: ruby:2.6
19
+ steps:
20
+ - checkout
21
+ - run: |
22
+ mkdir -p $HOME/.gem
23
+ touch $HOME/.gem/credentials
24
+ chmod 0600 $HOME/.gem/credentials
25
+ printf -- "---\n:rubygems_api_key: $RUBYGEM_PUBLISH_API_KEY\n" > $HOME/.gem/credentials
26
+ gem build *.gemspec
27
+ gem push *.gem
28
+
17
29
  workflows:
18
30
  version: 2
19
31
  tests:
@@ -30,3 +42,10 @@ workflows:
30
42
  ruby-version: "2.2"
31
43
  - faraday-version: "0.9.2"
32
44
  ruby-version: "3.0"
45
+ - publish:
46
+ filters:
47
+ branches:
48
+ only:
49
+ - master
50
+ requires:
51
+ - test
@@ -32,6 +32,9 @@ require_relative 'gocardless_pro/error/gocardless_error'
32
32
  require_relative 'gocardless_pro/error/invalid_api_usage_error'
33
33
  require_relative 'gocardless_pro/error/invalid_state_error'
34
34
  require_relative 'gocardless_pro/error/api_error'
35
+ require_relative 'gocardless_pro/error/permission_error'
36
+ require_relative 'gocardless_pro/error/authentication_error'
37
+ require_relative 'gocardless_pro/error/rate_limit_error'
35
38
  require_relative 'gocardless_pro/paginator'
36
39
  require_relative 'gocardless_pro/request'
37
40
  require_relative 'gocardless_pro/response'
@@ -50,6 +53,9 @@ require_relative 'gocardless_pro/services/billing_requests_service'
50
53
  require_relative 'gocardless_pro/resources/billing_request_flow'
51
54
  require_relative 'gocardless_pro/services/billing_request_flows_service'
52
55
 
56
+ require_relative 'gocardless_pro/resources/billing_request_template'
57
+ require_relative 'gocardless_pro/services/billing_request_templates_service'
58
+
53
59
  require_relative 'gocardless_pro/resources/creditor'
54
60
  require_relative 'gocardless_pro/services/creditors_service'
55
61
 
@@ -34,6 +34,10 @@ module GoCardlessPro
34
34
  @headers = options[:default_headers] || {}
35
35
  @headers['Authorization'] = "Bearer #{token}"
36
36
  @on_idempotency_conflict = options[:on_idempotency_conflict] || :fetch
37
+
38
+ unless %i[fetch raise].include?(@on_idempotency_conflict)
39
+ raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
40
+ end
37
41
  end
38
42
 
39
43
  # Make a request to the API
@@ -23,6 +23,11 @@ module GoCardlessPro
23
23
  @billing_request_flows ||= Services::BillingRequestFlowsService.new(@api_service)
24
24
  end
25
25
 
26
+ # Access to the service for billing_request_template to make API calls
27
+ def billing_request_templates
28
+ @billing_request_templates ||= Services::BillingRequestTemplatesService.new(@api_service)
29
+ end
30
+
26
31
  # Access to the service for creditor to make API calls
27
32
  def creditors
28
33
  @creditors ||= Services::CreditorsService.new(@api_service)
@@ -188,7 +193,7 @@ module GoCardlessPro
188
193
  'User-Agent' => user_agent.to_s,
189
194
  'Content-Type' => 'application/json',
190
195
  'GoCardless-Client-Library' => 'gocardless-pro-ruby',
191
- 'GoCardless-Client-Version' => '2.27.0',
196
+ 'GoCardless-Client-Version' => '2.28.0',
192
197
  },
193
198
  }
194
199
  end
@@ -0,0 +1,4 @@
1
+ module GoCardlessPro
2
+ class AuthenticationError < InvalidApiUsageError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module GoCardlessPro
2
+ class PermissionError < InvalidApiUsageError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module GoCardlessPro
2
+ class RateLimitError < InvalidApiUsageError
3
+ end
4
+ end
@@ -12,12 +12,23 @@ module GoCardlessPro
12
12
  if CLIENT_ERROR_STATUSES.include?(env.status)
13
13
  json_body ||= JSON.parse(env.body) unless env.body.empty?
14
14
  error_type = json_body['error']['type']
15
- raise(error_class_for_type(error_type), json_body['error'])
15
+
16
+ error_class = error_class_for_status(env.status) || error_class_for_type(error_type)
17
+
18
+ raise(error_class, json_body['error'])
16
19
  end
17
20
  end
18
21
 
19
22
  private
20
23
 
24
+ def error_class_for_status(code)
25
+ {
26
+ 401 => GoCardlessPro::AuthenticationError,
27
+ 403 => GoCardlessPro::PermissionError,
28
+ 429 => GoCardlessPro::RateLimitError,
29
+ }.fetch(code, nil)
30
+ end
31
+
21
32
  def error_class_for_type(type)
22
33
  {
23
34
  validation_failed: GoCardlessPro::ValidationError,
@@ -21,17 +21,15 @@ module GoCardlessPro
21
21
  # Creation of Bank Authorisations is only permitted from GoCardless hosted
22
22
  # UIs
23
23
  # (see Billing Request Flows) to ensure we meet regulatory requirements for
24
- # checkout flows. The exceptions are integrators with the custom payment
25
- # pages
26
- # upgrade, who have been audited to check their flows meet requirements.
24
+ # checkout flows.
27
25
  class BankAuthorisation
28
26
  attr_reader :authorisation_type
27
+ attr_reader :authorised_at
29
28
  attr_reader :created_at
30
29
  attr_reader :expires_at
31
30
  attr_reader :id
32
31
  attr_reader :last_visited_at
33
32
  attr_reader :redirect_uri
34
- attr_reader :short_url
35
33
  attr_reader :url
36
34
 
37
35
  # Initialize a bank_authorisation resource instance
@@ -40,13 +38,13 @@ module GoCardlessPro
40
38
  @object = object
41
39
 
42
40
  @authorisation_type = object['authorisation_type']
41
+ @authorised_at = object['authorised_at']
43
42
  @created_at = object['created_at']
44
43
  @expires_at = object['expires_at']
45
44
  @id = object['id']
46
45
  @last_visited_at = object['last_visited_at']
47
46
  @links = object['links']
48
47
  @redirect_uri = object['redirect_uri']
49
- @short_url = object['short_url']
50
48
  @url = object['url']
51
49
  @response = response
52
50
  end
@@ -12,10 +12,17 @@ module GoCardlessPro
12
12
  module Resources
13
13
  # Represents an instance of a billing_request resource returned from the API
14
14
 
15
- # Billing Requests
15
+ # Billing Requests help create resources that require input or action from a
16
+ # customer. An example of required input might be additional customer
17
+ # billing
18
+ # details, while an action would be asking a customer to authorise a payment
19
+ # using their mobile banking app.
20
+ #
21
+ # See [Billing Requests:
22
+ # Overview](https://developer.gocardless.com/getting-started/billing-requests/overview/)
23
+ # for how-to's, explanations and tutorials.
16
24
  class BillingRequest
17
25
  attr_reader :actions
18
- attr_reader :auto_fulfil
19
26
  attr_reader :created_at
20
27
  attr_reader :id
21
28
  attr_reader :mandate_request
@@ -30,7 +37,6 @@ module GoCardlessPro
30
37
  @object = object
31
38
 
32
39
  @actions = object['actions']
33
- @auto_fulfil = object['auto_fulfil']
34
40
  @created_at = object['created_at']
35
41
  @id = object['id']
36
42
  @links = object['links']
@@ -61,6 +67,14 @@ module GoCardlessPro
61
67
  @links = links || {}
62
68
  end
63
69
 
70
+ def bank_authorisation
71
+ @links['bank_authorisation']
72
+ end
73
+
74
+ def creditor
75
+ @links['creditor']
76
+ end
77
+
64
78
  def customer
65
79
  @links['customer']
66
80
  end
@@ -73,12 +87,20 @@ module GoCardlessPro
73
87
  @links['customer_billing_detail']
74
88
  end
75
89
 
76
- def mandate_bank_authorisation
77
- @links['mandate_bank_authorisation']
90
+ def mandate_request
91
+ @links['mandate_request']
92
+ end
93
+
94
+ def mandate_request_mandate
95
+ @links['mandate_request_mandate']
96
+ end
97
+
98
+ def payment_request
99
+ @links['payment_request']
78
100
  end
79
101
 
80
- def payment_bank_authorisation
81
- @links['payment_bank_authorisation']
102
+ def payment_request_payment
103
+ @links['payment_request_payment']
82
104
  end
83
105
  end
84
106
  end
@@ -17,9 +17,14 @@ module GoCardlessPro
17
17
  # authorisation (such as open banking single payments).
18
18
  class BillingRequestFlow
19
19
  attr_reader :authorisation_url
20
+ attr_reader :auto_fulfil
20
21
  attr_reader :created_at
21
22
  attr_reader :expires_at
23
+ attr_reader :id
24
+ attr_reader :lock_bank_account
25
+ attr_reader :lock_customer_details
22
26
  attr_reader :redirect_uri
27
+ attr_reader :session_token
23
28
 
24
29
  # Initialize a billing_request_flow resource instance
25
30
  # @param object [Hash] an object returned from the API
@@ -27,10 +32,15 @@ module GoCardlessPro
27
32
  @object = object
28
33
 
29
34
  @authorisation_url = object['authorisation_url']
35
+ @auto_fulfil = object['auto_fulfil']
30
36
  @created_at = object['created_at']
31
37
  @expires_at = object['expires_at']
38
+ @id = object['id']
32
39
  @links = object['links']
40
+ @lock_bank_account = object['lock_bank_account']
41
+ @lock_customer_details = object['lock_customer_details']
33
42
  @redirect_uri = object['redirect_uri']
43
+ @session_token = object['session_token']
34
44
  @response = response
35
45
  end
36
46
 
@@ -0,0 +1,68 @@
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 billing_request_template resource returned from the API
14
+
15
+ # Billing Request Templates
16
+ class BillingRequestTemplate
17
+ attr_reader :authorisation_url
18
+ attr_reader :created_at
19
+ attr_reader :id
20
+ attr_reader :mandate_request_currency
21
+ attr_reader :mandate_request_metadata
22
+ attr_reader :mandate_request_scheme
23
+ attr_reader :mandate_request_verify
24
+ attr_reader :metadata
25
+ attr_reader :name
26
+ attr_reader :payment_request_amount
27
+ attr_reader :payment_request_currency
28
+ attr_reader :payment_request_description
29
+ attr_reader :payment_request_metadata
30
+ attr_reader :payment_request_scheme
31
+ attr_reader :redirect_uri
32
+ attr_reader :updated_at
33
+
34
+ # Initialize a billing_request_template resource instance
35
+ # @param object [Hash] an object returned from the API
36
+ def initialize(object, response = nil)
37
+ @object = object
38
+
39
+ @authorisation_url = object['authorisation_url']
40
+ @created_at = object['created_at']
41
+ @id = object['id']
42
+ @mandate_request_currency = object['mandate_request_currency']
43
+ @mandate_request_metadata = object['mandate_request_metadata']
44
+ @mandate_request_scheme = object['mandate_request_scheme']
45
+ @mandate_request_verify = object['mandate_request_verify']
46
+ @metadata = object['metadata']
47
+ @name = object['name']
48
+ @payment_request_amount = object['payment_request_amount']
49
+ @payment_request_currency = object['payment_request_currency']
50
+ @payment_request_description = object['payment_request_description']
51
+ @payment_request_metadata = object['payment_request_metadata']
52
+ @payment_request_scheme = object['payment_request_scheme']
53
+ @redirect_uri = object['redirect_uri']
54
+ @updated_at = object['updated_at']
55
+ @response = response
56
+ end
57
+
58
+ def api_response
59
+ ApiResponse.new(@response)
60
+ end
61
+
62
+ # Provides the billing_request_template resource as a hash of all its readable attributes
63
+ def to_h
64
+ @object
65
+ end
66
+ end
67
+ end
68
+ end
@@ -12,6 +12,15 @@ module GoCardlessPro
12
12
  module Resources
13
13
  # Represents an instance of a payer_authorisation resource returned from the API
14
14
 
15
+ # <p class="restricted-notice">
16
+ # Payer Authorisations is deprecated in favour of
17
+ # <a
18
+ # href="https://developer.gocardless.com/getting-started/billing-requests/overview/">
19
+ # Billing Requests</a>. Please consider using Billing Requests to build
20
+ # any
21
+ # future integrations.
22
+ # </p>
23
+ #
15
24
  # Payer Authorisation resource acts as a wrapper for creating customer, bank
16
25
  # account and mandate details in a single request.
17
26
  # PayerAuthorisation API enables the integrators to build their own custom
@@ -51,8 +51,6 @@ module GoCardlessPro
51
51
  raise IdempotencyConflict, e.error
52
52
  when :fetch
53
53
  return get(e.conflicting_resource_id)
54
- else
55
- raise ArgumentError, 'Unknown mode for :on_idempotency_conflict'
56
54
  end
57
55
  end
58
56
 
@@ -29,6 +29,29 @@ module GoCardlessPro
29
29
  Resources::BillingRequestFlow.new(unenvelope_body(response.body), response)
30
30
  end
31
31
 
32
+ # Returns the flow having generated a fresh session token which can be used to
33
+ # power
34
+ # integrations that manipulate the flow.
35
+ # Example URL: /billing_request_flows/:identity/actions/initialise
36
+ #
37
+ # @param identity # Unique identifier, beginning with "BRQ".
38
+ # @param options [Hash] parameters as a hash, under a params key.
39
+ def initialise(identity, options = {})
40
+ path = sub_url('/billing_request_flows/:identity/actions/initialise', 'identity' => identity)
41
+
42
+ params = options.delete(:params) || {}
43
+ options[:params] = {}
44
+ options[:params]['data'] = params
45
+
46
+ options[:retry_failures] = false
47
+
48
+ response = make_request(:post, path, options)
49
+
50
+ return if response.body.nil?
51
+
52
+ Resources::BillingRequestFlow.new(unenvelope_body(response.body), response)
53
+ end
54
+
32
55
  private
33
56
 
34
57
  # Unenvelope the response of the body using the service's `envelope_key`
@@ -0,0 +1,131 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # This client is automatically generated from a template and JSON schema definition.
6
+ # See https://github.com/gocardless/gocardless-pro-ruby#contributing before editing.
7
+ #
8
+
9
+ module GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the BillingRequestTemplate endpoints
12
+ class BillingRequestTemplatesService < BaseService
13
+ # Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your
14
+ # Billing Request Templates.
15
+ # Example URL: /billing_request_templates
16
+ # @param options [Hash] parameters as a hash, under a params key.
17
+ def list(options = {})
18
+ path = '/billing_request_templates'
19
+
20
+ options[:retry_failures] = true
21
+
22
+ response = make_request(:get, path, options)
23
+
24
+ ListResponse.new(
25
+ response: response,
26
+ unenveloped_body: unenvelope_body(response.body),
27
+ resource_class: Resources::BillingRequestTemplate
28
+ )
29
+ end
30
+
31
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
32
+ #
33
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
34
+ # Otherwise they will be the body of the request.
35
+ def all(options = {})
36
+ Paginator.new(
37
+ service: self,
38
+ options: options
39
+ ).enumerator
40
+ end
41
+
42
+ # Fetches a Billing Request Template
43
+ # Example URL: /billing_request_templates/:identity
44
+ #
45
+ # @param identity # Unique identifier, beginning with "BRT".
46
+ # @param options [Hash] parameters as a hash, under a params key.
47
+ def get(identity, options = {})
48
+ path = sub_url('/billing_request_templates/:identity', 'identity' => identity)
49
+
50
+ options[:retry_failures] = true
51
+
52
+ response = make_request(:get, path, options)
53
+
54
+ return if response.body.nil?
55
+
56
+ Resources::BillingRequestTemplate.new(unenvelope_body(response.body), response)
57
+ end
58
+
59
+ #
60
+ # Example URL: /billing_request_templates
61
+ # @param options [Hash] parameters as a hash, under a params key.
62
+ def create(options = {})
63
+ path = '/billing_request_templates'
64
+
65
+ params = options.delete(:params) || {}
66
+ options[:params] = {}
67
+ options[:params][envelope_key] = params
68
+
69
+ options[:retry_failures] = true
70
+
71
+ begin
72
+ response = make_request(:post, path, options)
73
+
74
+ # Response doesn't raise any errors until #body is called
75
+ response.tap(&:body)
76
+ rescue InvalidStateError => e
77
+ if e.idempotent_creation_conflict?
78
+ case @api_service.on_idempotency_conflict
79
+ when :raise
80
+ raise IdempotencyConflict, e.error
81
+ when :fetch
82
+ return get(e.conflicting_resource_id)
83
+ end
84
+ end
85
+
86
+ raise e
87
+ end
88
+
89
+ return if response.body.nil?
90
+
91
+ Resources::BillingRequestTemplate.new(unenvelope_body(response.body), response)
92
+ end
93
+
94
+ # Updates a Billing Request Template, which will affect all future Billing
95
+ # Requests created by this template.
96
+ # Example URL: /billing_requests/:identity
97
+ #
98
+ # @param identity # Unique identifier, beginning with "BRQ".
99
+ # @param options [Hash] parameters as a hash, under a params key.
100
+ def update(identity, options = {})
101
+ path = sub_url('/billing_requests/:identity', 'identity' => identity)
102
+
103
+ params = options.delete(:params) || {}
104
+ options[:params] = {}
105
+ options[:params][envelope_key] = params
106
+
107
+ options[:retry_failures] = true
108
+
109
+ response = make_request(:put, path, options)
110
+
111
+ return if response.body.nil?
112
+
113
+ Resources::BillingRequestTemplate.new(unenvelope_body(response.body), response)
114
+ end
115
+
116
+ private
117
+
118
+ # Unenvelope the response of the body using the service's `envelope_key`
119
+ #
120
+ # @param body [Hash]
121
+ def unenvelope_body(body)
122
+ body[envelope_key] || body['data']
123
+ end
124
+
125
+ # return the key which API responses will envelope data under
126
+ def envelope_key
127
+ 'billing_request_templates'
128
+ end
129
+ end
130
+ end
131
+ end