diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 820b5c1ae..939bb1750 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.112.0" + ".": "0.113.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 9462bec8d..d8bf6f020 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 172 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-e1901db484e520cc1f6aa88c8b00d0fcda30c8f9e5ea562a12b9edfc3fb3b6d6.yml -openapi_spec_hash: 59c317749628f3ed4cc7911b68f6351f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-9791980619fc7ce8afb01f77dfe3c660a540975327378287cb666136ae4b0a99.yml +openapi_spec_hash: 0752074b2a7b0534329a1e3176c94a62 config_hash: aab05d0cf41f1f6b9f4d5677273c1600 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e2469475..0e08861ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.113.0 (2025-11-20) + +Full Changelog: [v0.112.0...v0.113.0](https://github.com/lithic-com/lithic-java/compare/v0.112.0...v0.113.0) + +### Features + +* **api:** Add Payoff Details ([d1ee88a](https://github.com/lithic-com/lithic-java/commit/d1ee88a985345da5724757142198d696169347d1)) + + +### Bug Fixes + +* **api:** Modify return type of returns API to payment-transaction ([d1ee88a](https://github.com/lithic-com/lithic-java/commit/d1ee88a985345da5724757142198d696169347d1)) + ## 0.112.0 (2025-11-17) Full Changelog: [v0.111.0...v0.112.0](https://github.com/lithic-com/lithic-java/compare/v0.111.0...v0.112.0) diff --git a/README.md b/README.md index 2e03962db..9e88223b2 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.lithic.api/lithic-java)](https://central.sonatype.com/artifact/com.lithic.api/lithic-java/0.112.0) -[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.112.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.112.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.lithic.api/lithic-java)](https://central.sonatype.com/artifact/com.lithic.api/lithic-java/0.113.0) +[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.113.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.113.0) @@ -13,7 +13,7 @@ The Lithic Java SDK is similar to the Lithic Kotlin SDK but with minor differenc -The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.lithic.api/lithic-java/0.112.0). +The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.lithic.api/lithic-java/0.113.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.lithic.com](https://docs.lithic ### Gradle ```kotlin -implementation("com.lithic.api:lithic-java:0.112.0") +implementation("com.lithic.api:lithic-java:0.113.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.lithic.api:lithic-java:0.112.0") com.lithic.api lithic-java - 0.112.0 + 0.113.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index ebb49cb87..ee8a549d7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.lithic.api" - version = "0.112.0" // x-release-please-version + version = "0.113.0" // x-release-please-version } subprojects { diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/core/ObjectMappers.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/core/ObjectMappers.kt index 553092256..1154cadf6 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/core/ObjectMappers.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/core/ObjectMappers.kt @@ -24,6 +24,7 @@ import java.io.InputStream import java.time.DateTimeException import java.time.LocalDate import java.time.LocalDateTime +import java.time.OffsetDateTime import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.time.temporal.ChronoField @@ -37,6 +38,7 @@ fun jsonMapper(): JsonMapper = SimpleModule() .addSerializer(InputStreamSerializer) .addDeserializer(LocalDateTime::class.java, LenientLocalDateTimeDeserializer()) + .addDeserializer(OffsetDateTime::class.java, LenientOffsetDateTimeDeserializer()) ) .withCoercionConfig(LogicalType.Boolean) { it.setCoercion(CoercionInputShape.Integer, CoercionAction.Fail) @@ -165,3 +167,31 @@ private class LenientLocalDateTimeDeserializer : } } } + +/** + * A deserializer that can deserialize [OffsetDateTime], assuming UTC when a timezone isn't given. + */ +private class LenientOffsetDateTimeDeserializer : + StdDeserializer(OffsetDateTime::class.java) { + override fun logicalType(): LogicalType = LogicalType.DateTime + + override fun deserialize(p: JsonParser, context: DeserializationContext?): OffsetDateTime { + val exceptions = mutableListOf() + + try { + return OffsetDateTime.parse(p.text) + } catch (e: DateTimeException) { + exceptions.add(e) + } + + try { + return OffsetDateTime.parse(p.text + 'Z') + } catch (e: DateTimeException) { + exceptions.add(e) + } + + throw JsonParseException(p, "Cannot parse `OffsetDateTime` from value: ${p.text}").apply { + exceptions.forEach { addSuppressed(it) } + } + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/PaymentReturnResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/PaymentReturnResponse.kt deleted file mode 100644 index 49ac4fad5..000000000 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/PaymentReturnResponse.kt +++ /dev/null @@ -1,402 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.models - -import com.fasterxml.jackson.annotation.JsonAnyGetter -import com.fasterxml.jackson.annotation.JsonAnySetter -import com.fasterxml.jackson.annotation.JsonCreator -import com.fasterxml.jackson.annotation.JsonProperty -import com.lithic.api.core.Enum -import com.lithic.api.core.ExcludeMissing -import com.lithic.api.core.JsonField -import com.lithic.api.core.JsonMissing -import com.lithic.api.core.JsonValue -import com.lithic.api.core.checkRequired -import com.lithic.api.errors.LithicInvalidDataException -import java.util.Collections -import java.util.Objects -import kotlin.jvm.optionals.getOrNull - -/** Response from ACH operations including returns */ -class PaymentReturnResponse -@JsonCreator(mode = JsonCreator.Mode.DISABLED) -private constructor( - private val result: JsonField, - private val transactionGroupUuid: JsonField, - private val transactionUuid: JsonField, - private val additionalProperties: MutableMap, -) { - - @JsonCreator - private constructor( - @JsonProperty("result") - @ExcludeMissing - result: JsonField = JsonMissing.of(), - @JsonProperty("transaction_group_uuid") - @ExcludeMissing - transactionGroupUuid: JsonField = JsonMissing.of(), - @JsonProperty("transaction_uuid") - @ExcludeMissing - transactionUuid: JsonField = JsonMissing.of(), - ) : this(result, transactionGroupUuid, transactionUuid, mutableMapOf()) - - /** - * Transaction result - * - * @throws LithicInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun result(): TransactionResult = result.getRequired("result") - - /** - * Globally unique identifier for the transaction group - * - * @throws LithicInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun transactionGroupUuid(): String = transactionGroupUuid.getRequired("transaction_group_uuid") - - /** - * Globally unique identifier for the transaction - * - * @throws LithicInvalidDataException if the JSON field has an unexpected type or is - * unexpectedly missing or null (e.g. if the server responded with an unexpected value). - */ - fun transactionUuid(): String = transactionUuid.getRequired("transaction_uuid") - - /** - * Returns the raw JSON value of [result]. - * - * Unlike [result], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("result") @ExcludeMissing fun _result(): JsonField = result - - /** - * Returns the raw JSON value of [transactionGroupUuid]. - * - * Unlike [transactionGroupUuid], this method doesn't throw if the JSON field has an unexpected - * type. - */ - @JsonProperty("transaction_group_uuid") - @ExcludeMissing - fun _transactionGroupUuid(): JsonField = transactionGroupUuid - - /** - * Returns the raw JSON value of [transactionUuid]. - * - * Unlike [transactionUuid], this method doesn't throw if the JSON field has an unexpected type. - */ - @JsonProperty("transaction_uuid") - @ExcludeMissing - fun _transactionUuid(): JsonField = transactionUuid - - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } - - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) - - fun toBuilder() = Builder().from(this) - - companion object { - - /** - * Returns a mutable builder for constructing an instance of [PaymentReturnResponse]. - * - * The following fields are required: - * ```java - * .result() - * .transactionGroupUuid() - * .transactionUuid() - * ``` - */ - @JvmStatic fun builder() = Builder() - } - - /** A builder for [PaymentReturnResponse]. */ - class Builder internal constructor() { - - private var result: JsonField? = null - private var transactionGroupUuid: JsonField? = null - private var transactionUuid: JsonField? = null - private var additionalProperties: MutableMap = mutableMapOf() - - @JvmSynthetic - internal fun from(paymentReturnResponse: PaymentReturnResponse) = apply { - result = paymentReturnResponse.result - transactionGroupUuid = paymentReturnResponse.transactionGroupUuid - transactionUuid = paymentReturnResponse.transactionUuid - additionalProperties = paymentReturnResponse.additionalProperties.toMutableMap() - } - - /** Transaction result */ - fun result(result: TransactionResult) = result(JsonField.of(result)) - - /** - * Sets [Builder.result] to an arbitrary JSON value. - * - * You should usually call [Builder.result] with a well-typed [TransactionResult] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun result(result: JsonField) = apply { this.result = result } - - /** Globally unique identifier for the transaction group */ - fun transactionGroupUuid(transactionGroupUuid: String) = - transactionGroupUuid(JsonField.of(transactionGroupUuid)) - - /** - * Sets [Builder.transactionGroupUuid] to an arbitrary JSON value. - * - * You should usually call [Builder.transactionGroupUuid] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun transactionGroupUuid(transactionGroupUuid: JsonField) = apply { - this.transactionGroupUuid = transactionGroupUuid - } - - /** Globally unique identifier for the transaction */ - fun transactionUuid(transactionUuid: String) = - transactionUuid(JsonField.of(transactionUuid)) - - /** - * Sets [Builder.transactionUuid] to an arbitrary JSON value. - * - * You should usually call [Builder.transactionUuid] with a well-typed [String] value - * instead. This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun transactionUuid(transactionUuid: JsonField) = apply { - this.transactionUuid = transactionUuid - } - - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } - - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } - - fun putAllAdditionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.putAll(additionalProperties) - } - - fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - - /** - * Returns an immutable instance of [PaymentReturnResponse]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .result() - * .transactionGroupUuid() - * .transactionUuid() - * ``` - * - * @throws IllegalStateException if any required field is unset. - */ - fun build(): PaymentReturnResponse = - PaymentReturnResponse( - checkRequired("result", result), - checkRequired("transactionGroupUuid", transactionGroupUuid), - checkRequired("transactionUuid", transactionUuid), - additionalProperties.toMutableMap(), - ) - } - - private var validated: Boolean = false - - fun validate(): PaymentReturnResponse = apply { - if (validated) { - return@apply - } - - result().validate() - transactionGroupUuid() - transactionUuid() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic - internal fun validity(): Int = - (result.asKnown().getOrNull()?.validity() ?: 0) + - (if (transactionGroupUuid.asKnown().isPresent) 1 else 0) + - (if (transactionUuid.asKnown().isPresent) 1 else 0) - - /** Transaction result */ - class TransactionResult @JsonCreator private constructor(private val value: JsonField) : - Enum { - - /** - * Returns this class instance's raw value. - * - * This is usually only useful if this instance was deserialized from data that doesn't - * match any known member, and you want to know that value. For example, if the SDK is on an - * older version than the API, then the API may respond with new members that the SDK is - * unaware of. - */ - @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - - companion object { - - @JvmField val APPROVED = of("APPROVED") - - @JvmField val DECLINED = of("DECLINED") - - @JvmStatic fun of(value: String) = TransactionResult(JsonField.of(value)) - } - - /** An enum containing [TransactionResult]'s known values. */ - enum class Known { - APPROVED, - DECLINED, - } - - /** - * An enum containing [TransactionResult]'s known values, as well as an [_UNKNOWN] member. - * - * An instance of [TransactionResult] can contain an unknown value in a couple of cases: - * - It was deserialized from data that doesn't match any known member. For example, if the - * SDK is on an older version than the API, then the API may respond with new members that - * the SDK is unaware of. - * - It was constructed with an arbitrary value using the [of] method. - */ - enum class Value { - APPROVED, - DECLINED, - /** - * An enum member indicating that [TransactionResult] was instantiated with an unknown - * value. - */ - _UNKNOWN, - } - - /** - * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] - * if the class was instantiated with an unknown value. - * - * Use the [known] method instead if you're certain the value is always known or if you want - * to throw for the unknown case. - */ - fun value(): Value = - when (this) { - APPROVED -> Value.APPROVED - DECLINED -> Value.DECLINED - else -> Value._UNKNOWN - } - - /** - * Returns an enum member corresponding to this class instance's value. - * - * Use the [value] method instead if you're uncertain the value is always known and don't - * want to throw for the unknown case. - * - * @throws LithicInvalidDataException if this class instance's value is a not a known - * member. - */ - fun known(): Known = - when (this) { - APPROVED -> Known.APPROVED - DECLINED -> Known.DECLINED - else -> throw LithicInvalidDataException("Unknown TransactionResult: $value") - } - - /** - * Returns this class instance's primitive wire representation. - * - * This differs from the [toString] method because that method is primarily for debugging - * and generally doesn't throw. - * - * @throws LithicInvalidDataException if this class instance's value does not have the - * expected primitive type. - */ - fun asString(): String = - _value().asString().orElseThrow { LithicInvalidDataException("Value is not a String") } - - private var validated: Boolean = false - - fun validate(): TransactionResult = apply { - if (validated) { - return@apply - } - - known() - validated = true - } - - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false - } - - /** - * Returns a score indicating how many valid values are contained in this object - * recursively. - * - * Used for best match union deserialization. - */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is TransactionResult && value == other.value - } - - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is PaymentReturnResponse && - result == other.result && - transactionGroupUuid == other.transactionGroupUuid && - transactionUuid == other.transactionUuid && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { - Objects.hash(result, transactionGroupUuid, transactionUuid, additionalProperties) - } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "PaymentReturnResponse{result=$result, transactionGroupUuid=$transactionGroupUuid, transactionUuid=$transactionUuid, additionalProperties=$additionalProperties}" -} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt index d6f076ff7..1e695745c 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt @@ -44,6 +44,7 @@ private constructor( private val interestDetails: JsonField, private val nextPaymentDueDate: JsonField, private val nextStatementEndDate: JsonField, + private val payoffDetails: JsonField, private val additionalProperties: MutableMap, ) { @@ -110,6 +111,9 @@ private constructor( @JsonProperty("next_statement_end_date") @ExcludeMissing nextStatementEndDate: JsonField = JsonMissing.of(), + @JsonProperty("payoff_details") + @ExcludeMissing + payoffDetails: JsonField = JsonMissing.of(), ) : this( token, accountStanding, @@ -132,6 +136,7 @@ private constructor( interestDetails, nextPaymentDueDate, nextStatementEndDate, + payoffDetails, mutableMapOf(), ) @@ -296,6 +301,14 @@ private constructor( fun nextStatementEndDate(): Optional = nextStatementEndDate.getOptional("next_statement_end_date") + /** + * Details on number and size of payments to pay off balance + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun payoffDetails(): Optional = payoffDetails.getOptional("payoff_details") + /** * Returns the raw JSON value of [token]. * @@ -482,6 +495,15 @@ private constructor( @ExcludeMissing fun _nextStatementEndDate(): JsonField = nextStatementEndDate + /** + * Returns the raw JSON value of [payoffDetails]. + * + * Unlike [payoffDetails], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("payoff_details") + @ExcludeMissing + fun _payoffDetails(): JsonField = payoffDetails + @JsonAnySetter private fun putAdditionalProperty(key: String, value: JsonValue) { additionalProperties.put(key, value) @@ -548,6 +570,7 @@ private constructor( private var interestDetails: JsonField = JsonMissing.of() private var nextPaymentDueDate: JsonField = JsonMissing.of() private var nextStatementEndDate: JsonField = JsonMissing.of() + private var payoffDetails: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic @@ -573,6 +596,7 @@ private constructor( interestDetails = statement.interestDetails nextPaymentDueDate = statement.nextPaymentDueDate nextStatementEndDate = statement.nextStatementEndDate + payoffDetails = statement.payoffDetails additionalProperties = statement.additionalProperties.toMutableMap() } @@ -872,6 +896,25 @@ private constructor( this.nextStatementEndDate = nextStatementEndDate } + /** Details on number and size of payments to pay off balance */ + fun payoffDetails(payoffDetails: PayoffDetails?) = + payoffDetails(JsonField.ofNullable(payoffDetails)) + + /** Alias for calling [Builder.payoffDetails] with `payoffDetails.orElse(null)`. */ + fun payoffDetails(payoffDetails: Optional) = + payoffDetails(payoffDetails.getOrNull()) + + /** + * Sets [Builder.payoffDetails] to an arbitrary JSON value. + * + * You should usually call [Builder.payoffDetails] with a well-typed [PayoffDetails] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun payoffDetails(payoffDetails: JsonField) = apply { + this.payoffDetails = payoffDetails + } + fun additionalProperties(additionalProperties: Map) = apply { this.additionalProperties.clear() putAllAdditionalProperties(additionalProperties) @@ -943,6 +986,7 @@ private constructor( interestDetails, nextPaymentDueDate, nextStatementEndDate, + payoffDetails, additionalProperties.toMutableMap(), ) } @@ -975,6 +1019,7 @@ private constructor( interestDetails().ifPresent { it.validate() } nextPaymentDueDate() nextStatementEndDate() + payoffDetails().ifPresent { it.validate() } validated = true } @@ -1013,7 +1058,8 @@ private constructor( (ytdTotals.asKnown().getOrNull()?.validity() ?: 0) + (interestDetails.asKnown().getOrNull()?.validity() ?: 0) + (if (nextPaymentDueDate.asKnown().isPresent) 1 else 0) + - (if (nextStatementEndDate.asKnown().isPresent) 1 else 0) + (if (nextStatementEndDate.asKnown().isPresent) 1 else 0) + + (payoffDetails.asKnown().getOrNull()?.validity() ?: 0) class AccountStanding @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -3127,6 +3173,395 @@ private constructor( "InterestDetails{actualInterestCharged=$actualInterestCharged, dailyBalanceAmounts=$dailyBalanceAmounts, effectiveApr=$effectiveApr, interestCalculationMethod=$interestCalculationMethod, interestForPeriod=$interestForPeriod, primeRate=$primeRate, minimumInterestCharged=$minimumInterestCharged, additionalProperties=$additionalProperties}" } + /** Details on number and size of payments to pay off balance */ + class PayoffDetails + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val minimumPaymentMonths: JsonField, + private val minimumPaymentTotal: JsonField, + private val payoffPeriodLengthMonths: JsonField, + private val payoffPeriodMonthlyPaymentAmount: JsonField, + private val payoffPeriodPaymentTotal: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("minimum_payment_months") + @ExcludeMissing + minimumPaymentMonths: JsonField = JsonMissing.of(), + @JsonProperty("minimum_payment_total") + @ExcludeMissing + minimumPaymentTotal: JsonField = JsonMissing.of(), + @JsonProperty("payoff_period_length_months") + @ExcludeMissing + payoffPeriodLengthMonths: JsonField = JsonMissing.of(), + @JsonProperty("payoff_period_monthly_payment_amount") + @ExcludeMissing + payoffPeriodMonthlyPaymentAmount: JsonField = JsonMissing.of(), + @JsonProperty("payoff_period_payment_total") + @ExcludeMissing + payoffPeriodPaymentTotal: JsonField = JsonMissing.of(), + ) : this( + minimumPaymentMonths, + minimumPaymentTotal, + payoffPeriodLengthMonths, + payoffPeriodMonthlyPaymentAmount, + payoffPeriodPaymentTotal, + mutableMapOf(), + ) + + /** + * The number of months it would take to pay off the balance in full by only paying the + * minimum payment. "NA" will signal negative or zero amortization + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun minimumPaymentMonths(): String = + minimumPaymentMonths.getRequired("minimum_payment_months") + + /** + * The sum of all interest and principal paid, in cents, when only paying minimum monthly + * payment. "NA" will signal negative or zero amortization + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun minimumPaymentTotal(): String = minimumPaymentTotal.getRequired("minimum_payment_total") + + /** + * Number of months to full pay off + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun payoffPeriodLengthMonths(): Long = + payoffPeriodLengthMonths.getRequired("payoff_period_length_months") + + /** + * The amount needed to be paid, in cents, each month in order to pay off current balance in + * the payoff period + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun payoffPeriodMonthlyPaymentAmount(): Long = + payoffPeriodMonthlyPaymentAmount.getRequired("payoff_period_monthly_payment_amount") + + /** + * The sum of all interest and principal paid, in cents, when paying off in the payoff + * period + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun payoffPeriodPaymentTotal(): Long = + payoffPeriodPaymentTotal.getRequired("payoff_period_payment_total") + + /** + * Returns the raw JSON value of [minimumPaymentMonths]. + * + * Unlike [minimumPaymentMonths], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("minimum_payment_months") + @ExcludeMissing + fun _minimumPaymentMonths(): JsonField = minimumPaymentMonths + + /** + * Returns the raw JSON value of [minimumPaymentTotal]. + * + * Unlike [minimumPaymentTotal], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("minimum_payment_total") + @ExcludeMissing + fun _minimumPaymentTotal(): JsonField = minimumPaymentTotal + + /** + * Returns the raw JSON value of [payoffPeriodLengthMonths]. + * + * Unlike [payoffPeriodLengthMonths], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("payoff_period_length_months") + @ExcludeMissing + fun _payoffPeriodLengthMonths(): JsonField = payoffPeriodLengthMonths + + /** + * Returns the raw JSON value of [payoffPeriodMonthlyPaymentAmount]. + * + * Unlike [payoffPeriodMonthlyPaymentAmount], this method doesn't throw if the JSON field + * has an unexpected type. + */ + @JsonProperty("payoff_period_monthly_payment_amount") + @ExcludeMissing + fun _payoffPeriodMonthlyPaymentAmount(): JsonField = payoffPeriodMonthlyPaymentAmount + + /** + * Returns the raw JSON value of [payoffPeriodPaymentTotal]. + * + * Unlike [payoffPeriodPaymentTotal], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("payoff_period_payment_total") + @ExcludeMissing + fun _payoffPeriodPaymentTotal(): JsonField = payoffPeriodPaymentTotal + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [PayoffDetails]. + * + * The following fields are required: + * ```java + * .minimumPaymentMonths() + * .minimumPaymentTotal() + * .payoffPeriodLengthMonths() + * .payoffPeriodMonthlyPaymentAmount() + * .payoffPeriodPaymentTotal() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [PayoffDetails]. */ + class Builder internal constructor() { + + private var minimumPaymentMonths: JsonField? = null + private var minimumPaymentTotal: JsonField? = null + private var payoffPeriodLengthMonths: JsonField? = null + private var payoffPeriodMonthlyPaymentAmount: JsonField? = null + private var payoffPeriodPaymentTotal: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(payoffDetails: PayoffDetails) = apply { + minimumPaymentMonths = payoffDetails.minimumPaymentMonths + minimumPaymentTotal = payoffDetails.minimumPaymentTotal + payoffPeriodLengthMonths = payoffDetails.payoffPeriodLengthMonths + payoffPeriodMonthlyPaymentAmount = payoffDetails.payoffPeriodMonthlyPaymentAmount + payoffPeriodPaymentTotal = payoffDetails.payoffPeriodPaymentTotal + additionalProperties = payoffDetails.additionalProperties.toMutableMap() + } + + /** + * The number of months it would take to pay off the balance in full by only paying the + * minimum payment. "NA" will signal negative or zero amortization + */ + fun minimumPaymentMonths(minimumPaymentMonths: String) = + minimumPaymentMonths(JsonField.of(minimumPaymentMonths)) + + /** + * Sets [Builder.minimumPaymentMonths] to an arbitrary JSON value. + * + * You should usually call [Builder.minimumPaymentMonths] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun minimumPaymentMonths(minimumPaymentMonths: JsonField) = apply { + this.minimumPaymentMonths = minimumPaymentMonths + } + + /** + * The sum of all interest and principal paid, in cents, when only paying minimum + * monthly payment. "NA" will signal negative or zero amortization + */ + fun minimumPaymentTotal(minimumPaymentTotal: String) = + minimumPaymentTotal(JsonField.of(minimumPaymentTotal)) + + /** + * Sets [Builder.minimumPaymentTotal] to an arbitrary JSON value. + * + * You should usually call [Builder.minimumPaymentTotal] with a well-typed [String] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun minimumPaymentTotal(minimumPaymentTotal: JsonField) = apply { + this.minimumPaymentTotal = minimumPaymentTotal + } + + /** Number of months to full pay off */ + fun payoffPeriodLengthMonths(payoffPeriodLengthMonths: Long) = + payoffPeriodLengthMonths(JsonField.of(payoffPeriodLengthMonths)) + + /** + * Sets [Builder.payoffPeriodLengthMonths] to an arbitrary JSON value. + * + * You should usually call [Builder.payoffPeriodLengthMonths] with a well-typed [Long] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun payoffPeriodLengthMonths(payoffPeriodLengthMonths: JsonField) = apply { + this.payoffPeriodLengthMonths = payoffPeriodLengthMonths + } + + /** + * The amount needed to be paid, in cents, each month in order to pay off current + * balance in the payoff period + */ + fun payoffPeriodMonthlyPaymentAmount(payoffPeriodMonthlyPaymentAmount: Long) = + payoffPeriodMonthlyPaymentAmount(JsonField.of(payoffPeriodMonthlyPaymentAmount)) + + /** + * Sets [Builder.payoffPeriodMonthlyPaymentAmount] to an arbitrary JSON value. + * + * You should usually call [Builder.payoffPeriodMonthlyPaymentAmount] with a well-typed + * [Long] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun payoffPeriodMonthlyPaymentAmount( + payoffPeriodMonthlyPaymentAmount: JsonField + ) = apply { this.payoffPeriodMonthlyPaymentAmount = payoffPeriodMonthlyPaymentAmount } + + /** + * The sum of all interest and principal paid, in cents, when paying off in the payoff + * period + */ + fun payoffPeriodPaymentTotal(payoffPeriodPaymentTotal: Long) = + payoffPeriodPaymentTotal(JsonField.of(payoffPeriodPaymentTotal)) + + /** + * Sets [Builder.payoffPeriodPaymentTotal] to an arbitrary JSON value. + * + * You should usually call [Builder.payoffPeriodPaymentTotal] with a well-typed [Long] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun payoffPeriodPaymentTotal(payoffPeriodPaymentTotal: JsonField) = apply { + this.payoffPeriodPaymentTotal = payoffPeriodPaymentTotal + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [PayoffDetails]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .minimumPaymentMonths() + * .minimumPaymentTotal() + * .payoffPeriodLengthMonths() + * .payoffPeriodMonthlyPaymentAmount() + * .payoffPeriodPaymentTotal() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): PayoffDetails = + PayoffDetails( + checkRequired("minimumPaymentMonths", minimumPaymentMonths), + checkRequired("minimumPaymentTotal", minimumPaymentTotal), + checkRequired("payoffPeriodLengthMonths", payoffPeriodLengthMonths), + checkRequired( + "payoffPeriodMonthlyPaymentAmount", + payoffPeriodMonthlyPaymentAmount, + ), + checkRequired("payoffPeriodPaymentTotal", payoffPeriodPaymentTotal), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): PayoffDetails = apply { + if (validated) { + return@apply + } + + minimumPaymentMonths() + minimumPaymentTotal() + payoffPeriodLengthMonths() + payoffPeriodMonthlyPaymentAmount() + payoffPeriodPaymentTotal() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (minimumPaymentMonths.asKnown().isPresent) 1 else 0) + + (if (minimumPaymentTotal.asKnown().isPresent) 1 else 0) + + (if (payoffPeriodLengthMonths.asKnown().isPresent) 1 else 0) + + (if (payoffPeriodMonthlyPaymentAmount.asKnown().isPresent) 1 else 0) + + (if (payoffPeriodPaymentTotal.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is PayoffDetails && + minimumPaymentMonths == other.minimumPaymentMonths && + minimumPaymentTotal == other.minimumPaymentTotal && + payoffPeriodLengthMonths == other.payoffPeriodLengthMonths && + payoffPeriodMonthlyPaymentAmount == other.payoffPeriodMonthlyPaymentAmount && + payoffPeriodPaymentTotal == other.payoffPeriodPaymentTotal && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + minimumPaymentMonths, + minimumPaymentTotal, + payoffPeriodLengthMonths, + payoffPeriodMonthlyPaymentAmount, + payoffPeriodPaymentTotal, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "PayoffDetails{minimumPaymentMonths=$minimumPaymentMonths, minimumPaymentTotal=$minimumPaymentTotal, payoffPeriodLengthMonths=$payoffPeriodLengthMonths, payoffPeriodMonthlyPaymentAmount=$payoffPeriodMonthlyPaymentAmount, payoffPeriodPaymentTotal=$payoffPeriodPaymentTotal, additionalProperties=$additionalProperties}" + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -3154,6 +3589,7 @@ private constructor( interestDetails == other.interestDetails && nextPaymentDueDate == other.nextPaymentDueDate && nextStatementEndDate == other.nextStatementEndDate && + payoffDetails == other.payoffDetails && additionalProperties == other.additionalProperties } @@ -3180,6 +3616,7 @@ private constructor( interestDetails, nextPaymentDueDate, nextStatementEndDate, + payoffDetails, additionalProperties, ) } @@ -3187,5 +3624,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Statement{token=$token, accountStanding=$accountStanding, amountDue=$amountDue, availableCredit=$availableCredit, created=$created, creditLimit=$creditLimit, creditProductToken=$creditProductToken, daysInBillingCycle=$daysInBillingCycle, endingBalance=$endingBalance, financialAccountToken=$financialAccountToken, paymentDueDate=$paymentDueDate, periodTotals=$periodTotals, startingBalance=$startingBalance, statementEndDate=$statementEndDate, statementStartDate=$statementStartDate, statementType=$statementType, updated=$updated, ytdTotals=$ytdTotals, interestDetails=$interestDetails, nextPaymentDueDate=$nextPaymentDueDate, nextStatementEndDate=$nextStatementEndDate, additionalProperties=$additionalProperties}" + "Statement{token=$token, accountStanding=$accountStanding, amountDue=$amountDue, availableCredit=$availableCredit, created=$created, creditLimit=$creditLimit, creditProductToken=$creditProductToken, daysInBillingCycle=$daysInBillingCycle, endingBalance=$endingBalance, financialAccountToken=$financialAccountToken, paymentDueDate=$paymentDueDate, periodTotals=$periodTotals, startingBalance=$startingBalance, statementEndDate=$statementEndDate, statementStartDate=$statementStartDate, statementType=$statementType, updated=$updated, ytdTotals=$ytdTotals, interestDetails=$interestDetails, nextPaymentDueDate=$nextPaymentDueDate, nextStatementEndDate=$nextStatementEndDate, payoffDetails=$payoffDetails, additionalProperties=$additionalProperties}" } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsync.kt index 8ec1ec651..2e0dd10da 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsync.kt @@ -14,7 +14,6 @@ import com.lithic.api.models.PaymentRetrieveParams import com.lithic.api.models.PaymentRetryParams import com.lithic.api.models.PaymentRetryResponse import com.lithic.api.models.PaymentReturnParams -import com.lithic.api.models.PaymentReturnResponse import com.lithic.api.models.PaymentSimulateActionParams import com.lithic.api.models.PaymentSimulateActionResponse import com.lithic.api.models.PaymentSimulateReceiptParams @@ -150,10 +149,7 @@ interface PaymentServiceAsync { * * By default this endpoint is not enabled for your account. Please contact your * implementations manager to enable this feature. */ - fun return_( - paymentToken: String, - params: PaymentReturnParams, - ): CompletableFuture = + fun return_(paymentToken: String, params: PaymentReturnParams): CompletableFuture = return_(paymentToken, params, RequestOptions.none()) /** @see return_ */ @@ -161,18 +157,18 @@ interface PaymentServiceAsync { paymentToken: String, params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture = + ): CompletableFuture = return_(params.toBuilder().paymentToken(paymentToken).build(), requestOptions) /** @see return_ */ - fun return_(params: PaymentReturnParams): CompletableFuture = + fun return_(params: PaymentReturnParams): CompletableFuture = return_(params, RequestOptions.none()) /** @see return_ */ fun return_( params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture + ): CompletableFuture /** Simulate payment lifecycle event */ fun simulateAction( @@ -378,7 +374,7 @@ interface PaymentServiceAsync { fun return_( paymentToken: String, params: PaymentReturnParams, - ): CompletableFuture> = + ): CompletableFuture> = return_(paymentToken, params, RequestOptions.none()) /** @see return_ */ @@ -386,20 +382,18 @@ interface PaymentServiceAsync { paymentToken: String, params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> = + ): CompletableFuture> = return_(params.toBuilder().paymentToken(paymentToken).build(), requestOptions) /** @see return_ */ - fun return_( - params: PaymentReturnParams - ): CompletableFuture> = + fun return_(params: PaymentReturnParams): CompletableFuture> = return_(params, RequestOptions.none()) /** @see return_ */ fun return_( params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> + ): CompletableFuture> /** * Returns a raw HTTP response for `post /v1/simulate/payments/{payment_token}/action`, but diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsyncImpl.kt index 2806dbab2..5ccec83c1 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/PaymentServiceAsyncImpl.kt @@ -26,7 +26,6 @@ import com.lithic.api.models.PaymentRetrieveParams import com.lithic.api.models.PaymentRetryParams import com.lithic.api.models.PaymentRetryResponse import com.lithic.api.models.PaymentReturnParams -import com.lithic.api.models.PaymentReturnResponse import com.lithic.api.models.PaymentSimulateActionParams import com.lithic.api.models.PaymentSimulateActionResponse import com.lithic.api.models.PaymentSimulateReceiptParams @@ -82,7 +81,7 @@ class PaymentServiceAsyncImpl internal constructor(private val clientOptions: Cl override fun return_( params: PaymentReturnParams, requestOptions: RequestOptions, - ): CompletableFuture = + ): CompletableFuture = // post /v1/payments/{payment_token}/return withRawResponse().return_(params, requestOptions).thenApply { it.parse() } @@ -263,13 +262,12 @@ class PaymentServiceAsyncImpl internal constructor(private val clientOptions: Cl } } - private val returnHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val returnHandler: Handler = jsonHandler(clientOptions.jsonMapper) override fun return_( params: PaymentReturnParams, requestOptions: RequestOptions, - ): CompletableFuture> { + ): CompletableFuture> { // We check here instead of in the params builder because this can be specified // positionally or in the params class. checkRequired("paymentToken", params.paymentToken().getOrNull()) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentService.kt index a6660e8f4..f9120c5e5 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentService.kt @@ -15,7 +15,6 @@ import com.lithic.api.models.PaymentRetrieveParams import com.lithic.api.models.PaymentRetryParams import com.lithic.api.models.PaymentRetryResponse import com.lithic.api.models.PaymentReturnParams -import com.lithic.api.models.PaymentReturnResponse import com.lithic.api.models.PaymentSimulateActionParams import com.lithic.api.models.PaymentSimulateActionResponse import com.lithic.api.models.PaymentSimulateReceiptParams @@ -144,7 +143,7 @@ interface PaymentService { * * By default this endpoint is not enabled for your account. Please contact your * implementations manager to enable this feature. */ - fun return_(paymentToken: String, params: PaymentReturnParams): PaymentReturnResponse = + fun return_(paymentToken: String, params: PaymentReturnParams): Payment = return_(paymentToken, params, RequestOptions.none()) /** @see return_ */ @@ -152,18 +151,16 @@ interface PaymentService { paymentToken: String, params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): PaymentReturnResponse = - return_(params.toBuilder().paymentToken(paymentToken).build(), requestOptions) + ): Payment = return_(params.toBuilder().paymentToken(paymentToken).build(), requestOptions) /** @see return_ */ - fun return_(params: PaymentReturnParams): PaymentReturnResponse = - return_(params, RequestOptions.none()) + fun return_(params: PaymentReturnParams): Payment = return_(params, RequestOptions.none()) /** @see return_ */ fun return_( params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): PaymentReturnResponse + ): Payment /** Simulate payment lifecycle event */ fun simulateAction( @@ -362,10 +359,7 @@ interface PaymentService { * otherwise the same as [PaymentService.return_]. */ @MustBeClosed - fun return_( - paymentToken: String, - params: PaymentReturnParams, - ): HttpResponseFor = + fun return_(paymentToken: String, params: PaymentReturnParams): HttpResponseFor = return_(paymentToken, params, RequestOptions.none()) /** @see return_ */ @@ -374,12 +368,12 @@ interface PaymentService { paymentToken: String, params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor = + ): HttpResponseFor = return_(params.toBuilder().paymentToken(paymentToken).build(), requestOptions) /** @see return_ */ @MustBeClosed - fun return_(params: PaymentReturnParams): HttpResponseFor = + fun return_(params: PaymentReturnParams): HttpResponseFor = return_(params, RequestOptions.none()) /** @see return_ */ @@ -387,7 +381,7 @@ interface PaymentService { fun return_( params: PaymentReturnParams, requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor + ): HttpResponseFor /** * Returns a raw HTTP response for `post /v1/simulate/payments/{payment_token}/action`, but diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentServiceImpl.kt index e204ed271..7ab67081a 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/PaymentServiceImpl.kt @@ -26,7 +26,6 @@ import com.lithic.api.models.PaymentRetrieveParams import com.lithic.api.models.PaymentRetryParams import com.lithic.api.models.PaymentRetryResponse import com.lithic.api.models.PaymentReturnParams -import com.lithic.api.models.PaymentReturnResponse import com.lithic.api.models.PaymentSimulateActionParams import com.lithic.api.models.PaymentSimulateActionResponse import com.lithic.api.models.PaymentSimulateReceiptParams @@ -72,10 +71,7 @@ class PaymentServiceImpl internal constructor(private val clientOptions: ClientO // post /v1/payments/{payment_token}/retry withRawResponse().retry(params, requestOptions).parse() - override fun return_( - params: PaymentReturnParams, - requestOptions: RequestOptions, - ): PaymentReturnResponse = + override fun return_(params: PaymentReturnParams, requestOptions: RequestOptions): Payment = // post /v1/payments/{payment_token}/return withRawResponse().return_(params, requestOptions).parse() @@ -243,13 +239,12 @@ class PaymentServiceImpl internal constructor(private val clientOptions: ClientO } } - private val returnHandler: Handler = - jsonHandler(clientOptions.jsonMapper) + private val returnHandler: Handler = jsonHandler(clientOptions.jsonMapper) override fun return_( params: PaymentReturnParams, requestOptions: RequestOptions, - ): HttpResponseFor { + ): HttpResponseFor { // We check here instead of in the params builder because this can be specified // positionally or in the params class. checkRequired("paymentToken", params.paymentToken().getOrNull()) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/core/ObjectMappersTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/core/ObjectMappersTest.kt index d32233935..3977f5171 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/core/ObjectMappersTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/core/ObjectMappersTest.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.databind.exc.MismatchedInputException import com.fasterxml.jackson.module.kotlin.readValue import java.time.LocalDateTime +import java.time.OffsetDateTime import kotlin.reflect.KClass import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable @@ -99,4 +100,19 @@ internal class ObjectMappersTest { assertDoesNotThrow { jsonMapper().readValue(json) } } + + enum class LenientOffsetDateTimeTestCase(val string: String) { + DATE_TIME("1998-04-21T04:00:00"), + ZONED_DATE_TIME_1("1998-04-21T04:00:00+03:00"), + ZONED_DATE_TIME_2("1998-04-21T04:00:00Z"), + } + + @ParameterizedTest + @EnumSource + fun readOffsetDateTime_lenient(testCase: LenientOffsetDateTimeTestCase) { + val jsonMapper = jsonMapper() + val json = jsonMapper.writeValueAsString(testCase.string) + + assertDoesNotThrow { jsonMapper().readValue(json) } + } } diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/PaymentReturnResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/PaymentReturnResponseTest.kt deleted file mode 100644 index 83227c16c..000000000 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/PaymentReturnResponseTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. - -package com.lithic.api.models - -import com.fasterxml.jackson.module.kotlin.jacksonTypeRef -import com.lithic.api.core.jsonMapper -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -internal class PaymentReturnResponseTest { - - @Test - fun create() { - val paymentReturnResponse = - PaymentReturnResponse.builder() - .result(PaymentReturnResponse.TransactionResult.APPROVED) - .transactionGroupUuid("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .transactionUuid("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - - assertThat(paymentReturnResponse.result()) - .isEqualTo(PaymentReturnResponse.TransactionResult.APPROVED) - assertThat(paymentReturnResponse.transactionGroupUuid()) - .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(paymentReturnResponse.transactionUuid()) - .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - } - - @Test - fun roundtrip() { - val jsonMapper = jsonMapper() - val paymentReturnResponse = - PaymentReturnResponse.builder() - .result(PaymentReturnResponse.TransactionResult.APPROVED) - .transactionGroupUuid("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .transactionUuid("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .build() - - val roundtrippedPaymentReturnResponse = - jsonMapper.readValue( - jsonMapper.writeValueAsString(paymentReturnResponse), - jacksonTypeRef(), - ) - - assertThat(roundtrippedPaymentReturnResponse).isEqualTo(paymentReturnResponse) - } -} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementTest.kt index ee3f699f1..550c9a4f8 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementTest.kt @@ -119,6 +119,15 @@ internal class StatementTest { ) .nextPaymentDueDate(LocalDate.parse("2019-12-27")) .nextStatementEndDate(LocalDate.parse("2019-12-27")) + .payoffDetails( + Statement.PayoffDetails.builder() + .minimumPaymentMonths("minimum_payment_months") + .minimumPaymentTotal("minimum_payment_total") + .payoffPeriodLengthMonths(0L) + .payoffPeriodMonthlyPaymentAmount(0L) + .payoffPeriodPaymentTotal(0L) + .build() + ) .build() assertThat(statement.token()).isEqualTo("token") @@ -230,6 +239,16 @@ internal class StatementTest { ) assertThat(statement.nextPaymentDueDate()).contains(LocalDate.parse("2019-12-27")) assertThat(statement.nextStatementEndDate()).contains(LocalDate.parse("2019-12-27")) + assertThat(statement.payoffDetails()) + .contains( + Statement.PayoffDetails.builder() + .minimumPaymentMonths("minimum_payment_months") + .minimumPaymentTotal("minimum_payment_total") + .payoffPeriodLengthMonths(0L) + .payoffPeriodMonthlyPaymentAmount(0L) + .payoffPeriodPaymentTotal(0L) + .build() + ) } @Test @@ -340,6 +359,15 @@ internal class StatementTest { ) .nextPaymentDueDate(LocalDate.parse("2019-12-27")) .nextStatementEndDate(LocalDate.parse("2019-12-27")) + .payoffDetails( + Statement.PayoffDetails.builder() + .minimumPaymentMonths("minimum_payment_months") + .minimumPaymentTotal("minimum_payment_total") + .payoffPeriodLengthMonths(0L) + .payoffPeriodMonthlyPaymentAmount(0L) + .payoffPeriodPaymentTotal(0L) + .build() + ) .build() val roundtrippedStatement = diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementsTest.kt index 04c2aff8b..9acf115b1 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementsTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/StatementsTest.kt @@ -121,6 +121,15 @@ internal class StatementsTest { ) .nextPaymentDueDate(LocalDate.parse("2019-12-27")) .nextStatementEndDate(LocalDate.parse("2019-12-27")) + .payoffDetails( + Statement.PayoffDetails.builder() + .minimumPaymentMonths("minimum_payment_months") + .minimumPaymentTotal("minimum_payment_total") + .payoffPeriodLengthMonths(0L) + .payoffPeriodMonthlyPaymentAmount(0L) + .payoffPeriodPaymentTotal(0L) + .build() + ) .build() ) .hasMore(true) @@ -232,6 +241,15 @@ internal class StatementsTest { ) .nextPaymentDueDate(LocalDate.parse("2019-12-27")) .nextStatementEndDate(LocalDate.parse("2019-12-27")) + .payoffDetails( + Statement.PayoffDetails.builder() + .minimumPaymentMonths("minimum_payment_months") + .minimumPaymentTotal("minimum_payment_total") + .payoffPeriodLengthMonths(0L) + .payoffPeriodMonthlyPaymentAmount(0L) + .payoffPeriodPaymentTotal(0L) + .build() + ) .build() ) assertThat(statements.hasMore()).isEqualTo(true) @@ -347,6 +365,15 @@ internal class StatementsTest { ) .nextPaymentDueDate(LocalDate.parse("2019-12-27")) .nextStatementEndDate(LocalDate.parse("2019-12-27")) + .payoffDetails( + Statement.PayoffDetails.builder() + .minimumPaymentMonths("minimum_payment_months") + .minimumPaymentTotal("minimum_payment_total") + .payoffPeriodLengthMonths(0L) + .payoffPeriodMonthlyPaymentAmount(0L) + .payoffPeriodPaymentTotal(0L) + .build() + ) .build() ) .hasMore(true) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/PaymentServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/PaymentServiceAsyncTest.kt index 7088c1c80..5660d0af9 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/PaymentServiceAsyncTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/PaymentServiceAsyncTest.kt @@ -104,7 +104,7 @@ internal class PaymentServiceAsyncTest { .build() val paymentServiceAsync = client.payments() - val responseFuture = + val paymentFuture = paymentServiceAsync.return_( PaymentReturnParams.builder() .paymentToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -116,8 +116,8 @@ internal class PaymentServiceAsyncTest { .build() ) - val response = responseFuture.get() - response.validate() + val payment = paymentFuture.get() + payment.validate() } @Test diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/PaymentServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/PaymentServiceTest.kt index e6b421c11..ed661980e 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/PaymentServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/PaymentServiceTest.kt @@ -100,7 +100,7 @@ internal class PaymentServiceTest { .build() val paymentService = client.payments() - val response = + val payment = paymentService.return_( PaymentReturnParams.builder() .paymentToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -112,7 +112,7 @@ internal class PaymentServiceTest { .build() ) - response.validate() + payment.validate() } @Test