gocardless_pro 0.3.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.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +146 -0
  6. data/circle.yml +3 -0
  7. data/demo.rb +9 -0
  8. data/gocardless_pro.gemspec +26 -0
  9. data/lib/gocardless_pro.rb +73 -0
  10. data/lib/gocardless_pro/api_service.rb +58 -0
  11. data/lib/gocardless_pro/client.rb +135 -0
  12. data/lib/gocardless_pro/error.rb +42 -0
  13. data/lib/gocardless_pro/error/gocardless_error.rb +5 -0
  14. data/lib/gocardless_pro/error/invalid_api_usage_error.rb +5 -0
  15. data/lib/gocardless_pro/error/invalid_state_error.rb +5 -0
  16. data/lib/gocardless_pro/error/validation_error.rb +5 -0
  17. data/lib/gocardless_pro/list_response.rb +29 -0
  18. data/lib/gocardless_pro/paginator.rb +43 -0
  19. data/lib/gocardless_pro/request.rb +69 -0
  20. data/lib/gocardless_pro/resources/creditor.rb +84 -0
  21. data/lib/gocardless_pro/resources/creditor_bank_account.rb +78 -0
  22. data/lib/gocardless_pro/resources/customer.rb +75 -0
  23. data/lib/gocardless_pro/resources/customer_bank_account.rb +80 -0
  24. data/lib/gocardless_pro/resources/event.rb +75 -0
  25. data/lib/gocardless_pro/resources/helper.rb +29 -0
  26. data/lib/gocardless_pro/resources/mandate.rb +70 -0
  27. data/lib/gocardless_pro/resources/payment.rb +87 -0
  28. data/lib/gocardless_pro/resources/payout.rb +66 -0
  29. data/lib/gocardless_pro/resources/redirect_flow.rb +106 -0
  30. data/lib/gocardless_pro/resources/refund.rb +71 -0
  31. data/lib/gocardless_pro/resources/subscription.rb +155 -0
  32. data/lib/gocardless_pro/response.rb +77 -0
  33. data/lib/gocardless_pro/services/base_service.rb +28 -0
  34. data/lib/gocardless_pro/services/creditor_bank_accounts_service.rb +119 -0
  35. data/lib/gocardless_pro/services/creditors_service.rb +113 -0
  36. data/lib/gocardless_pro/services/customer_bank_accounts_service.rb +154 -0
  37. data/lib/gocardless_pro/services/customers_service.rb +113 -0
  38. data/lib/gocardless_pro/services/events_service.rb +80 -0
  39. data/lib/gocardless_pro/services/helpers_service.rb +99 -0
  40. data/lib/gocardless_pro/services/mandates_service.rb +173 -0
  41. data/lib/gocardless_pro/services/payments_service.rb +168 -0
  42. data/lib/gocardless_pro/services/payouts_service.rb +82 -0
  43. data/lib/gocardless_pro/services/redirect_flows_service.rb +98 -0
  44. data/lib/gocardless_pro/services/refunds_service.rb +132 -0
  45. data/lib/gocardless_pro/services/subscriptions_service.rb +134 -0
  46. data/lib/gocardless_pro/version.rb +8 -0
  47. data/spec/api_service_spec.rb +73 -0
  48. data/spec/client_spec.rb +19 -0
  49. data/spec/error_spec.rb +44 -0
  50. data/spec/resources/creditor_bank_account_spec.rb +109 -0
  51. data/spec/resources/creditor_spec.rb +125 -0
  52. data/spec/resources/customer_bank_account_spec.rb +109 -0
  53. data/spec/resources/customer_spec.rb +135 -0
  54. data/spec/resources/event_spec.rb +113 -0
  55. data/spec/resources/helper_spec.rb +23 -0
  56. data/spec/resources/mandate_spec.rb +97 -0
  57. data/spec/resources/payment_spec.rb +129 -0
  58. data/spec/resources/payout_spec.rb +89 -0
  59. data/spec/resources/redirect_flow_spec.rb +97 -0
  60. data/spec/resources/refund_spec.rb +77 -0
  61. data/spec/resources/subscription_spec.rb +165 -0
  62. data/spec/response_spec.rb +89 -0
  63. data/spec/services/creditor_bank_accounts_service_spec.rb +413 -0
  64. data/spec/services/creditors_service_spec.rb +388 -0
  65. data/spec/services/customer_bank_accounts_service_spec.rb +452 -0
  66. data/spec/services/customers_service_spec.rb +429 -0
  67. data/spec/services/events_service_spec.rb +217 -0
  68. data/spec/services/helpers_service_spec.rb +122 -0
  69. data/spec/services/mandates_service_spec.rb +495 -0
  70. data/spec/services/payments_service_spec.rb +546 -0
  71. data/spec/services/payouts_service_spec.rb +217 -0
  72. data/spec/services/redirect_flows_service_spec.rb +254 -0
  73. data/spec/services/refunds_service_spec.rb +323 -0
  74. data/spec/services/subscriptions_service_spec.rb +557 -0
  75. data/spec/spec_helper.rb +91 -0
  76. metadata +224 -0
