zuora-ruby 0.2.0 → 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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +11 -1
  4. data/README.md +101 -172
  5. data/bin/console +2 -2
  6. data/lib/utils/schema_model.rb +194 -0
  7. data/lib/zuora.rb +30 -72
  8. data/lib/zuora/calls/amend.rb +68 -0
  9. data/lib/zuora/calls/create.rb +9 -0
  10. data/lib/zuora/calls/delete.rb +20 -0
  11. data/lib/zuora/calls/generate.rb +22 -0
  12. data/lib/zuora/calls/login.rb +21 -0
  13. data/lib/zuora/calls/query.rb +15 -0
  14. data/lib/zuora/calls/subscribe.rb +75 -0
  15. data/lib/zuora/calls/update.rb +9 -0
  16. data/lib/zuora/calls/upsert.rb +29 -0
  17. data/lib/zuora/client.rb +84 -94
  18. data/lib/zuora/dispatcher.rb +45 -0
  19. data/lib/zuora/object.rb +5 -0
  20. data/lib/zuora/response.rb +50 -0
  21. data/lib/zuora/utils/envelope.rb +98 -0
  22. data/lib/zuora/version.rb +1 -4
  23. data/zuora_ruby.gemspec +10 -11
  24. metadata +57 -67
  25. data/lib/zuora/models.rb +0 -11
  26. data/lib/zuora/models/account.rb +0 -64
  27. data/lib/zuora/models/card_holder.rb +0 -54
  28. data/lib/zuora/models/contact.rb +0 -71
  29. data/lib/zuora/models/dirty.rb +0 -192
  30. data/lib/zuora/models/payment_method.rb +0 -1
  31. data/lib/zuora/models/payment_methods/credit_card.rb +0 -37
  32. data/lib/zuora/models/rate_plan.rb +0 -17
  33. data/lib/zuora/models/rate_plan_charge.rb +0 -119
  34. data/lib/zuora/models/subscription.rb +0 -80
  35. data/lib/zuora/models/tier.rb +0 -27
  36. data/lib/zuora/models/validation_predicates.rb +0 -29
  37. data/lib/zuora/resources.rb +0 -6
  38. data/lib/zuora/resources/accounts.rb +0 -20
  39. data/lib/zuora/resources/payment_methods.rb +0 -1
  40. data/lib/zuora/resources/payment_methods/credit_card.rb +0 -24
  41. data/lib/zuora/resources/subscriptions.rb +0 -17
  42. data/lib/zuora/serializers.rb +0 -1
  43. data/lib/zuora/serializers/attribute.rb +0 -35
  44. data/lib/zuora/serializers/noop.rb +0 -18
  45. data/zuora/fixtures/vcr_cassettes/account_create_.yml +0 -111
  46. data/zuora/fixtures/vcr_cassettes/account_update_.yml +0 -113
  47. data/zuora/fixtures/vcr_cassettes/subscription_create_.yml +0 -114
  48. data/zuora/fixtures/vcr_cassettes/subscription_update_.yml +0 -114
@@ -3,82 +3,40 @@
3
3
  # Dependencies
4
4
  require 'faraday'
5
5
  require 'json'
6
- require 'active_model'
7
- require 'active_model_serializers'
8
6
  require 'active_support'
7
+ require 'active_support/core_ext/string'
8
+ require 'hashie'
9
9
 
10
10
  module Zuora
11
- API_URL = 'https://api.zuora.com/rest/v1/'
12
- SANDBOX_URL = 'https://apisandbox-api.zuora.com/rest/v1/'
13
-
14
- STATE_ABBREVIATIONS = %w(AA AE AP AK AL AR AZ CA CO CT DC DE FL
15
- GA GU HI IA ID IL IN KS KY LA MA MD ME
16
- MI MN MO MS MT NC ND NE NH NJ NM NV NY
17
- OH OK OR PA PR RI SC SD TN TX UT VA VI
18
- VT WA WI WV WY)
19
-
20
- CREDIT_CARD_TYPES = %w(Visa MasterCard Amex Discover)
21
-
22
- MONTHS = %w(01 02 03 04 05 06 07 08 09 10 11 12)
23
-
24
- PAYMENT_TERMS = ['Due Upon Receipt', 'Net 30', 'Net 60', 'Net 90']
25
-
26
- # SUBSCRIPTION
27
-
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)
11
+ API_URL = 'https://api.zuora.com/rest/v1/'.freeze
12
+ SANDBOX_URL = 'https://apisandbox-api.zuora.com/rest/v1/'.freeze
13
+ NAMESPACES = {
14
+ 'xmlns:soapenv' => 'http://schemas.xmlsoap.org/soap/envelope/',
15
+ 'xmlns:api' => 'http://api.zuora.com/',
16
+ 'xmlns:obj' => 'http://object.api.zuora.com/',
17
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
18
+ }.freeze
19
+
20
+ RESPONSE_NAMESPACES = NAMESPACES.merge(
21
+ 'xmlns:ns1' => 'http://api.zuora.com/',
22
+ 'xmlns:ns2' => 'http://object.api.zuora.com/'
23
+ ).freeze
78
24
  end
