recurly 2.18.21 → 3.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +158 -110
- data/Rakefile +6 -0
- data/bin/bundle +105 -0
- data/bin/coderay +29 -0
- data/bin/console +14 -0
- data/bin/htmldiff +29 -0
- data/bin/ldiff +29 -0
- data/bin/pry +29 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/setup +8 -0
- data/bin/yard +29 -0
- data/bin/yardoc +29 -0
- data/bin/yri +29 -0
- data/lib/data/ca-certificates.crt +31 -0
- data/lib/recurly/client/operations.rb +935 -0
- data/lib/recurly/client.rb +198 -0
- data/lib/recurly/errors/api_errors.rb +35 -0
- data/lib/recurly/errors/network_errors.rb +8 -0
- data/lib/recurly/errors.rb +34 -0
- data/lib/recurly/pager.rb +119 -0
- data/lib/recurly/request.rb +30 -0
- data/lib/recurly/requests/account_acquisition_updatable.rb +22 -0
- data/lib/recurly/requests/account_create_only.rb +18 -0
- data/lib/recurly/requests/account_updatable.rb +50 -0
- data/lib/recurly/requests/add_on_create.rb +38 -0
- data/lib/recurly/requests/add_on_update.rb +38 -0
- data/lib/recurly/requests/address.rb +42 -0
- data/lib/recurly/requests/billing_info_create.rb +58 -0
- data/lib/recurly/requests/coupon_create_only.rb +66 -0
- data/lib/recurly/requests/coupon_updatable.rb +30 -0
- data/lib/recurly/requests/create_account.rb +62 -0
- data/lib/recurly/requests/create_coupon.rb +90 -0
- data/lib/recurly/requests/invoice_create.rb +42 -0
- data/lib/recurly/requests/invoice_refund.rb +30 -0
- data/lib/recurly/requests/line_item_create.rb +46 -0
- data/lib/recurly/requests/plan_create.rb +66 -0
- data/lib/recurly/requests/plan_update.rb +70 -0
- data/lib/recurly/requests/shipping_address_create.rb +58 -0
- data/lib/recurly/requests/shipping_address_update.rb +62 -0
- data/lib/recurly/requests/subscription_add_on_create.rb +22 -0
- data/lib/recurly/requests/subscription_change_create.rb +42 -0
- data/lib/recurly/requests/subscription_create.rb +86 -0
- data/lib/recurly/requests/subscription_update.rb +42 -0
- data/lib/recurly/requests/update_coupon.rb +30 -0
- data/lib/recurly/resource.rb +16 -1103
- data/lib/recurly/resources/account.rb +86 -0
- data/lib/recurly/resources/account_acquisition.rb +42 -0
- data/lib/recurly/resources/account_balance.rb +22 -0
- data/lib/recurly/resources/account_note.rb +30 -0
- data/lib/recurly/resources/add_on.rb +62 -0
- data/lib/recurly/resources/address.rb +42 -0
- data/lib/recurly/resources/billing_info.rb +62 -0
- data/lib/recurly/resources/coupon.rb +110 -0
- data/lib/recurly/resources/coupon_discount.rb +22 -0
- data/lib/recurly/resources/coupon_redemption.rb +46 -0
- data/lib/recurly/resources/credit_payment.rb +62 -0
- data/lib/recurly/resources/error.rb +18 -0
- data/lib/recurly/resources/error_may_have_transaction.rb +22 -0
- data/lib/recurly/resources/invoice.rb +138 -0
- data/lib/recurly/resources/invoice_collection.rb +18 -0
- data/lib/recurly/resources/line_item.rb +166 -0
- data/lib/recurly/resources/plan.rb +86 -0
- data/lib/recurly/resources/settings.rb +18 -0
- data/lib/recurly/resources/shipping_address.rb +74 -0
- data/lib/recurly/resources/site.rb +46 -0
- data/lib/recurly/resources/subscription.rb +134 -0
- data/lib/recurly/resources/subscription_add_on.rb +42 -0
- data/lib/recurly/resources/subscription_change.rb +54 -0
- data/lib/recurly/resources/tax_info.rb +18 -0
- data/lib/recurly/resources/transaction.rb +146 -0
- data/lib/recurly/resources/unique_coupon_code.rb +38 -0
- data/lib/recurly/resources/user.rb +38 -0
- data/lib/recurly/schema/json_deserializer.rb +53 -0
- data/lib/recurly/schema/json_parser.rb +71 -0
- data/lib/recurly/schema/request_caster.rb +66 -0
- data/lib/recurly/schema/schema_factory.rb +50 -0
- data/lib/recurly/schema/schema_validator.rb +125 -0
- data/lib/recurly/schema.rb +114 -0
- data/lib/recurly/version.rb +1 -10
- data/lib/recurly.rb +14 -145
- data/recurly.gemspec +32 -0
- data/scripts/build +4 -0
- data/scripts/clean +6 -0
- data/scripts/test +3 -0
- metadata +129 -173
- data/lib/recurly/account.rb +0 -209
- data/lib/recurly/account_acquisition.rb +0 -27
- data/lib/recurly/account_balance.rb +0 -21
- data/lib/recurly/add_on.rb +0 -46
- data/lib/recurly/address.rb +0 -25
- data/lib/recurly/adjustment.rb +0 -81
- data/lib/recurly/api/errors.rb +0 -208
- data/lib/recurly/api/net_http_adapter.rb +0 -111
- data/lib/recurly/api.rb +0 -110
- data/lib/recurly/billing_info.rb +0 -113
- data/lib/recurly/coupon.rb +0 -136
- data/lib/recurly/credit_payment.rb +0 -32
- data/lib/recurly/custom_field.rb +0 -15
- data/lib/recurly/delivery.rb +0 -19
- data/lib/recurly/error.rb +0 -13
- data/lib/recurly/gift_card.rb +0 -85
- data/lib/recurly/helper.rb +0 -51
- data/lib/recurly/invoice.rb +0 -304
- data/lib/recurly/invoice_collection.rb +0 -14
- data/lib/recurly/item.rb +0 -36
- data/lib/recurly/js.rb +0 -14
- data/lib/recurly/juris_detail.rb +0 -15
- data/lib/recurly/measured_unit.rb +0 -16
- data/lib/recurly/money.rb +0 -120
- data/lib/recurly/note.rb +0 -14
- data/lib/recurly/plan.rb +0 -43
- data/lib/recurly/purchase.rb +0 -238
- data/lib/recurly/redemption.rb +0 -46
- data/lib/recurly/resource/association.rb +0 -16
- data/lib/recurly/resource/errors.rb +0 -20
- data/lib/recurly/resource/pager.rb +0 -313
- data/lib/recurly/shipping_address.rb +0 -26
- data/lib/recurly/shipping_fee.rb +0 -17
- data/lib/recurly/shipping_method.rb +0 -13
- data/lib/recurly/subscription/add_ons.rb +0 -82
- data/lib/recurly/subscription.rb +0 -366
- data/lib/recurly/subscription_add_on.rb +0 -58
- data/lib/recurly/tax_detail.rb +0 -18
- data/lib/recurly/tax_type.rb +0 -13
- data/lib/recurly/tier.rb +0 -18
- data/lib/recurly/transaction/errors.rb +0 -115
- data/lib/recurly/transaction.rb +0 -131
- data/lib/recurly/usage.rb +0 -28
- data/lib/recurly/verify.rb +0 -12
- data/lib/recurly/webhook/account_notification.rb +0 -13
- data/lib/recurly/webhook/billing_info_update_failed_notification.rb +0 -6
- data/lib/recurly/webhook/billing_info_updated_notification.rb +0 -6
- data/lib/recurly/webhook/canceled_account_notification.rb +0 -6
- data/lib/recurly/webhook/canceled_gift_card_notification.rb +0 -6
- data/lib/recurly/webhook/canceled_subscription_notification.rb +0 -6
- data/lib/recurly/webhook/closed_credit_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/closed_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/credit_payment_notification.rb +0 -12
- data/lib/recurly/webhook/deactivated_item_notification.rb +0 -6
- data/lib/recurly/webhook/deleted_shipping_address_notification.rb +0 -6
- data/lib/recurly/webhook/dunning_notification.rb +0 -14
- data/lib/recurly/webhook/expired_subscription_notification.rb +0 -6
- data/lib/recurly/webhook/failed_charge_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/failed_payment_notification.rb +0 -6
- data/lib/recurly/webhook/fraud_info_updated_notification.rb +0 -6
- data/lib/recurly/webhook/gift_card_notification.rb +0 -8
- data/lib/recurly/webhook/invoice_notification.rb +0 -12
- data/lib/recurly/webhook/item_notification.rb +0 -7
- data/lib/recurly/webhook/low_balance_gift_card_notification.rb +0 -6
- data/lib/recurly/webhook/new_account_notification.rb +0 -6
- data/lib/recurly/webhook/new_charge_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/new_credit_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/new_credit_payment_notification.rb +0 -6
- data/lib/recurly/webhook/new_dunning_event_notification.rb +0 -6
- data/lib/recurly/webhook/new_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/new_item_notification.rb +0 -6
- data/lib/recurly/webhook/new_shipping_address_notification.rb +0 -6
- data/lib/recurly/webhook/new_subscription_notification.rb +0 -6
- data/lib/recurly/webhook/new_usage_notification.rb +0 -8
- data/lib/recurly/webhook/notification.rb +0 -18
- data/lib/recurly/webhook/paid_charge_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/past_due_charge_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/past_due_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/paused_subscription_renewal_notification.rb +0 -6
- data/lib/recurly/webhook/prerenewal_notification.rb +0 -6
- data/lib/recurly/webhook/processing_charge_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/processing_credit_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/processing_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/processing_payment_notification.rb +0 -6
- data/lib/recurly/webhook/purchased_gift_card_notification.rb +0 -7
- data/lib/recurly/webhook/reactivated_account_notification.rb +0 -6
- data/lib/recurly/webhook/reactivated_item_notification.rb +0 -6
- data/lib/recurly/webhook/redeemed_gift_card_notification.rb +0 -7
- data/lib/recurly/webhook/regenerated_gift_card_notification.rb +0 -6
- data/lib/recurly/webhook/renewed_subscription_notification.rb +0 -6
- data/lib/recurly/webhook/reopened_charge_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/reopened_credit_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/scheduled_payment_notification.rb +0 -6
- data/lib/recurly/webhook/scheduled_subscription_pause_notification.rb +0 -6
- data/lib/recurly/webhook/scheduled_subscription_update_notification.rb +0 -6
- data/lib/recurly/webhook/subscription_notification.rb +0 -12
- data/lib/recurly/webhook/subscription_pause_canceled_notification.rb +0 -6
- data/lib/recurly/webhook/subscription_pause_modified_notification.rb +0 -6
- data/lib/recurly/webhook/subscription_paused_notification.rb +0 -6
- data/lib/recurly/webhook/subscription_resumed_notification.rb +0 -6
- data/lib/recurly/webhook/successful_payment_notification.rb +0 -6
- data/lib/recurly/webhook/successful_refund_notification.rb +0 -6
- data/lib/recurly/webhook/transaction_authorized_notification.rb +0 -6
- data/lib/recurly/webhook/transaction_notification.rb +0 -12
- data/lib/recurly/webhook/transaction_status_updated_notification.rb +0 -6
- data/lib/recurly/webhook/updated_account_notification.rb +0 -6
- data/lib/recurly/webhook/updated_balance_gift_card_notification.rb +0 -7
- data/lib/recurly/webhook/updated_gift_card_notification.rb +0 -6
- data/lib/recurly/webhook/updated_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/updated_item_notification.rb +0 -6
- data/lib/recurly/webhook/updated_shipping_address_notification.rb +0 -6
- data/lib/recurly/webhook/updated_subscription_notification.rb +0 -6
- data/lib/recurly/webhook/void_payment_notification.rb +0 -6
- data/lib/recurly/webhook/voided_credit_invoice_notification.rb +0 -6
- data/lib/recurly/webhook/voided_credit_payment_notification.rb +0 -6
- data/lib/recurly/webhook.rb +0 -113
- data/lib/recurly/xml/nokogiri.rb +0 -60
- data/lib/recurly/xml/rexml.rb +0 -52
- data/lib/recurly/xml.rb +0 -122
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'logger'
|
3
|
+
require_relative './schema/json_parser'
|
4
|
+
|
5
|
+
module Recurly
|
6
|
+
class Client
|
7
|
+
require_relative './client/operations'
|
8
|
+
|
9
|
+
BASE_URL = "https://partner-api.recurly.com/"
|
10
|
+
|
11
|
+
# The last result of the *X-RateLimit-Limit* header
|
12
|
+
# @return [Integer] The rate limit applied to this client.
|
13
|
+
attr_reader :rate_limit
|
14
|
+
|
15
|
+
# The last result of the *X-RateLimit-Remaining* header
|
16
|
+
# @return [Integer] The number of remaining requests, decrements per request.
|
17
|
+
attr_reader :rate_limit_remaining
|
18
|
+
|
19
|
+
# The last result of the *X-RateLimit-Reset* header
|
20
|
+
# @return [DateTime] The DateTime in which the request count will be reset.
|
21
|
+
attr_reader :rate_limit_reset
|
22
|
+
|
23
|
+
# Initialize a client. It requires an API key.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# API_KEY = '83749879bbde395b5fe0cc1a5abf8e5'
|
27
|
+
# SITE_ID = 'dqzlv9shi7wa'
|
28
|
+
# client = Recurly::Client.new(site_id: SITE_ID, api_key: API_KEY)
|
29
|
+
# # You can optionally use the subdomain instead of the site id
|
30
|
+
# client = Recurly::Client.new(subdomain: 'mysite-prod', api_key: API_KEY)
|
31
|
+
# sub = client.get_subscription(subscription_id: 'abcd123456')
|
32
|
+
# @example
|
33
|
+
# # You can also pass the initializer a block. This will give you
|
34
|
+
# # a client scoped for just that block
|
35
|
+
# Recurly::Client.new(subdomain: 'mysite-prod', api_key: API_KEY) do |client|
|
36
|
+
# sub = client.get_subscription(subscription_id: 'abcd123456')
|
37
|
+
# end
|
38
|
+
# @example
|
39
|
+
# # If you only plan on using the client for more than one site,
|
40
|
+
# # you should initialize a new client for each site.
|
41
|
+
#
|
42
|
+
# # Give a `site_id`
|
43
|
+
# client = Recurly::Client.new(api_key: API_KEY, site_id: SITE_ID)
|
44
|
+
# # Or use the subdomain
|
45
|
+
# client = Recurly::Client.new(api_key: API_KEY, subdomain: 'mysite-dev')
|
46
|
+
#
|
47
|
+
# sub = client.get_subscription(subscription_id: 'abcd123456')
|
48
|
+
#
|
49
|
+
# # you should create a new client to connect to another site
|
50
|
+
# client = Recurly::Client.new(api_key: API_KEY, subdomain: 'mysite-prod')
|
51
|
+
# sub = client.get_subscription(subscription_id: 'abcd7890')
|
52
|
+
#
|
53
|
+
# @param api_key [String] The private API key
|
54
|
+
# @param site_id [String] The site you wish to be scoped to.
|
55
|
+
# @param subdomain [String] Optional subdomain for the site you wish to be scoped to. Providing this makes all the `site_id` parameters optional.
|
56
|
+
def initialize(api_key:, site_id: nil, subdomain: nil, **options)
|
57
|
+
if site_id
|
58
|
+
@site_id = site_id
|
59
|
+
elsif subdomain
|
60
|
+
@site_id = "subdomain-#{subdomain}"
|
61
|
+
else
|
62
|
+
raise ArgumentError, "You must pass a site_id or subdomain argument to initialize the Client"
|
63
|
+
end
|
64
|
+
|
65
|
+
@log_level = options[:log_level] || Logger::WARN
|
66
|
+
@logger = Logger.new(STDOUT)
|
67
|
+
@logger.level = @log_level
|
68
|
+
|
69
|
+
@conn = Faraday.new(url: BASE_URL) do |faraday|
|
70
|
+
if @log_level == Logger::INFO
|
71
|
+
faraday.response :logger
|
72
|
+
end
|
73
|
+
faraday.basic_auth(api_key, '')
|
74
|
+
faraday.adapter :net_http do |http| # yields Net::HTTP
|
75
|
+
# Let's not use the bundled cert in production yet
|
76
|
+
# but we will use these certs for any other staging or dev environment
|
77
|
+
unless BASE_URL.end_with?('.recurly.com')
|
78
|
+
http.ca_file = File.join(File.dirname(__FILE__), '../data/ca-certificates.crt')
|
79
|
+
end
|
80
|
+
http.use_ssl = true
|
81
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
82
|
+
http.open_timeout = 50
|
83
|
+
http.read_timeout = 60
|
84
|
+
http.keep_alive_timeout = 60
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# TODO this is undocumented until we finalize it
|
89
|
+
@extra_headers = options[:headers] || {}
|
90
|
+
|
91
|
+
# execute block with this client if given
|
92
|
+
yield(self) if block_given?
|
93
|
+
end
|
94
|
+
|
95
|
+
def next_page(pager)
|
96
|
+
run_request(:get, pager.next, nil, headers)
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
def pager(path, **options)
|
102
|
+
Pager.new(client: self, path: path, options: options)
|
103
|
+
end
|
104
|
+
|
105
|
+
def get(path, **options)
|
106
|
+
response = run_request(:get, path, options.compact, headers)
|
107
|
+
raise_api_error!(response) if response.status != 200
|
108
|
+
JSONParser.parse(self, response.body)
|
109
|
+
rescue Faraday::ClientError => ex
|
110
|
+
raise_network_error!(ex)
|
111
|
+
end
|
112
|
+
|
113
|
+
def post(path, request_data, request_class, **options)
|
114
|
+
request = request_class.new(request_data)
|
115
|
+
request.validate!
|
116
|
+
logger.info("POST BODY #{JSON.dump(request_data)}")
|
117
|
+
response = run_request(:post, path, JSON.dump(request.attributes), headers)
|
118
|
+
raise_api_error!(response) if response.status != 201
|
119
|
+
JSONParser.parse(self, response.body)
|
120
|
+
rescue Faraday::ClientError => ex
|
121
|
+
raise_network_error!(ex)
|
122
|
+
end
|
123
|
+
|
124
|
+
def put(path, request_data, request_class, **options)
|
125
|
+
request = request_class.new(request_data)
|
126
|
+
request.validate!
|
127
|
+
logger.info("PUT BODY #{JSON.dump(request_data)}")
|
128
|
+
response = run_request(:put, path, JSON.dump(request_data), headers)
|
129
|
+
raise_api_error!(response) if ![200, 201].include?(response.status)
|
130
|
+
JSONParser.parse(self, response.body)
|
131
|
+
rescue Faraday::ClientError => ex
|
132
|
+
raise_network_error!(ex)
|
133
|
+
end
|
134
|
+
|
135
|
+
def delete(path, **options)
|
136
|
+
response = run_request(:delete, path, options.compact, headers)
|
137
|
+
raise_api_error!(response) if ![200, 201].include?(response.status)
|
138
|
+
JSONParser.parse(self, response.body)
|
139
|
+
rescue Faraday::ClientError => ex
|
140
|
+
raise_network_error!(ex)
|
141
|
+
end
|
142
|
+
|
143
|
+
protected
|
144
|
+
|
145
|
+
# Used by the operations.rb file to interpolate paths
|
146
|
+
attr_reader :site_id
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
# @return [Logger]
|
151
|
+
attr_reader :logger
|
152
|
+
|
153
|
+
def run_request(method, url, body, headers)
|
154
|
+
read_headers @conn.run_request(method, url, body, headers)
|
155
|
+
end
|
156
|
+
|
157
|
+
def raise_network_error!(ex)
|
158
|
+
error_class = case ex
|
159
|
+
when Faraday::TimeoutError
|
160
|
+
Errors::TimeoutError
|
161
|
+
when Faraday::ConnectionFailed
|
162
|
+
Errors::ConnectionFailed
|
163
|
+
when Faraday::SSLError
|
164
|
+
Errors::SSLError
|
165
|
+
else
|
166
|
+
Errors::NetworkError
|
167
|
+
end
|
168
|
+
|
169
|
+
raise error_class, ex.message
|
170
|
+
end
|
171
|
+
|
172
|
+
def raise_api_error!(response)
|
173
|
+
error = JSONParser.parse(self, response.body)
|
174
|
+
error_class = Errors::APIError.error_class(error.type)
|
175
|
+
raise error_class.new(response, error)
|
176
|
+
end
|
177
|
+
|
178
|
+
def read_headers(response)
|
179
|
+
@rate_limit = response.headers['x-ratelimit-limit'].to_i
|
180
|
+
@rate_limit_remaining = response.headers['x-ratelimit-remaining'].to_i
|
181
|
+
@rate_limit_reset = Time.at(response.headers['x-ratelimit-reset'].to_i).to_datetime
|
182
|
+
response
|
183
|
+
end
|
184
|
+
|
185
|
+
def headers
|
186
|
+
{
|
187
|
+
'Accept' => "application/vnd.recurly.#{api_version}", # got this method from operations.rb
|
188
|
+
'Content-Type' => 'application/json',
|
189
|
+
'User-Agent' => "Recurly/#{VERSION}; #{RUBY_DESCRIPTION}"
|
190
|
+
}.merge(@extra_headers)
|
191
|
+
end
|
192
|
+
|
193
|
+
def interpolate_path(path, **options)
|
194
|
+
path = path.gsub("{", "%{")
|
195
|
+
path % options
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Recurly
|
2
|
+
module Errors
|
3
|
+
class BadRequestError < Errors::APIError; end
|
4
|
+
|
5
|
+
class InternalServerError < Errors::APIError; end
|
6
|
+
|
7
|
+
class ImmutableSubscriptionError < Errors::APIError; end
|
8
|
+
|
9
|
+
class InvalidApiKeyError < Errors::APIError; end
|
10
|
+
|
11
|
+
class InvalidApiVersionError < Errors::APIError; end
|
12
|
+
|
13
|
+
class InvalidContentTypeError < Errors::APIError; end
|
14
|
+
|
15
|
+
class InvalidPermissionsError < Errors::APIError; end
|
16
|
+
|
17
|
+
class InvalidTokenError < Errors::APIError; end
|
18
|
+
|
19
|
+
class NotFoundError < Errors::APIError; end
|
20
|
+
|
21
|
+
class SimultaneousRequestError < Errors::APIError; end
|
22
|
+
|
23
|
+
class TransactionError < Errors::APIError; end
|
24
|
+
|
25
|
+
class UnauthorizedError < Errors::APIError; end
|
26
|
+
|
27
|
+
class UnavailableInApiVersionError < Errors::APIError; end
|
28
|
+
|
29
|
+
class UnknownApiVersionError < Errors::APIError; end
|
30
|
+
|
31
|
+
class ValidationError < Errors::APIError; end
|
32
|
+
|
33
|
+
class MissingFeatureError < Errors::APIError; end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Recurly
|
2
|
+
module Errors
|
3
|
+
class APIError < StandardError
|
4
|
+
# @!attribute recurly_error
|
5
|
+
# @return [Recurly::Resources::Error] The {Recurly::Resources::Error} object
|
6
|
+
attr_reader :recurly_error
|
7
|
+
|
8
|
+
# Looks up an Error class by name
|
9
|
+
# @example
|
10
|
+
# Errors.error_class('BadRequestError')
|
11
|
+
# #=> Errors::BadRequestError
|
12
|
+
# @param error_key [String]
|
13
|
+
# @return [Errors::APIError,Errors::NetworkError]
|
14
|
+
def self.error_class(error_key)
|
15
|
+
class_name = error_key.split('_').map(&:capitalize).join
|
16
|
+
class_name += "Error" unless class_name.end_with?("Error")
|
17
|
+
Errors.const_get(class_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(response, error)
|
21
|
+
super("#{self.class.name}: #{error.message}")
|
22
|
+
@response = response
|
23
|
+
@recurly_error = error
|
24
|
+
end
|
25
|
+
|
26
|
+
def status_code
|
27
|
+
@response.status
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
require_relative "./errors/api_errors"
|
33
|
+
require_relative "./errors/network_errors"
|
34
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Recurly
|
2
|
+
class Pager
|
3
|
+
attr_accessor :client
|
4
|
+
attr_reader :data, :next
|
5
|
+
|
6
|
+
def initialize(client:, path:, options: {})
|
7
|
+
@client = client
|
8
|
+
@path = path
|
9
|
+
@options = options
|
10
|
+
@next = build_path(@path, @options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Enumerates each "page" from the server.
|
14
|
+
# This method yields a given block with the array of items
|
15
|
+
# in the page `data` and the page number the pagination is on
|
16
|
+
# `page_num` which is 0-indexed.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# plans = client.list_plans()
|
20
|
+
# plans.each_page do |data|
|
21
|
+
# data.each do |plan|
|
22
|
+
# puts "Plan: #{plan.id}"
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# @example
|
26
|
+
# plans = client.list_plans()
|
27
|
+
# plans.each_page.each_with_index do |data, page_num|
|
28
|
+
# puts "Page Number: #{page_num}"
|
29
|
+
# data.each do |plan|
|
30
|
+
# puts "Plan: #{plan.id}"
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
def each_page(&block)
|
34
|
+
if block_given?
|
35
|
+
page_enumerator.each(&block)
|
36
|
+
else
|
37
|
+
page_enumerator
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Enumerates each item on the server. Each item is yielded to the
|
42
|
+
# block presenting the effect of a continuous stream of items.
|
43
|
+
# In reality, the pager is fetching blocks of data (pages) under the hood.
|
44
|
+
# This method yields a given block with the next item to process.
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# plans = client.list_plans()
|
48
|
+
# plans.each do |plan|
|
49
|
+
# puts "Plan: #{plan.id}"
|
50
|
+
# end
|
51
|
+
# @example
|
52
|
+
# plans = client.list_plans()
|
53
|
+
# plans.each.each_with_index do |plan, idx|
|
54
|
+
# puts "Plan #{idx}: #{plan.id}"
|
55
|
+
# end
|
56
|
+
def each(&block)
|
57
|
+
if block_given?
|
58
|
+
item_enumerator.each(&block)
|
59
|
+
else
|
60
|
+
item_enumerator
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def has_more?
|
65
|
+
!!@has_more
|
66
|
+
end
|
67
|
+
|
68
|
+
def requires_client?
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def from_json(data)
|
75
|
+
@data = data['data'].map do |resource_data|
|
76
|
+
JSONParser.from_json(resource_data)
|
77
|
+
end
|
78
|
+
@next = data['next']
|
79
|
+
@has_more = data['has_more']
|
80
|
+
end
|
81
|
+
|
82
|
+
def item_enumerator
|
83
|
+
Enumerator.new do |yielder|
|
84
|
+
page_enumerator.each do |data|
|
85
|
+
data.each do |item|
|
86
|
+
yielder << item
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def page_enumerator
|
93
|
+
Enumerator.new do |yielder|
|
94
|
+
loop do
|
95
|
+
fetch_next!
|
96
|
+
yielder << data
|
97
|
+
unless has_more?
|
98
|
+
rewind!
|
99
|
+
break
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def fetch_next!
|
106
|
+
response = @client.next_page(self)
|
107
|
+
from_json(JSON.parse(response.body))
|
108
|
+
end
|
109
|
+
|
110
|
+
def rewind!
|
111
|
+
@data = []
|
112
|
+
@next = build_path(@path, @options)
|
113
|
+
end
|
114
|
+
|
115
|
+
def build_path(path, options)
|
116
|
+
"#{path}?#{URI.encode_www_form(options)}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Recurly
|
2
|
+
# This class represents a request to Recurly.
|
3
|
+
# It's used to validate requests data as well as
|
4
|
+
# cast and serialize the request data to JSON.
|
5
|
+
class Request
|
6
|
+
extend Schema::SchemaFactory
|
7
|
+
extend Schema::RequestCaster
|
8
|
+
include Schema::SchemaValidator
|
9
|
+
|
10
|
+
attr_reader :attributes
|
11
|
+
|
12
|
+
def ==(other_resource)
|
13
|
+
self.attributes == other_resource.attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def initialize(attributes = {})
|
19
|
+
@attributes = self.class.cast(attributes.clone)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
self.inspect
|
24
|
+
end
|
25
|
+
|
26
|
+
def schema
|
27
|
+
self.class.schema
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Recurly
|
2
|
+
module Requests
|
3
|
+
class AccountAcquisitionUpdatable < Request
|
4
|
+
|
5
|
+
# @!attribute campaign
|
6
|
+
# @return [String] An arbitrary identifier for the marketing campaign that led to the acquisition of this account.
|
7
|
+
define_attribute :campaign, String
|
8
|
+
|
9
|
+
# @!attribute channel
|
10
|
+
# @return [String] The channel through which the account was acquired.
|
11
|
+
define_attribute :channel, String, {:enum => ["referral", "social_media", "email", "paid_search", "organic_search", "direct_traffic", "marketing_content", "blog", "events", "outbound_sales", "advertising", "public_relations", "other"]}
|
12
|
+
|
13
|
+
# @!attribute cost
|
14
|
+
# @return [Hash] Account balance
|
15
|
+
define_attribute :cost, Hash
|
16
|
+
|
17
|
+
# @!attribute subchannel
|
18
|
+
# @return [String] An arbitrary subchannel string representing a distinction/subcategory within a broader channel.
|
19
|
+
define_attribute :subchannel, String
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|