From 797426125cd8ed15d394418b856841cb18f63232 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 00:40:03 +0000 Subject: [PATCH 1/2] feat(api): api update --- .stats.yml | 8 +- .../cards/CardCreateDetailsIframeParams.kt | 427 ++++++++++++++++++ .../api/models/cards/CardDetailsParams.kt | 5 +- .../api/models/cards/CardIframeUrl.kt | 387 ++++++++++++++++ .../api/services/async/CardServiceAsync.kt | 87 +++- .../services/async/CardServiceAsyncImpl.kt | 43 ++ .../api/services/blocking/CardService.kt | 88 +++- .../api/services/blocking/CardServiceImpl.kt | 40 ++ .../CardCreateDetailsIframeParamsTest.kt | 48 ++ .../api/models/cards/CardIframeUrlTest.kt | 47 ++ .../services/async/CardServiceAsyncTest.kt | 22 + .../api/services/blocking/CardServiceTest.kt | 21 + 12 files changed, 1216 insertions(+), 7 deletions(-) create mode 100644 increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParams.kt create mode 100644 increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardIframeUrl.kt create mode 100644 increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParamsTest.kt create mode 100644 increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardIframeUrlTest.kt diff --git a/.stats.yml b/.stats.yml index ebd672bf3..564ef9424 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 214 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-e37d9eb06122e71071da98a7375420ce776ad9aa05176bed89a232bd6854f26b.yml -openapi_spec_hash: 8ffb1a0fd8523b24113105717c5d85d8 -config_hash: b0b366d8c705ea0efe62093bae953e5a +configured_endpoints: 215 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-9a5905fe541badfa11ad0641e7aea625c9fb0bc59ba33b1d43d8e88cbbdd71b2.yml +openapi_spec_hash: 4347de40c3142cd56c2185aac9a6739e +config_hash: 0b0a2503208283b283fc5bc6df6a07a5 diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParams.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParams.kt new file mode 100644 index 000000000..b2d0040f1 --- /dev/null +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParams.kt @@ -0,0 +1,427 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.increase.api.models.cards + +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.increase.api.core.ExcludeMissing +import com.increase.api.core.JsonField +import com.increase.api.core.JsonMissing +import com.increase.api.core.JsonValue +import com.increase.api.core.Params +import com.increase.api.core.http.Headers +import com.increase.api.core.http.QueryParams +import com.increase.api.errors.IncreaseInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Create an iframe URL for a Card to display the card details. More details about styling and usage + * can be found in the [documentation](/documentation/embedded-card-component). + */ +class CardCreateDetailsIframeParams +private constructor( + private val cardId: String?, + private val body: Body, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** The identifier of the Card to retrieve details for. */ + fun cardId(): Optional = Optional.ofNullable(cardId) + + /** + * The identifier of the Physical Card to retrieve details for. + * + * @throws IncreaseInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun physicalCardId(): Optional = body.physicalCardId() + + /** + * Returns the raw JSON value of [physicalCardId]. + * + * Unlike [physicalCardId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _physicalCardId(): JsonField = body._physicalCardId() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): CardCreateDetailsIframeParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of + * [CardCreateDetailsIframeParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CardCreateDetailsIframeParams]. */ + class Builder internal constructor() { + + private var cardId: String? = null + private var body: Body.Builder = Body.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(cardCreateDetailsIframeParams: CardCreateDetailsIframeParams) = apply { + cardId = cardCreateDetailsIframeParams.cardId + body = cardCreateDetailsIframeParams.body.toBuilder() + additionalHeaders = cardCreateDetailsIframeParams.additionalHeaders.toBuilder() + additionalQueryParams = cardCreateDetailsIframeParams.additionalQueryParams.toBuilder() + } + + /** The identifier of the Card to retrieve details for. */ + fun cardId(cardId: String?) = apply { this.cardId = cardId } + + /** Alias for calling [Builder.cardId] with `cardId.orElse(null)`. */ + fun cardId(cardId: Optional) = cardId(cardId.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [physicalCardId] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** The identifier of the Physical Card to retrieve details for. */ + fun physicalCardId(physicalCardId: String) = apply { body.physicalCardId(physicalCardId) } + + /** + * Sets [Builder.physicalCardId] to an arbitrary JSON value. + * + * You should usually call [Builder.physicalCardId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun physicalCardId(physicalCardId: JsonField) = apply { + body.physicalCardId(physicalCardId) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [CardCreateDetailsIframeParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CardCreateDetailsIframeParams = + CardCreateDetailsIframeParams( + cardId, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): Body = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> cardId ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + class Body + private constructor( + private val physicalCardId: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("physical_card_id") + @ExcludeMissing + physicalCardId: JsonField = JsonMissing.of() + ) : this(physicalCardId, mutableMapOf()) + + /** + * The identifier of the Physical Card to retrieve details for. + * + * @throws IncreaseInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun physicalCardId(): Optional = physicalCardId.getOptional("physical_card_id") + + /** + * Returns the raw JSON value of [physicalCardId]. + * + * Unlike [physicalCardId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("physical_card_id") + @ExcludeMissing + fun _physicalCardId(): JsonField = physicalCardId + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var physicalCardId: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + physicalCardId = body.physicalCardId + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** The identifier of the Physical Card to retrieve details for. */ + fun physicalCardId(physicalCardId: String) = + physicalCardId(JsonField.of(physicalCardId)) + + /** + * Sets [Builder.physicalCardId] to an arbitrary JSON value. + * + * You should usually call [Builder.physicalCardId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun physicalCardId(physicalCardId: JsonField) = apply { + this.physicalCardId = physicalCardId + } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(physicalCardId, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + physicalCardId() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: IncreaseInvalidDataException) { + 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 (physicalCardId.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + physicalCardId == other.physicalCardId && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(physicalCardId, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{physicalCardId=$physicalCardId, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CardCreateDetailsIframeParams && + cardId == other.cardId && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(cardId, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "CardCreateDetailsIframeParams{cardId=$cardId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardDetailsParams.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardDetailsParams.kt index ae066aaef..d4c911a4e 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardDetailsParams.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardDetailsParams.kt @@ -9,7 +9,10 @@ import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull -/** Retrieve sensitive details for a Card */ +/** + * Sensitive details for a Card include the primary account number, expiry, card verification code, + * and PIN. + */ class CardDetailsParams private constructor( private val cardId: String?, diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardIframeUrl.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardIframeUrl.kt new file mode 100644 index 000000000..86cb1b129 --- /dev/null +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/cards/CardIframeUrl.kt @@ -0,0 +1,387 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.increase.api.models.cards + +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.increase.api.core.Enum +import com.increase.api.core.ExcludeMissing +import com.increase.api.core.JsonField +import com.increase.api.core.JsonMissing +import com.increase.api.core.JsonValue +import com.increase.api.core.checkRequired +import com.increase.api.errors.IncreaseInvalidDataException +import java.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** An object containing the iframe URL for a Card. */ +class CardIframeUrl +private constructor( + private val expiresAt: JsonField, + private val iframeUrl: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("expires_at") + @ExcludeMissing + expiresAt: JsonField = JsonMissing.of(), + @JsonProperty("iframe_url") @ExcludeMissing iframeUrl: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(expiresAt, iframeUrl, type, mutableMapOf()) + + /** + * The time the iframe URL will expire. + * + * @throws IncreaseInvalidDataException 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 expiresAt(): OffsetDateTime = expiresAt.getRequired("expires_at") + + /** + * The iframe URL for the Card. Treat this as an opaque URL. + * + * @throws IncreaseInvalidDataException 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 iframeUrl(): String = iframeUrl.getRequired("iframe_url") + + /** + * A constant representing the object's type. For this resource it will always be + * `card_iframe_url`. + * + * @throws IncreaseInvalidDataException 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 type(): Type = type.getRequired("type") + + /** + * Returns the raw JSON value of [expiresAt]. + * + * Unlike [expiresAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("expires_at") + @ExcludeMissing + fun _expiresAt(): JsonField = expiresAt + + /** + * Returns the raw JSON value of [iframeUrl]. + * + * Unlike [iframeUrl], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("iframe_url") @ExcludeMissing fun _iframeUrl(): JsonField = iframeUrl + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @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 [CardIframeUrl]. + * + * The following fields are required: + * ```java + * .expiresAt() + * .iframeUrl() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CardIframeUrl]. */ + class Builder internal constructor() { + + private var expiresAt: JsonField? = null + private var iframeUrl: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(cardIframeUrl: CardIframeUrl) = apply { + expiresAt = cardIframeUrl.expiresAt + iframeUrl = cardIframeUrl.iframeUrl + type = cardIframeUrl.type + additionalProperties = cardIframeUrl.additionalProperties.toMutableMap() + } + + /** The time the iframe URL will expire. */ + fun expiresAt(expiresAt: OffsetDateTime) = expiresAt(JsonField.of(expiresAt)) + + /** + * Sets [Builder.expiresAt] to an arbitrary JSON value. + * + * You should usually call [Builder.expiresAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun expiresAt(expiresAt: JsonField) = apply { this.expiresAt = expiresAt } + + /** The iframe URL for the Card. Treat this as an opaque URL. */ + fun iframeUrl(iframeUrl: String) = iframeUrl(JsonField.of(iframeUrl)) + + /** + * Sets [Builder.iframeUrl] to an arbitrary JSON value. + * + * You should usually call [Builder.iframeUrl] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun iframeUrl(iframeUrl: JsonField) = apply { this.iframeUrl = iframeUrl } + + /** + * A constant representing the object's type. For this resource it will always be + * `card_iframe_url`. + */ + fun type(type: Type) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [Type] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + 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 [CardIframeUrl]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .expiresAt() + * .iframeUrl() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CardIframeUrl = + CardIframeUrl( + checkRequired("expiresAt", expiresAt), + checkRequired("iframeUrl", iframeUrl), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CardIframeUrl = apply { + if (validated) { + return@apply + } + + expiresAt() + iframeUrl() + type().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: IncreaseInvalidDataException) { + 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 (expiresAt.asKnown().isPresent) 1 else 0) + + (if (iframeUrl.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** + * A constant representing the object's type. For this resource it will always be + * `card_iframe_url`. + */ + class Type @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 CARD_IFRAME_URL = of("card_iframe_url") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + CARD_IFRAME_URL + } + + /** + * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Type] 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 { + CARD_IFRAME_URL, + /** An enum member indicating that [Type] 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) { + CARD_IFRAME_URL -> Value.CARD_IFRAME_URL + 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 IncreaseInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + CARD_IFRAME_URL -> Known.CARD_IFRAME_URL + else -> throw IncreaseInvalidDataException("Unknown Type: $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 IncreaseInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + IncreaseInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): Type = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: IncreaseInvalidDataException) { + 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 Type && 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 CardIframeUrl && + expiresAt == other.expiresAt && + iframeUrl == other.iframeUrl && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(expiresAt, iframeUrl, type, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CardIframeUrl{expiresAt=$expiresAt, iframeUrl=$iframeUrl, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsync.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsync.kt index 7c5c4677a..643698c0d 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsync.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsync.kt @@ -6,9 +6,11 @@ import com.increase.api.core.ClientOptions import com.increase.api.core.RequestOptions import com.increase.api.core.http.HttpResponseFor import com.increase.api.models.cards.Card +import com.increase.api.models.cards.CardCreateDetailsIframeParams import com.increase.api.models.cards.CardCreateParams import com.increase.api.models.cards.CardDetails import com.increase.api.models.cards.CardDetailsParams +import com.increase.api.models.cards.CardIframeUrl import com.increase.api.models.cards.CardListPageAsync import com.increase.api.models.cards.CardListParams import com.increase.api.models.cards.CardRetrieveParams @@ -118,7 +120,49 @@ interface CardServiceAsync { fun list(requestOptions: RequestOptions): CompletableFuture = list(CardListParams.none(), requestOptions) - /** Retrieve sensitive details for a Card */ + /** + * Create an iframe URL for a Card to display the card details. More details about styling and + * usage can be found in the [documentation](/documentation/embedded-card-component). + */ + fun createDetailsIframe(cardId: String): CompletableFuture = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + createDetailsIframe(params.toBuilder().cardId(cardId).build(), requestOptions) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + ): CompletableFuture = createDetailsIframe(cardId, params, RequestOptions.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see createDetailsIframe */ + fun createDetailsIframe( + params: CardCreateDetailsIframeParams + ): CompletableFuture = createDetailsIframe(params, RequestOptions.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + requestOptions: RequestOptions, + ): CompletableFuture = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none(), requestOptions) + + /** + * Sensitive details for a Card include the primary account number, expiry, card verification + * code, and PIN. + */ fun details(cardId: String): CompletableFuture = details(cardId, CardDetailsParams.none()) @@ -275,6 +319,47 @@ interface CardServiceAsync { ): CompletableFuture> = list(CardListParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `post /cards/{card_id}/create_details_iframe`, but is + * otherwise the same as [CardServiceAsync.createDetailsIframe]. + */ + fun createDetailsIframe(cardId: String): CompletableFuture> = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + createDetailsIframe(params.toBuilder().cardId(cardId).build(), requestOptions) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + ): CompletableFuture> = + createDetailsIframe(cardId, params, RequestOptions.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see createDetailsIframe */ + fun createDetailsIframe( + params: CardCreateDetailsIframeParams + ): CompletableFuture> = + createDetailsIframe(params, RequestOptions.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /cards/{card_id}/details`, but is otherwise the same * as [CardServiceAsync.details]. diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsyncImpl.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsyncImpl.kt index 2a06cf2f5..285012808 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsyncImpl.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/async/CardServiceAsyncImpl.kt @@ -17,9 +17,11 @@ import com.increase.api.core.http.json import com.increase.api.core.http.parseable import com.increase.api.core.prepareAsync import com.increase.api.models.cards.Card +import com.increase.api.models.cards.CardCreateDetailsIframeParams import com.increase.api.models.cards.CardCreateParams import com.increase.api.models.cards.CardDetails import com.increase.api.models.cards.CardDetailsParams +import com.increase.api.models.cards.CardIframeUrl import com.increase.api.models.cards.CardListPageAsync import com.increase.api.models.cards.CardListPageResponse import com.increase.api.models.cards.CardListParams @@ -69,6 +71,13 @@ class CardServiceAsyncImpl internal constructor(private val clientOptions: Clien // get /cards withRawResponse().list(params, requestOptions).thenApply { it.parse() } + override fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /cards/{card_id}/create_details_iframe + withRawResponse().createDetailsIframe(params, requestOptions).thenApply { it.parse() } + override fun details( params: CardDetailsParams, requestOptions: RequestOptions, @@ -222,6 +231,40 @@ class CardServiceAsyncImpl internal constructor(private val clientOptions: Clien } } + private val createDetailsIframeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("cardId", params.cardId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("cards", params._pathParam(0), "create_details_iframe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { createDetailsIframeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + private val detailsHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardService.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardService.kt index b777893de..301587c2d 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardService.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardService.kt @@ -7,9 +7,11 @@ import com.increase.api.core.ClientOptions import com.increase.api.core.RequestOptions import com.increase.api.core.http.HttpResponseFor import com.increase.api.models.cards.Card +import com.increase.api.models.cards.CardCreateDetailsIframeParams import com.increase.api.models.cards.CardCreateParams import com.increase.api.models.cards.CardDetails import com.increase.api.models.cards.CardDetailsParams +import com.increase.api.models.cards.CardIframeUrl import com.increase.api.models.cards.CardListPage import com.increase.api.models.cards.CardListParams import com.increase.api.models.cards.CardRetrieveParams @@ -110,7 +112,45 @@ interface CardService { fun list(requestOptions: RequestOptions): CardListPage = list(CardListParams.none(), requestOptions) - /** Retrieve sensitive details for a Card */ + /** + * Create an iframe URL for a Card to display the card details. More details about styling and + * usage can be found in the [documentation](/documentation/embedded-card-component). + */ + fun createDetailsIframe(cardId: String): CardIframeUrl = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CardIframeUrl = + createDetailsIframe(params.toBuilder().cardId(cardId).build(), requestOptions) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + ): CardIframeUrl = createDetailsIframe(cardId, params, RequestOptions.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CardIframeUrl + + /** @see createDetailsIframe */ + fun createDetailsIframe(params: CardCreateDetailsIframeParams): CardIframeUrl = + createDetailsIframe(params, RequestOptions.none()) + + /** @see createDetailsIframe */ + fun createDetailsIframe(cardId: String, requestOptions: RequestOptions): CardIframeUrl = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none(), requestOptions) + + /** + * Sensitive details for a Card include the primary account number, expiry, card verification + * code, and PIN. + */ fun details(cardId: String): CardDetails = details(cardId, CardDetailsParams.none()) /** @see details */ @@ -265,6 +305,52 @@ interface CardService { fun list(requestOptions: RequestOptions): HttpResponseFor = list(CardListParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `post /cards/{card_id}/create_details_iframe`, but is + * otherwise the same as [CardService.createDetailsIframe]. + */ + @MustBeClosed + fun createDetailsIframe(cardId: String): HttpResponseFor = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none()) + + /** @see createDetailsIframe */ + @MustBeClosed + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + createDetailsIframe(params.toBuilder().cardId(cardId).build(), requestOptions) + + /** @see createDetailsIframe */ + @MustBeClosed + fun createDetailsIframe( + cardId: String, + params: CardCreateDetailsIframeParams = CardCreateDetailsIframeParams.none(), + ): HttpResponseFor = + createDetailsIframe(cardId, params, RequestOptions.none()) + + /** @see createDetailsIframe */ + @MustBeClosed + fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see createDetailsIframe */ + @MustBeClosed + fun createDetailsIframe( + params: CardCreateDetailsIframeParams + ): HttpResponseFor = createDetailsIframe(params, RequestOptions.none()) + + /** @see createDetailsIframe */ + @MustBeClosed + fun createDetailsIframe( + cardId: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + createDetailsIframe(cardId, CardCreateDetailsIframeParams.none(), requestOptions) + /** * Returns a raw HTTP response for `get /cards/{card_id}/details`, but is otherwise the same * as [CardService.details]. diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardServiceImpl.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardServiceImpl.kt index 966685b62..7fac4e858 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardServiceImpl.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/CardServiceImpl.kt @@ -17,9 +17,11 @@ import com.increase.api.core.http.json import com.increase.api.core.http.parseable import com.increase.api.core.prepare import com.increase.api.models.cards.Card +import com.increase.api.models.cards.CardCreateDetailsIframeParams import com.increase.api.models.cards.CardCreateParams import com.increase.api.models.cards.CardDetails import com.increase.api.models.cards.CardDetailsParams +import com.increase.api.models.cards.CardIframeUrl import com.increase.api.models.cards.CardListPage import com.increase.api.models.cards.CardListPageResponse import com.increase.api.models.cards.CardListParams @@ -55,6 +57,13 @@ class CardServiceImpl internal constructor(private val clientOptions: ClientOpti // get /cards withRawResponse().list(params, requestOptions).parse() + override fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions, + ): CardIframeUrl = + // post /cards/{card_id}/create_details_iframe + withRawResponse().createDetailsIframe(params, requestOptions).parse() + override fun details(params: CardDetailsParams, requestOptions: RequestOptions): CardDetails = // get /cards/{card_id}/details withRawResponse().details(params, requestOptions).parse() @@ -192,6 +201,37 @@ class CardServiceImpl internal constructor(private val clientOptions: ClientOpti } } + private val createDetailsIframeHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun createDetailsIframe( + params: CardCreateDetailsIframeParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("cardId", params.cardId().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("cards", params._pathParam(0), "create_details_iframe") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { createDetailsIframeHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + private val detailsHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParamsTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParamsTest.kt new file mode 100644 index 000000000..f1309a233 --- /dev/null +++ b/increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardCreateDetailsIframeParamsTest.kt @@ -0,0 +1,48 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.increase.api.models.cards + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CardCreateDetailsIframeParamsTest { + + @Test + fun create() { + CardCreateDetailsIframeParams.builder() + .cardId("card_oubs0hwk5rn6knuecxg2") + .physicalCardId("physical_card_id") + .build() + } + + @Test + fun pathParams() { + val params = + CardCreateDetailsIframeParams.builder().cardId("card_oubs0hwk5rn6knuecxg2").build() + + assertThat(params._pathParam(0)).isEqualTo("card_oubs0hwk5rn6knuecxg2") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + CardCreateDetailsIframeParams.builder() + .cardId("card_oubs0hwk5rn6knuecxg2") + .physicalCardId("physical_card_id") + .build() + + val body = params._body() + + assertThat(body.physicalCardId()).contains("physical_card_id") + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + CardCreateDetailsIframeParams.builder().cardId("card_oubs0hwk5rn6knuecxg2").build() + + val body = params._body() + } +} diff --git a/increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardIframeUrlTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardIframeUrlTest.kt new file mode 100644 index 000000000..53c1a7b43 --- /dev/null +++ b/increase-java-core/src/test/kotlin/com/increase/api/models/cards/CardIframeUrlTest.kt @@ -0,0 +1,47 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.increase.api.models.cards + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.increase.api.core.jsonMapper +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CardIframeUrlTest { + + @Test + fun create() { + val cardIframeUrl = + CardIframeUrl.builder() + .expiresAt(OffsetDateTime.parse("2020-01-31T23:59:59Z")) + .iframeUrl("https://increase.com/card_details_iframe/index.html?token=0") + .type(CardIframeUrl.Type.CARD_IFRAME_URL) + .build() + + assertThat(cardIframeUrl.expiresAt()) + .isEqualTo(OffsetDateTime.parse("2020-01-31T23:59:59Z")) + assertThat(cardIframeUrl.iframeUrl()) + .isEqualTo("https://increase.com/card_details_iframe/index.html?token=0") + assertThat(cardIframeUrl.type()).isEqualTo(CardIframeUrl.Type.CARD_IFRAME_URL) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val cardIframeUrl = + CardIframeUrl.builder() + .expiresAt(OffsetDateTime.parse("2020-01-31T23:59:59Z")) + .iframeUrl("https://increase.com/card_details_iframe/index.html?token=0") + .type(CardIframeUrl.Type.CARD_IFRAME_URL) + .build() + + val roundtrippedCardIframeUrl = + jsonMapper.readValue( + jsonMapper.writeValueAsString(cardIframeUrl), + jacksonTypeRef(), + ) + + assertThat(roundtrippedCardIframeUrl).isEqualTo(cardIframeUrl) + } +} diff --git a/increase-java-core/src/test/kotlin/com/increase/api/services/async/CardServiceAsyncTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/services/async/CardServiceAsyncTest.kt index fd14215c9..249de5e2a 100644 --- a/increase-java-core/src/test/kotlin/com/increase/api/services/async/CardServiceAsyncTest.kt +++ b/increase-java-core/src/test/kotlin/com/increase/api/services/async/CardServiceAsyncTest.kt @@ -4,6 +4,7 @@ package com.increase.api.services.async import com.increase.api.TestServerExtension import com.increase.api.client.okhttp.IncreaseOkHttpClientAsync +import com.increase.api.models.cards.CardCreateDetailsIframeParams import com.increase.api.models.cards.CardCreateParams import com.increase.api.models.cards.CardUpdateParams import org.junit.jupiter.api.Test @@ -119,6 +120,27 @@ internal class CardServiceAsyncTest { page.response().validate() } + @Test + fun createDetailsIframe() { + val client = + IncreaseOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val cardServiceAsync = client.cards() + + val cardIframeUrlFuture = + cardServiceAsync.createDetailsIframe( + CardCreateDetailsIframeParams.builder() + .cardId("card_oubs0hwk5rn6knuecxg2") + .physicalCardId("physical_card_id") + .build() + ) + + val cardIframeUrl = cardIframeUrlFuture.get() + cardIframeUrl.validate() + } + @Test fun details() { val client = diff --git a/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/CardServiceTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/CardServiceTest.kt index c5a6bd92c..c7a8ac424 100644 --- a/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/CardServiceTest.kt +++ b/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/CardServiceTest.kt @@ -4,6 +4,7 @@ package com.increase.api.services.blocking import com.increase.api.TestServerExtension import com.increase.api.client.okhttp.IncreaseOkHttpClient +import com.increase.api.models.cards.CardCreateDetailsIframeParams import com.increase.api.models.cards.CardCreateParams import com.increase.api.models.cards.CardUpdateParams import org.junit.jupiter.api.Test @@ -115,6 +116,26 @@ internal class CardServiceTest { page.response().validate() } + @Test + fun createDetailsIframe() { + val client = + IncreaseOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My API Key") + .build() + val cardService = client.cards() + + val cardIframeUrl = + cardService.createDetailsIframe( + CardCreateDetailsIframeParams.builder() + .cardId("card_oubs0hwk5rn6knuecxg2") + .physicalCardId("physical_card_id") + .build() + ) + + cardIframeUrl.validate() + } + @Test fun details() { val client = From 7a2b4fe68c53515e8299d3c31b6b45742d2942ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 00:40:29 +0000 Subject: [PATCH 2/2] release: 0.288.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 10 +++++----- build.gradle.kts | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index bc9e45054..401c03881 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.287.0" + ".": "0.288.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index fd6eaa00e..4826503cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.288.0 (2025-08-20) + +Full Changelog: [v0.287.0...v0.288.0](https://github.com/Increase/increase-java/compare/v0.287.0...v0.288.0) + +### Features + +* **api:** api update ([7974261](https://github.com/Increase/increase-java/commit/797426125cd8ed15d394418b856841cb18f63232)) + ## 0.287.0 (2025-08-20) Full Changelog: [v0.286.0...v0.287.0](https://github.com/Increase/increase-java/compare/v0.286.0...v0.287.0) diff --git a/README.md b/README.md index 853f574ae..d4ea50dc8 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.increase.api/increase-java)](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.287.0) -[![javadoc](https://javadoc.io/badge2/com.increase.api/increase-java/0.287.0/javadoc.svg)](https://javadoc.io/doc/com.increase.api/increase-java/0.287.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.increase.api/increase-java)](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.288.0) +[![javadoc](https://javadoc.io/badge2/com.increase.api/increase-java/0.288.0/javadoc.svg)](https://javadoc.io/doc/com.increase.api/increase-java/0.288.0) @@ -13,7 +13,7 @@ The Increase Java SDK is similar to the Increase Kotlin SDK but with minor diffe -The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.287.0). +The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.288.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [increase.com](https://increase.com/d ### Gradle ```kotlin -implementation("com.increase.api:increase-java:0.287.0") +implementation("com.increase.api:increase-java:0.288.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.increase.api:increase-java:0.287.0") com.increase.api increase-java - 0.287.0 + 0.288.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 6f9d28dfd..e0cac684b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.increase.api" - version = "0.287.0" // x-release-please-version + version = "0.288.0" // x-release-please-version } subprojects {