79
25
 
80
26
  require_relative 'zuora/version'
27
+ require_relative 'zuora/utils/envelope'
81
28
  require_relative 'zuora/client'
82
- require_relative 'zuora/models'
83
- require_relative 'zuora/serializers'
84
- require_relative 'zuora/resources'
29
+ require_relative 'zuora/object'
30
+ require_relative 'zuora/dispatcher'
31
+ require_relative 'zuora/response'
32
+
33
+ require_relative 'zuora/calls/upsert'
34
+
35
+ require_relative 'zuora/calls/amend'
36
+ require_relative 'zuora/calls/create'
37
+ require_relative 'zuora/calls/delete'
38
+ require_relative 'zuora/calls/generate'
39
+ require_relative 'zuora/calls/login'
40
+ require_relative 'zuora/calls/query'
41
+ require_relative 'zuora/calls/subscribe'
42
+ require_relative 'zuora/calls/update'
@@ -0,0 +1,68 @@
1
+ module Zuora
2
+ module Calls
3
+ class Amend < Hashie::Dash
4
+ property :amendments, required: true
5
+ property :amend_options
6
+ property :preview_options
7
+
8
+ # Returns a function that given a builder, constructs an Ammendment
9
+ # @return [Callable] function of builder
10
+ def xml_builder
11
+ lambda do |builder|
12
+ builder[:api].amend do
13
+ builder[:api].requests do
14
+ build_object builder, :amendments, :obj
15
+ build_object builder, :amend_options, :api
16
+ build_object builder, :preview_options, :api
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # Builds one node. Behavior differs based on whether value is a hash
25
+ # If value is a hash, a parent node is rendered and the call is applied
26
+ # to its children.
27
+ # If it is a child node, a child node is rendered.
28
+ # @param [Nokogiri::XML::Builder] builder
29
+ # @param [Symbol] child_ns - child namespace
30
+ # @param [Symbol] field - snake case name of a Zuora object or field
31
+ # @param [Enumerable or Object] - parent or child node
32
+ # @return nil
33
+ def build_node(builder, child_ns, field, value)
34
+ field = Zuora::Utils::Envelope.to_zuora_key field
35
+ if value.respond_to?(:each)
36
+ # Parent
37
+ builder[:api].send(field) { build_nodes builder, value, child_ns }
38
+ else
39
+ # Child
40
+ builder[child_ns].send(field, value)
41
+ end
42
+ end
43
+
44
+ # Takes a hash and builds SOAP XML nodes. See build_node for behavior.
45
+ # @param [Nokogiri::XML::Builder] builder
46
+ # @param [Enumerable] root
47
+ # @param [Symbol] child_ns - child node namespace
48
+ # @return nil
49
+ def build_nodes(builder, root, child_ns)
50
+ root.each(&->(k, v) { build_node builder, child_ns, k, v })
51
+ end
52
+
53
+ # Helper to recursively build XML from nested objects.
54
+ # @param [Nokogiri::XML::Builder] builder
55
+ # @param [Symbol] property_name - name of a property on this object
56
+ # @param [Symbol] child_ns - namespace of child node fields
57
+ # @return nil
58
+ def build_object(builder, property_name, child_ns)
59
+ object = send property_name
60
+ fail 'Objects must respond to each' unless object.respond_to?(:each)
61
+ object_name = Zuora::Utils::Envelope.to_zuora_key property_name
62
+ builder[:api].send(object_name) do
63
+ build_nodes builder, object, child_ns
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,9 @@
1
+ module Zuora
2
+ module Calls
3
+ class Create < Zuora::Calls::Upsert
4
+ def call_name
5
+ :create
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module Zuora
2
+ module Calls
3
+ class Delete < Hashie::Dash
4
+ property :type, required: true
5
+ property :ids, required: true
6
+
7
+ def xml_builder
8
+ fail 'Must be Enumerable' unless ids.respond_to? :each
9
+ lambda do |builder|
10
+ builder[:api].delete do
11
+ builder[:api].type type
12
+ ids.each do |id|
13
+ builder[:api].ids id
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ module Zuora
2
+ module Calls
3
+ class Generate < Hashie::Dash
4
+ property :objects, required: true
5
+
6
+ OBJECT_TYPE = :Invoice
7
+
8
+ # Generates a function that takes a builder
9
+ # and updates object(s) of type.
10
+ # @return [Callable] - function of builder
11
+ def xml_builder
12
+ fail 'objects must respond to :each' unless objects.respond_to?(:each)
13
+
14
+ lambda do |builder|
15
+ builder[:api].generate do
16
+ Zuora::Utils::Envelope.build_objects builder, OBJECT_TYPE, objects
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Zuora
2
+ module Calls
3
+ class Login < Hashie::Dash
4
+ # @params [String] username
5
+ # @params [String] password
6
+ property :username, required: true
7
+ property :password, required: true
8
+
9
+ # Generates a function that adds login fields to a buidler
10
+ # @return [Callable] builder - a function of builder
11
+ def xml_builder
12
+ lambda do |builder|
13
+ builder[:api].login do
14
+ builder[:api].username(username)
15
+ builder[:api].password(password)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Zuora
2
+ module Calls
3
+ class Query < Hashie::Dash
4
+ def initialize(query_string)
5
+ @query_string = query_string
6
+ end
7
+
8
+ def xml_builder
9
+ lambda do |builder|
10
+ builder[:api].query { builder[:api].queryString(@query_string) }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,75 @@
1
+ module Zuora
2
+ module Calls
3
+ class Subscribe < Hashie::Dash
4
+ property :account, required: true
5
+ property :payment_method
6
+ property :bill_to_contact, required: true
7
+ property :sold_to_contact
8
+ property :subscribe_options
9
+ property :subscription
10
+ property :rate_plan
11
+
12
+ SIMPLE_OBJECTS = [:account, :payment_method, :bill_to_contact].freeze
13
+
14
+ # Generates a function that adds login fields to a buidler
15
+ # @return [Callable] function of builder
16
+ def xml_builder
17
+ lambda do |builder|
18
+ builder[:api].subscribe do
19
+ builder[:api].subscribes do
20
+ build_simple_objects builder
21
+ build_complex_objects builder
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # Builds the non-complex / non-nested part of the subscribe request
30
+ # @param [Nokogiri::XML::Builder] builder
31
+ def build_simple_objects(builder)
32
+ SIMPLE_OBJECTS.each do |obj_name|
33
+ obj = send obj_name
34
+ next unless obj
35
+ zuora_name = Zuora::Utils::Envelope.to_zuora_key obj_name
36
+ builder[:api].send(zuora_name) do
37
+ Zuora::Utils::Envelope.build_fields(builder, :obj, obj)
38
+ end
39
+ end
40
+ end
41
+
42
+ # Builds the complex, nested part of the subscribe request
43
+ # @param [Nokogiri::XML::Builder] builder
44
+ def build_complex_objects(builder)
45
+ builder[:api].SubscribeOptions do
46
+ Zuora::Utils::Envelope.build_fields(builder, :api, subscribe_options)
47
+ end if subscribe_options
48
+
49
+ builder[:api].SubscriptionData do
50
+ build_object(builder, :Subscription, subscription)
51
+ builder[:api].RatePlanData do
52
+ build_object(builder, :RatePlan, rate_plan)
53
+ end
54
+ end
55
+ end
56
+
57
+ # Helper for building one object
58
+ # [Nokogiri::XML::Builder] builder
59
+ # [Symbol] type
60
+ # [Hash] data
61
+ def build_object(builder, type, data)
62
+ builder[:api].send(type) do
63
+ build_fields builder, data
64
+ end if data
65
+ end
66
+
67
+ # [Nokogiri::XML::Builder] builder
68
+ # [Nokogiri::XML::Builder] builder
69
+ # [Hash] data
70
+ def build_fields(builder, data)
71
+ Zuora::Utils::Envelope.build_fields(builder, :obj, data)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,9 @@
1
+ module Zuora
2
+ module Calls
3
+ class Update < Zuora::Calls::Upsert
4
+ def call_name
5
+ :update
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Zuora
2
+ module Calls
3
+ class Upsert < Hashie::Dash
4
+ # Base class for Create and Update
5
+
6
+ # @params [Symbol] type e.g. :BillRun, :Refund
7
+ # @params [Array] objects - collection of objects of type `type`
8
+ property :type, required: true
9
+ property :objects, required: true
10
+
11
+ def call_name
12
+ fail 'This class is abstract. Subclassers must def :call_name'
13
+ end
14
+
15
+ # Generates a function that takes a builder
16
+ # adds call of call_name and z-object(s) ogit rf type
17
+ # @return [Callable] - function of builder
18
+ def xml_builder
19
+ fail 'objects must respond to :each' unless objects.respond_to?(:each)
20
+
21
+ lambda do |builder|
22
+ builder[:api].send(call_name) do
23
+ Zuora::Utils::Envelope.build_objects builder, type, objects
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,138 +1,128 @@
1
- # encoding: utf-8
2
1
  require 'faraday'
