zuora-ruby 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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