zuora-ruby 0.1.0 → 0.2.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/.gitignore +2 -1
- data/.rubocop.yml +27 -3
- data/README.md +37 -19
- data/lib/zuora.rb +51 -0
- data/lib/zuora/client.rb +51 -25
- data/lib/zuora/models.rb +4 -3
- data/lib/zuora/models/account.rb +58 -47
- data/lib/zuora/models/card_holder.rb +46 -52
- data/lib/zuora/models/contact.rb +65 -38
- data/lib/zuora/models/dirty.rb +192 -0
- data/lib/zuora/models/payment_methods/credit_card.rb +23 -23
- data/lib/zuora/models/rate_plan.rb +6 -10
- data/lib/zuora/models/rate_plan_charge.rb +111 -49
- data/lib/zuora/models/subscription.rb +72 -42
- data/lib/zuora/models/tier.rb +16 -16
- data/lib/zuora/models/validation_predicates.rb +29 -0
- data/lib/zuora/resources.rb +0 -11
- data/lib/zuora/resources/accounts.rb +9 -8
- data/lib/zuora/resources/payment_methods/credit_card.rb +1 -3
- data/lib/zuora/resources/subscriptions.rb +2 -6
- data/lib/zuora/serializers/attribute.rb +3 -3
- data/lib/zuora/version.rb +1 -1
- data/zuora/fixtures/vcr_cassettes/account_create_.yml +111 -0
- data/zuora/fixtures/vcr_cassettes/account_update_.yml +113 -0
- data/zuora/fixtures/vcr_cassettes/subscription_create_.yml +114 -0
- data/zuora/fixtures/vcr_cassettes/subscription_update_.yml +114 -0
- data/zuora_ruby.gemspec +2 -3
- metadata +13 -8
- data/lib/zuora/models/utils.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da6c115de2be80e51003cee17072c6c06e578199
|
4
|
+
data.tar.gz: 6e48747729c511bd9fd2892eb8d97b1b9a3786a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1ea116b905657af8fef4d060239583187eefa02fbceb623ce1676a083efd3a2cb46916cec0c0beed5cedab0ca802abf3ccf42aab24b1bf3d2613744ae00e713
|
7
|
+
data.tar.gz: 7bdeb438f2581dfa8dc1aa9d01c008ba8cfdad614831bf0de642ef56a3e6ecf197b81a2919082d735dc5c7c62bfcefa3c6af858210e90062482587aabfc932fd
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -17,6 +17,30 @@ Style/Encoding:
|
|
17
17
|
AbcSize:
|
18
18
|
Enabled: false
|
19
19
|
|
20
|
-
|
21
|
-
Enabled:
|
22
|
-
|
20
|
+
Rails/TimeZone:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/AlignParameters:
|
24
|
+
EnforcedStyle: with_fixed_indentation
|
25
|
+
SupportedStyles:
|
26
|
+
- with_first_parameter
|
27
|
+
- with_fixed_indentation
|
28
|
+
|
29
|
+
Style/CaseIndentation:
|
30
|
+
IndentWhenRelativeTo: end
|
31
|
+
SupportedStyles:
|
32
|
+
- case
|
33
|
+
- end
|
34
|
+
IndentOneStep: false
|
35
|
+
|
36
|
+
Style/IndentHash:
|
37
|
+
EnforcedStyle: consistent
|
38
|
+
SupportedStyles:
|
39
|
+
- special_inside_parentheses
|
40
|
+
- consistent
|
41
|
+
|
42
|
+
Style/MultilineOperationIndentation:
|
43
|
+
EnforcedStyle: indented
|
44
|
+
SupportedStyles:
|
45
|
+
- aligned
|
46
|
+
- indented
|
data/README.md
CHANGED
@@ -5,9 +5,27 @@
|
|
5
5
|
# Zuora REST API: Ruby Client
|
6
6
|
|
7
7
|
This library implements a Ruby client wrapping Zuora's REST API.
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
|
9
|
+
### Model
|
10
|
+
A base module called `DirtyValidAttr` provides `dirty_model_attr`
|
11
|
+
* **Accessors**: attribute name provides getters and setters, as in `attr_accessor`
|
12
|
+
* **Validations** `valid: max_length(3) `
|
13
|
+
* Includes a library of predicate higher order validation functions
|
14
|
+
* **Coercions** `coerce: ->(value) { value.to_s } `
|
15
|
+
* **Type Checks** `type: String`
|
16
|
+
* **Required Attributes**: `:required: true`
|
17
|
+
|
18
|
+
### Resource
|
19
|
+
* **HTTP requests**: that are authenticated with provided credentials
|
20
|
+
* **Zuora API endpoints**:
|
21
|
+
|
22
|
+
### Utilities
|
23
|
+
- **Serialization**: Ruby <=> JSON serializer provided, just provide a module or class that respnds to `.serialize(hash)`
|
24
|
+
|
25
|
+
### Development: Specs and Testing
|
26
|
+
- **Factories**: for generating sample valid and invalid data that works with the API
|
27
|
+
- **Unit**: factories for testing model valdiations
|
28
|
+
- **Integration**: Tests against or memoized (via `VCR`) HTTP responses
|
11
29
|
|
12
30
|
## Quickstart
|
13
31
|
```ruby
|
@@ -15,9 +33,6 @@ This library implements a Ruby client wrapping Zuora's REST API.
|
|
15
33
|
client = Zuora::Client.new(username, password)
|
16
34
|
# Create a model
|
17
35
|
account = Zuora::Models::Account.new(...)
|
18
|
-
# Validate
|
19
|
-
account.valid? # true or false, check account.errors if false
|
20
|
-
# Select a serializer (snake_case -> lowerCamelCase)
|
21
36
|
serializer = Zuora::Serializers::Attribute
|
22
37
|
# Low level HTTP API
|
23
38
|
client.get('/rest/v1/accounts', serializer.serialze account)
|
@@ -33,14 +48,10 @@ used in subsequent requests. An optional third, truthy value enables Sandbox ins
|
|
33
48
|
Use `client.<get|post|put>(url, params)` to make HTTP requests via the authenticated client. Request and response body will be converted to/from Ruby via `farraday_middleware`.
|
34
49
|
|
35
50
|
3. ***Models:*** Ruby interface for constructing valid Zuora objects.
|
36
|
-
-
|
37
|
-
- `account.valid?` a boolean indicating validity
|
38
|
-
- `account.errors` a hash of error message(s)
|
39
|
-
- `account.attributes` an array of attribute names
|
51
|
+
- Documentation coming soon. In the mean time, check comments in `Zuora::Models::Dirty`.
|
40
52
|
|
41
53
|
4. **Serializers:** Recursive data transformations for mapping between formats; a Ruby -> JSON serializer is included; `snake_case` attributes are transformed into JSON `lowerCamelCase` recursively in a nested structure.
|
42
54
|
- ex. `Zuora::Serializers::Attribute.serialize account`
|
43
|
-
|
44
55
|
|
45
56
|
5. **Resources:** Wraps Zuora REST API endpoints. Hand a valid model and (optionally) a serializer to a Resource to trigger a request. Request will be made for valid models only. An exception will be raised if the model is invalid. Otherwise, a `Farraday::Response` object will be returned (responding to `.status`, `.headers`, and `.body`).
|
46
57
|
|
@@ -68,9 +79,9 @@ Models implement (recursive, nested) Zuora validations using `ActiveModel::Model
|
|
68
79
|
## Resources
|
69
80
|
In module `Zuora::Resources::`
|
70
81
|
* `Account.create!` **[working]**
|
71
|
-
* `Account.update!` [
|
72
|
-
* `Subscription.create!` [
|
73
|
-
* `Subscription.update!` [
|
82
|
+
* `Account.update!` **[working]**
|
83
|
+
* `Subscription.create!` **[working]**
|
84
|
+
* `Subscription.update!` **[working]**
|
74
85
|
* `Subscription.cancel!` [in progress]
|
75
86
|
* `PaymentMethod.update!` [in progress]
|
76
87
|
|
@@ -181,11 +192,18 @@ pp response
|
|
181
192
|
@on_complete_callbacks=[]>
|
182
193
|
```
|
183
194
|
# Changelog
|
184
|
-
* **[0.1.0] Initial release
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
*
|
195
|
+
* **[0.1.0 - 2016-01-12]** Initial release
|
196
|
+
* **[0.2.0] - 2016-01-14]** Models
|
197
|
+
- Refactored client to clarify logic
|
198
|
+
- Replaces `ActiveRecord::Model` and `::Validations` with a base module that provides powerful and extensible facilities for modeling remote resources in Ruby.
|
199
|
+
* required attributes, coercions, validations, type checking
|
200
|
+
* dirty attribute tracking
|
201
|
+
* extensible predicate library
|
202
|
+
- Implements fine-grained validations per Zuora spec
|
203
|
+
- Removes invalid model state paradigm used via `ActiveModel` in version 0.1.0.
|
204
|
+
- A model now performs its validations on `.new`, and will raise a detailed exception on mistyped, invalid or uncoercable data.
|
205
|
+
- Adds VCR for mocking out HTTP requests
|
206
|
+
- Adds integration specs for `Subscribe` `create!` and `update!` and `Account` `create!` and `update!`
|
189
207
|
|
190
208
|
# Commit rights
|
191
209
|
Anyone who has a patch accepted may request commit rights. Please do so inside the pull request post-merge.
|
data/lib/zuora.rb
CHANGED
@@ -23,7 +23,58 @@ module Zuora
|
|
23
23
|
|
24
24
|
PAYMENT_TERMS = ['Due Upon Receipt', 'Net 30', 'Net 60', 'Net 90']
|
25
25
|
|
26
|
+
# SUBSCRIPTION
|
27
|
+
|
26
28
|
SUBSCRIPTION_TERM_TYPES = %w(TERMED EVERGREEN)
|
29
|
+
|
30
|
+
DISCOUNT_TYPES = %w(ONETIME
|
31
|
+
RECURRING
|
32
|
+
USAGE
|
33
|
+
ONETIMERECURRING
|
34
|
+
ONETIMEUSAGE
|
35
|
+
RECURRINGUSAGE
|
36
|
+
ONETIMERECURRINGUSAG) # typo in zuora docs?
|
37
|
+
|
38
|
+
DISCOUNT_LEVELS = %w(rateplan subscription account)
|
39
|
+
|
40
|
+
LIST_PRICE_BASES = %w(Per_Billing_Period
|
41
|
+
Per_Month
|
42
|
+
Per_Week)
|
43
|
+
|
44
|
+
TRIGGER_EVENTS = %w(UCE USA UCA USD)
|
45
|
+
|
46
|
+
END_DATE_CONDITIONS = %w(Subscription_End
|
47
|
+
Fixed_Period
|
48
|
+
Specific_End_Date)
|
49
|
+
|
50
|
+
UP_TO_PERIODS = %w(Days Weeks Months Years)
|
51
|
+
|
52
|
+
BILLING_PERIODS = %w(Month
|
53
|
+
Quarter
|
54
|
+
Semi_Annual
|
55
|
+
Annual
|
56
|
+
Eighteen_Months
|
57
|
+
Two_Years
|
58
|
+
Three_Years
|
59
|
+
Five_Years
|
60
|
+
Specific_Months
|
61
|
+
Subscription_Term
|
62
|
+
Week
|
63
|
+
Specific_Weeks)
|
64
|
+
|
65
|
+
BILLING_TIMINGS = %w(IN_ADVANCE IN_ARREARS)
|
66
|
+
|
67
|
+
BILL_CYCLE_TYPES = %w(DefaultFromCustomer
|
68
|
+
SpecificDayofMonth
|
69
|
+
SubscriptionStartDay
|
70
|
+
ChargeTriggerDay
|
71
|
+
SpecificDayOfWeek)
|
72
|
+
|
73
|
+
PRICE_CHANGE_OPTIONS = %w(NoChange
|
74
|
+
SpecificPercentageValue
|
75
|
+
UseLatestProductCatalogPricing)
|
76
|
+
|
77
|
+
WEEKDAYS = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)
|
27
78
|
end
|
28
79
|
|
29
80
|
require_relative 'zuora/version'
|
data/lib/zuora/client.rb
CHANGED
@@ -11,7 +11,7 @@ module Zuora
|
|
11
11
|
ErrorResponse = Class.new StandardError
|
12
12
|
|
13
13
|
class Client
|
14
|
-
|
14
|
+
attr_reader :connection
|
15
15
|
|
16
16
|
# Creates a connection instance.
|
17
17
|
# Makes an initial HTTP request to fetch session token.
|
@@ -22,30 +22,19 @@ module Zuora
|
|
22
22
|
# @param [Boolean] sandbox
|
23
23
|
# @return [Zuora::Client] with .connection, .put, .post
|
24
24
|
def initialize(username, password, sandbox = false)
|
25
|
-
|
25
|
+
base_url = api_url sandbox
|
26
|
+
conn = connection base_url
|
26
27
|
|
27
|
-
response =
|
28
|
-
req.url '/rest/v1/connections'
|
29
|
-
req.headers['apiAccessKeyId'] = username
|
30
|
-
req.headers['apiSecretAccessKey'] = password
|
31
|
-
req.headers['Content-Type'] = 'application/json'
|
32
|
-
end
|
28
|
+
response = auth_request conn, username, password
|
33
29
|
|
34
|
-
|
35
|
-
@auth_cookie = response.headers['set-cookie'].split(' ')[0]
|
36
|
-
@connection = connection(url)
|
37
|
-
else
|
38
|
-
fail ConnectionError, response.body['reasons']
|
39
|
-
end
|
30
|
+
handle_response response, conn
|
40
31
|
end
|
41
32
|
|
42
33
|
# @param [String] url - URL of request
|
43
34
|
# @return [Faraday::Response] A response, with .headers, .status & .body
|
44
35
|
def get(url)
|
45
36
|
@connection.get do |req|
|
46
|
-
req
|
47
|
-
req.headers['Content-Type'] = 'application/json'
|
48
|
-
req.headers['Cookie'] = @auth_cookie
|
37
|
+
set_request_headers! req, url
|
49
38
|
end
|
50
39
|
end
|
51
40
|
|
@@ -54,9 +43,7 @@ module Zuora
|
|
54
43
|
# @return [Faraday::Response] A response, with .headers, .status & .body
|
55
44
|
def post(url, params)
|
56
45
|
response = @connection.post do |req|
|
57
|
-
req
|
58
|
-
req.headers['Content-Type'] = 'application/json'
|
59
|
-
req.headers['Cookie'] = @auth_cookie
|
46
|
+
set_request_headers! req, url
|
60
47
|
req.body = JSON.generate params
|
61
48
|
end
|
62
49
|
|
@@ -72,11 +59,9 @@ module Zuora
|
|
72
59
|
# @param [Params] params - Data to be sent in request body
|
73
60
|
# @return [Faraday::Response] A response, with .headers, .status & .body
|
74
61
|
def put(url, params)
|
75
|
-
response = @connection.put do |
|
76
|
-
|
77
|
-
|
78
|
-
req.headers['Cookie'] = @auth_cookie
|
79
|
-
req.body = JSON.generate params
|
62
|
+
response = @connection.put do |request|
|
63
|
+
set_request_headers! request, url
|
64
|
+
request.body = JSON.generate params
|
80
65
|
end
|
81
66
|
|
82
67
|
response
|
@@ -89,6 +74,47 @@ module Zuora
|
|
89
74
|
|
90
75
|
private
|
91
76
|
|
77
|
+
# Make connection attempt
|
78
|
+
# @param [Faraday::Connection] conn
|
79
|
+
# @param [String] username
|
80
|
+
# @param [String] password
|
81
|
+
def auth_request(conn, username, password)
|
82
|
+
conn.post do |request|
|
83
|
+
set_auth_request_headers! request, username, password
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Sets instance variables or throws Connection error
|
88
|
+
# @param [Faraday::Response] response
|
89
|
+
# @param [Faraday::Connection] conn
|
90
|
+
def handle_response(response, conn)
|
91
|
+
if response.status == 200
|
92
|
+
@auth_cookie = response.headers['set-cookie'].split(' ')[0]
|
93
|
+
@connection = conn
|
94
|
+
else
|
95
|
+
fail ConnectionError, response.body['reasons']
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param [Faraday::Request] request - Faraday::Request builder
|
100
|
+
# @param [String] username - Zuora username
|
101
|
+
# @param [String] password - Zuora password
|
102
|
+
def set_auth_request_headers!(request, username, password)
|
103
|
+
request.url '/rest/v1/connections'
|
104
|
+
request.headers['apiAccessKeyId'] = username
|
105
|
+
request.headers['apiSecretAccessKey'] = password
|
106
|
+
request.headers['Content-Type'] = 'application/json'
|
107
|
+
end
|
108
|
+
|
109
|
+
# @param [Faraday::Request] request - Faraday Request builder
|
110
|
+
# @param [String] url - Relative URL for HTTP request
|
111
|
+
# @return [Nil]
|
112
|
+
def set_request_headers!(request, url)
|
113
|
+
request.url url
|
114
|
+
request.headers['Content-Type'] = 'application/json'
|
115
|
+
request.headers['Cookie'] = @auth_cookie
|
116
|
+
end
|
117
|
+
|
92
118
|
# @param [String] url
|
93
119
|
# @return [Faraday::Client]
|
94
120
|
def connection(url)
|
data/lib/zuora/models.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
require_relative 'models/
|
1
|
+
require_relative 'models/dirty'
|
2
|
+
require_relative 'models/validation_predicates'
|
2
3
|
|
3
|
-
require_relative 'models/account'
|
4
|
-
require_relative 'models/card_holder'
|
5
4
|
require_relative 'models/contact'
|
6
5
|
require_relative 'models/payment_method'
|
6
|
+
require_relative 'models/account'
|
7
|
+
require_relative 'models/card_holder'
|
7
8
|
require_relative 'models/rate_plan'
|
8
9
|
require_relative 'models/rate_plan_charge'
|
9
10
|
require_relative 'models/subscription'
|
data/lib/zuora/models/account.rb
CHANGED
@@ -1,53 +1,64 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Zuora
|
4
2
|
module Models
|
5
3
|
class Account
|
6
|
-
include
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
4
|
+
include DirtyValidAttr
|
5
|
+
|
6
|
+
dirty_valid_attr :account_number,
|
7
|
+
type: String
|
8
|
+
|
9
|
+
dirty_valid_attr :auto_pay,
|
10
|
+
type: Boolean,
|
11
|
+
required?: true
|
12
|
+
|
13
|
+
dirty_valid_attr :bill_to_contact,
|
14
|
+
type: Zuora::Models::Contact,
|
15
|
+
required?: true
|
16
|
+
|
17
|
+
dirty_valid_attr :bill_cycle_day,
|
18
|
+
type: String
|
19
|
+
|
20
|
+
dirty_valid_attr :crm_id,
|
21
|
+
type: String
|
22
|
+
|
23
|
+
dirty_valid_attr :currency,
|
24
|
+
type: String,
|
25
|
+
valid?: length(3)
|
26
|
+
|
27
|
+
dirty_valid_attr :credit_card,
|
28
|
+
type: Zuora::Models::PaymentMethods::CreditCard,
|
29
|
+
required?: true
|
30
|
+
|
31
|
+
dirty_valid_attr :name,
|
32
|
+
type: String
|
33
|
+
|
34
|
+
dirty_valid_attr :hpm_credit_card_payment_method_id,
|
35
|
+
type: String
|
36
|
+
|
37
|
+
dirty_valid_attr :notes,
|
38
|
+
type: String
|
39
|
+
|
40
|
+
dirty_valid_attr :invoice_template_id,
|
41
|
+
type: String
|
42
|
+
|
43
|
+
dirty_valid_attr :communication_profile_id,
|
44
|
+
type: String
|
45
|
+
|
46
|
+
dirty_valid_attr :payment_gateway,
|
47
|
+
type: String
|
48
|
+
|
49
|
+
dirty_valid_attr :payment_term,
|
50
|
+
type: String,
|
51
|
+
required?: true,
|
52
|
+
valid?: one_of(Zuora::PAYMENT_TERMS)
|
53
|
+
|
54
|
+
dirty_valid_attr :sold_to_contact,
|
55
|
+
type: Zuora::Models::Contact,
|
56
|
+
required?: true
|
57
|
+
|
58
|
+
dirty_valid_attr :subscription,
|
59
|
+
type: String
|
60
|
+
|
61
|
+
alias_method :initialize, :initialize_attributes!
|
51
62
|
end
|
52
63
|
end
|
53
64
|
end
|