3
2
  require 'faraday_middleware'
4
- require 'json'
3
+ require 'nokogiri'
5
4
 
6
5
  module Zuora
7
6
  # Unable to connect. Check username / password
8
- ConnectionError = Class.new StandardError
7
+ SoapConnectionError = Class.new StandardError
9
8
 
10
9
  # Non-success response
11
- ErrorResponse = Class.new StandardError
10
+ SoapErrorResponse = Class.new StandardError
12
11
 
13
12
  class Client
14
- attr_reader :connection
13
+ attr_accessor :session_token
14
+
15
+ SOAP_API_URI = '/apps/services/a/74.0'.freeze
16
+ SESSION_TOKEN_XPATH =
17
+ %w(//soapenv:Envelope soapenv:Body api:loginResponse
18
+ api:result api:Session).join('/').freeze
15
19
 
16
20
  # Creates a connection instance.
17
- # Makes an initial HTTP request to fetch session token.
18
- # Subsequent requests made with .get, .post, and .put
19
- # contain the authenticated session id in their headers.
21
+ # Makes an initial SOAP request to fetch session token.
22
+ # Subsequent requests contain the authenticated session id
23
+ # in headers.
20
24
  # @param [String] username
21
25
  # @param [String] password
22
26
  # @param [Boolean] sandbox