@@ -0,0 +1,98 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+
9
+ module GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the RedirectFlow endpoints
12
+ class RedirectFlowsService < BaseService
13
+ # Creates a redirect flow object which can then be used to redirect your
14
+ # customer to the GoCardless Pro hosted payment pages.
15
+ # Example URL: /redirect_flows
16
+ # @param options [Hash] parameters as a hash, under a params key.
17
+ def create(options = {})
18
+ path = '/redirect_flows'
19
+
20
+ params = options.delete(:params) || {}
21
+ options[:params] = {}
22
+ options[:params][envelope_key] = params
23
+ response = make_request(:post, path, options)
24
+
25
+ return if response.body.nil?
26
+ Resources::RedirectFlow.new(unenvelope_body(response.body))
27
+ end
28
+
29
+ # Returns all details about a single redirect flow
30
+ # Example URL: /redirect_flows/:identity
31
+ #
32
+ # @param identity # Unique identifier, beginning with "RE".
33
+ # @param options [Hash] parameters as a hash, under a params key.
34
+ def get(identity, options = {})
35
+ path = sub_url('/redirect_flows/:identity', 'identity' => identity)
36
+
37
+ response = make_request(:get, path, options)
38
+
39
+ return if response.body.nil?
40
+ Resources::RedirectFlow.new(unenvelope_body(response.body))
41
+ end
42
+
43
+ # This creates a
44
+ # [customer](https://developer.gocardless.com/pro/2015-04-29/#api-endpoints-customers),
45
+ # [customer bank
46
+ # account](https://developer.gocardless.com/pro/2015-04-29/#api-endpoints-customer-bank-accounts),
47
+ # and
48
+ # [mandate](https://developer.gocardless.com/pro/2015-04-29/#api-endpoints-mandates)
49
+ # using the details supplied by your customer and returns the ID of the created
50
+ # mandate.
51
+ #
52
+ # This will return a `redirect_flow_incomplete` error if your
53
+ # customer has not yet been redirected back to your site, and a
54
+ # `redirect_flow_already_completed` error if your integration has already
55
+ # completed this flow. It will return a `bad_request` error if the
56
+ # `session_token` differs to the one supplied when the redirect flow was
57
+ # created.
58
+ # Example URL: /redirect_flows/:identity/actions/complete
59
+ #
60
+ # @param identity # Unique identifier, beginning with "RE".
61
+ # @param options [Hash] parameters as a hash, under a params key.
62
+ def complete(identity, options = {})
63
+ path = sub_url('/redirect_flows/:identity/actions/complete', 'identity' => identity)
64
+
65
+ params = options.delete(:params) || {}
66
+ options[:params] = {}
67
+ options[:params]['data'] = params
68
+ response = make_request(:post, path, options)
69
+
70
+ return if response.body.nil?
71
+ Resources::RedirectFlow.new(unenvelope_body(response.body))
72
+ end
73
+
74
+ # Unenvelope the response of the body using the service's `envelope_key`
75
+ #
76
+ # @param body [Hash]
77
+ def unenvelope_body(body)
78
+ body[envelope_key] || body['data']
79
+ end
80
+
81
+ private
82
+
83
+ # return the key which API responses will envelope data under
84
+ def envelope_key
85
+ 'redirect_flows'
86
+ end
87
+
88
+ # take a URL with placeholder params and substitute them out for the acutal value
89
+ # @param url [String] the URL with placeholders in
90
+ # @param param_map [Hash] a hash of placeholders and their actual values
91
+ def sub_url(url, param_map)
92
+ param_map.reduce(url) do |new_url, (param, value)|
93
+ new_url.gsub(":#{param}", value)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,132 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+
9
+ module GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the Refund endpoints
12
+ class RefundsService < BaseService
13
+ # Creates a new refund object.
14
+ #
15
+ # This fails with:<a
16
+ # name="refund_payment_invalid_state"></a><a
17
+ # name="total_amount_confirmation_invalid"></a><a
18
+ # name="number_of_refunds_exceeded"></a>
19
+ #
20
+ # - `refund_payment_invalid_state`
21
+ # error if the linked
22
+ # [payment](https://developer.gocardless.com/pro/2015-04-29/#api-endpoints-payments)
23
+ # isn't either `confirmed` or `paid_out`.
24
+ #
25
+ # -
26
+ # `total_amount_confirmation_invalid` if the confirmation amount doesn't match
27
+ # the total amount refunded for the payment. This safeguard is there to prevent
28
+ # two processes from creating refunds without awareness of each other.
29
+ #
30
+ # -
31
+ # `number_of_refunds_exceeded` if five or more refunds have already been created
32
+ # against the payment.
33
+ #
34
+ # Example URL: /refunds
35
+ # @param options [Hash] parameters as a hash, under a params key.
36
+ def create(options = {})
37
+ path = '/refunds'
38
+
39
+ params = options.delete(:params) || {}
40
+ options[:params] = {}
41
+ options[:params][envelope_key] = params
42
+ response = make_request(:post, path, options)
43
+
44
+ return if response.body.nil?
45
+ Resources::Refund.new(unenvelope_body(response.body))
46
+ end
47
+
48
+ # Returns a
49
+ # [cursor-paginated](https://developer.gocardless.com/pro/2015-04-29/#overview-cursor-pagination)
50
+ # list of your refunds.
51
+ # Example URL: /refunds
52
+ # @param options [Hash] parameters as a hash, under a params key.
53
+ def list(options = {})
54
+ path = '/refunds'
55
+
56
+ response = make_request(:get, path, options)
57
+ ListResponse.new(
58
+ raw_response: response,
59
+ unenveloped_body: unenvelope_body(response.body),
60
+ resource_class: Resources::Refund
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
+ path: '/refunds',
72
+ options: options,
73
+ resource_class: Resources::Refund
74
+ ).enumerator
75
+ end
76
+
77
+ # Retrieves all details for a single refund
78
+ # Example URL: /refunds/:identity
79
+ #
80
+ # @param identity # Unique identifier, beginning with "RF"
81
+ # @param options [Hash] parameters as a hash, under a params key.
82
+ def get(identity, options = {})
83
+ path = sub_url('/refunds/:identity', 'identity' => identity)
84
+
85
+ response = make_request(:get, path, options)
86
+
87
+ return if response.body.nil?
88
+ Resources::Refund.new(unenvelope_body(response.body))
89
+ end
90
+
91
+ # Updates a refund object.
92
+ # Example URL: /refunds/:identity
93
+ #
94
+ # @param identity # Unique identifier, beginning with "RF"
95
+ # @param options [Hash] parameters as a hash, under a params key.
96
+ def update(identity, options = {})
97
+ path = sub_url('/refunds/:identity', 'identity' => identity)
98
+
99
+ params = options.delete(:params) || {}
100
+ options[:params] = {}
101
+ options[:params][envelope_key] = params
102
+ response = make_request(:put, path, options)
103
+
104
+ return if response.body.nil?
105
+ Resources::Refund.new(unenvelope_body(response.body))
106
+ end
107
+
108
+ # Unenvelope the response of the body using the service's `envelope_key`
109
+ #
110
+ # @param body [Hash]
111
+ def unenvelope_body(body)
112
+ body[envelope_key] || body['data']
113
+ end
114
+
115
+ private
116
+
117
+ # return the key which API responses will envelope data under
118
+ def envelope_key
119
+ 'refunds'
120
+ end
121
+
122
+ # take a URL with placeholder params and substitute them out for the acutal value
123
+ # @param url [String] the URL with placeholders in
124
+ # @param param_map [Hash] a hash of placeholders and their actual values
125
+ def sub_url(url, param_map)
126
+ param_map.reduce(url) do |new_url, (param, value)|
127
+ new_url.gsub(":#{param}", value)
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,134 @@
1
+ require_relative './base_service'
2
+
3
+ # encoding: utf-8
4
+ #
5
+ # WARNING: Do not edit by hand, this file was generated by Crank:
6
+ #
7
+ # https://github.com/gocardless/crank
8
+
9
+ module GoCardlessPro
10
+ module Services
11
+ # Service for making requests to the Subscription endpoints
12
+ class SubscriptionsService < BaseService
13
+ # Creates a new subscription object
14
+ # Example URL: /subscriptions
15
+ # @param options [Hash] parameters as a hash, under a params key.
16
+ def create(options = {})
17
+ path = '/subscriptions'
18
+
19
+ params = options.delete(:params) || {}
20
+ options[:params] = {}
21
+ options[:params][envelope_key] = params
22
+ response = make_request(:post, path, options)
23
+
24
+ return if response.body.nil?
25
+ Resources::Subscription.new(unenvelope_body(response.body))
26
+ end
27
+
28
+ # Returns a
29
+ # [cursor-paginated](https://developer.gocardless.com/pro/2015-04-29/#overview-cursor-pagination)
30
+ # list of your subscriptions.
31
+ # Example URL: /subscriptions
32
+ # @param options [Hash] parameters as a hash, under a params key.
33
+ def list(options = {})
34
+ path = '/subscriptions'
35
+
36
+ response = make_request(:get, path, options)
37
+ ListResponse.new(
38
+ raw_response: response,
39
+ unenveloped_body: unenvelope_body(response.body),
40
+ resource_class: Resources::Subscription
41
+ )
42
+ end
43
+
44
+ # Get a lazily enumerated list of all the items returned. This is simmilar to the `list` method but will paginate for you automatically.
45
+ #
46
+ # @param options [Hash] parameters as a hash. If the request is a GET, these will be converted to query parameters.
47
+ # Otherwise they will be the body of the request.
48
+ def all(options = {})
49
+ Paginator.new(
50
+ service: self,
51
+ path: '/subscriptions',
52
+ options: options,
53
+ resource_class: Resources::Subscription
54
+ ).enumerator
55
+ end
56
+
57
+ # Retrieves the details of a single subscription.
58
+ # Example URL: /subscriptions/:identity
59
+ #
60
+ # @param identity # Unique identifier, beginning with "SB"
61
+ # @param options [Hash] parameters as a hash, under a params key.
62
+ def get(identity, options = {})
63
+ path = sub_url('/subscriptions/:identity', 'identity' => identity)
64
+
65
+ response = make_request(:get, path, options)
66
+
67
+ return if response.body.nil?
68
+ Resources::Subscription.new(unenvelope_body(response.body))
69
+ end
70
+
71
+ # Updates a subscription object.
72
+ # Example URL: /subscriptions/:identity
73
+ #
74
+ # @param identity # Unique identifier, beginning with "SB"
75
+ # @param options [Hash] parameters as a hash, under a params key.
76
+ def update(identity, options = {})
77
+ path = sub_url('/subscriptions/:identity', 'identity' => identity)
78
+
79
+ params = options.delete(:params) || {}
80
+ options[:params] = {}
81
+ options[:params][envelope_key] = params
82
+ response = make_request(:put, path, options)
83
+
84
+ return if response.body.nil?
85
+ Resources::Subscription.new(unenvelope_body(response.body))
86
+ end
87
+
88
+ # Immediately cancels a subscription; no more payments will be created under it.
89
+ # Any metadata supplied to this endpoint will be stored on the payment
90
+ # cancellation event it causes.
91
+ #
92
+ # This will fail with a cancellation_failed
93
+ # error if the subscription is already cancelled or finished.
94
+ # Example URL: /subscriptions/:identity/actions/cancel
95
+ #
96
+ # @param identity # Unique identifier, beginning with "SB"
97
+ # @param options [Hash] parameters as a hash, under a params key.
98
+ def cancel(identity, options = {})
99
+ path = sub_url('/subscriptions/:identity/actions/cancel', 'identity' => identity)
100
+
101
+ params = options.delete(:params) || {}
102
+ options[:params] = {}
103
+ options[:params]['data'] = params
104
+ response = make_request(:post, path, options)
105
+
106
+ return if response.body.nil?
107
+ Resources::Subscription.new(unenvelope_body(response.body))
108
+ end
109
+
110
+ # Unenvelope the response of the body using the service's `envelope_key`
111
+ #
112
+ # @param body [Hash]
113
+ def unenvelope_body(body)
114
+ body[envelope_key] || body['data']
115
+ end
116
+
117
+ private
118
+
119
+ # return the key which API responses will envelope data under
120
+ def envelope_key
121
+ 'subscriptions'
122
+ end
123
+
124
+ # take a URL with placeholder params and substitute them out for the acutal value
125
+ # @param url [String] the URL with placeholders in
126
+ # @param param_map [Hash] a hash of placeholders and their actual values
127
+ def sub_url(url, param_map)
128
+ param_map.reduce(url) do |new_url, (param, value)|
129
+ new_url.gsub(":#{param}", value)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,8 @@
1
+
2
+ module GoCardlessPro
3
+ end
4
+
5
+ module GoCardlessPro
6
+ # Current version of the GC gem
7
+ VERSION = '0.3.0'
8
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe GoCardlessPro::ApiService do
4
+ subject(:service) { described_class.new("https://api.example.com", "secret_token") }
5
+
6
+ it "uses basic auth" do
7
+ stub = stub_request(:get, 'https://api.example.com/customers').
8
+ with(headers: { "Authorization" => "Bearer secret_token" })
9
+ service.make_request(:get, "/customers")
10
+ expect(stub).to have_been_requested
11
+ end
12
+
13
+ describe "making a get request without any parameters" do
14
+ it "is expected to call the correct stub" do
15
+ stub = stub_request(:get, /.*api.example.com\/customers/)
16
+ service.make_request(:get, "/customers")
17
+ expect(stub).to have_been_requested
18
+ end
19
+ end
20
+
21
+ describe "making a get request with query parameters" do
22
+ it "correctly passes the query parameters" do
23
+ stub = stub_request(:get, /.*api.example.com\/customers\?a=1&b=2/)
24
+ service.make_request(:get, "/customers", params: { a: 1, b: 2 })
25
+ expect(stub).to have_been_requested
26
+ end
27
+ end
28
+
29
+ describe "making a post request with some data" do
30
+ it "passes the data in as the post body" do
31
+ stub = stub_request(:post, /.*api.example.com\/customers/).
32
+ with(body: { given_name: "Jack", family_name: "Franklin" })
33
+ service.make_request(:post, "/customers", params: {
34
+ given_name: "Jack",
35
+ family_name: "Franklin"
36
+ })
37
+ expect(stub).to have_been_requested
38
+ end
39
+ end
40
+
41
+ describe "making a post request with data and custom header" do
42
+ it "passes the data in as the post body" do
43
+ stub = stub_request(:post, /.*api.example.com\/customers/).
44
+ with(
45
+ body: { given_name: "Jack", family_name: "Franklin" },
46
+ headers: { 'Foo' => 'Bar' }
47
+ )
48
+
49
+ service.make_request(:post, "/customers", {
50
+ params: {
51
+ given_name: "Jack",
52
+ family_name: "Franklin"
53
+ },
54
+ headers: {
55
+ 'Foo' => 'Bar'
56
+ }
57
+ })
58
+ expect(stub).to have_been_requested
59
+ end
60
+ end
61
+
62
+ describe "making a put request with some data" do
63
+ it "passes the data in as the request body" do
64
+ stub = stub_request(:put, /.*api.example.com\/customers\/CU123/).
65
+ with(body: { given_name: "Jack", family_name: "Franklin" })
66
+ service.make_request(:put, "/customers/CU123", params: {
67
+ given_name: "Jack",
68
+ family_name: "Franklin"
69
+ })
70
+ expect(stub).to have_been_requested
71
+ end
72
+ end
73
+ end