/** * 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/play_2_7_client */ package com.hbc.api.fraud.v0.models { /** * Envelope data */ final case class AdditionalData( inAuthId: _root_.java.util.UUID ) /** * General address model */ final case class Address( name: String, streetLineOne: String, streetLineTwo: _root_.scala.Option[String] = None, city: String, state: String, zip: String, country: String ) /** * A customer's complete credit card information * * @param expiryDate MM-YY that the credit card expires * @param authCode CVV code on the back of the card * @param avsResponse Address Verification System response, Codes are available here: * https://www.chasepaymentech.com/address_verification_service.html */ final case class CreditCard( nameOnCard: String, billingAddress: com.hbc.api.fraud.v0.models.Address, cardType: String, cardNumber: String, authorizedAmount: BigDecimal, fullAmount: BigDecimal, expiryDate: String, authCode: String, responseCode: Int, merchantId: _root_.scala.Option[Int] = None, registerNumber: _root_.scala.Option[String] = None, transactionNumber: String, avsResponse: String ) /** * Customer model */ final case class Customer( customerType: com.hbc.api.fraud.v0.models.CustomerType, accountId: String, creationDate: _root_.org.joda.time.LocalDate, firstName: String, lastName: String, emailAddress: String ) /** * Response model to OMS containing the transaction they've sent and the decision * we've made * * @param createdDate Date this record was first created within the database */ final case class DBRecord( transactionId: String, lastModifiedDate: _root_.scala.Option[_root_.org.joda.time.LocalDate] = None, createdDate: _root_.scala.Option[_root_.org.joda.time.LocalDate] = None, transaction: com.hbc.api.fraud.v0.models.Transaction, decision: com.hbc.api.fraud.v0.models.Decision ) /** * Defines decision information */ final case class Decision( transactionId: String, recommendationCode: com.hbc.api.fraud.v0.models.RecommendationCode, crossReference: _root_.scala.Option[_root_.java.util.UUID] = None, rulesTripped: _root_.scala.Option[String] = None, totalScore: Int, remarks: _root_.scala.Option[String] = None ) /** * Error response model * * @param message Error description message * @param error Error code */ final case class Error( message: String, error: String ) /** * Single item * * @param svsNumber Product style number (parent number) * @param skuNumber HBC internally generated number for items (alias SKN) * @param upcNumber The number on the barcode that could be used across different retailers * @param classNumber Signifies business category of an item (pants, tops, shirts, etc.) * @param price Price of single item * @param extendedPrice Total price of all items ordered */ final case class Item( svsNumber: Int, skuNumber: Int, upcNumber: _root_.scala.Option[Int] = None, classNumber: _root_.scala.Option[Int] = None, color: _root_.scala.Option[String] = None, size: _root_.scala.Option[String] = None, currentStatus: String, department: Int, signOnDelivery: _root_.scala.Option[String] = None, giftWrapped: _root_.scala.Option[Boolean] = None, costAmount: _root_.scala.Option[BigDecimal] = None, marginAmount: _root_.scala.Option[BigDecimal] = None, description: String, price: BigDecimal, extendedPrice: BigDecimal, quantity: Int, groupNumber: Int, shippingAddress: com.hbc.api.fraud.v0.models.Address, shippingMethod: String, shippingCountry: String ) /** * Promotion model * * @param promotionAmount Dollar amount discounted by the promotion */ final case class Promo( promotionCode: String, promotionAmount: BigDecimal ) /** * Defines data expected to come in from OMS describing a transaction * * @param source Order source (web, store, etc) * @param additionalData Additional `envelope` data sent through our system to f-s, should include * InAuthId */ final case class Transaction( orderId: String, groupId: String, orderTotal: BigDecimal, shippingCost: BigDecimal, currencyCode: String, storeNumber: Int, salesRep: _root_.scala.Option[String] = None, lastModifiedDate: _root_.scala.Option[_root_.org.joda.time.LocalDate] = None, banner: com.hbc.api.fraud.v0.models.Banner, creditCard: com.hbc.api.fraud.v0.models.CreditCard, promos: _root_.scala.Option[Seq[com.hbc.api.fraud.v0.models.Promo]] = None, items: Seq[com.hbc.api.fraud.v0.models.Item], ipAddress: _root_.scala.Option[String] = None, source: String, customer: com.hbc.api.fraud.v0.models.Customer, additionalData: _root_.scala.Option[com.hbc.api.fraud.v0.models.AdditionalData] = None ) /** * Our lovely store chains */ sealed trait Banner extends _root_.scala.Product with _root_.scala.Serializable object Banner { case object Lat extends Banner { override def toString = "lat" } case object S5a extends Banner { override def toString = "s5a" } case object O5a extends Banner { override def toString = "o5a" } case object Bay extends Banner { override def toString = "bay" } /** * UNDEFINED captures values that are sent either in error or * that were added by the server after this library was * generated. We want to make it easy and obvious to users of * this library to handle this case gracefully. * * We use all CAPS for the variable name to avoid collisions * with the camel cased values above. */ final case class UNDEFINED(override val toString: String) extends Banner /** * all returns a list of all the valid, known values. We use * lower case to avoid collisions with the camel cased values * above. */ val all: scala.List[Banner] = scala.List(Lat, S5a, O5a, Bay) private val byName: Map[String, Banner] = all.map(x => x.toString.toLowerCase -> x).toMap def apply(value: String): Banner = fromString(value).getOrElse(UNDEFINED(value)) def fromString(value: String): _root_.scala.Option[Banner] = byName.get(value.toLowerCase) } /** * Possible types of customers */ sealed trait CustomerType extends _root_.scala.Product with _root_.scala.Serializable object CustomerType { case object Guest extends CustomerType { override def toString = "guest" } case object Registered extends CustomerType { override def toString = "registered" } case object Employee extends CustomerType { override def toString = "employee" } /** * UNDEFINED captures values that are sent either in error or * that were added by the server after this library was * generated. We want to make it easy and obvious to users of * this library to handle this case gracefully. * * We use all CAPS for the variable name to avoid collisions * with the camel cased values above. */ final case class UNDEFINED(override val toString: String) extends CustomerType /** * all returns a list of all the valid, known values. We use * lower case to avoid collisions with the camel cased values * above. */ val all: scala.List[CustomerType] = scala.List(Guest, Registered, Employee) private val byName: Map[String, CustomerType] = all.map(x => x.toString.toLowerCase -> x).toMap def apply(value: String): CustomerType = fromString(value).getOrElse(UNDEFINED(value)) def fromString(value: String): _root_.scala.Option[CustomerType] = byName.get(value.toLowerCase) } /** * Enum describing the possible responses */ sealed trait RecommendationCode extends _root_.scala.Product with _root_.scala.Serializable object RecommendationCode { case object Reject extends RecommendationCode { override def toString = "reject" } case object Review extends RecommendationCode { override def toString = "review" } case object Accept extends RecommendationCode { override def toString = "accept" } /** * UNDEFINED captures values that are sent either in error or * that were added by the server after this library was * generated. We want to make it easy and obvious to users of * this library to handle this case gracefully. * * We use all CAPS for the variable name to avoid collisions * with the camel cased values above. */ final case class UNDEFINED(override val toString: String) extends RecommendationCode /** * all returns a list of all the valid, known values. We use * lower case to avoid collisions with the camel cased values * above. */ val all: scala.List[RecommendationCode] = scala.List(Reject, Review, Accept) private val byName: Map[String, RecommendationCode] = all.map(x => x.toString.toLowerCase -> x).toMap def apply(value: String): RecommendationCode = fromString(value).getOrElse(UNDEFINED(value)) def fromString(value: String): _root_.scala.Option[RecommendationCode] = byName.get(value.toLowerCase) } } package com.hbc.api.fraud.v0.models { package object json { import play.api.libs.json.__ import play.api.libs.json.JsString import play.api.libs.json.Writes import play.api.libs.functional.syntax._ import com.hbc.api.fraud.v0.models.json._ private[v0] implicit val jsonReadsUUID: play.api.libs.json.Reads[_root_.java.util.UUID] = __.read[String].map { str => _root_.java.util.UUID.fromString(str) } private[v0] implicit val jsonWritesUUID: play.api.libs.json.Writes[_root_.java.util.UUID] = (x: _root_.java.util.UUID) => play.api.libs.json.JsString(x.toString) private[v0] implicit val jsonReadsJodaDateTime: play.api.libs.json.Reads[_root_.org.joda.time.DateTime] = __.read[String].map { str => _root_.org.joda.time.format.ISODateTimeFormat.dateTimeParser.parseDateTime(str) } private[v0] implicit val jsonWritesJodaDateTime: play.api.libs.json.Writes[_root_.org.joda.time.DateTime] = (x: _root_.org.joda.time.DateTime) => { play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.dateTime.print(x)) } private[v0] implicit val jsonReadsJodaLocalDate: play.api.libs.json.Reads[_root_.org.joda.time.LocalDate] = __.read[String].map { str => _root_.org.joda.time.format.ISODateTimeFormat.dateTimeParser.parseLocalDate(str) } private[v0] implicit val jsonWritesJodaLocalDate: play.api.libs.json.Writes[_root_.org.joda.time.LocalDate] = (x: _root_.org.joda.time.LocalDate) => { play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.date.print(x)) } implicit val jsonReadsApiFraudBanner: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Banner] = new play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Banner] { def reads(js: play.api.libs.json.JsValue): play.api.libs.json.JsResult[com.hbc.api.fraud.v0.models.Banner] = { js match { case v: play.api.libs.json.JsString => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.Banner(v.value)) case _ => { (js \ "value").validate[String] match { case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.Banner(v)) case _: play.api.libs.json.JsError => (js \ "Banner").validate[String] match { case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.Banner(v)) case err: play.api.libs.json.JsError => err } } } } } } def jsonWritesApiFraudBanner(obj: com.hbc.api.fraud.v0.models.Banner) = { play.api.libs.json.JsString(obj.toString) } def jsObjectBanner(obj: com.hbc.api.fraud.v0.models.Banner) = { play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(obj.toString)) } implicit def jsonWritesApiFraudBanner: play.api.libs.json.Writes[Banner] = { (obj: com.hbc.api.fraud.v0.models.Banner) => { com.hbc.api.fraud.v0.models.json.jsonWritesApiFraudBanner(obj) } } implicit val jsonReadsApiFraudCustomerType: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.CustomerType] = new play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.CustomerType] { def reads(js: play.api.libs.json.JsValue): play.api.libs.json.JsResult[com.hbc.api.fraud.v0.models.CustomerType] = { js match { case v: play.api.libs.json.JsString => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.CustomerType(v.value)) case _ => { (js \ "value").validate[String] match { case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.CustomerType(v)) case _: play.api.libs.json.JsError => (js \ "CustomerType").validate[String] match { case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.CustomerType(v)) case err: play.api.libs.json.JsError => err } } } } } } def jsonWritesApiFraudCustomerType(obj: com.hbc.api.fraud.v0.models.CustomerType) = { play.api.libs.json.JsString(obj.toString) } def jsObjectCustomerType(obj: com.hbc.api.fraud.v0.models.CustomerType) = { play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(obj.toString)) } implicit def jsonWritesApiFraudCustomerType: play.api.libs.json.Writes[CustomerType] = { (obj: com.hbc.api.fraud.v0.models.CustomerType) => { com.hbc.api.fraud.v0.models.json.jsonWritesApiFraudCustomerType(obj) } } implicit val jsonReadsApiFraudRecommendationCode: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.RecommendationCode] = new play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.RecommendationCode] { def reads(js: play.api.libs.json.JsValue): play.api.libs.json.JsResult[com.hbc.api.fraud.v0.models.RecommendationCode] = { js match { case v: play.api.libs.json.JsString => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.RecommendationCode(v.value)) case _ => { (js \ "value").validate[String] match { case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.RecommendationCode(v)) case _: play.api.libs.json.JsError => (js \ "RecommendationCode").validate[String] match { case play.api.libs.json.JsSuccess(v, _) => play.api.libs.json.JsSuccess(com.hbc.api.fraud.v0.models.RecommendationCode(v)) case err: play.api.libs.json.JsError => err } } } } } } def jsonWritesApiFraudRecommendationCode(obj: com.hbc.api.fraud.v0.models.RecommendationCode) = { play.api.libs.json.JsString(obj.toString) } def jsObjectRecommendationCode(obj: com.hbc.api.fraud.v0.models.RecommendationCode) = { play.api.libs.json.Json.obj("value" -> play.api.libs.json.JsString(obj.toString)) } implicit def jsonWritesApiFraudRecommendationCode: play.api.libs.json.Writes[RecommendationCode] = { (obj: com.hbc.api.fraud.v0.models.RecommendationCode) => { com.hbc.api.fraud.v0.models.json.jsonWritesApiFraudRecommendationCode(obj) } } implicit def jsonReadsApiFraudAdditionalData: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.AdditionalData] = { (__ \ "inAuthId").read[_root_.java.util.UUID].map { x => AdditionalData(inAuthId = x) } } def jsObjectAdditionalData(obj: com.hbc.api.fraud.v0.models.AdditionalData): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "inAuthId" -> play.api.libs.json.JsString(obj.inAuthId.toString) ) } implicit def jsonWritesApiFraudAdditionalData: play.api.libs.json.Writes[AdditionalData] = { (obj: com.hbc.api.fraud.v0.models.AdditionalData) => { com.hbc.api.fraud.v0.models.json.jsObjectAdditionalData(obj) } } implicit def jsonReadsApiFraudAddress: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Address] = { for { name <- (__ \ "name").read[String] streetLineOne <- (__ \ "streetLineOne").read[String] streetLineTwo <- (__ \ "streetLineTwo").readNullable[String] city <- (__ \ "city").read[String] state <- (__ \ "state").read[String] zip <- (__ \ "zip").read[String] country <- (__ \ "country").read[String] } yield Address(name, streetLineOne, streetLineTwo, city, state, zip, country) } def jsObjectAddress(obj: com.hbc.api.fraud.v0.models.Address): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "name" -> play.api.libs.json.JsString(obj.name), "streetLineOne" -> play.api.libs.json.JsString(obj.streetLineOne), "city" -> play.api.libs.json.JsString(obj.city), "state" -> play.api.libs.json.JsString(obj.state), "zip" -> play.api.libs.json.JsString(obj.zip), "country" -> play.api.libs.json.JsString(obj.country) ) ++ (obj.streetLineTwo match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("streetLineTwo" -> play.api.libs.json.JsString(x)) }) } implicit def jsonWritesApiFraudAddress: play.api.libs.json.Writes[Address] = { (obj: com.hbc.api.fraud.v0.models.Address) => { com.hbc.api.fraud.v0.models.json.jsObjectAddress(obj) } } implicit def jsonReadsApiFraudCreditCard: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.CreditCard] = { for { nameOnCard <- (__ \ "nameOnCard").read[String] billingAddress <- (__ \ "billingAddress").read[com.hbc.api.fraud.v0.models.Address] cardType <- (__ \ "cardType").read[String] cardNumber <- (__ \ "cardNumber").read[String] authorizedAmount <- (__ \ "authorizedAmount").read[BigDecimal] fullAmount <- (__ \ "fullAmount").read[BigDecimal] expiryDate <- (__ \ "expiryDate").read[String] authCode <- (__ \ "authCode").read[String] responseCode <- (__ \ "responseCode").read[Int] merchantId <- (__ \ "merchantId").readNullable[Int] registerNumber <- (__ \ "registerNumber").readNullable[String] transactionNumber <- (__ \ "transactionNumber").read[String] avsResponse <- (__ \ "avsResponse").read[String] } yield CreditCard(nameOnCard, billingAddress, cardType, cardNumber, authorizedAmount, fullAmount, expiryDate, authCode, responseCode, merchantId, registerNumber, transactionNumber, avsResponse) } def jsObjectCreditCard(obj: com.hbc.api.fraud.v0.models.CreditCard): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "nameOnCard" -> play.api.libs.json.JsString(obj.nameOnCard), "billingAddress" -> com.hbc.api.fraud.v0.models.json.jsObjectAddress(obj.billingAddress), "cardType" -> play.api.libs.json.JsString(obj.cardType), "cardNumber" -> play.api.libs.json.JsString(obj.cardNumber), "authorizedAmount" -> play.api.libs.json.JsNumber(obj.authorizedAmount), "fullAmount" -> play.api.libs.json.JsNumber(obj.fullAmount), "expiryDate" -> play.api.libs.json.JsString(obj.expiryDate), "authCode" -> play.api.libs.json.JsString(obj.authCode), "responseCode" -> play.api.libs.json.JsNumber(obj.responseCode), "transactionNumber" -> play.api.libs.json.JsString(obj.transactionNumber), "avsResponse" -> play.api.libs.json.JsString(obj.avsResponse) ) ++ (obj.merchantId match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("merchantId" -> play.api.libs.json.JsNumber(x)) }) ++ (obj.registerNumber match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("registerNumber" -> play.api.libs.json.JsString(x)) }) } implicit def jsonWritesApiFraudCreditCard: play.api.libs.json.Writes[CreditCard] = { (obj: com.hbc.api.fraud.v0.models.CreditCard) => { com.hbc.api.fraud.v0.models.json.jsObjectCreditCard(obj) } } implicit def jsonReadsApiFraudCustomer: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Customer] = { for { customerType <- (__ \ "customerType").read[com.hbc.api.fraud.v0.models.CustomerType] accountId <- (__ \ "accountId").read[String] creationDate <- (__ \ "creationDate").read[_root_.org.joda.time.LocalDate] firstName <- (__ \ "firstName").read[String] lastName <- (__ \ "lastName").read[String] emailAddress <- (__ \ "emailAddress").read[String] } yield Customer(customerType, accountId, creationDate, firstName, lastName, emailAddress) } def jsObjectCustomer(obj: com.hbc.api.fraud.v0.models.Customer): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "customerType" -> play.api.libs.json.JsString(obj.customerType.toString), "accountId" -> play.api.libs.json.JsString(obj.accountId), "creationDate" -> play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.date.print(obj.creationDate)), "firstName" -> play.api.libs.json.JsString(obj.firstName), "lastName" -> play.api.libs.json.JsString(obj.lastName), "emailAddress" -> play.api.libs.json.JsString(obj.emailAddress) ) } implicit def jsonWritesApiFraudCustomer: play.api.libs.json.Writes[Customer] = { (obj: com.hbc.api.fraud.v0.models.Customer) => { com.hbc.api.fraud.v0.models.json.jsObjectCustomer(obj) } } implicit def jsonReadsApiFraudDBRecord: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.DBRecord] = { for { transactionId <- (__ \ "transactionId").read[String] lastModifiedDate <- (__ \ "lastModifiedDate").readNullable[_root_.org.joda.time.LocalDate] createdDate <- (__ \ "createdDate").readNullable[_root_.org.joda.time.LocalDate] transaction <- (__ \ "transaction").read[com.hbc.api.fraud.v0.models.Transaction] decision <- (__ \ "decision").read[com.hbc.api.fraud.v0.models.Decision] } yield DBRecord(transactionId, lastModifiedDate, createdDate, transaction, decision) } def jsObjectDBRecord(obj: com.hbc.api.fraud.v0.models.DBRecord): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "transactionId" -> play.api.libs.json.JsString(obj.transactionId), "transaction" -> com.hbc.api.fraud.v0.models.json.jsObjectTransaction(obj.transaction), "decision" -> com.hbc.api.fraud.v0.models.json.jsObjectDecision(obj.decision) ) ++ (obj.lastModifiedDate match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("lastModifiedDate" -> play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.date.print(x))) }) ++ (obj.createdDate match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("createdDate" -> play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.date.print(x))) }) } implicit def jsonWritesApiFraudDBRecord: play.api.libs.json.Writes[DBRecord] = { (obj: com.hbc.api.fraud.v0.models.DBRecord) => { com.hbc.api.fraud.v0.models.json.jsObjectDBRecord(obj) } } implicit def jsonReadsApiFraudDecision: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Decision] = { for { transactionId <- (__ \ "transactionId").read[String] recommendationCode <- (__ \ "recommendationCode").read[com.hbc.api.fraud.v0.models.RecommendationCode] crossReference <- (__ \ "crossReference").readNullable[_root_.java.util.UUID] rulesTripped <- (__ \ "rulesTripped").readNullable[String] totalScore <- (__ \ "totalScore").read[Int] remarks <- (__ \ "remarks").readNullable[String] } yield Decision(transactionId, recommendationCode, crossReference, rulesTripped, totalScore, remarks) } def jsObjectDecision(obj: com.hbc.api.fraud.v0.models.Decision): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "transactionId" -> play.api.libs.json.JsString(obj.transactionId), "recommendationCode" -> play.api.libs.json.JsString(obj.recommendationCode.toString), "totalScore" -> play.api.libs.json.JsNumber(obj.totalScore) ) ++ (obj.crossReference match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("crossReference" -> play.api.libs.json.JsString(x.toString)) }) ++ (obj.rulesTripped match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("rulesTripped" -> play.api.libs.json.JsString(x)) }) ++ (obj.remarks match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("remarks" -> play.api.libs.json.JsString(x)) }) } implicit def jsonWritesApiFraudDecision: play.api.libs.json.Writes[Decision] = { (obj: com.hbc.api.fraud.v0.models.Decision) => { com.hbc.api.fraud.v0.models.json.jsObjectDecision(obj) } } implicit def jsonReadsApiFraudError: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Error] = { for { message <- (__ \ "message").read[String] error <- (__ \ "error").read[String] } yield Error(message, error) } def jsObjectError(obj: com.hbc.api.fraud.v0.models.Error): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "message" -> play.api.libs.json.JsString(obj.message), "error" -> play.api.libs.json.JsString(obj.error) ) } implicit def jsonWritesApiFraudError: play.api.libs.json.Writes[Error] = { (obj: com.hbc.api.fraud.v0.models.Error) => { com.hbc.api.fraud.v0.models.json.jsObjectError(obj) } } implicit def jsonReadsApiFraudItem: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Item] = { for { svsNumber <- (__ \ "svsNumber").read[Int] skuNumber <- (__ \ "skuNumber").read[Int] upcNumber <- (__ \ "upcNumber").readNullable[Int] classNumber <- (__ \ "classNumber").readNullable[Int] color <- (__ \ "color").readNullable[String] size <- (__ \ "size").readNullable[String] currentStatus <- (__ \ "currentStatus").read[String] department <- (__ \ "department").read[Int] signOnDelivery <- (__ \ "signOnDelivery").readNullable[String] giftWrapped <- (__ \ "giftWrapped").readNullable[Boolean] costAmount <- (__ \ "costAmount").readNullable[BigDecimal] marginAmount <- (__ \ "marginAmount").readNullable[BigDecimal] description <- (__ \ "description").read[String] price <- (__ \ "price").read[BigDecimal] extendedPrice <- (__ \ "extendedPrice").read[BigDecimal] quantity <- (__ \ "quantity").read[Int] groupNumber <- (__ \ "groupNumber").read[Int] shippingAddress <- (__ \ "shippingAddress").read[com.hbc.api.fraud.v0.models.Address] shippingMethod <- (__ \ "shippingMethod").read[String] shippingCountry <- (__ \ "shippingCountry").read[String] } yield Item(svsNumber, skuNumber, upcNumber, classNumber, color, size, currentStatus, department, signOnDelivery, giftWrapped, costAmount, marginAmount, description, price, extendedPrice, quantity, groupNumber, shippingAddress, shippingMethod, shippingCountry) } def jsObjectItem(obj: com.hbc.api.fraud.v0.models.Item): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "svsNumber" -> play.api.libs.json.JsNumber(obj.svsNumber), "skuNumber" -> play.api.libs.json.JsNumber(obj.skuNumber), "currentStatus" -> play.api.libs.json.JsString(obj.currentStatus), "department" -> play.api.libs.json.JsNumber(obj.department), "description" -> play.api.libs.json.JsString(obj.description), "price" -> play.api.libs.json.JsNumber(obj.price), "extendedPrice" -> play.api.libs.json.JsNumber(obj.extendedPrice), "quantity" -> play.api.libs.json.JsNumber(obj.quantity), "groupNumber" -> play.api.libs.json.JsNumber(obj.groupNumber), "shippingAddress" -> com.hbc.api.fraud.v0.models.json.jsObjectAddress(obj.shippingAddress), "shippingMethod" -> play.api.libs.json.JsString(obj.shippingMethod), "shippingCountry" -> play.api.libs.json.JsString(obj.shippingCountry) ) ++ (obj.upcNumber match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("upcNumber" -> play.api.libs.json.JsNumber(x)) }) ++ (obj.classNumber match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("classNumber" -> play.api.libs.json.JsNumber(x)) }) ++ (obj.color match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("color" -> play.api.libs.json.JsString(x)) }) ++ (obj.size match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("size" -> play.api.libs.json.JsString(x)) }) ++ (obj.signOnDelivery match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("signOnDelivery" -> play.api.libs.json.JsString(x)) }) ++ (obj.giftWrapped match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("giftWrapped" -> play.api.libs.json.JsBoolean(x)) }) ++ (obj.costAmount match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("costAmount" -> play.api.libs.json.JsNumber(x)) }) ++ (obj.marginAmount match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("marginAmount" -> play.api.libs.json.JsNumber(x)) }) } implicit def jsonWritesApiFraudItem: play.api.libs.json.Writes[Item] = { (obj: com.hbc.api.fraud.v0.models.Item) => { com.hbc.api.fraud.v0.models.json.jsObjectItem(obj) } } implicit def jsonReadsApiFraudPromo: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Promo] = { for { promotionCode <- (__ \ "promotionCode").read[String] promotionAmount <- (__ \ "promotionAmount").read[BigDecimal] } yield Promo(promotionCode, promotionAmount) } def jsObjectPromo(obj: com.hbc.api.fraud.v0.models.Promo): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "promotionCode" -> play.api.libs.json.JsString(obj.promotionCode), "promotionAmount" -> play.api.libs.json.JsNumber(obj.promotionAmount) ) } implicit def jsonWritesApiFraudPromo: play.api.libs.json.Writes[Promo] = { (obj: com.hbc.api.fraud.v0.models.Promo) => { com.hbc.api.fraud.v0.models.json.jsObjectPromo(obj) } } implicit def jsonReadsApiFraudTransaction: play.api.libs.json.Reads[com.hbc.api.fraud.v0.models.Transaction] = { for { orderId <- (__ \ "orderId").read[String] groupId <- (__ \ "groupId").read[String] orderTotal <- (__ \ "orderTotal").read[BigDecimal] shippingCost <- (__ \ "shippingCost").read[BigDecimal] currencyCode <- (__ \ "currencyCode").read[String] storeNumber <- (__ \ "storeNumber").read[Int] salesRep <- (__ \ "salesRep").readNullable[String] lastModifiedDate <- (__ \ "lastModifiedDate").readNullable[_root_.org.joda.time.LocalDate] banner <- (__ \ "banner").read[com.hbc.api.fraud.v0.models.Banner] creditCard <- (__ \ "creditCard").read[com.hbc.api.fraud.v0.models.CreditCard] promos <- (__ \ "promos").readNullable[Seq[com.hbc.api.fraud.v0.models.Promo]] items <- (__ \ "items").read[Seq[com.hbc.api.fraud.v0.models.Item]] ipAddress <- (__ \ "ipAddress").readNullable[String] source <- (__ \ "source").read[String] customer <- (__ \ "customer").read[com.hbc.api.fraud.v0.models.Customer] additionalData <- (__ \ "additionalData").readNullable[com.hbc.api.fraud.v0.models.AdditionalData] } yield Transaction(orderId, groupId, orderTotal, shippingCost, currencyCode, storeNumber, salesRep, lastModifiedDate, banner, creditCard, promos, items, ipAddress, source, customer, additionalData) } def jsObjectTransaction(obj: com.hbc.api.fraud.v0.models.Transaction): play.api.libs.json.JsObject = { play.api.libs.json.Json.obj( "orderId" -> play.api.libs.json.JsString(obj.orderId), "groupId" -> play.api.libs.json.JsString(obj.groupId), "orderTotal" -> play.api.libs.json.JsNumber(obj.orderTotal), "shippingCost" -> play.api.libs.json.JsNumber(obj.shippingCost), "currencyCode" -> play.api.libs.json.JsString(obj.currencyCode), "storeNumber" -> play.api.libs.json.JsNumber(obj.storeNumber), "banner" -> play.api.libs.json.JsString(obj.banner.toString), "creditCard" -> com.hbc.api.fraud.v0.models.json.jsObjectCreditCard(obj.creditCard), "items" -> play.api.libs.json.Json.toJson(obj.items), "source" -> play.api.libs.json.JsString(obj.source), "customer" -> com.hbc.api.fraud.v0.models.json.jsObjectCustomer(obj.customer) ) ++ (obj.salesRep match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("salesRep" -> play.api.libs.json.JsString(x)) }) ++ (obj.lastModifiedDate match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("lastModifiedDate" -> play.api.libs.json.JsString(_root_.org.joda.time.format.ISODateTimeFormat.date.print(x))) }) ++ (obj.promos match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("promos" -> play.api.libs.json.Json.toJson(x)) }) ++ (obj.ipAddress match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("ipAddress" -> play.api.libs.json.JsString(x)) }) ++ (obj.additionalData match { case None => play.api.libs.json.Json.obj() case Some(x) => play.api.libs.json.Json.obj("additionalData" -> com.hbc.api.fraud.v0.models.json.jsObjectAdditionalData(x)) }) } implicit def jsonWritesApiFraudTransaction: play.api.libs.json.Writes[Transaction] = { (obj: com.hbc.api.fraud.v0.models.Transaction) => { com.hbc.api.fraud.v0.models.json.jsObjectTransaction(obj) } } } } package com.hbc.api.fraud.v0 { object Bindables { import play.api.mvc.{PathBindable, QueryStringBindable} // import models directly for backwards compatibility with prior versions of the generator import Core._ import Models._ object Core { implicit def pathBindableDateTimeIso8601(implicit stringBinder: QueryStringBindable[String]): PathBindable[_root_.org.joda.time.DateTime] = ApibuilderPathBindable(ApibuilderTypes.dateTimeIso8601) implicit def queryStringBindableDateTimeIso8601(implicit stringBinder: QueryStringBindable[String]): QueryStringBindable[_root_.org.joda.time.DateTime] = ApibuilderQueryStringBindable(ApibuilderTypes.dateTimeIso8601) implicit def pathBindableDateIso8601(implicit stringBinder: QueryStringBindable[String]): PathBindable[_root_.org.joda.time.LocalDate] = ApibuilderPathBindable(ApibuilderTypes.dateIso8601) implicit def queryStringBindableDateIso8601(implicit stringBinder: QueryStringBindable[String]): QueryStringBindable[_root_.org.joda.time.LocalDate] = ApibuilderQueryStringBindable(ApibuilderTypes.dateIso8601) } object Models { import com.hbc.api.fraud.v0.models._ val bannerConverter: ApibuilderTypeConverter[com.hbc.api.fraud.v0.models.Banner] = new ApibuilderTypeConverter[com.hbc.api.fraud.v0.models.Banner] { override def convert(value: String): com.hbc.api.fraud.v0.models.Banner = com.hbc.api.fraud.v0.models.Banner(value) override def convert(value: com.hbc.api.fraud.v0.models.Banner): String = value.toString override def example: com.hbc.api.fraud.v0.models.Banner = com.hbc.api.fraud.v0.models.Banner.Lat override def validValues: Seq[com.hbc.api.fraud.v0.models.Banner] = com.hbc.api.fraud.v0.models.Banner.all } implicit def pathBindableBanner(implicit stringBinder: QueryStringBindable[String]): PathBindable[com.hbc.api.fraud.v0.models.Banner] = ApibuilderPathBindable(bannerConverter) implicit def queryStringBindableBanner(implicit stringBinder: QueryStringBindable[String]): QueryStringBindable[com.hbc.api.fraud.v0.models.Banner] = ApibuilderQueryStringBindable(bannerConverter) val customerTypeConverter: ApibuilderTypeConverter[com.hbc.api.fraud.v0.models.CustomerType] = new ApibuilderTypeConverter[com.hbc.api.fraud.v0.models.CustomerType] { override def convert(value: String): com.hbc.api.fraud.v0.models.CustomerType = com.hbc.api.fraud.v0.models.CustomerType(value) override def convert(value: com.hbc.api.fraud.v0.models.CustomerType): String = value.toString override def example: com.hbc.api.fraud.v0.models.CustomerType = com.hbc.api.fraud.v0.models.CustomerType.Guest override def validValues: Seq[com.hbc.api.fraud.v0.models.CustomerType] = com.hbc.api.fraud.v0.models.CustomerType.all } implicit def pathBindableCustomerType(implicit stringBinder: QueryStringBindable[String]): PathBindable[com.hbc.api.fraud.v0.models.CustomerType] = ApibuilderPathBindable(customerTypeConverter) implicit def queryStringBindableCustomerType(implicit stringBinder: QueryStringBindable[String]): QueryStringBindable[com.hbc.api.fraud.v0.models.CustomerType] = ApibuilderQueryStringBindable(customerTypeConverter) val recommendationCodeConverter: ApibuilderTypeConverter[com.hbc.api.fraud.v0.models.RecommendationCode] = new ApibuilderTypeConverter[com.hbc.api.fraud.v0.models.RecommendationCode] { override def convert(value: String): com.hbc.api.fraud.v0.models.RecommendationCode = com.hbc.api.fraud.v0.models.RecommendationCode(value) override def convert(value: com.hbc.api.fraud.v0.models.RecommendationCode): String = value.toString override def example: com.hbc.api.fraud.v0.models.RecommendationCode = com.hbc.api.fraud.v0.models.RecommendationCode.Reject override def validValues: Seq[com.hbc.api.fraud.v0.models.RecommendationCode] = com.hbc.api.fraud.v0.models.RecommendationCode.all } implicit def pathBindableRecommendationCode(implicit stringBinder: QueryStringBindable[String]): PathBindable[com.hbc.api.fraud.v0.models.RecommendationCode] = ApibuilderPathBindable(recommendationCodeConverter) implicit def queryStringBindableRecommendationCode(implicit stringBinder: QueryStringBindable[String]): QueryStringBindable[com.hbc.api.fraud.v0.models.RecommendationCode] = ApibuilderQueryStringBindable(recommendationCodeConverter) } trait ApibuilderTypeConverter[T] { def convert(value: String): T def convert(value: T): String def example: T def validValues: Seq[T] = Nil def errorMessage(key: String, value: String, ex: java.lang.Exception): String = { val base = s"Invalid value '$value' for parameter '$key'. " validValues.toList match { case Nil => base + "Ex: " + convert(example) case values => base + ". Valid values are: " + values.mkString("'", "', '", "'") } } } object ApibuilderTypes { val dateTimeIso8601: ApibuilderTypeConverter[_root_.org.joda.time.DateTime] = new ApibuilderTypeConverter[_root_.org.joda.time.DateTime] { override def convert(value: String): _root_.org.joda.time.DateTime = _root_.org.joda.time.format.ISODateTimeFormat.dateTimeParser.parseDateTime(value) override def convert(value: _root_.org.joda.time.DateTime): String = _root_.org.joda.time.format.ISODateTimeFormat.dateTime.print(value) override def example: _root_.org.joda.time.DateTime = _root_.org.joda.time.DateTime.now } val dateIso8601: ApibuilderTypeConverter[_root_.org.joda.time.LocalDate] = new ApibuilderTypeConverter[_root_.org.joda.time.LocalDate] { override def convert(value: String): _root_.org.joda.time.LocalDate = _root_.org.joda.time.format.ISODateTimeFormat.dateTimeParser.parseLocalDate(value) override def convert(value: _root_.org.joda.time.LocalDate): String = _root_.org.joda.time.format.ISODateTimeFormat.date.print(value) override def example: _root_.org.joda.time.LocalDate = _root_.org.joda.time.LocalDate.now } } final case class ApibuilderQueryStringBindable[T]( converters: ApibuilderTypeConverter[T] ) extends QueryStringBindable[T] { override def bind(key: String, params: Map[String, Seq[String]]): _root_.scala.Option[_root_.scala.Either[String, T]] = { params.getOrElse(key, Nil).headOption.map { v => try { Right( converters.convert(v) ) } catch { case ex: java.lang.Exception => Left( converters.errorMessage(key, v, ex) ) } } } override def unbind(key: String, value: T): String = { s"$key=${converters.convert(value)}" } } final case class ApibuilderPathBindable[T]( converters: ApibuilderTypeConverter[T] ) extends PathBindable[T] { override def bind(key: String, value: String): _root_.scala.Either[String, T] = { try { Right( converters.convert(value) ) } catch { case ex: java.lang.Exception => Left( converters.errorMessage(key, value, ex) ) } } override def unbind(key: String, value: T): String = { converters.convert(value) } } } } package com.hbc.api.fraud.v0 { object Constants { val BaseUrl = "http://fraud-frozone" val Namespace = "com.hbc.api.fraud.v0" val UserAgent = "apibuilder app.apibuilder.io/hbc/api-fraud/0.0.2/play_2_7_client" val Version = "0.0.2" val VersionMajor = 0 } class Client( ws: play.api.libs.ws.WSClient, val baseUrl: String = "http://fraud-frozone", auth: scala.Option[com.hbc.api.fraud.v0.Authorization] = None, defaultHeaders: Seq[(String, String)] = Nil ) extends interfaces.Client { import com.hbc.api.fraud.v0.models.json._ private val logger = play.api.Logger("com.hbc.api.fraud.v0.Client") logger.info(s"Initializing com.hbc.api.fraud.v0.Client for url $baseUrl") def decisions: Decisions = Decisions def transactions: Transactions = Transactions object Decisions extends Decisions { override def post( decision: com.hbc.api.fraud.v0.models.Decision, requestHeaders: Seq[(String, String)] = Nil )(implicit ec: scala.concurrent.ExecutionContext): scala.concurrent.Future[Unit] = { val payload = play.api.libs.json.Json.toJson(decision) _executeRequest("POST", s"/decision", body = Some(payload), requestHeaders = requestHeaders).map { case r if r.status == 200 => () case r if r.status == 400 => throw com.hbc.api.fraud.v0.errors.ErrorsResponse(r) case r => throw com.hbc.api.fraud.v0.errors.FailedRequest(r.status, s"Unsupported response code[${r.status}]. Expected: 200, 400") } } } object Transactions extends Transactions { override def post( transaction: com.hbc.api.fraud.v0.models.Transaction, requestHeaders: Seq[(String, String)] = Nil )(implicit ec: scala.concurrent.ExecutionContext): scala.concurrent.Future[com.hbc.api.fraud.v0.models.Decision] = { val payload = play.api.libs.json.Json.toJson(transaction) _executeRequest("POST", s"/transaction", body = Some(payload), requestHeaders = requestHeaders).map { case r if r.status == 200 => _root_.com.hbc.api.fraud.v0.Client.parseJson("com.hbc.api.fraud.v0.models.Decision", r, _.validate[com.hbc.api.fraud.v0.models.Decision]) case r if r.status == 400 => throw com.hbc.api.fraud.v0.errors.ErrorsResponse(r) case r => throw com.hbc.api.fraud.v0.errors.FailedRequest(r.status, s"Unsupported response code[${r.status}]. Expected: 200, 400") } } } def _requestHolder(path: String): play.api.libs.ws.WSRequest = { val holder = ws.url(baseUrl + path).addHttpHeaders( "User-Agent" -> Constants.UserAgent, "X-Apidoc-Version" -> Constants.Version, "X-Apidoc-Version-Major" -> Constants.VersionMajor.toString ).addHttpHeaders(defaultHeaders: _*) auth.fold(holder) { case Authorization.Basic(username, password) => { holder.withAuth(username, password.getOrElse(""), play.api.libs.ws.WSAuthScheme.BASIC) } } } def _logRequest(method: String, req: play.api.libs.ws.WSRequest): play.api.libs.ws.WSRequest = { val queryComponents = for { (name, values) <- req.queryString value <- values } yield s"$name=$value" val url = s"${req.url}${queryComponents.mkString("?", "&", "")}" auth.fold(logger.info(s"curl -X $method '$url'")) { _ => logger.info(s"curl -X $method -u '[REDACTED]:' '$url'") } req } def _executeRequest( method: String, path: String, queryParameters: Seq[(String, String)] = Nil, requestHeaders: Seq[(String, String)] = Nil, body: Option[play.api.libs.json.JsValue] = None ): scala.concurrent.Future[play.api.libs.ws.WSResponse] = { method.toUpperCase match { case "GET" => { _logRequest("GET", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).get() } case "POST" => { _logRequest("POST", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).post(body.getOrElse(play.api.libs.json.Json.obj())) } case "PUT" => { _logRequest("PUT", _requestHolder(path).addHttpHeaders(_withJsonContentType(requestHeaders): _*).addQueryStringParameters(queryParameters: _*)).put(body.getOrElse(play.api.libs.json.Json.obj())) } case "PATCH" => { _logRequest("PATCH", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).patch(body.getOrElse(play.api.libs.json.Json.obj())) } case "DELETE" => { _logRequest("DELETE", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).delete() } case "HEAD" => { _logRequest("HEAD", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).head() } case "OPTIONS" => { _logRequest("OPTIONS", _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)).options() } case _ => { _logRequest(method, _requestHolder(path).addHttpHeaders(requestHeaders: _*).addQueryStringParameters(queryParameters: _*)) sys.error("Unsupported method[%s]".format(method)) } } } /** * Adds a Content-Type: application/json header unless the specified requestHeaders * already contain a Content-Type header */ def _withJsonContentType(headers: Seq[(String, String)]): Seq[(String, String)] = { headers.find { _._1.toUpperCase == "CONTENT-TYPE" } match { case None => headers ++ Seq("Content-Type" -> "application/json; charset=UTF-8") case Some(_) => headers } } } object Client { def parseJson[T]( className: String, r: play.api.libs.ws.WSResponse, f: (play.api.libs.json.JsValue => play.api.libs.json.JsResult[T]) ): T = { f(play.api.libs.json.Json.parse(r.body)) match { case play.api.libs.json.JsSuccess(x, _) => x case play.api.libs.json.JsError(errors) => { throw com.hbc.api.fraud.v0.errors.FailedRequest(r.status, s"Invalid json for class[" + className + "]: " + errors.mkString(" ")) } } } } sealed trait Authorization extends _root_.scala.Product with _root_.scala.Serializable object Authorization { final case class Basic(username: String, password: Option[String] = None) extends Authorization } package interfaces { trait Client { def baseUrl: String def decisions: com.hbc.api.fraud.v0.Decisions def transactions: com.hbc.api.fraud.v0.Transactions } } trait Decisions { /** * Consumes the decision about a transaction (usually meant for manual review) and * triggers OMS to process/cancel the order */ def post( decision: com.hbc.api.fraud.v0.models.Decision, requestHeaders: Seq[(String, String)] = Nil )(implicit ec: scala.concurrent.ExecutionContext): scala.concurrent.Future[Unit] } trait Transactions { /** * Provides decision about a transaction by supplying order or other information */ def post( transaction: com.hbc.api.fraud.v0.models.Transaction, requestHeaders: Seq[(String, String)] = Nil )(implicit ec: scala.concurrent.ExecutionContext): scala.concurrent.Future[com.hbc.api.fraud.v0.models.Decision] } package errors { import com.hbc.api.fraud.v0.models.json._ final case class ErrorsResponse( response: play.api.libs.ws.WSResponse, message: Option[String] = None ) extends Exception(message.getOrElse(s"${response.status}: ${response.body}")) { lazy val errors = _root_.com.hbc.api.fraud.v0.Client.parseJson("Seq[com.hbc.api.fraud.v0.models.Error]", response, _.validate[Seq[com.hbc.api.fraud.v0.models.Error]]) } final case class FailedRequest(responseCode: Int, message: String, requestUri: Option[_root_.java.net.URI] = None) extends _root_.java.lang.Exception(s"HTTP $responseCode: $message") } }