23
- # @return [Zuora::Client] with .connection, .put, .post
24
- def initialize(username, password, sandbox = false)
25
- base_url = api_url sandbox
26
- conn = connection base_url
27
+ # @return [Zuora::SoapClient]
28
+ def initialize(username, password, sandbox = true)
29
+ @username = username
30
+ @password = password
31
+ @sandbox = sandbox
32
+ end
27
33
 
28
- response = auth_request conn, username, password
34
+ # Makes auth request, handles response
35
+ # @return [Faraday::Response]
36
+ def authenticate!
37
+ auth_response = call! :login,
38
+ username: @username,
39
+ password: @password
29
40
 
30
- handle_response response, conn
41
+ handle_auth_response auth_response
42
+ rescue Object => e
43
+ raise SoapConnectionError, e
31
44
  end
32
45
 
33
- # @param [String] url - URL of request
34
- # @return [Faraday::Response] A response, with .headers, .status & .body
35
- def get(url)
36
- @connection.get do |req|
37
- set_request_headers! req, url
38
- end
39
- end
46
+ # Fire a request
47
+ # @param [Xml] body - an object responding to .xml
48
+ # @return [Zuora::Response]
49
+ def request!(body)
50
+ fail 'body must support .to_xml' unless body.respond_to? :to_xml
40
51
 
41
- # @param [String] url - URL for HTTP POST request
42
- # @param [Params] params - Data to be sent in request body
43
- # @return [Faraday::Response] A response, with .headers, .status & .body
44
- def post(url, params)
45
- response = @connection.post do |req|
46
- set_request_headers! req, url
47
- req.body = JSON.generate params
52
+ raw_response = connection.post do |request|
53
+ request.url SOAP_API_URI
54
+ request.headers['Content-Type'] = 'text/xml'
55
+ request.body = body.to_xml
48
56
  end
