# Generated by API Builder - https://www.apibuilder.io # Service version: 0.0.2 # User agent: apibuilder app.apibuilder.io/hbc/api-fraud/0.0.2/ruby_client require 'cgi' require 'net/http' require 'net/https' require 'uri' require 'base64' require 'date' require 'rubygems' require 'json' require 'bigdecimal' # API documentation for the fraud service module Com module Hbc module Api module Fraud module V0 class Client module Constants BASE_URL = 'http://fraud-frozone' unless defined?(Constants::BASE_URL) NAMESPACE = 'com.hbc.api.fraud.v0' unless defined?(Constants::NAMESPACE) USER_AGENT = 'apibuilder app.apibuilder.io/hbc/api-fraud/0.0.2/ruby_client' unless defined?(Constants::USER_AGENT) VERSION = '0.0.2' unless defined?(Constants::VERSION) VERSION_MAJOR = 0 unless defined?(VERSION_MAJOR) end attr_reader :url def initialize(url, opts={}) @url = HttpClient::Preconditions.assert_class('url', url, String) @base_url = URI(url) @authorization = HttpClient::Preconditions.assert_class_or_nil('authorization', opts.delete(:authorization), HttpClient::Authorization) @default_headers = HttpClient::Preconditions.assert_class('default_headers', opts.delete(:default_headers) || {}, Hash) @http_handler = opts.delete(:http_handler) || HttpClient::DefaultHttpHandler.new HttpClient::Preconditions.assert_empty_opts(opts) HttpClient::Preconditions.check_state(url.match(/http.+/i), "URL[%s] must start with http" % url) end # Creates an instance of the client using the base url specified in the API spec. def Client.at_base_url(opts={}) Client.new(Constants::BASE_URL, opts) end def request(path=nil) HttpClient::Preconditions.assert_class_or_nil('path', path, String) request = HttpClient::Request.new(@http_handler, @base_url, path.to_s).with_header('User-Agent', Constants::USER_AGENT).with_header('X-Apidoc-Version', Constants::VERSION).with_header('X-Apidoc-Version-Major', Constants::VERSION_MAJOR) @default_headers.each do |key, value| request = request.with_header(key, value) end if @authorization request = request.with_auth(@authorization) end request end def decisions @decisions ||= ::Com::Hbc::Api::Fraud::V0::Clients::Decisions.new(self) end def transactions @transactions ||= ::Com::Hbc::Api::Fraud::V0::Clients::Transactions.new(self) end end module Clients class Decisions def initialize(client) @client = HttpClient::Preconditions.assert_class('client', client, ::Com::Hbc::Api::Fraud::V0::Client) end # Consumes the decision about a transaction (usually meant for manual review) # and triggers OMS to process/cancel the order def post(decision) (x = decision; x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Decision) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Decision.new(x)) r = @client.request("/decision").with_json(decision.to_json).post nil end end class Transactions def initialize(client) @client = HttpClient::Preconditions.assert_class('client', client, ::Com::Hbc::Api::Fraud::V0::Client) end # Provides decision about a transaction by supplying order or other # information def post(transaction) (x = transaction; x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Transaction) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Transaction.new(x)) r = @client.request("/transaction").with_json(transaction.to_json).post ::Com::Hbc::Api::Fraud::V0::Models::Decision.new(r) end end end module Models class Banner attr_reader :value def initialize(value) @value = HttpClient::Preconditions.assert_class('value', value, String) end # Returns the instance of Banner for this value, creating a new instance for an unknown value def Banner.apply(value) if value.instance_of?(Banner) value else HttpClient::Preconditions.assert_class_or_nil('value', value, String) value.nil? ? nil : (from_string(value) || Banner.new(value)) end end # Returns the instance of Banner for this value, or nil if not found def Banner.from_string(value) HttpClient::Preconditions.assert_class('value', value, String) Banner.ALL.find { |v| v.value == value } end def Banner.ALL @@all ||= [Banner.lat, Banner.s5a, Banner.o5a, Banner.bay] end def Banner.lat @@_lat ||= Banner.new('lat') end def Banner.s5a @@_s5a ||= Banner.new('s5a') end def Banner.o5a @@_o5a ||= Banner.new('o5a') end def Banner.bay @@_bay ||= Banner.new('bay') end def to_hash value end end class CustomerType attr_reader :value def initialize(value) @value = HttpClient::Preconditions.assert_class('value', value, String) end # Returns the instance of CustomerType for this value, creating a new instance for an unknown value def CustomerType.apply(value) if value.instance_of?(CustomerType) value else HttpClient::Preconditions.assert_class_or_nil('value', value, String) value.nil? ? nil : (from_string(value) || CustomerType.new(value)) end end # Returns the instance of CustomerType for this value, or nil if not found def CustomerType.from_string(value) HttpClient::Preconditions.assert_class('value', value, String) CustomerType.ALL.find { |v| v.value == value } end def CustomerType.ALL @@all ||= [CustomerType.guest, CustomerType.registered, CustomerType.employee] end def CustomerType.guest @@_guest ||= CustomerType.new('guest') end def CustomerType.registered @@_registered ||= CustomerType.new('registered') end def CustomerType.employee @@_employee ||= CustomerType.new('employee') end def to_hash value end end class RecommendationCode attr_reader :value def initialize(value) @value = HttpClient::Preconditions.assert_class('value', value, String) end # Returns the instance of RecommendationCode for this value, creating a new instance for an unknown value def RecommendationCode.apply(value) if value.instance_of?(RecommendationCode) value else HttpClient::Preconditions.assert_class_or_nil('value', value, String) value.nil? ? nil : (from_string(value) || RecommendationCode.new(value)) end end # Returns the instance of RecommendationCode for this value, or nil if not found def RecommendationCode.from_string(value) HttpClient::Preconditions.assert_class('value', value, String) RecommendationCode.ALL.find { |v| v.value == value } end def RecommendationCode.ALL @@all ||= [RecommendationCode.reject, RecommendationCode.review, RecommendationCode.accept] end def RecommendationCode.reject @@_reject ||= RecommendationCode.new('reject') end def RecommendationCode.review @@_review ||= RecommendationCode.new('review') end def RecommendationCode.accept @@_accept ||= RecommendationCode.new('accept') end def to_hash value end end # Envelope data class AdditionalData attr_reader :inAuthId def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:inAuthId], 'AdditionalData') @inAuthId = HttpClient::Preconditions.assert_class('inAuthId', HttpClient::Helper.to_uuid(opts.delete(:inAuthId)), String) end def to_json JSON.dump(to_hash) end def copy(incoming={}) AdditionalData.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :inAuthId => inAuthId } end end # General address model class Address attr_reader :name, :streetLineOne, :streetLineTwo, :city, :state, :zip, :country def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:name, :streetLineOne, :city, :state, :zip, :country], 'Address') @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String) @streetLineOne = HttpClient::Preconditions.assert_class('streetLineOne', opts.delete(:streetLineOne), String) @streetLineTwo = (x = opts.delete(:streetLineTwo); x.nil? ? nil : HttpClient::Preconditions.assert_class('streetLineTwo', x, String)) @city = HttpClient::Preconditions.assert_class('city', opts.delete(:city), String) @state = HttpClient::Preconditions.assert_class('state', opts.delete(:state), String) @zip = HttpClient::Preconditions.assert_class('zip', opts.delete(:zip), String) @country = HttpClient::Preconditions.assert_class('country', opts.delete(:country), String) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Address.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :name => name, :streetLineOne => streetLineOne, :streetLineTwo => streetLineTwo, :city => city, :state => state, :zip => zip, :country => country } end end # A customer's complete credit card information class CreditCard attr_reader :nameOnCard, :billingAddress, :cardType, :cardNumber, :authorizedAmount, :fullAmount, :expiryDate, :authCode, :responseCode, :merchantId, :registerNumber, :transactionNumber, :avsResponse def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:nameOnCard, :billingAddress, :cardType, :cardNumber, :authorizedAmount, :fullAmount, :expiryDate, :authCode, :responseCode, :transactionNumber, :avsResponse], 'CreditCard') @nameOnCard = HttpClient::Preconditions.assert_class('nameOnCard', opts.delete(:nameOnCard), String) @billingAddress = (x = opts.delete(:billingAddress); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Address) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Address.new(x)) @cardType = HttpClient::Preconditions.assert_class('cardType', opts.delete(:cardType), String) @cardNumber = HttpClient::Preconditions.assert_class('cardNumber', opts.delete(:cardNumber), String) @authorizedAmount = HttpClient::Preconditions.assert_class('authorizedAmount', HttpClient::Helper.to_big_decimal(opts.delete(:authorizedAmount)), BigDecimal) @fullAmount = HttpClient::Preconditions.assert_class('fullAmount', HttpClient::Helper.to_big_decimal(opts.delete(:fullAmount)), BigDecimal) @expiryDate = HttpClient::Preconditions.assert_class('expiryDate', opts.delete(:expiryDate), String) @authCode = HttpClient::Preconditions.assert_class('authCode', opts.delete(:authCode), String) @responseCode = HttpClient::Preconditions.assert_class('responseCode', opts.delete(:responseCode), Integer) @merchantId = (x = opts.delete(:merchantId); x.nil? ? nil : HttpClient::Preconditions.assert_class('merchantId', x, Integer)) @registerNumber = (x = opts.delete(:registerNumber); x.nil? ? nil : HttpClient::Preconditions.assert_class('registerNumber', x, String)) @transactionNumber = HttpClient::Preconditions.assert_class('transactionNumber', opts.delete(:transactionNumber), String) @avsResponse = HttpClient::Preconditions.assert_class('avsResponse', opts.delete(:avsResponse), String) end def to_json JSON.dump(to_hash) end def copy(incoming={}) CreditCard.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :nameOnCard => nameOnCard, :billingAddress => billingAddress.to_hash, :cardType => cardType, :cardNumber => cardNumber, :authorizedAmount => authorizedAmount.to_f.to_s, :fullAmount => fullAmount.to_f.to_s, :expiryDate => expiryDate, :authCode => authCode, :responseCode => responseCode, :merchantId => merchantId, :registerNumber => registerNumber, :transactionNumber => transactionNumber, :avsResponse => avsResponse } end end # Customer model class Customer attr_reader :customerType, :accountId, :creationDate, :firstName, :lastName, :emailAddress def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:customerType, :accountId, :creationDate, :firstName, :lastName, :emailAddress], 'Customer') @customerType = (x = opts.delete(:customerType); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::CustomerType) ? x : ::Com::Hbc::Api::Fraud::V0::Models::CustomerType.apply(x)) @accountId = HttpClient::Preconditions.assert_class('accountId', opts.delete(:accountId), String) @creationDate = HttpClient::Preconditions.assert_class('creationDate', HttpClient::Helper.to_date_iso8601(opts.delete(:creationDate)), Date) @firstName = HttpClient::Preconditions.assert_class('firstName', opts.delete(:firstName), String) @lastName = HttpClient::Preconditions.assert_class('lastName', opts.delete(:lastName), String) @emailAddress = HttpClient::Preconditions.assert_class('emailAddress', opts.delete(:emailAddress), String) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Customer.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :customerType => customerType.value, :accountId => accountId, :creationDate => creationDate, :firstName => firstName, :lastName => lastName, :emailAddress => emailAddress } end end # Response model to OMS containing the transaction they've sent and the decision # we've made class DBRecord attr_reader :transactionId, :lastModifiedDate, :createdDate, :transaction, :decision def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:transactionId, :transaction, :decision], 'DBRecord') @transactionId = HttpClient::Preconditions.assert_class('transactionId', opts.delete(:transactionId), String) @lastModifiedDate = (x = opts.delete(:lastModifiedDate); x.nil? ? nil : HttpClient::Preconditions.assert_class('lastModifiedDate', HttpClient::Helper.to_date_iso8601(x), Date)) @createdDate = (x = opts.delete(:createdDate); x.nil? ? nil : HttpClient::Preconditions.assert_class('createdDate', HttpClient::Helper.to_date_iso8601(x), Date)) @transaction = (x = opts.delete(:transaction); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Transaction) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Transaction.new(x)) @decision = (x = opts.delete(:decision); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Decision) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Decision.new(x)) end def to_json JSON.dump(to_hash) end def copy(incoming={}) DBRecord.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :transactionId => transactionId, :lastModifiedDate => lastModifiedDate, :createdDate => createdDate, :transaction => transaction.to_hash, :decision => decision.to_hash } end end # Defines decision information class Decision attr_reader :transactionId, :recommendationCode, :crossReference, :rulesTripped, :totalScore, :remarks def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:transactionId, :recommendationCode, :totalScore], 'Decision') @transactionId = HttpClient::Preconditions.assert_class('transactionId', opts.delete(:transactionId), String) @recommendationCode = (x = opts.delete(:recommendationCode); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::RecommendationCode) ? x : ::Com::Hbc::Api::Fraud::V0::Models::RecommendationCode.apply(x)) @crossReference = (x = opts.delete(:crossReference); x.nil? ? nil : HttpClient::Preconditions.assert_class('crossReference', HttpClient::Helper.to_uuid(x), String)) @rulesTripped = (x = opts.delete(:rulesTripped); x.nil? ? nil : HttpClient::Preconditions.assert_class('rulesTripped', x, String)) @totalScore = HttpClient::Preconditions.assert_class('totalScore', opts.delete(:totalScore), Integer) @remarks = (x = opts.delete(:remarks); x.nil? ? nil : HttpClient::Preconditions.assert_class('remarks', x, String)) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Decision.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :transactionId => transactionId, :recommendationCode => recommendationCode.value, :crossReference => crossReference, :rulesTripped => rulesTripped, :totalScore => totalScore, :remarks => remarks } end end # Error response model class Error attr_reader :message, :error def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:message, :error], 'Error') @message = HttpClient::Preconditions.assert_class('message', opts.delete(:message), String) @error = HttpClient::Preconditions.assert_class('error', opts.delete(:error), String) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Error.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :message => message, :error => error } end end # Single item class Item attr_reader :svsNumber, :skuNumber, :upcNumber, :classNumber, :color, :size, :currentStatus, :department, :signOnDelivery, :giftWrapped, :costAmount, :marginAmount, :description, :price, :extendedPrice, :quantity, :groupNumber, :shippingAddress, :shippingMethod, :shippingCountry def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:svsNumber, :skuNumber, :currentStatus, :department, :description, :price, :extendedPrice, :quantity, :groupNumber, :shippingAddress, :shippingMethod, :shippingCountry], 'Item') @svsNumber = HttpClient::Preconditions.assert_class('svsNumber', opts.delete(:svsNumber), Integer) @skuNumber = HttpClient::Preconditions.assert_class('skuNumber', opts.delete(:skuNumber), Integer) @upcNumber = (x = opts.delete(:upcNumber); x.nil? ? nil : HttpClient::Preconditions.assert_class('upcNumber', x, Integer)) @classNumber = (x = opts.delete(:classNumber); x.nil? ? nil : HttpClient::Preconditions.assert_class('classNumber', x, Integer)) @color = (x = opts.delete(:color); x.nil? ? nil : HttpClient::Preconditions.assert_class('color', x, String)) @size = (x = opts.delete(:size); x.nil? ? nil : HttpClient::Preconditions.assert_class('size', x, String)) @currentStatus = HttpClient::Preconditions.assert_class('currentStatus', opts.delete(:currentStatus), String) @department = HttpClient::Preconditions.assert_class('department', opts.delete(:department), Integer) @signOnDelivery = (x = opts.delete(:signOnDelivery); x.nil? ? nil : HttpClient::Preconditions.assert_class('signOnDelivery', x, String)) @giftWrapped = (x = opts.delete(:giftWrapped); x.nil? ? nil : HttpClient::Preconditions.assert_boolean('giftWrapped', x)) @costAmount = (x = opts.delete(:costAmount); x.nil? ? nil : HttpClient::Preconditions.assert_class('costAmount', HttpClient::Helper.to_big_decimal(x), BigDecimal)) @marginAmount = (x = opts.delete(:marginAmount); x.nil? ? nil : HttpClient::Preconditions.assert_class('marginAmount', HttpClient::Helper.to_big_decimal(x), BigDecimal)) @description = HttpClient::Preconditions.assert_class('description', opts.delete(:description), String) @price = HttpClient::Preconditions.assert_class('price', HttpClient::Helper.to_big_decimal(opts.delete(:price)), BigDecimal) @extendedPrice = HttpClient::Preconditions.assert_class('extendedPrice', HttpClient::Helper.to_big_decimal(opts.delete(:extendedPrice)), BigDecimal) @quantity = HttpClient::Preconditions.assert_class('quantity', opts.delete(:quantity), Integer) @groupNumber = HttpClient::Preconditions.assert_class('groupNumber', opts.delete(:groupNumber), Integer) @shippingAddress = (x = opts.delete(:shippingAddress); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Address) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Address.new(x)) @shippingMethod = HttpClient::Preconditions.assert_class('shippingMethod', opts.delete(:shippingMethod), String) @shippingCountry = HttpClient::Preconditions.assert_class('shippingCountry', opts.delete(:shippingCountry), String) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Item.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :svsNumber => svsNumber, :skuNumber => skuNumber, :upcNumber => upcNumber, :classNumber => classNumber, :color => color, :size => size, :currentStatus => currentStatus, :department => department, :signOnDelivery => signOnDelivery, :giftWrapped => giftWrapped, :costAmount => costAmount.to_f.to_s, :marginAmount => marginAmount.to_f.to_s, :description => description, :price => price.to_f.to_s, :extendedPrice => extendedPrice.to_f.to_s, :quantity => quantity, :groupNumber => groupNumber, :shippingAddress => shippingAddress.to_hash, :shippingMethod => shippingMethod, :shippingCountry => shippingCountry } end end # Promotion model class Promo attr_reader :promotionCode, :promotionAmount def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:promotionCode, :promotionAmount], 'Promo') @promotionCode = HttpClient::Preconditions.assert_class('promotionCode', opts.delete(:promotionCode), String) @promotionAmount = HttpClient::Preconditions.assert_class('promotionAmount', HttpClient::Helper.to_big_decimal(opts.delete(:promotionAmount)), BigDecimal) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Promo.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :promotionCode => promotionCode, :promotionAmount => promotionAmount.to_f.to_s } end end # Defines data expected to come in from OMS describing a transaction class Transaction attr_reader :orderId, :groupId, :orderTotal, :shippingCost, :currencyCode, :storeNumber, :salesRep, :lastModifiedDate, :banner, :creditCard, :promos, :items, :ipAddress, :source, :customer, :additionalData def initialize(incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) HttpClient::Preconditions.require_keys(opts, [:orderId, :groupId, :orderTotal, :shippingCost, :currencyCode, :storeNumber, :banner, :creditCard, :items, :source, :customer], 'Transaction') @orderId = HttpClient::Preconditions.assert_class('orderId', opts.delete(:orderId), String) @groupId = HttpClient::Preconditions.assert_class('groupId', opts.delete(:groupId), String) @orderTotal = HttpClient::Preconditions.assert_class('orderTotal', HttpClient::Helper.to_big_decimal(opts.delete(:orderTotal)), BigDecimal) @shippingCost = HttpClient::Preconditions.assert_class('shippingCost', HttpClient::Helper.to_big_decimal(opts.delete(:shippingCost)), BigDecimal) @currencyCode = HttpClient::Preconditions.assert_class('currencyCode', opts.delete(:currencyCode), String) @storeNumber = HttpClient::Preconditions.assert_class('storeNumber', opts.delete(:storeNumber), Integer) @salesRep = (x = opts.delete(:salesRep); x.nil? ? nil : HttpClient::Preconditions.assert_class('salesRep', x, String)) @lastModifiedDate = (x = opts.delete(:lastModifiedDate); x.nil? ? nil : HttpClient::Preconditions.assert_class('lastModifiedDate', HttpClient::Helper.to_date_iso8601(x), Date)) @banner = (x = opts.delete(:banner); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Banner) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Banner.apply(x)) @creditCard = (x = opts.delete(:creditCard); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::CreditCard) ? x : ::Com::Hbc::Api::Fraud::V0::Models::CreditCard.new(x)) @promos = (x = opts.delete(:promos); x.nil? ? nil : HttpClient::Preconditions.assert_class('promos', x, Array).map { |v| (x = v; x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Promo) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Promo.new(x)) }) @items = HttpClient::Preconditions.assert_class('items', opts.delete(:items), Array).map { |v| (x = v; x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Item) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Item.new(x)) } @ipAddress = (x = opts.delete(:ipAddress); x.nil? ? nil : HttpClient::Preconditions.assert_class('ipAddress', x, String)) @source = HttpClient::Preconditions.assert_class('source', opts.delete(:source), String) @customer = (x = opts.delete(:customer); x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::Customer) ? x : ::Com::Hbc::Api::Fraud::V0::Models::Customer.new(x)) @additionalData = (x = opts.delete(:additionalData); x.nil? ? nil : (x = x; x.is_a?(::Com::Hbc::Api::Fraud::V0::Models::AdditionalData) ? x : ::Com::Hbc::Api::Fraud::V0::Models::AdditionalData.new(x))) end def to_json JSON.dump(to_hash) end def copy(incoming={}) Transaction.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming))) end def to_hash { :orderId => orderId, :groupId => groupId, :orderTotal => orderTotal.to_f.to_s, :shippingCost => shippingCost.to_f.to_s, :currencyCode => currencyCode, :storeNumber => storeNumber, :salesRep => salesRep, :lastModifiedDate => lastModifiedDate, :banner => banner.value, :creditCard => creditCard.to_hash, :promos => promos.nil? ? nil : promos.map { |o| o.to_hash }, :items => items.map { |o| o.to_hash }, :ipAddress => ipAddress, :source => source, :customer => customer.to_hash, :additionalData => additionalData.nil? ? nil : additionalData.to_hash } end end end # ===== END OF SERVICE DEFINITION ===== module HttpClient class HttpHandler # Returns a client instance to use # # @param base_uri The base URI for this API # @param path the Requested full http path (including any query strings) def instance(base_uri, path) raise "Override in subclass" end end class HttpHandlerInstance # Executes a request. The provided request object will be an # instance of Net::HTTP (e.g. Net::HTTP::Get) def execute(request) raise "Override in subclass" end end class DefaultHttpHandler < HttpHandler def instance(base_uri, path) DefaultHttpHandlerInstance.new(base_uri) end end class DefaultHttpHandlerInstance < HttpHandlerInstance attr_reader :client def initialize(base_uri) @base_uri = Preconditions.assert_class('base_uri', base_uri, URI) @client = Net::HTTP.new(@base_uri.host, @base_uri.port) if @base_uri.scheme == "https" configure_ssl end end def execute(request) response = begin @client.request(request) rescue SocketError => e raise StandardError.new("Error accessing uri[#{full_uri(request.path)}]: #{e}") end case response when Net::HTTPSuccess response.body else body = response.body rescue nil raise HttpClient::ServerError.new(response.code.to_i, response.message, :body => body, :uri => full_uri(request.path).to_s) end end def full_uri(path) path.start_with?(@base_uri.to_s) ? path : File.join(@base_uri.to_s, path) end # Called to configure SSL if the base uri requires it def configure_ssl @client.use_ssl = true @client.verify_mode = OpenSSL::SSL::VERIFY_PEER @client.cert_store = OpenSSL::X509::Store.new @client.cert_store.set_default_paths end end class Request attr_reader :base_uri, :path, :full_uri def initialize(http_handler, base_uri, path) @http_handler = http_handler @base_uri = Preconditions.assert_class('base_uri', base_uri, URI) @path = Preconditions.assert_class('path', path, String) @full_uri = @base_uri.to_s + @path @params = nil @body = nil @auth = nil @headers = {} @header_keys_lower_case = [] end def with_header(name, value) Preconditions.check_not_blank('name', name, "Header name is required") Preconditions.check_not_blank('value', value, "Header value is required") Preconditions.check_state(!@headers.has_key?(name), "Duplicate header named[%s]" % name) @headers[name] = value @header_keys_lower_case << name.downcase self end def with_auth(auth) Preconditions.assert_class('auth', auth, HttpClient::Authorization) Preconditions.check_state(@auth.nil?, "auth previously set") if auth.scheme.name == AuthScheme::BASIC.name @auth = auth else raise "Auth Scheme[#{auth.scheme.name}] not supported" end self end def with_query(params) Preconditions.assert_class('params', params, Hash) Preconditions.check_state(@params.nil?, "Already have query parameters") @params = params self end # Wrapper to set Content-Type header to application/json and set # the provided json document as the body def with_json(json) @headers['Content-Type'] ||= 'application/json; charset=UTF-8' with_body(json) end def with_body(body) Preconditions.check_not_blank('body', body) @body = body self end def get(&block) do_request(Net::HTTP::Get, &block) end def delete(&block) do_request(Net::HTTP::Delete, &block) end def options(&block) do_request(Net::HTTP::Options, &block) end def post(&block) do_request(Net::HTTP::Post, &block) end def put(&block) do_request(Net::HTTP::Put, &block) end class PATCH < Net::HTTP::Put METHOD = "PATCH" end def patch(&block) do_request(PATCH, &block) end def do_request(klass) Preconditions.assert_class('klass', klass, Class) uri = @full_uri.dup if q = to_query(@params) uri += "?%s" % q end request = klass.send(:new, uri) # DEBUG curl = ['curl'] # DEBUG if klass != Net::HTTP::Get # DEBUG curl << "-X%s" % klass.name.split("::").last.upcase # DEBUG end if @body # DEBUG tmpfile = "/tmp/rest_client.tmp" # DEBUG File.open(tmpfile, "w") { |os| os << @body.to_s } # DEBUG curl << "-d@%s" % tmpfile request.body = @body end if @auth # DEBUG curl << "-u \"%s:%s\"" % [@auth.username, @auth.password] Preconditions.check_state(!@header_keys_lower_case.include?("authorization"), "Cannot specify both an Authorization header and an auth instance") user_pass = "%s:%s" % [@auth.username, @auth.password] encoded = Base64.encode64(user_pass).to_s.split("\n").map(&:strip).join request.add_field("Authorization", "Basic %s" % encoded) end @headers.each { |key, value| # DEBUG curl << "-H \"%s: %s\"" % [key, value] request.add_field(key, value) } # DEBUG curl << "'%s%s'" % [@base_uri, path] # DEBUG puts curl.join(" ") raw_response = @http_handler.instance(@base_uri, request.path).execute(request) response = raw_response.to_s == "" ? nil : JSON.parse(raw_response) if block_given? yield response else response end end private def to_query(params={}) parts = (params || {}).map { |k,v| if v.is_a?(Enumerable) v.map { |el| "%s=%s" % [k, CGI.escape(el.to_s)] } else "%s=%s" % [k, CGI.escape(v.to_s)] end } parts.empty? ? nil : parts.join("&") end end class ServerError < StandardError attr_reader :code, :details, :body, :uri def initialize(code, details, incoming={}) opts = HttpClient::Helper.symbolize_keys(incoming) @code = HttpClient::Preconditions.assert_class('code', code, Integer) @details = HttpClient::Preconditions.assert_class('details', details, String) @body = HttpClient::Preconditions.assert_class_or_nil('body', opts.delete(:body), String) @uri = HttpClient::Preconditions.assert_class_or_nil('uri', opts.delete(:uri), String) HttpClient::Preconditions.assert_empty_opts(opts) super(self.message) end def message m = "%s %s" % [@code, @details] if @body m << ": %s" % @body end m end def body_json @body ? JSON.parse(@body) : nil end end class PreconditionException < StandardError attr_reader :message def initialize(message) super(message) @message = message end end module Preconditions def Preconditions.check_argument(expression, error_message=nil) if !expression raise PreconditionException.new(error_message || "check_argument failed") end nil end def Preconditions.check_state(expression, error_message=nil) if !expression raise PreconditionException.new(error_message || "check_state failed") end nil end def Preconditions.check_not_nil(field_name, reference, error_message=nil) if reference.nil? raise PreconditionException.new(error_message || "argument for %s cannot be nil" % field_name) end reference end def Preconditions.check_not_blank(field_name, reference, error_message=nil) if reference.to_s.strip == "" raise PreconditionException.new(error_message || "argument for %s cannot be blank" % field_name) end reference end # Throws an error if opts is not empty. Useful when parsing # arguments to a function def Preconditions.assert_empty_opts(opts) if !opts.empty? raise PreconditionException.new("Invalid opts: #{opts.keys.inspect}\n#{opts.inspect}") end end # Requires that the provided hash has the specified keys. # @param fields A list of symbols def Preconditions.require_keys(hash, fields, error_prefix=nil) missing = fields.select { |f| !hash.has_key?(f) } if !missing.empty? msg = "Missing required fields: " + missing.join(", ") raise PreconditionException.new(error_prefix.empty? ? msg : "#{error_prefix}: #{msg}") end end # Asserts that value is not nill and is_?(klass). Returns # value. Common use is # # amount = Preconditions.assert_class('amount', amount, BigDecimal) def Preconditions.assert_class(field_name, value, klass) Preconditions.check_not_nil('field_name', field_name) Preconditions.check_not_nil('klass', klass) Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of class %s" % [field_name, klass.name]) Preconditions.check_state(value.is_a?(klass), "Value for #{field_name} is of type[#{value.class}] - class[#{klass}] is required. value[#{value.inspect.to_s}]") value end def Preconditions.assert_class_or_nil(field_name, value, klass) if !value.nil? Preconditions.assert_class(field_name, value, klass) end end def Preconditions.assert_boolean(field_name, value) Preconditions.check_not_nil('field_name', field_name) Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of TrueClass or FalseClass" % field_name) Preconditions.check_state(value.is_a?(TrueClass) || value.is_a?(FalseClass), "Value for #{field_name} is of type[#{value.class}] - class[TrueClass or FalseClass] is required. value[#{value.inspect.to_s}]") value end def Preconditions.assert_boolean_or_nil(field_name, value) if !value.nil? Preconditions.assert_boolean(field_name, value) end end def Preconditions.assert_collection_of_class(field_name, values, klass) Preconditions.assert_class(field_name, values, Array) values.each { |v| Preconditions.assert_class(field_name, v, klass) } end def Preconditions.assert_hash_of_class(field_name, hash, klass) Preconditions.assert_class(field_name, hash, Hash) values.each { |k, v| Preconditions.assert_class(field_name, v, klass) } end end class AuthScheme attr_reader :name def initialize(name) @name = HttpClient::Preconditions.check_not_blank('name', name) end BASIC = AuthScheme.new("basic") unless defined?(BASIC) end class Authorization attr_reader :scheme, :username, :password def initialize(scheme, username, opts={}) @scheme = HttpClient::Preconditions.assert_class('schema', scheme, AuthScheme) @username = HttpClient::Preconditions.check_not_blank('username', username, "username is required") @password = HttpClient::Preconditions.assert_class_or_nil('password', opts.delete(:password), String) HttpClient::Preconditions.assert_empty_opts(opts) end def Authorization.basic(username, password=nil) Authorization.new(AuthScheme::BASIC, username, :password => password) end end module Helper def Helper.symbolize_keys(hash) Preconditions.assert_class('hash', hash, Hash) new_hash = {} hash.each { |k, v| new_hash[k.to_sym] = v } new_hash end def Helper.to_big_decimal(value) value ? BigDecimal(value.to_s) : nil end def Helper.to_object(value) value ? (value.is_a?(Hash) ? value : JSON.parse(value)) : nil end def Helper.to_uuid(value) Preconditions.check_state(value.nil? || value.match(/^\w\w\w\w\w\w\w\w\-\w\w\w\w\-\w\w\w\w\-\w\w\w\w\-\w\w\w\w\w\w\w\w\w\w\w\w$/), "Invalid guid[%s]" % value) value end def Helper.to_date_iso8601(value) if value.is_a?(Date) value elsif value Date.parse(value.to_s) else nil end end def Helper.to_date_time_iso8601(value) if value.is_a?(DateTime) value elsif value DateTime.parse(value.to_s) else nil end end def Helper.date_iso8601_to_string(value) value.nil? ? nil : value.strftime('%Y-%m-%d') end def Helper.date_time_iso8601_to_string(value) value.nil? ? nil : value.strftime('%Y-%m-%dT%H:%M:%S%z') end TRUE_STRINGS = ['t', 'true', 'y', 'yes', 'on', '1', 'trueclass'] unless defined?(TRUE_STRINGS) FALSE_STRINGS = ['f', 'false', 'n', 'no', 'off', '0', 'falseclass'] unless defined?(FALSE_STRINGS) def Helper.to_boolean(field_name, value) string = value.to_s.strip.downcase if TRUE_STRINGS.include?(string) true elsif FALSE_STRINGS.include?(string) false elsif string != "" raise PreconditionException.new("Unsupported boolean value[#{string}]. For true, must be one of: #{TRUE_STRINGS.inspect}. For false, must be one of: #{FALSE_STRINGS.inspect}") else nil end end end end end end end end end