49
57
 
50
- response
51
- # if response.body['success']
52
- # return response
53
- # else
54
- # raise ErrorResponse.new(response)
55
- # end
58
+ Zuora::Response.new(raw_response)
56
59
  end
57
60
 
58
- # @param [String] url - URL for HTTP PUT request
59
- # @param [Params] params - Data to be sent in request body
60
- # @return [Faraday::Response] A response, with .headers, .status & .body
61
- def put(url, params)
62
- response = @connection.put do |request|
63
- set_request_headers! request, url
64
- request.body = JSON.generate params
65
- end
66
-
67
- response
68
- # if response.body['success']
69
- # return response
70
- # else
71
- # raise ErrorResponse.new(response)
72
- # end
61
+ # The primary interface via which users should make SOAP requests.
62
+ # client.call :create, object_name: :BillRun, data: {...}
63
+ # client.call :subscribe, account: {...}, sold_to_contact: {...}
64
+ # @param [Symbol] call_name - one of :create, :subscribe, :amend, :update
65
+ # @return [Faraday:Response] - response
66
+ def call!(call_name, *args)
67
+ factory = Zuora::Dispatcher.send call_name
68
+ xml_builder = factory.new(*args).xml_builder
69
+ request_data = envelope_for call_name, xml_builder
70
+ request! request_data
73
71
  end
74
72
 
75
73
  private
76
74
 
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
75
+ # Generate envelope for request
76
+ # @param [Symbol] call name - one of the supported calls (see #call)
77
+ # @param [Callable] builder_modifier - function taking a builder
78
+ # @return [Nokogiri::XML::Builder]
79
+ def envelope_for(call_name, xml_builder_modifier)
80
+ if call_name == :login
81
+ Zuora::Utils::Envelope.xml(nil, xml_builder_modifier)
82
+ else
83
+ Zuora::Utils::Envelope.authenticated_xml(@session_token) do |b|
84
+ xml_builder_modifier.call b
85
+ end
84
86
  end
85
87
  end
86
88
 
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
89
+ # Handle auth response, setting session
90
+ # @params [Faraday::Response]
91
+ # @return [Faraday::Response]
92
+ # @throw [SoapErrorResponse]
93
+ def handle_auth_response(response)
94
+ if response.raw.status == 200
95
+ @session_token = extract_session_token response
94
96
  else
95
- fail ConnectionError, response.body['reasons']
97
+ message = 'Unable to connect with provided credentials'
98
+ fail SoapErrorResponse, message
96
99
  end
100
+ response
97
101
  end
98
102
 
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
103
+ # Extracts session token from response and sets instance variable
104
+ # for use in subsequent requests
105
+ # @param [Faraday::Response] response - response to auth request
106
+ def extract_session_token(response)
107
+ Nokogiri::XML(response.raw.body).xpath(
108
+ SESSION_TOKEN_XPATH, Zuora::NAMESPACES
109
+ ).text
116
110
  end
117
111
 
118
- # @param [String] url
119
- # @return [Faraday::Client]
120
- def connection(url)
121
- Faraday.new(url, ssl: { verify: false }) do |conn|
122
- conn.request :json
123
- conn.response :json, content_type: /\bjson$/
124
- conn.use :instrumentation
112
+ # Initializes a connection using api_url
113
+ # @return [Faraday::Connection]
114
+ def connection
115
+ Faraday.new(api_url, ssl: { verify: false }) do |conn|
125
116
  conn.adapter Faraday.default_adapter
126
117
  end
127
118
  end
128
119
 
129
- # @param [Boolean] sandbox - Use the sandbox url?
130
- # @return [String] the API url
131
- def api_url(sandbox)
132
- if sandbox
133
- Zuora::SANDBOX_URL
120
+ # @return [String] - SOAP url based on @sandbox
121
+ def api_url
122
+ if @sandbox
123
+ 'https://apisandbox.zuora.com/apps/services/a/74.0'
134
124
  else
135
- Zuora::API_URL
125
+ 'https://api.zuora.com/apps/services/a/74.0'
136
126
  end
137
127
  end
138
128
  end