diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 988e843f..b6700282 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.116.0" + ".": "0.117.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 0080147f..5a93d129 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 176 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-ce2adff9b644ed4562b5342a4a43d0b40c98d43b4e063b4626f4ca5d342f1b92.yml -openapi_spec_hash: fbc84b866ce96457261ac58b4e75c71d -config_hash: 31d71922d7838f34ae0875c9b8026d99 +configured_endpoints: 177 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-c24eebe942f400bff8922a6fbef1ce551ad14f61eb4da21b50d823a62ca42586.yml +openapi_spec_hash: b79ed927e625dedff69cea29131a34d9 +config_hash: 693dddc4721eef512d75ab6c60897794 diff --git a/CHANGELOG.md b/CHANGELOG.md index fb6fe40f..3bc58031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## 0.117.0 (2026-02-18) + +Full Changelog: [v0.116.0...v0.117.0](https://github.com/lithic-com/lithic-java/compare/v0.116.0...v0.117.0) + +### Features + +* **api:** Add /v2/auth_rules/results endpoint for listing rule evaluation data ([6064b3a](https://github.com/lithic-com/lithic-java/commit/6064b3a6c4481eeee5dd71091b9a8362134277f6)) +* **api:** Add amounts object to ASA request ([b7d7006](https://github.com/lithic-com/lithic-java/commit/b7d700661fd0c506e43229c04fd12d81cef3505c)) +* **api:** Add hold token field to book transfers ([7796bac](https://github.com/lithic-com/lithic-java/commit/7796bac615b7324cd9c50bc1c1b35c181d4ffce9)) +* **api:** Add naics_code to account holder requests/responses ([c9ff6da](https://github.com/lithic-com/lithic-java/commit/c9ff6daa033e4022ac9208f4ff81d18346f53695)) +* **api:** Add network specific wallet recommendation reasons ([56b15ff](https://github.com/lithic-com/lithic-java/commit/56b15ffec613c66071c67444273dc8ffd569bce5)) +* **api:** Add PENDING_REVIEW status to KYB enrollment simulation ([a0a4acc](https://github.com/lithic-com/lithic-java/commit/a0a4acc37ebbd6a40fc6769855f87e4b2e20ce30)) +* **api:** Add result schemas for Authorization and Authentication (3DS) actions ([61d743a](https://github.com/lithic-com/lithic-java/commit/61d743af0994d360aab6b9700c620809e0372bf3)) +* **api:** add webhook signature verification ([4e26f35](https://github.com/lithic-com/lithic-java/commit/4e26f350ebf038f7fa0562a484a6fea5a2d85de4)) +* **client:** add connection pooling option ([2b5bf16](https://github.com/lithic-com/lithic-java/commit/2b5bf16839b77bd880a73a2c4211176accc27864)) +* **client:** add more convenience service method overloads ([41826de](https://github.com/lithic-com/lithic-java/commit/41826de4dac92b85774ea9dcdb754a1bb58ada93)) + + +### Bug Fixes + +* add missing fields ([b075f58](https://github.com/lithic-com/lithic-java/commit/b075f58683c40bd097d18490992744526f74161a)) +* **api:** Update /v2/auth_rules/results endpoint parameter naming and action types ([74dcc48](https://github.com/lithic-com/lithic-java/commit/74dcc48075f54e964f4c8179a6121c53e6a28283)) +* **client:** mark request body as required ([bce1e00](https://github.com/lithic-com/lithic-java/commit/bce1e00834c884f5b930821c7a7949fad1f38f56)) + + +### Chores + +* configure new SDK language ([2ddf823](https://github.com/lithic-com/lithic-java/commit/2ddf82360b21d85b57231fafc022f10ef909df40)) +* Enable stainless MCP in config ([2f605c1](https://github.com/lithic-com/lithic-java/commit/2f605c19967c7c77dec0358e1ccbacbadf9fc632)) +* **internal:** allow passing args to `./scripts/test` ([b327fb6](https://github.com/lithic-com/lithic-java/commit/b327fb6b7736803c3fd6a0806fe528aeeb96f428)) +* **internal:** make `OkHttp` constructor internal ([92d0d62](https://github.com/lithic-com/lithic-java/commit/92d0d62f76d7eac438e901813dbce1fcf32c22fc)) +* **internal:** remove unnecessary base URL ([2146e4b](https://github.com/lithic-com/lithic-java/commit/2146e4bb9d84df595bcc204ca589f6a0e861dff8)) +* **internal:** update `TestServerExtension` comment ([1d44ad9](https://github.com/lithic-com/lithic-java/commit/1d44ad909ecfd24ab000cfcd3db3874bcf18e97e)) +* **internal:** upgrade AssertJ ([71b1a8b](https://github.com/lithic-com/lithic-java/commit/71b1a8bb689d8740ddf53c0b85745d240ea83981)) + + +### Documentation + +* Fix documentation of tokenization channel and tokenization source for tokenization rules ([c863228](https://github.com/lithic-com/lithic-java/commit/c8632283a23548a67d038da60a064d70ef03d017)) + ## 0.116.0 (2026-01-27) Full Changelog: [v0.115.0...v0.116.0](https://github.com/lithic-com/lithic-java/compare/v0.115.0...v0.116.0) diff --git a/README.md b/README.md index 7829b853..5b40c425 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.116.0) -[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.116.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.116.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.117.0) +[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.117.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.117.0) @@ -11,9 +11,18 @@ The Lithic Java SDK provides convenient access to the [Lithic REST API](https:// The Lithic Java SDK is similar to the Lithic Kotlin SDK but with minor differences that make it more ergonomic for use in Java, such as `Optional` instead of nullable values, `Stream` instead of `Sequence`, and `CompletableFuture` instead of suspend functions. +## MCP Server + +Use the Lithic MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application. + +[![Add to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en-US/install-mcp?name=lithic-mcp&config=eyJuYW1lIjoibGl0aGljLW1jcCIsInRyYW5zcG9ydCI6Imh0dHAiLCJ1cmwiOiJodHRwczovL2xpdGhpYy5zdGxtY3AuY29tIiwiaGVhZGVycyI6eyJ4LWxpdGhpYy1hcGkta2V5IjoiTXkgTGl0aGljIEFQSSBLZXkifX0) +[![Install in VS Code](https://img.shields.io/badge/_-Add_to_VS_Code-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA0MCA0MCI+PHBhdGggZmlsbD0iI0VFRSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMzAuMjM1IDM5Ljg4NGEyLjQ5MSAyLjQ5MSAwIDAgMS0xLjc4MS0uNzNMMTIuNyAyNC43OGwtMy40NiAyLjYyNC0zLjQwNiAyLjU4MmExLjY2NSAxLjY2NSAwIDAgMS0xLjA4Mi4zMzggMS42NjQgMS42NjQgMCAwIDEtMS4wNDYtLjQzMWwtMi4yLTJhMS42NjYgMS42NjYgMCAwIDEgMC0yLjQ2M0w3LjQ1OCAyMCA0LjY3IDE3LjQ1MyAxLjUwNyAxNC41N2ExLjY2NSAxLjY2NSAwIDAgMSAwLTIuNDYzbDIuMi0yYTEuNjY1IDEuNjY1IDAgMCAxIDIuMTMtLjA5N2w2Ljg2MyA1LjIwOUwyOC40NTIuODQ0YTIuNDg4IDIuNDg4IDAgMCAxIDEuODQxLS43MjljLjM1MS4wMDkuNjk5LjA5MSAxLjAxOS4yNDVsOC4yMzYgMy45NjFhMi41IDIuNSAwIDAgMSAxLjQxNSAyLjI1M3YuMDk5LS4wNDVWMzMuMzd2LS4wNDUuMDk1YTIuNTAxIDIuNTAxIDAgMCAxLTEuNDE2IDIuMjU3bC04LjIzNSAzLjk2MWEyLjQ5MiAyLjQ5MiAwIDAgMS0xLjA3Ny4yNDZabS43MTYtMjguOTQ3LTExLjk0OCA5LjA2MiAxMS45NTIgOS4wNjUtLjAwNC0xOC4xMjdaIi8+PC9zdmc+)](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22lithic-mcp%22%2C%22type%22%3A%22http%22%2C%22url%22%3A%22https%3A%2F%2Flithic.stlmcp.com%22%2C%22headers%22%3A%7B%22x-lithic-api-key%22%3A%22My%20Lithic%20API%20Key%22%7D%7D) + +> Note: You may need to set environment variables in your MCP client. + -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.116.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.117.0). @@ -24,7 +33,7 @@ The REST API documentation can be found on [docs.lithic.com](https://docs.lithic ### Gradle ```kotlin -implementation("com.lithic.api:lithic-java:0.116.0") +implementation("com.lithic.api:lithic-java:0.117.0") ``` ### Maven @@ -33,7 +42,7 @@ implementation("com.lithic.api:lithic-java:0.116.0") com.lithic.api lithic-java - 0.116.0 + 0.117.0 ``` @@ -491,6 +500,25 @@ LithicClient client = LithicOkHttpClient.builder() .build(); ``` +### Connection pooling + +To customize the underlying OkHttp connection pool, configure the client using the `maxIdleConnections` and `keepAliveDuration` methods: + +```java +import com.lithic.api.client.LithicClient; +import com.lithic.api.client.okhttp.LithicOkHttpClient; +import java.time.Duration; + +LithicClient client = LithicOkHttpClient.builder() + .fromEnv() + // If `maxIdleConnections` is set, then `keepAliveDuration` must be set, and vice versa. + .maxIdleConnections(10) + .keepAliveDuration(Duration.ofMinutes(2)) + .build(); +``` + +If both options are unset, OkHttp's default connection pool settings are used. + ### HTTPS > [!NOTE] diff --git a/build.gradle.kts b/build.gradle.kts index 72a101ec..3371f3d6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.lithic.api" - version = "0.116.0" // x-release-please-version + version = "0.117.0" // x-release-please-version } subprojects { diff --git a/lithic-java-client-okhttp/build.gradle.kts b/lithic-java-client-okhttp/build.gradle.kts index 0d61bae3..1227e287 100644 --- a/lithic-java-client-okhttp/build.gradle.kts +++ b/lithic-java-client-okhttp/build.gradle.kts @@ -10,6 +10,6 @@ dependencies { implementation("com.squareup.okhttp3:logging-interceptor:4.12.0") testImplementation(kotlin("test")) - testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") } diff --git a/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClient.kt b/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClient.kt index ac00e64a..824255b1 100644 --- a/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClient.kt +++ b/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClient.kt @@ -49,6 +49,8 @@ class LithicOkHttpClient private constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null + private var maxIdleConnections: Int? = null + private var keepAliveDuration: Duration? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null @@ -77,6 +79,46 @@ class LithicOkHttpClient private constructor() { /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + /** + * The maximum number of idle connections kept by the underlying OkHttp connection pool. + * + * If this is set, then [keepAliveDuration] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun maxIdleConnections(maxIdleConnections: Int?) = apply { + this.maxIdleConnections = maxIdleConnections + } + + /** + * Alias for [Builder.maxIdleConnections]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxIdleConnections(maxIdleConnections: Int) = + maxIdleConnections(maxIdleConnections as Int?) + + /** + * Alias for calling [Builder.maxIdleConnections] with `maxIdleConnections.orElse(null)`. + */ + fun maxIdleConnections(maxIdleConnections: Optional) = + maxIdleConnections(maxIdleConnections.getOrNull()) + + /** + * The keep-alive duration for idle connections in the underlying OkHttp connection pool. + * + * If this is set, then [maxIdleConnections] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun keepAliveDuration(keepAliveDuration: Duration?) = apply { + this.keepAliveDuration = keepAliveDuration + } + + /** Alias for calling [Builder.keepAliveDuration] with `keepAliveDuration.orElse(null)`. */ + fun keepAliveDuration(keepAliveDuration: Optional) = + keepAliveDuration(keepAliveDuration.getOrNull()) + /** * The socket factory used to secure HTTPS connections. * @@ -344,6 +386,8 @@ class LithicOkHttpClient private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .maxIdleConnections(maxIdleConnections) + .keepAliveDuration(keepAliveDuration) .dispatcherExecutorService(dispatcherExecutorService) .sslSocketFactory(sslSocketFactory) .trustManager(trustManager) diff --git a/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClientAsync.kt b/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClientAsync.kt index aebe796e..9224b380 100644 --- a/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClientAsync.kt +++ b/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/LithicOkHttpClientAsync.kt @@ -49,6 +49,8 @@ class LithicOkHttpClientAsync private constructor() { private var clientOptions: ClientOptions.Builder = ClientOptions.builder() private var dispatcherExecutorService: ExecutorService? = null private var proxy: Proxy? = null + private var maxIdleConnections: Int? = null + private var keepAliveDuration: Duration? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null private var hostnameVerifier: HostnameVerifier? = null @@ -77,6 +79,46 @@ class LithicOkHttpClientAsync private constructor() { /** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */ fun proxy(proxy: Optional) = proxy(proxy.getOrNull()) + /** + * The maximum number of idle connections kept by the underlying OkHttp connection pool. + * + * If this is set, then [keepAliveDuration] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun maxIdleConnections(maxIdleConnections: Int?) = apply { + this.maxIdleConnections = maxIdleConnections + } + + /** + * Alias for [Builder.maxIdleConnections]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun maxIdleConnections(maxIdleConnections: Int) = + maxIdleConnections(maxIdleConnections as Int?) + + /** + * Alias for calling [Builder.maxIdleConnections] with `maxIdleConnections.orElse(null)`. + */ + fun maxIdleConnections(maxIdleConnections: Optional) = + maxIdleConnections(maxIdleConnections.getOrNull()) + + /** + * The keep-alive duration for idle connections in the underlying OkHttp connection pool. + * + * If this is set, then [maxIdleConnections] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun keepAliveDuration(keepAliveDuration: Duration?) = apply { + this.keepAliveDuration = keepAliveDuration + } + + /** Alias for calling [Builder.keepAliveDuration] with `keepAliveDuration.orElse(null)`. */ + fun keepAliveDuration(keepAliveDuration: Optional) = + keepAliveDuration(keepAliveDuration.getOrNull()) + /** * The socket factory used to secure HTTPS connections. * @@ -344,6 +386,8 @@ class LithicOkHttpClientAsync private constructor() { OkHttpClient.builder() .timeout(clientOptions.timeout()) .proxy(proxy) + .maxIdleConnections(maxIdleConnections) + .keepAliveDuration(keepAliveDuration) .dispatcherExecutorService(dispatcherExecutorService) .sslSocketFactory(sslSocketFactory) .trustManager(trustManager) diff --git a/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/OkHttpClient.kt b/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/OkHttpClient.kt index 02e25515..5c5c1167 100644 --- a/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/OkHttpClient.kt +++ b/lithic-java-client-okhttp/src/main/kotlin/com/lithic/api/client/okhttp/OkHttpClient.kt @@ -16,11 +16,13 @@ import java.time.Duration import java.util.concurrent.CancellationException import java.util.concurrent.CompletableFuture import java.util.concurrent.ExecutorService +import java.util.concurrent.TimeUnit import javax.net.ssl.HostnameVerifier import javax.net.ssl.SSLSocketFactory import javax.net.ssl.X509TrustManager import okhttp3.Call import okhttp3.Callback +import okhttp3.ConnectionPool import okhttp3.Dispatcher import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.MediaType @@ -33,7 +35,7 @@ import okhttp3.logging.HttpLoggingInterceptor import okio.BufferedSink class OkHttpClient -private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient { +internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClient) : HttpClient { override fun execute(request: HttpRequest, requestOptions: RequestOptions): HttpResponse { val call = newCall(request, requestOptions) @@ -200,6 +202,8 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien private var timeout: Timeout = Timeout.default() private var proxy: Proxy? = null + private var maxIdleConnections: Int? = null + private var keepAliveDuration: Duration? = null private var dispatcherExecutorService: ExecutorService? = null private var sslSocketFactory: SSLSocketFactory? = null private var trustManager: X509TrustManager? = null @@ -211,6 +215,28 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien fun proxy(proxy: Proxy?) = apply { this.proxy = proxy } + /** + * Sets the maximum number of idle connections kept by the underlying [ConnectionPool]. + * + * If this is set, then [keepAliveDuration] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun maxIdleConnections(maxIdleConnections: Int?) = apply { + this.maxIdleConnections = maxIdleConnections + } + + /** + * Sets the keep-alive duration for idle connections in the underlying [ConnectionPool]. + * + * If this is set, then [maxIdleConnections] must also be set. + * + * If unset, then OkHttp's default is used. + */ + fun keepAliveDuration(keepAliveDuration: Duration?) = apply { + this.keepAliveDuration = keepAliveDuration + } + fun dispatcherExecutorService(dispatcherExecutorService: ExecutorService?) = apply { this.dispatcherExecutorService = dispatcherExecutorService } @@ -240,6 +266,22 @@ private constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClien .apply { dispatcherExecutorService?.let { dispatcher(Dispatcher(it)) } + val maxIdleConnections = maxIdleConnections + val keepAliveDuration = keepAliveDuration + if (maxIdleConnections != null && keepAliveDuration != null) { + connectionPool( + ConnectionPool( + maxIdleConnections, + keepAliveDuration.toNanos(), + TimeUnit.NANOSECONDS, + ) + ) + } else { + check((maxIdleConnections != null) == (keepAliveDuration != null)) { + "Both or none of `maxIdleConnections` and `keepAliveDuration` must be set, but only one was set" + } + } + val sslSocketFactory = sslSocketFactory val trustManager = trustManager if (sslSocketFactory != null && trustManager != null) { diff --git a/lithic-java-core/build.gradle.kts b/lithic-java-core/build.gradle.kts index 151c17eb..dc2ea195 100644 --- a/lithic-java-core/build.gradle.kts +++ b/lithic-java-core/build.gradle.kts @@ -22,6 +22,7 @@ dependencies { api("com.fasterxml.jackson.core:jackson-core:2.18.2") api("com.fasterxml.jackson.core:jackson-databind:2.18.2") api("com.google.errorprone:error_prone_annotations:2.33.0") + api("com.standardwebhooks:standardwebhooks:1.1.0") implementation("com.fasterxml.jackson.core:jackson-annotations:2.18.2") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.18.2") @@ -33,7 +34,7 @@ dependencies { testImplementation(kotlin("test")) testImplementation(project(":lithic-java-client-okhttp")) testImplementation("com.github.tomakehurst:wiremock-jre8:2.35.2") - testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.3") testImplementation("org.junit-pioneer:junit-pioneer:1.9.1") diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/core/UnwrapWebhookParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/core/UnwrapWebhookParams.kt new file mode 100644 index 00000000..8c748395 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/core/UnwrapWebhookParams.kt @@ -0,0 +1,102 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.core + +import com.lithic.api.core.http.Headers +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +class UnwrapWebhookParams +private constructor( + private val body: String, + private val headers: Headers?, + private val secret: String?, +) { + + /** The raw JSON body of the webhook request. */ + fun body(): String = body + + /** The headers from the webhook request. */ + fun headers(): Optional = Optional.ofNullable(headers) + + /** The secret used to verify the webhook signature. */ + fun secret(): Optional = Optional.ofNullable(secret) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [UnwrapWebhookParams]. + * + * The following fields are required: + * ```java + * .body() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UnwrapWebhookParams]. */ + class Builder internal constructor() { + + private var body: String? = null + private var headers: Headers? = null + private var secret: String? = null + + @JvmSynthetic + internal fun from(unwrapWebhookParams: UnwrapWebhookParams) = apply { + body = unwrapWebhookParams.body + headers = unwrapWebhookParams.headers + secret = unwrapWebhookParams.secret + } + + /** The raw JSON body of the webhook request. */ + fun body(body: String) = apply { this.body = body } + + /** The headers from the webhook request. */ + fun headers(headers: Headers?) = apply { this.headers = headers } + + /** Alias for calling [Builder.headers] with `headers.orElse(null)`. */ + fun headers(headers: Optional) = headers(headers.getOrNull()) + + /** The secret used to verify the webhook signature. */ + fun secret(secret: String?) = apply { this.secret = secret } + + /** Alias for calling [Builder.secret] with `secret.orElse(null)`. */ + fun secret(secret: Optional) = secret(secret.getOrNull()) + + /** + * Returns an immutable instance of [UnwrapWebhookParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): UnwrapWebhookParams = + UnwrapWebhookParams(checkRequired("body", body), headers, secret) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is UnwrapWebhookParams && + body == other.body && + headers == other.headers && + secret == other.secret + } + + private val hashCode: Int by lazy { Objects.hash(body, headers, secret) } + + override fun hashCode(): Int = hashCode + + override fun toString() = "UnwrapWebhookParams{body=$body, headers=$headers, secret=$secret}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/errors/LithicWebhookException.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/errors/LithicWebhookException.kt new file mode 100644 index 00000000..c00f08f9 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/errors/LithicWebhookException.kt @@ -0,0 +1,5 @@ +package com.lithic.api.errors + +class LithicWebhookException +@JvmOverloads +constructor(message: String? = null, cause: Throwable? = null) : LithicException(message, cause) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolder.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolder.kt index 94557f28..0bf76e54 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolder.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolder.kt @@ -36,6 +36,7 @@ private constructor( private val exemptionType: JsonField, private val externalId: JsonField, private val individual: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val phoneNumber: JsonField, private val requiredDocuments: JsonField>, @@ -82,6 +83,7 @@ private constructor( @JsonProperty("individual") @ExcludeMissing individual: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") @ExcludeMissing naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -115,6 +117,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, requiredDocuments, @@ -245,6 +248,15 @@ private constructor( fun individual(): Optional = individual.getOptional("individual") + /** + * Only present when user_type == "BUSINESS". 6-digit North American Industry Classification + * System (NAICS) code for the business. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Only present when user_type == "BUSINESS". User-submitted description of the business. * @@ -299,8 +311,8 @@ private constructor( /** * The type of Account Holder. If the type is "INDIVIDUAL", the "individual" attribute will be * present. If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will be - * present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. * * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -430,6 +442,13 @@ private constructor( @ExcludeMissing fun _individual(): JsonField = individual + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("naics_code") @ExcludeMissing fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -545,6 +564,7 @@ private constructor( private var exemptionType: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() private var individual: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var phoneNumber: JsonField = JsonMissing.of() private var requiredDocuments: JsonField>? = null @@ -572,6 +592,7 @@ private constructor( exemptionType = accountHolder.exemptionType externalId = accountHolder.externalId individual = accountHolder.individual + naicsCode = accountHolder.naicsCode natureOfBusiness = accountHolder.natureOfBusiness phoneNumber = accountHolder.phoneNumber requiredDocuments = accountHolder.requiredDocuments.map { it.toMutableList() } @@ -811,6 +832,21 @@ private constructor( this.individual = individual } + /** + * Only present when user_type == "BUSINESS". 6-digit North American Industry Classification + * System (NAICS) code for the business. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Only present when user_type == "BUSINESS". User-submitted description of the business. */ @@ -926,8 +962,8 @@ private constructor( /** * The type of Account Holder. If the type is "INDIVIDUAL", the "individual" attribute will * be present. If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will - * be present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. */ fun userType(userType: UserType) = userType(JsonField.of(userType)) @@ -1013,6 +1049,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, (requiredDocuments ?: JsonMissing.of()).map { it.toImmutable() }, @@ -1044,6 +1081,7 @@ private constructor( exemptionType().ifPresent { it.validate() } externalId() individual().ifPresent { it.validate() } + naicsCode() natureOfBusiness() phoneNumber() requiredDocuments().ifPresent { it.forEach { it.validate() } } @@ -1083,6 +1121,7 @@ private constructor( (exemptionType.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + (individual.asKnown().getOrNull()?.validity() ?: 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (phoneNumber.asKnown().isPresent) 1 else 0) + (requiredDocuments.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + @@ -2447,8 +2486,8 @@ private constructor( /** * The type of Account Holder. If the type is "INDIVIDUAL", the "individual" attribute will be * present. If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will be - * present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. */ class UserType @JsonCreator private constructor(private val value: JsonField) : Enum { @@ -3226,6 +3265,7 @@ private constructor( exemptionType == other.exemptionType && externalId == other.externalId && individual == other.individual && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && phoneNumber == other.phoneNumber && requiredDocuments == other.requiredDocuments && @@ -3251,6 +3291,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, requiredDocuments, @@ -3266,5 +3307,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "AccountHolder{token=$token, created=$created, accountToken=$accountToken, beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessAccountToken=$businessAccountToken, businessEntity=$businessEntity, controlPerson=$controlPerson, email=$email, exemptionType=$exemptionType, externalId=$externalId, individual=$individual, natureOfBusiness=$natureOfBusiness, phoneNumber=$phoneNumber, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, userType=$userType, verificationApplication=$verificationApplication, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "AccountHolder{token=$token, created=$created, accountToken=$accountToken, beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessAccountToken=$businessAccountToken, businessEntity=$businessEntity, controlPerson=$controlPerson, email=$email, exemptionType=$exemptionType, externalId=$externalId, individual=$individual, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, phoneNumber=$phoneNumber, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, userType=$userType, verificationApplication=$verificationApplication, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderCreateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderCreateParams.kt index d31c3821..6240d0c4 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderCreateParams.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderCreateParams.kt @@ -453,6 +453,7 @@ private constructor( private val beneficialOwnerIndividuals: JsonField>, private val controlPerson: JsonField, private val externalId: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val tosTimestamp: JsonField, private val websiteUrl: JsonField, @@ -474,6 +475,9 @@ private constructor( @JsonProperty("external_id") @ExcludeMissing externalId: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") + @ExcludeMissing + naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -491,6 +495,7 @@ private constructor( beneficialOwnerIndividuals, controlPerson, externalId, + naicsCode, natureOfBusiness, tosTimestamp, websiteUrl, @@ -546,6 +551,14 @@ private constructor( */ fun externalId(): Optional = externalId.getOptional("external_id") + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Short description of the company's line of business (i.e., what does the company * do?). @@ -623,6 +636,16 @@ private constructor( @ExcludeMissing fun _externalId(): JsonField = externalId + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("naics_code") + @ExcludeMissing + fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -696,6 +719,7 @@ private constructor( null private var controlPerson: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var tosTimestamp: JsonField = JsonMissing.of() private var websiteUrl: JsonField = JsonMissing.of() @@ -709,6 +733,7 @@ private constructor( kybDelegated.beneficialOwnerIndividuals.map { it.toMutableList() } controlPerson = kybDelegated.controlPerson externalId = kybDelegated.externalId + naicsCode = kybDelegated.naicsCode natureOfBusiness = kybDelegated.natureOfBusiness tosTimestamp = kybDelegated.tosTimestamp websiteUrl = kybDelegated.websiteUrl @@ -810,6 +835,21 @@ private constructor( this.externalId = externalId } + /** + * 6-digit North American Industry Classification System (NAICS) code for the + * business. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Short description of the company's line of business (i.e., what does the company * do?). @@ -912,6 +952,7 @@ private constructor( (beneficialOwnerIndividuals ?: JsonMissing.of()).map { it.toImmutable() }, controlPerson, externalId, + naicsCode, natureOfBusiness, tosTimestamp, websiteUrl, @@ -931,6 +972,7 @@ private constructor( beneficialOwnerIndividuals().ifPresent { it.forEach { it.validate() } } controlPerson().ifPresent { it.validate() } externalId() + naicsCode() natureOfBusiness() tosTimestamp() websiteUrl() @@ -960,6 +1002,7 @@ private constructor( } ?: 0) + (controlPerson.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (tosTimestamp.asKnown().isPresent) 1 else 0) + (if (websiteUrl.asKnown().isPresent) 1 else 0) + @@ -2014,6 +2057,7 @@ private constructor( beneficialOwnerIndividuals == other.beneficialOwnerIndividuals && controlPerson == other.controlPerson && externalId == other.externalId && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && tosTimestamp == other.tosTimestamp && websiteUrl == other.websiteUrl && @@ -2027,6 +2071,7 @@ private constructor( beneficialOwnerIndividuals, controlPerson, externalId, + naicsCode, natureOfBusiness, tosTimestamp, websiteUrl, @@ -2038,7 +2083,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "KybDelegated{businessEntity=$businessEntity, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, controlPerson=$controlPerson, externalId=$externalId, natureOfBusiness=$natureOfBusiness, tosTimestamp=$tosTimestamp, websiteUrl=$websiteUrl, workflow=$workflow, additionalProperties=$additionalProperties}" + "KybDelegated{businessEntity=$businessEntity, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, controlPerson=$controlPerson, externalId=$externalId, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, tosTimestamp=$tosTimestamp, websiteUrl=$websiteUrl, workflow=$workflow, additionalProperties=$additionalProperties}" } } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewParams.kt index 3320660d..94680149 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewParams.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewParams.kt @@ -600,6 +600,8 @@ private constructor( @JvmField val REJECTED = of("REJECTED") + @JvmField val PENDING_REVIEW = of("PENDING_REVIEW") + @JvmStatic fun of(value: String) = Status(JsonField.of(value)) } @@ -607,6 +609,7 @@ private constructor( enum class Known { ACCEPTED, REJECTED, + PENDING_REVIEW, } /** @@ -621,6 +624,7 @@ private constructor( enum class Value { ACCEPTED, REJECTED, + PENDING_REVIEW, /** An enum member indicating that [Status] was instantiated with an unknown value. */ _UNKNOWN, } @@ -636,6 +640,7 @@ private constructor( when (this) { ACCEPTED -> Value.ACCEPTED REJECTED -> Value.REJECTED + PENDING_REVIEW -> Value.PENDING_REVIEW else -> Value._UNKNOWN } @@ -652,6 +657,7 @@ private constructor( when (this) { ACCEPTED -> Known.ACCEPTED REJECTED -> Known.REJECTED + PENDING_REVIEW -> Known.PENDING_REVIEW else -> throw LithicInvalidDataException("Unknown Status: $value") } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponse.kt index 2a9e0c44..9ec3b45e 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponse.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponse.kt @@ -36,6 +36,7 @@ private constructor( private val exemptionType: JsonField, private val externalId: JsonField, private val individual: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val phoneNumber: JsonField, private val requiredDocuments: JsonField>, @@ -81,6 +82,7 @@ private constructor( @JsonProperty("individual") @ExcludeMissing individual: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") @ExcludeMissing naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -114,6 +116,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, requiredDocuments, @@ -246,6 +249,15 @@ private constructor( */ fun individual(): Optional = individual.getOptional("individual") + /** + * Only present when user_type == "BUSINESS". 6-digit North American Industry Classification + * System (NAICS) code for the business. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Only present when user_type == "BUSINESS". User-submitted description of the business. * @@ -298,8 +310,8 @@ private constructor( * present. * * If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will be - * present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. * * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -426,6 +438,13 @@ private constructor( @ExcludeMissing fun _individual(): JsonField = individual + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("naics_code") @ExcludeMissing fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -531,6 +550,7 @@ private constructor( private var exemptionType: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() private var individual: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var phoneNumber: JsonField = JsonMissing.of() private var requiredDocuments: JsonField>? = null @@ -565,6 +585,7 @@ private constructor( exemptionType = accountHolderSimulateEnrollmentReviewResponse.exemptionType externalId = accountHolderSimulateEnrollmentReviewResponse.externalId individual = accountHolderSimulateEnrollmentReviewResponse.individual + naicsCode = accountHolderSimulateEnrollmentReviewResponse.naicsCode natureOfBusiness = accountHolderSimulateEnrollmentReviewResponse.natureOfBusiness phoneNumber = accountHolderSimulateEnrollmentReviewResponse.phoneNumber requiredDocuments = @@ -815,6 +836,21 @@ private constructor( */ fun individual(individual: JsonField) = apply { this.individual = individual } + /** + * Only present when user_type == "BUSINESS". 6-digit North American Industry Classification + * System (NAICS) code for the business. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Only present when user_type == "BUSINESS". User-submitted description of the business. */ @@ -929,8 +965,8 @@ private constructor( * be present. * * If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will - * be present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. */ fun userType(userType: UserType) = userType(JsonField.of(userType)) @@ -1009,6 +1045,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, (requiredDocuments ?: JsonMissing.of()).map { it.toImmutable() }, @@ -1040,6 +1077,7 @@ private constructor( exemptionType().ifPresent { it.validate() } externalId() individual().ifPresent { it.validate() } + naicsCode() natureOfBusiness() phoneNumber() requiredDocuments().ifPresent { it.forEach { it.validate() } } @@ -1079,6 +1117,7 @@ private constructor( (exemptionType.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + (individual.asKnown().getOrNull()?.validity() ?: 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (phoneNumber.asKnown().isPresent) 1 else 0) + (requiredDocuments.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + @@ -2483,8 +2522,8 @@ private constructor( * present. * * If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will be - * present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. */ class UserType @JsonCreator private constructor(private val value: JsonField) : Enum { @@ -3444,6 +3483,7 @@ private constructor( exemptionType == other.exemptionType && externalId == other.externalId && individual == other.individual && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && phoneNumber == other.phoneNumber && requiredDocuments == other.requiredDocuments && @@ -3469,6 +3509,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, requiredDocuments, @@ -3484,5 +3525,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "AccountHolderSimulateEnrollmentReviewResponse{token=$token, accountToken=$accountToken, beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessAccountToken=$businessAccountToken, businessEntity=$businessEntity, controlPerson=$controlPerson, created=$created, email=$email, exemptionType=$exemptionType, externalId=$externalId, individual=$individual, natureOfBusiness=$natureOfBusiness, phoneNumber=$phoneNumber, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, userType=$userType, verificationApplication=$verificationApplication, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "AccountHolderSimulateEnrollmentReviewResponse{token=$token, accountToken=$accountToken, beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessAccountToken=$businessAccountToken, businessEntity=$businessEntity, controlPerson=$controlPerson, created=$created, email=$email, exemptionType=$exemptionType, externalId=$externalId, individual=$individual, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, phoneNumber=$phoneNumber, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, userType=$userType, verificationApplication=$verificationApplication, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateParams.kt index 35fd00bc..54a08bcc 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateParams.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateParams.kt @@ -473,6 +473,7 @@ private constructor( private val businessEntity: JsonField, private val controlPerson: JsonField, private val externalId: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val websiteUrl: JsonField, private val additionalProperties: MutableMap, @@ -495,6 +496,9 @@ private constructor( @JsonProperty("external_id") @ExcludeMissing externalId: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") + @ExcludeMissing + naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -507,6 +511,7 @@ private constructor( businessEntity, controlPerson, externalId, + naicsCode, natureOfBusiness, websiteUrl, mutableMapOf(), @@ -569,6 +574,14 @@ private constructor( */ fun externalId(): Optional = externalId.getOptional("external_id") + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Short description of the company's line of business (i.e., what does the company * do?). @@ -640,6 +653,16 @@ private constructor( @ExcludeMissing fun _externalId(): JsonField = externalId + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("naics_code") + @ExcludeMissing + fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -689,6 +712,7 @@ private constructor( private var businessEntity: JsonField = JsonMissing.of() private var controlPerson: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var websiteUrl: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -702,6 +726,7 @@ private constructor( businessEntity = kybPatchRequest.businessEntity controlPerson = kybPatchRequest.controlPerson externalId = kybPatchRequest.externalId + naicsCode = kybPatchRequest.naicsCode natureOfBusiness = kybPatchRequest.natureOfBusiness websiteUrl = kybPatchRequest.websiteUrl additionalProperties = kybPatchRequest.additionalProperties.toMutableMap() @@ -839,6 +864,21 @@ private constructor( this.externalId = externalId } + /** + * 6-digit North American Industry Classification System (NAICS) code for the + * business. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Short description of the company's line of business (i.e., what does the company * do?). @@ -905,6 +945,7 @@ private constructor( businessEntity, controlPerson, externalId, + naicsCode, natureOfBusiness, websiteUrl, additionalProperties.toMutableMap(), @@ -923,6 +964,7 @@ private constructor( businessEntity().ifPresent { it.validate() } controlPerson().ifPresent { it.validate() } externalId() + naicsCode() natureOfBusiness() websiteUrl() validated = true @@ -952,6 +994,7 @@ private constructor( (businessEntity.asKnown().getOrNull()?.validity() ?: 0) + (controlPerson.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (websiteUrl.asKnown().isPresent) 1 else 0) @@ -1951,6 +1994,7 @@ private constructor( businessEntity == other.businessEntity && controlPerson == other.controlPerson && externalId == other.externalId && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && websiteUrl == other.websiteUrl && additionalProperties == other.additionalProperties @@ -1963,6 +2007,7 @@ private constructor( businessEntity, controlPerson, externalId, + naicsCode, natureOfBusiness, websiteUrl, additionalProperties, @@ -1972,7 +2017,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "KybPatchRequest{beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessEntity=$businessEntity, controlPerson=$controlPerson, externalId=$externalId, natureOfBusiness=$natureOfBusiness, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "KybPatchRequest{beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessEntity=$businessEntity, controlPerson=$controlPerson, externalId=$externalId, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } /** The KYC request payload for updating an account holder. */ diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateResponse.kt index 9178f9da..2291db7d 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateResponse.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdateResponse.kt @@ -225,6 +225,7 @@ private constructor( private val exemptionType: JsonField, private val externalId: JsonField, private val individual: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val phoneNumber: JsonField, private val requiredDocuments: JsonField>, @@ -270,6 +271,9 @@ private constructor( @JsonProperty("individual") @ExcludeMissing individual: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") + @ExcludeMissing + naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -305,6 +309,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, requiredDocuments, @@ -437,6 +442,15 @@ private constructor( */ fun individual(): Optional = individual.getOptional("individual") + /** + * Only present when user_type == "BUSINESS". 6-digit North American Industry Classification + * System (NAICS) code for the business. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Only present when user_type == "BUSINESS". User-submitted description of the business. * @@ -492,8 +506,8 @@ private constructor( * be present. * * If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will - * be present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. * * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). @@ -626,6 +640,13 @@ private constructor( @ExcludeMissing fun _individual(): JsonField = individual + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("naics_code") @ExcludeMissing fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -731,6 +752,7 @@ private constructor( private var exemptionType: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() private var individual: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var phoneNumber: JsonField = JsonMissing.of() private var requiredDocuments: JsonField>? = null @@ -758,6 +780,7 @@ private constructor( exemptionType = kybKycPatchResponse.exemptionType externalId = kybKycPatchResponse.externalId individual = kybKycPatchResponse.individual + naicsCode = kybKycPatchResponse.naicsCode natureOfBusiness = kybKycPatchResponse.natureOfBusiness phoneNumber = kybKycPatchResponse.phoneNumber requiredDocuments = kybKycPatchResponse.requiredDocuments.map { it.toMutableList() } @@ -1009,6 +1032,21 @@ private constructor( this.individual = individual } + /** + * Only present when user_type == "BUSINESS". 6-digit North American Industry + * Classification System (NAICS) code for the business. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Only present when user_type == "BUSINESS". User-submitted description of the * business. @@ -1128,8 +1166,8 @@ private constructor( * will be present. * * If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes - * will be present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. */ fun userType(userType: UserType) = userType(JsonField.of(userType)) @@ -1207,6 +1245,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, (requiredDocuments ?: JsonMissing.of()).map { it.toImmutable() }, @@ -1238,6 +1277,7 @@ private constructor( exemptionType().ifPresent { it.validate() } externalId() individual().ifPresent { it.validate() } + naicsCode() natureOfBusiness() phoneNumber() requiredDocuments().ifPresent { it.forEach { it.validate() } } @@ -1279,6 +1319,7 @@ private constructor( (exemptionType.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + (individual.asKnown().getOrNull()?.validity() ?: 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (phoneNumber.asKnown().isPresent) 1 else 0) + (requiredDocuments.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + @@ -2719,8 +2760,8 @@ private constructor( * be present. * * If the type is "BUSINESS" then the "business_entity", "control_person", - * "beneficial_owner_individuals", "nature_of_business", and "website_url" attributes will - * be present. + * "beneficial_owner_individuals", "naics_code", "nature_of_business", and "website_url" + * attributes will be present. */ class UserType @JsonCreator private constructor(private val value: JsonField) : Enum { @@ -3713,6 +3754,7 @@ private constructor( exemptionType == other.exemptionType && externalId == other.externalId && individual == other.individual && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && phoneNumber == other.phoneNumber && requiredDocuments == other.requiredDocuments && @@ -3738,6 +3780,7 @@ private constructor( exemptionType, externalId, individual, + naicsCode, natureOfBusiness, phoneNumber, requiredDocuments, @@ -3753,7 +3796,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "KybKycPatchResponse{token=$token, accountToken=$accountToken, beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessAccountToken=$businessAccountToken, businessEntity=$businessEntity, controlPerson=$controlPerson, created=$created, email=$email, exemptionType=$exemptionType, externalId=$externalId, individual=$individual, natureOfBusiness=$natureOfBusiness, phoneNumber=$phoneNumber, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, userType=$userType, verificationApplication=$verificationApplication, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "KybKycPatchResponse{token=$token, accountToken=$accountToken, beneficialOwnerEntities=$beneficialOwnerEntities, beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessAccountToken=$businessAccountToken, businessEntity=$businessEntity, controlPerson=$controlPerson, created=$created, email=$email, exemptionType=$exemptionType, externalId=$externalId, individual=$individual, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, phoneNumber=$phoneNumber, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, userType=$userType, verificationApplication=$verificationApplication, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } class PatchResponse diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEvent.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEvent.kt index 9a49ea1a..2c1485c4 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEvent.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEvent.kt @@ -262,6 +262,7 @@ private constructor( private val updateRequest: JsonField, private val eventType: JsonField, private val externalId: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val websiteUrl: JsonField, private val additionalProperties: MutableMap, @@ -279,6 +280,9 @@ private constructor( @JsonProperty("external_id") @ExcludeMissing externalId: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") + @ExcludeMissing + naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -290,6 +294,7 @@ private constructor( updateRequest, eventType, externalId, + naicsCode, natureOfBusiness, websiteUrl, mutableMapOf(), @@ -327,6 +332,15 @@ private constructor( */ fun externalId(): Optional = externalId.getOptional("external_id") + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. Only + * present if naics_code was included in the update request. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Short description of the company's line of business (i.e., what does the company do?). * @@ -379,6 +393,13 @@ private constructor( @ExcludeMissing fun _externalId(): JsonField = externalId + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("naics_code") @ExcludeMissing fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -431,6 +452,7 @@ private constructor( private var updateRequest: JsonField? = null private var eventType: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var websiteUrl: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -441,6 +463,7 @@ private constructor( updateRequest = kybPayload.updateRequest eventType = kybPayload.eventType externalId = kybPayload.externalId + naicsCode = kybPayload.naicsCode natureOfBusiness = kybPayload.natureOfBusiness websiteUrl = kybPayload.websiteUrl additionalProperties = kybPayload.additionalProperties.toMutableMap() @@ -499,6 +522,21 @@ private constructor( */ fun externalId(externalId: JsonField) = apply { this.externalId = externalId } + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. + * Only present if naics_code was included in the update request. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Short description of the company's line of business (i.e., what does the company * do?). @@ -567,6 +605,7 @@ private constructor( checkRequired("updateRequest", updateRequest), eventType, externalId, + naicsCode, natureOfBusiness, websiteUrl, additionalProperties.toMutableMap(), @@ -584,6 +623,7 @@ private constructor( updateRequest().validate() eventType().ifPresent { it.validate() } externalId() + naicsCode() natureOfBusiness() websiteUrl() validated = true @@ -609,6 +649,7 @@ private constructor( (updateRequest.asKnown().getOrNull()?.validity() ?: 0) + (eventType.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (websiteUrl.asKnown().isPresent) 1 else 0) @@ -1978,6 +2019,7 @@ private constructor( updateRequest == other.updateRequest && eventType == other.eventType && externalId == other.externalId && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && websiteUrl == other.websiteUrl && additionalProperties == other.additionalProperties @@ -1989,6 +2031,7 @@ private constructor( updateRequest, eventType, externalId, + naicsCode, natureOfBusiness, websiteUrl, additionalProperties, @@ -1998,7 +2041,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "KybPayload{token=$token, updateRequest=$updateRequest, eventType=$eventType, externalId=$externalId, natureOfBusiness=$natureOfBusiness, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "KybPayload{token=$token, updateRequest=$updateRequest, eventType=$eventType, externalId=$externalId, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } /** KYC payload for an updated account holder. */ diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPage.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPage.kt new file mode 100644 index 00000000..80a97926 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPage.kt @@ -0,0 +1,193 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.AutoPager +import com.lithic.api.core.Page +import com.lithic.api.core.checkRequired +import com.lithic.api.services.blocking.authRules.V2Service +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** @see V2Service.listResults */ +class AuthRuleV2ListResultsPage +private constructor( + private val service: V2Service, + private val params: AuthRuleV2ListResultsParams, + private val response: AuthRuleV2ListResultsPageResponse, +) : Page { + + /** + * Delegates to [AuthRuleV2ListResultsPageResponse], but gracefully handles missing data. + * + * @see AuthRuleV2ListResultsPageResponse.data + */ + fun data(): List = + response._data().getOptional("data").getOrNull() ?: emptyList() + + /** + * Delegates to [AuthRuleV2ListResultsPageResponse], but gracefully handles missing data. + * + * @see AuthRuleV2ListResultsPageResponse.hasMore + */ + fun hasMore(): Optional = response._hasMore().getOptional("has_more") + + override fun items(): List = data() + + override fun hasNextPage(): Boolean = items().isNotEmpty() + + fun nextPageParams(): AuthRuleV2ListResultsParams = + if (params.endingBefore().isPresent) { + params + .toBuilder() + .endingBefore( + items() + .first() + .accept( + object : V2ListResultsResponse.Visitor> { + override fun visitAuthorizationResult( + authorizationResult: V2ListResultsResponse.AuthorizationResult + ): Optional = + authorizationResult._token().getOptional("token") + + override fun visitAuthentication3dsResult( + authentication3dsResult: + V2ListResultsResponse.Authentication3dsResult + ): Optional = + authentication3dsResult._token().getOptional("token") + + override fun visitTokenizationResult( + tokenizationResult: V2ListResultsResponse.TokenizationResult + ): Optional = + tokenizationResult._token().getOptional("token") + + override fun visitAchResult( + achResult: V2ListResultsResponse.AchResult + ): Optional = achResult._token().getOptional("token") + } + ) + ) + .build() + } else { + params + .toBuilder() + .startingAfter( + items() + .last() + .accept( + object : V2ListResultsResponse.Visitor> { + override fun visitAuthorizationResult( + authorizationResult: V2ListResultsResponse.AuthorizationResult + ): Optional = + authorizationResult._token().getOptional("token") + + override fun visitAuthentication3dsResult( + authentication3dsResult: + V2ListResultsResponse.Authentication3dsResult + ): Optional = + authentication3dsResult._token().getOptional("token") + + override fun visitTokenizationResult( + tokenizationResult: V2ListResultsResponse.TokenizationResult + ): Optional = + tokenizationResult._token().getOptional("token") + + override fun visitAchResult( + achResult: V2ListResultsResponse.AchResult + ): Optional = achResult._token().getOptional("token") + } + ) + ) + .build() + } + + override fun nextPage(): AuthRuleV2ListResultsPage = service.listResults(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) + + /** The parameters that were used to request this page. */ + fun params(): AuthRuleV2ListResultsParams = params + + /** The response that this page was parsed from. */ + fun response(): AuthRuleV2ListResultsPageResponse = response + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [AuthRuleV2ListResultsPage]. + * + * The following fields are required: + * ```java + * .service() + * .params() + * .response() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthRuleV2ListResultsPage]. */ + class Builder internal constructor() { + + private var service: V2Service? = null + private var params: AuthRuleV2ListResultsParams? = null + private var response: AuthRuleV2ListResultsPageResponse? = null + + @JvmSynthetic + internal fun from(authRuleV2ListResultsPage: AuthRuleV2ListResultsPage) = apply { + service = authRuleV2ListResultsPage.service + params = authRuleV2ListResultsPage.params + response = authRuleV2ListResultsPage.response + } + + fun service(service: V2Service) = apply { this.service = service } + + /** The parameters that were used to request this page. */ + fun params(params: AuthRuleV2ListResultsParams) = apply { this.params = params } + + /** The response that this page was parsed from. */ + fun response(response: AuthRuleV2ListResultsPageResponse) = apply { + this.response = response + } + + /** + * Returns an immutable instance of [AuthRuleV2ListResultsPage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .service() + * .params() + * .response() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuthRuleV2ListResultsPage = + AuthRuleV2ListResultsPage( + checkRequired("service", service), + checkRequired("params", params), + checkRequired("response", response), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthRuleV2ListResultsPage && + service == other.service && + params == other.params && + response == other.response + } + + override fun hashCode(): Int = Objects.hash(service, params, response) + + override fun toString() = + "AuthRuleV2ListResultsPage{service=$service, params=$params, response=$response}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageAsync.kt new file mode 100644 index 00000000..bf7822cf --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageAsync.kt @@ -0,0 +1,209 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.AutoPagerAsync +import com.lithic.api.core.PageAsync +import com.lithic.api.core.checkRequired +import com.lithic.api.services.async.authRules.V2ServiceAsync +import java.util.Objects +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import kotlin.jvm.optionals.getOrNull + +/** @see V2ServiceAsync.listResults */ +class AuthRuleV2ListResultsPageAsync +private constructor( + private val service: V2ServiceAsync, + private val streamHandlerExecutor: Executor, + private val params: AuthRuleV2ListResultsParams, + private val response: AuthRuleV2ListResultsPageResponse, +) : PageAsync { + + /** + * Delegates to [AuthRuleV2ListResultsPageResponse], but gracefully handles missing data. + * + * @see AuthRuleV2ListResultsPageResponse.data + */ + fun data(): List = + response._data().getOptional("data").getOrNull() ?: emptyList() + + /** + * Delegates to [AuthRuleV2ListResultsPageResponse], but gracefully handles missing data. + * + * @see AuthRuleV2ListResultsPageResponse.hasMore + */ + fun hasMore(): Optional = response._hasMore().getOptional("has_more") + + override fun items(): List = data() + + override fun hasNextPage(): Boolean = items().isNotEmpty() + + fun nextPageParams(): AuthRuleV2ListResultsParams = + if (params.endingBefore().isPresent) { + params + .toBuilder() + .endingBefore( + items() + .first() + .accept( + object : V2ListResultsResponse.Visitor> { + override fun visitAuthorizationResult( + authorizationResult: V2ListResultsResponse.AuthorizationResult + ): Optional = + authorizationResult._token().getOptional("token") + + override fun visitAuthentication3dsResult( + authentication3dsResult: + V2ListResultsResponse.Authentication3dsResult + ): Optional = + authentication3dsResult._token().getOptional("token") + + override fun visitTokenizationResult( + tokenizationResult: V2ListResultsResponse.TokenizationResult + ): Optional = + tokenizationResult._token().getOptional("token") + + override fun visitAchResult( + achResult: V2ListResultsResponse.AchResult + ): Optional = achResult._token().getOptional("token") + } + ) + ) + .build() + } else { + params + .toBuilder() + .startingAfter( + items() + .last() + .accept( + object : V2ListResultsResponse.Visitor> { + override fun visitAuthorizationResult( + authorizationResult: V2ListResultsResponse.AuthorizationResult + ): Optional = + authorizationResult._token().getOptional("token") + + override fun visitAuthentication3dsResult( + authentication3dsResult: + V2ListResultsResponse.Authentication3dsResult + ): Optional = + authentication3dsResult._token().getOptional("token") + + override fun visitTokenizationResult( + tokenizationResult: V2ListResultsResponse.TokenizationResult + ): Optional = + tokenizationResult._token().getOptional("token") + + override fun visitAchResult( + achResult: V2ListResultsResponse.AchResult + ): Optional = achResult._token().getOptional("token") + } + ) + ) + .build() + } + + override fun nextPage(): CompletableFuture = + service.listResults(nextPageParams()) + + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) + + /** The parameters that were used to request this page. */ + fun params(): AuthRuleV2ListResultsParams = params + + /** The response that this page was parsed from. */ + fun response(): AuthRuleV2ListResultsPageResponse = response + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [AuthRuleV2ListResultsPageAsync]. + * + * The following fields are required: + * ```java + * .service() + * .streamHandlerExecutor() + * .params() + * .response() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthRuleV2ListResultsPageAsync]. */ + class Builder internal constructor() { + + private var service: V2ServiceAsync? = null + private var streamHandlerExecutor: Executor? = null + private var params: AuthRuleV2ListResultsParams? = null + private var response: AuthRuleV2ListResultsPageResponse? = null + + @JvmSynthetic + internal fun from(authRuleV2ListResultsPageAsync: AuthRuleV2ListResultsPageAsync) = apply { + service = authRuleV2ListResultsPageAsync.service + streamHandlerExecutor = authRuleV2ListResultsPageAsync.streamHandlerExecutor + params = authRuleV2ListResultsPageAsync.params + response = authRuleV2ListResultsPageAsync.response + } + + fun service(service: V2ServiceAsync) = apply { this.service = service } + + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + + /** The parameters that were used to request this page. */ + fun params(params: AuthRuleV2ListResultsParams) = apply { this.params = params } + + /** The response that this page was parsed from. */ + fun response(response: AuthRuleV2ListResultsPageResponse) = apply { + this.response = response + } + + /** + * Returns an immutable instance of [AuthRuleV2ListResultsPageAsync]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .service() + * .streamHandlerExecutor() + * .params() + * .response() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuthRuleV2ListResultsPageAsync = + AuthRuleV2ListResultsPageAsync( + checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), + checkRequired("params", params), + checkRequired("response", response), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthRuleV2ListResultsPageAsync && + service == other.service && + streamHandlerExecutor == other.streamHandlerExecutor && + params == other.params && + response == other.response + } + + override fun hashCode(): Int = Objects.hash(service, streamHandlerExecutor, params, response) + + override fun toString() = + "AuthRuleV2ListResultsPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponse.kt new file mode 100644 index 00000000..4276fd48 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponse.kt @@ -0,0 +1,258 @@ +// 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.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkKnown +import com.lithic.api.core.checkRequired +import com.lithic.api.core.toImmutable +import com.lithic.api.errors.LithicInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +class AuthRuleV2ListResultsPageResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val data: JsonField>, + private val hasMore: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("data") + @ExcludeMissing + data: JsonField> = JsonMissing.of(), + @JsonProperty("has_more") @ExcludeMissing hasMore: JsonField = JsonMissing.of(), + ) : this(data, hasMore, mutableMapOf()) + + /** + * @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 data(): List = data.getRequired("data") + + /** + * Indicates whether there are more results to be retrieved by paging through the results. + * + * @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 hasMore(): Boolean = hasMore.getRequired("has_more") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField> = data + + /** + * Returns the raw JSON value of [hasMore]. + * + * Unlike [hasMore], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("has_more") @ExcludeMissing fun _hasMore(): JsonField = hasMore + + @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 + * [AuthRuleV2ListResultsPageResponse]. + * + * The following fields are required: + * ```java + * .data() + * .hasMore() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthRuleV2ListResultsPageResponse]. */ + class Builder internal constructor() { + + private var data: JsonField>? = null + private var hasMore: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(authRuleV2ListResultsPageResponse: AuthRuleV2ListResultsPageResponse) = + apply { + data = authRuleV2ListResultsPageResponse.data.map { it.toMutableList() } + hasMore = authRuleV2ListResultsPageResponse.hasMore + additionalProperties = + authRuleV2ListResultsPageResponse.additionalProperties.toMutableMap() + } + + fun data(data: List) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun data(data: JsonField>) = apply { + this.data = data.map { it.toMutableList() } + } + + /** + * Adds a single [V2ListResultsResponse] to [Builder.data]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addData(data: V2ListResultsResponse) = apply { + this.data = + (this.data ?: JsonField.of(mutableListOf())).also { + checkKnown("data", it).add(data) + } + } + + /** + * Alias for calling [addData] with + * `V2ListResultsResponse.ofAuthorizationResult(authorizationResult)`. + */ + fun addData(authorizationResult: V2ListResultsResponse.AuthorizationResult) = + addData(V2ListResultsResponse.ofAuthorizationResult(authorizationResult)) + + /** + * Alias for calling [addData] with + * `V2ListResultsResponse.ofAuthentication3dsResult(authentication3dsResult)`. + */ + fun addData(authentication3dsResult: V2ListResultsResponse.Authentication3dsResult) = + addData(V2ListResultsResponse.ofAuthentication3dsResult(authentication3dsResult)) + + /** + * Alias for calling [addData] with + * `V2ListResultsResponse.ofTokenizationResult(tokenizationResult)`. + */ + fun addData(tokenizationResult: V2ListResultsResponse.TokenizationResult) = + addData(V2ListResultsResponse.ofTokenizationResult(tokenizationResult)) + + /** Alias for calling [addData] with `V2ListResultsResponse.ofAchResult(achResult)`. */ + fun addData(achResult: V2ListResultsResponse.AchResult) = + addData(V2ListResultsResponse.ofAchResult(achResult)) + + /** + * Indicates whether there are more results to be retrieved by paging through the results. + */ + fun hasMore(hasMore: Boolean) = hasMore(JsonField.of(hasMore)) + + /** + * Sets [Builder.hasMore] to an arbitrary JSON value. + * + * You should usually call [Builder.hasMore] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun hasMore(hasMore: JsonField) = apply { this.hasMore = hasMore } + + 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 [AuthRuleV2ListResultsPageResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .hasMore() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuthRuleV2ListResultsPageResponse = + AuthRuleV2ListResultsPageResponse( + checkRequired("data", data).map { it.toImmutable() }, + checkRequired("hasMore", hasMore), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AuthRuleV2ListResultsPageResponse = apply { + if (validated) { + return@apply + } + + data().forEach { it.validate() } + hasMore() + 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 = + (data.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (hasMore.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthRuleV2ListResultsPageResponse && + data == other.data && + hasMore == other.hasMore && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(data, hasMore, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AuthRuleV2ListResultsPageResponse{data=$data, hasMore=$hasMore, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParams.kt new file mode 100644 index 00000000..99101e4b --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParams.kt @@ -0,0 +1,323 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.Params +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Lists Auth Rule evaluation results. + * + * **Limitations:** + * - Results are available for the past 3 months only + * - At least one filter (`event_token` or `auth_rule_token`) must be provided + * - When filtering by `event_token`, pagination is not supported + */ +class AuthRuleV2ListResultsParams +private constructor( + private val authRuleToken: String?, + private val endingBefore: String?, + private val eventToken: String?, + private val hasActions: Boolean?, + private val pageSize: Long?, + private val startingAfter: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Filter by Auth Rule token */ + fun authRuleToken(): Optional = Optional.ofNullable(authRuleToken) + + /** + * A cursor representing an item's token before which a page of results should end. Used to + * retrieve the previous page of results before this item. + */ + fun endingBefore(): Optional = Optional.ofNullable(endingBefore) + + /** Filter by event token */ + fun eventToken(): Optional = Optional.ofNullable(eventToken) + + /** + * Filter by whether the rule evaluation produced any actions. When not provided, all results + * are returned. + */ + fun hasActions(): Optional = Optional.ofNullable(hasActions) + + /** Page size (for pagination). */ + fun pageSize(): Optional = Optional.ofNullable(pageSize) + + /** + * A cursor representing an item's token after which a page of results should begin. Used to + * retrieve the next page of results after this item. + */ + fun startingAfter(): Optional = Optional.ofNullable(startingAfter) + + /** 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(): AuthRuleV2ListResultsParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of [AuthRuleV2ListResultsParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthRuleV2ListResultsParams]. */ + class Builder internal constructor() { + + private var authRuleToken: String? = null + private var endingBefore: String? = null + private var eventToken: String? = null + private var hasActions: Boolean? = null + private var pageSize: Long? = null + private var startingAfter: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(authRuleV2ListResultsParams: AuthRuleV2ListResultsParams) = apply { + authRuleToken = authRuleV2ListResultsParams.authRuleToken + endingBefore = authRuleV2ListResultsParams.endingBefore + eventToken = authRuleV2ListResultsParams.eventToken + hasActions = authRuleV2ListResultsParams.hasActions + pageSize = authRuleV2ListResultsParams.pageSize + startingAfter = authRuleV2ListResultsParams.startingAfter + additionalHeaders = authRuleV2ListResultsParams.additionalHeaders.toBuilder() + additionalQueryParams = authRuleV2ListResultsParams.additionalQueryParams.toBuilder() + } + + /** Filter by Auth Rule token */ + fun authRuleToken(authRuleToken: String?) = apply { this.authRuleToken = authRuleToken } + + /** Alias for calling [Builder.authRuleToken] with `authRuleToken.orElse(null)`. */ + fun authRuleToken(authRuleToken: Optional) = + authRuleToken(authRuleToken.getOrNull()) + + /** + * A cursor representing an item's token before which a page of results should end. Used to + * retrieve the previous page of results before this item. + */ + fun endingBefore(endingBefore: String?) = apply { this.endingBefore = endingBefore } + + /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ + fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) + + /** Filter by event token */ + fun eventToken(eventToken: String?) = apply { this.eventToken = eventToken } + + /** Alias for calling [Builder.eventToken] with `eventToken.orElse(null)`. */ + fun eventToken(eventToken: Optional) = eventToken(eventToken.getOrNull()) + + /** + * Filter by whether the rule evaluation produced any actions. When not provided, all + * results are returned. + */ + fun hasActions(hasActions: Boolean?) = apply { this.hasActions = hasActions } + + /** + * Alias for [Builder.hasActions]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun hasActions(hasActions: Boolean) = hasActions(hasActions as Boolean?) + + /** Alias for calling [Builder.hasActions] with `hasActions.orElse(null)`. */ + fun hasActions(hasActions: Optional) = hasActions(hasActions.getOrNull()) + + /** Page size (for pagination). */ + fun pageSize(pageSize: Long?) = apply { this.pageSize = pageSize } + + /** + * Alias for [Builder.pageSize]. + * + * This unboxed primitive overload exists for backwards compatibility. + */ + fun pageSize(pageSize: Long) = pageSize(pageSize as Long?) + + /** Alias for calling [Builder.pageSize] with `pageSize.orElse(null)`. */ + fun pageSize(pageSize: Optional) = pageSize(pageSize.getOrNull()) + + /** + * A cursor representing an item's token after which a page of results should begin. Used to + * retrieve the next page of results after this item. + */ + fun startingAfter(startingAfter: String?) = apply { this.startingAfter = startingAfter } + + /** Alias for calling [Builder.startingAfter] with `startingAfter.orElse(null)`. */ + fun startingAfter(startingAfter: Optional) = + startingAfter(startingAfter.getOrNull()) + + 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 [AuthRuleV2ListResultsParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AuthRuleV2ListResultsParams = + AuthRuleV2ListResultsParams( + authRuleToken, + endingBefore, + eventToken, + hasActions, + pageSize, + startingAfter, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + authRuleToken?.let { put("auth_rule_token", it) } + endingBefore?.let { put("ending_before", it) } + eventToken?.let { put("event_token", it) } + hasActions?.let { put("has_actions", it.toString()) } + pageSize?.let { put("page_size", it.toString()) } + startingAfter?.let { put("starting_after", it) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthRuleV2ListResultsParams && + authRuleToken == other.authRuleToken && + endingBefore == other.endingBefore && + eventToken == other.eventToken && + hasActions == other.hasActions && + pageSize == other.pageSize && + startingAfter == other.startingAfter && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + authRuleToken, + endingBefore, + eventToken, + hasActions, + pageSize, + startingAfter, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "AuthRuleV2ListResultsParams{authRuleToken=$authRuleToken, endingBefore=$endingBefore, eventToken=$eventToken, hasActions=$hasActions, pageSize=$pageSize, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/BookTransferCreateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/BookTransferCreateParams.kt index 5c137b6e..b6127076 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/BookTransferCreateParams.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/BookTransferCreateParams.kt @@ -95,6 +95,14 @@ private constructor( */ fun externalId(): Optional = body.externalId() + /** + * Token of an existing hold to settle when this transfer is initiated + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun holdToken(): Optional = body.holdToken() + /** * Optional descriptor for the transfer. * @@ -169,6 +177,13 @@ private constructor( */ fun _externalId(): JsonField = body._externalId() + /** + * Returns the raw JSON value of [holdToken]. + * + * Unlike [holdToken], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _holdToken(): JsonField = body._holdToken() + /** * Returns the raw JSON value of [memo]. * @@ -351,6 +366,18 @@ private constructor( */ fun externalId(externalId: JsonField) = apply { body.externalId(externalId) } + /** Token of an existing hold to settle when this transfer is initiated */ + fun holdToken(holdToken: String) = apply { body.holdToken(holdToken) } + + /** + * Sets [Builder.holdToken] to an arbitrary JSON value. + * + * You should usually call [Builder.holdToken] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun holdToken(holdToken: JsonField) = apply { body.holdToken(holdToken) } + /** Optional descriptor for the transfer. */ fun memo(memo: String) = apply { body.memo(memo) } @@ -537,6 +564,7 @@ private constructor( private val type: JsonField, private val token: JsonField, private val externalId: JsonField, + private val holdToken: JsonField, private val memo: JsonField, private val onClosedAccount: JsonField, private val additionalProperties: MutableMap, @@ -562,6 +590,9 @@ private constructor( @JsonProperty("external_id") @ExcludeMissing externalId: JsonField = JsonMissing.of(), + @JsonProperty("hold_token") + @ExcludeMissing + holdToken: JsonField = JsonMissing.of(), @JsonProperty("memo") @ExcludeMissing memo: JsonField = JsonMissing.of(), @JsonProperty("on_closed_account") @ExcludeMissing @@ -575,6 +606,7 @@ private constructor( type, token, externalId, + holdToken, memo, onClosedAccount, mutableMapOf(), @@ -648,6 +680,14 @@ private constructor( */ fun externalId(): Optional = externalId.getOptional("external_id") + /** + * Token of an existing hold to settle when this transfer is initiated + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun holdToken(): Optional = holdToken.getOptional("hold_token") + /** * Optional descriptor for the transfer. * @@ -731,6 +771,13 @@ private constructor( @ExcludeMissing fun _externalId(): JsonField = externalId + /** + * Returns the raw JSON value of [holdToken]. + * + * Unlike [holdToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("hold_token") @ExcludeMissing fun _holdToken(): JsonField = holdToken + /** * Returns the raw JSON value of [memo]. * @@ -790,6 +837,7 @@ private constructor( private var type: JsonField? = null private var token: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() + private var holdToken: JsonField = JsonMissing.of() private var memo: JsonField = JsonMissing.of() private var onClosedAccount: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -804,6 +852,7 @@ private constructor( type = createBookTransferRequest.type token = createBookTransferRequest.token externalId = createBookTransferRequest.externalId + holdToken = createBookTransferRequest.holdToken memo = createBookTransferRequest.memo onClosedAccount = createBookTransferRequest.onClosedAccount additionalProperties = createBookTransferRequest.additionalProperties.toMutableMap() @@ -924,6 +973,18 @@ private constructor( */ fun externalId(externalId: JsonField) = apply { this.externalId = externalId } + /** Token of an existing hold to settle when this transfer is initiated */ + fun holdToken(holdToken: String) = holdToken(JsonField.of(holdToken)) + + /** + * Sets [Builder.holdToken] to an arbitrary JSON value. + * + * You should usually call [Builder.holdToken] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun holdToken(holdToken: JsonField) = apply { this.holdToken = holdToken } + /** Optional descriptor for the transfer. */ fun memo(memo: String) = memo(JsonField.of(memo)) @@ -997,6 +1058,7 @@ private constructor( checkRequired("type", type), token, externalId, + holdToken, memo, onClosedAccount, additionalProperties.toMutableMap(), @@ -1018,6 +1080,7 @@ private constructor( type().validate() token() externalId() + holdToken() memo() onClosedAccount().ifPresent { it.validate() } validated = true @@ -1047,6 +1110,7 @@ private constructor( (type.asKnown().getOrNull()?.validity() ?: 0) + (if (token.asKnown().isPresent) 1 else 0) + (if (externalId.asKnown().isPresent) 1 else 0) + + (if (holdToken.asKnown().isPresent) 1 else 0) + (if (memo.asKnown().isPresent) 1 else 0) + (onClosedAccount.asKnown().getOrNull()?.validity() ?: 0) @@ -1064,6 +1128,7 @@ private constructor( type == other.type && token == other.token && externalId == other.externalId && + holdToken == other.holdToken && memo == other.memo && onClosedAccount == other.onClosedAccount && additionalProperties == other.additionalProperties @@ -1079,6 +1144,7 @@ private constructor( type, token, externalId, + holdToken, memo, onClosedAccount, additionalProperties, @@ -1088,7 +1154,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "CreateBookTransferRequest{amount=$amount, category=$category, fromFinancialAccountToken=$fromFinancialAccountToken, subtype=$subtype, toFinancialAccountToken=$toFinancialAccountToken, type=$type, token=$token, externalId=$externalId, memo=$memo, onClosedAccount=$onClosedAccount, additionalProperties=$additionalProperties}" + "CreateBookTransferRequest{amount=$amount, category=$category, fromFinancialAccountToken=$fromFinancialAccountToken, subtype=$subtype, toFinancialAccountToken=$toFinancialAccountToken, type=$type, token=$token, externalId=$externalId, holdToken=$holdToken, memo=$memo, onClosedAccount=$onClosedAccount, additionalProperties=$additionalProperties}" } class BookTransferCategory diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEvent.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEvent.kt index 758a8889..8fcd14ef 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEvent.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEvent.kt @@ -27,6 +27,7 @@ private constructor( private val token: JsonField, private val acquirerFee: JsonField, private val amount: JsonField, + private val amounts: JsonField, private val authorizationAmount: JsonField, private val avs: JsonField, private val card: JsonField, @@ -63,6 +64,7 @@ private constructor( @ExcludeMissing acquirerFee: JsonField = JsonMissing.of(), @JsonProperty("amount") @ExcludeMissing amount: JsonField = JsonMissing.of(), + @JsonProperty("amounts") @ExcludeMissing amounts: JsonField = JsonMissing.of(), @JsonProperty("authorization_amount") @ExcludeMissing authorizationAmount: JsonField = JsonMissing.of(), @@ -129,6 +131,7 @@ private constructor( token, acquirerFee, amount, + amounts, authorizationAmount, avs, card, @@ -176,22 +179,35 @@ private constructor( fun acquirerFee(): Long = acquirerFee.getRequired("acquirer_fee") /** - * Authorization amount of the transaction (in cents), including any acquirer fees. The contents - * of this field are identical to `authorization_amount`. + * Deprecated, use `amounts`. Authorization amount of the transaction (in cents), including any + * acquirer fees. The contents of this field are identical to `authorization_amount`. * * @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 amount(): Long = amount.getRequired("amount") + @Deprecated("deprecated") fun amount(): Long = amount.getRequired("amount") /** - * The base transaction amount (in cents) plus the acquirer fee field. This is the amount the - * issuer should authorize against unless the issuer is paying the acquirer fee on behalf of the - * cardholder. + * Structured amounts for this authorization. The `cardholder` and `merchant` amounts reflect + * the original network authorization values. For programs with hold adjustments enabled (e.g., + * automated fuel dispensers or tipping MCCs), the `hold` amount may exceed the `cardholder` and + * `merchant` amounts to account for anticipated final transaction amounts such as tips or fuel + * fill-ups * * @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 amounts(): Amounts = amounts.getRequired("amounts") + + /** + * Deprecated, use `amounts`. The base transaction amount (in cents) plus the acquirer fee + * field. This is the amount the issuer should authorize against unless the issuer is paying the + * acquirer fee on behalf of the cardholder. + * + * @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). + */ + @Deprecated("deprecated") fun authorizationAmount(): Long = authorizationAmount.getRequired("authorization_amount") /** @@ -209,11 +225,13 @@ private constructor( fun card(): AsaRequestCard = card.getRequired("card") /** - * 3-character alphabetic ISO 4217 code for cardholder's billing currency. + * Deprecated, use `amounts`. 3-character alphabetic ISO 4217 code for cardholder's billing + * currency. * * @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). */ + @Deprecated("deprecated") fun cardholderCurrency(): String = cardholderCurrency.getRequired("cardholder_currency") /** @@ -250,14 +268,15 @@ private constructor( fun merchant(): Merchant = merchant.getRequired("merchant") /** - * The amount that the merchant will receive, denominated in `merchant_currency` and in the - * smallest currency unit. Note the amount includes `acquirer_fee`, similar to - * `authorization_amount`. It will be different from `authorization_amount` if the merchant is - * taking payment in a different currency. + * Deprecated, use `amounts`. The amount that the merchant will receive, denominated in + * `merchant_currency` and in the smallest currency unit. Note the amount includes + * `acquirer_fee`, similar to `authorization_amount`. It will be different from + * `authorization_amount` if the merchant is taking payment in a different currency. * * @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). */ + @Deprecated("deprecated") fun merchantAmount(): Long = merchantAmount.getRequired("merchant_amount") /** @@ -266,14 +285,17 @@ private constructor( * @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). */ + @Deprecated("deprecated") fun merchantCurrency(): String = merchantCurrency.getRequired("merchant_currency") /** - * Amount (in cents) of the transaction that has been settled, including any acquirer fees + * Deprecated, use `amounts`. Amount (in cents) of the transaction that has been settled, + * including any acquirer fees. * * @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). */ + @Deprecated("deprecated") fun settledAmount(): Long = settledAmount.getRequired("settled_amount") /** @@ -317,14 +339,16 @@ private constructor( fun cashback(): Optional = cashback.getOptional("cashback") /** - * If the transaction was requested in a currency other than the settlement currency, this field - * will be populated to indicate the rate used to translate the merchant_amount to the amount - * (i.e., `merchant_amount` x `conversion_rate` = `amount`). Note that the `merchant_amount` is - * in the local currency and the amount is in the settlement currency. + * Deprecated, use `amounts`. If the transaction was requested in a currency other than the + * settlement currency, this field will be populated to indicate the rate used to translate the + * merchant_amount to the amount (i.e., `merchant_amount` x `conversion_rate` = `amount`). Note + * that the `merchant_amount` is in the local currency and the amount is in the settlement + * currency. * * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the * server responded with an unexpected value). */ + @Deprecated("deprecated") fun conversionRate(): Optional = conversionRate.getOptional("conversion_rate") /** @@ -425,7 +449,17 @@ private constructor( * * Unlike [amount], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + @Deprecated("deprecated") + @JsonProperty("amount") + @ExcludeMissing + fun _amount(): JsonField = amount + + /** + * Returns the raw JSON value of [amounts]. + * + * Unlike [amounts], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amounts") @ExcludeMissing fun _amounts(): JsonField = amounts /** * Returns the raw JSON value of [authorizationAmount]. @@ -433,6 +467,7 @@ private constructor( * Unlike [authorizationAmount], this method doesn't throw if the JSON field has an unexpected * type. */ + @Deprecated("deprecated") @JsonProperty("authorization_amount") @ExcludeMissing fun _authorizationAmount(): JsonField = authorizationAmount @@ -457,6 +492,7 @@ private constructor( * Unlike [cardholderCurrency], this method doesn't throw if the JSON field has an unexpected * type. */ + @Deprecated("deprecated") @JsonProperty("cardholder_currency") @ExcludeMissing fun _cardholderCurrency(): JsonField = cardholderCurrency @@ -494,6 +530,7 @@ private constructor( * * Unlike [merchantAmount], this method doesn't throw if the JSON field has an unexpected type. */ + @Deprecated("deprecated") @JsonProperty("merchant_amount") @ExcludeMissing fun _merchantAmount(): JsonField = merchantAmount @@ -504,6 +541,7 @@ private constructor( * Unlike [merchantCurrency], this method doesn't throw if the JSON field has an unexpected * type. */ + @Deprecated("deprecated") @JsonProperty("merchant_currency") @ExcludeMissing fun _merchantCurrency(): JsonField = merchantCurrency @@ -513,6 +551,7 @@ private constructor( * * Unlike [settledAmount], this method doesn't throw if the JSON field has an unexpected type. */ + @Deprecated("deprecated") @JsonProperty("settled_amount") @ExcludeMissing fun _settledAmount(): JsonField = settledAmount @@ -565,6 +604,7 @@ private constructor( * * Unlike [conversionRate], this method doesn't throw if the JSON field has an unexpected type. */ + @Deprecated("deprecated") @JsonProperty("conversion_rate") @ExcludeMissing fun _conversionRate(): JsonField = conversionRate @@ -665,6 +705,7 @@ private constructor( * .token() * .acquirerFee() * .amount() + * .amounts() * .authorizationAmount() * .avs() * .card() @@ -689,6 +730,7 @@ private constructor( private var token: JsonField? = null private var acquirerFee: JsonField? = null private var amount: JsonField? = null + private var amounts: JsonField? = null private var authorizationAmount: JsonField? = null private var avs: JsonField? = null private var card: JsonField? = null @@ -725,6 +767,7 @@ private constructor( token = cardAuthorizationApprovalRequestWebhookEvent.token acquirerFee = cardAuthorizationApprovalRequestWebhookEvent.acquirerFee amount = cardAuthorizationApprovalRequestWebhookEvent.amount + amounts = cardAuthorizationApprovalRequestWebhookEvent.amounts authorizationAmount = cardAuthorizationApprovalRequestWebhookEvent.authorizationAmount avs = cardAuthorizationApprovalRequestWebhookEvent.avs card = cardAuthorizationApprovalRequestWebhookEvent.card @@ -784,10 +827,10 @@ private constructor( fun acquirerFee(acquirerFee: JsonField) = apply { this.acquirerFee = acquirerFee } /** - * Authorization amount of the transaction (in cents), including any acquirer fees. The - * contents of this field are identical to `authorization_amount`. + * Deprecated, use `amounts`. Authorization amount of the transaction (in cents), including + * any acquirer fees. The contents of this field are identical to `authorization_amount`. */ - fun amount(amount: Long) = amount(JsonField.of(amount)) + @Deprecated("deprecated") fun amount(amount: Long) = amount(JsonField.of(amount)) /** * Sets [Builder.amount] to an arbitrary JSON value. @@ -795,13 +838,32 @@ private constructor( * You should usually call [Builder.amount] with a well-typed [Long] value instead. This * method is primarily for setting the field to an undocumented or not yet supported value. */ + @Deprecated("deprecated") fun amount(amount: JsonField) = apply { this.amount = amount } /** - * The base transaction amount (in cents) plus the acquirer fee field. This is the amount - * the issuer should authorize against unless the issuer is paying the acquirer fee on - * behalf of the cardholder. + * Structured amounts for this authorization. The `cardholder` and `merchant` amounts + * reflect the original network authorization values. For programs with hold adjustments + * enabled (e.g., automated fuel dispensers or tipping MCCs), the `hold` amount may exceed + * the `cardholder` and `merchant` amounts to account for anticipated final transaction + * amounts such as tips or fuel fill-ups + */ + fun amounts(amounts: Amounts) = amounts(JsonField.of(amounts)) + + /** + * Sets [Builder.amounts] to an arbitrary JSON value. + * + * You should usually call [Builder.amounts] with a well-typed [Amounts] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun amounts(amounts: JsonField) = apply { this.amounts = amounts } + + /** + * Deprecated, use `amounts`. The base transaction amount (in cents) plus the acquirer fee + * field. This is the amount the issuer should authorize against unless the issuer is paying + * the acquirer fee on behalf of the cardholder. */ + @Deprecated("deprecated") fun authorizationAmount(authorizationAmount: Long) = authorizationAmount(JsonField.of(authorizationAmount)) @@ -812,6 +874,7 @@ private constructor( * instead. This method is primarily for setting the field to an undocumented or not yet * supported value. */ + @Deprecated("deprecated") fun authorizationAmount(authorizationAmount: JsonField) = apply { this.authorizationAmount = authorizationAmount } @@ -838,7 +901,11 @@ private constructor( */ fun card(card: JsonField) = apply { this.card = card } - /** 3-character alphabetic ISO 4217 code for cardholder's billing currency. */ + /** + * Deprecated, use `amounts`. 3-character alphabetic ISO 4217 code for cardholder's billing + * currency. + */ + @Deprecated("deprecated") fun cardholderCurrency(cardholderCurrency: String) = cardholderCurrency(JsonField.of(cardholderCurrency)) @@ -849,6 +916,7 @@ private constructor( * instead. This method is primarily for setting the field to an undocumented or not yet * supported value. */ + @Deprecated("deprecated") fun cardholderCurrency(cardholderCurrency: JsonField) = apply { this.cardholderCurrency = cardholderCurrency } @@ -906,11 +974,12 @@ private constructor( fun merchant(merchant: JsonField) = apply { this.merchant = merchant } /** - * The amount that the merchant will receive, denominated in `merchant_currency` and in the - * smallest currency unit. Note the amount includes `acquirer_fee`, similar to - * `authorization_amount`. It will be different from `authorization_amount` if the merchant - * is taking payment in a different currency. + * Deprecated, use `amounts`. The amount that the merchant will receive, denominated in + * `merchant_currency` and in the smallest currency unit. Note the amount includes + * `acquirer_fee`, similar to `authorization_amount`. It will be different from + * `authorization_amount` if the merchant is taking payment in a different currency. */ + @Deprecated("deprecated") fun merchantAmount(merchantAmount: Long) = merchantAmount(JsonField.of(merchantAmount)) /** @@ -920,11 +989,13 @@ private constructor( * This method is primarily for setting the field to an undocumented or not yet supported * value. */ + @Deprecated("deprecated") fun merchantAmount(merchantAmount: JsonField) = apply { this.merchantAmount = merchantAmount } /** 3-character alphabetic ISO 4217 code for the local currency of the transaction. */ + @Deprecated("deprecated") fun merchantCurrency(merchantCurrency: String) = merchantCurrency(JsonField.of(merchantCurrency)) @@ -935,13 +1006,16 @@ private constructor( * instead. This method is primarily for setting the field to an undocumented or not yet * supported value. */ + @Deprecated("deprecated") fun merchantCurrency(merchantCurrency: JsonField) = apply { this.merchantCurrency = merchantCurrency } /** - * Amount (in cents) of the transaction that has been settled, including any acquirer fees + * Deprecated, use `amounts`. Amount (in cents) of the transaction that has been settled, + * including any acquirer fees. */ + @Deprecated("deprecated") fun settledAmount(settledAmount: Long) = settledAmount(JsonField.of(settledAmount)) /** @@ -951,6 +1025,7 @@ private constructor( * This method is primarily for setting the field to an undocumented or not yet supported * value. */ + @Deprecated("deprecated") fun settledAmount(settledAmount: JsonField) = apply { this.settledAmount = settledAmount } @@ -1025,11 +1100,13 @@ private constructor( fun cashback(cashback: JsonField) = apply { this.cashback = cashback } /** - * If the transaction was requested in a currency other than the settlement currency, this - * field will be populated to indicate the rate used to translate the merchant_amount to the - * amount (i.e., `merchant_amount` x `conversion_rate` = `amount`). Note that the - * `merchant_amount` is in the local currency and the amount is in the settlement currency. + * Deprecated, use `amounts`. If the transaction was requested in a currency other than the + * settlement currency, this field will be populated to indicate the rate used to translate + * the merchant_amount to the amount (i.e., `merchant_amount` x `conversion_rate` = + * `amount`). Note that the `merchant_amount` is in the local currency and the amount is in + * the settlement currency. */ + @Deprecated("deprecated") fun conversionRate(conversionRate: Double) = conversionRate(JsonField.of(conversionRate)) /** @@ -1039,6 +1116,7 @@ private constructor( * instead. This method is primarily for setting the field to an undocumented or not yet * supported value. */ + @Deprecated("deprecated") fun conversionRate(conversionRate: JsonField) = apply { this.conversionRate = conversionRate } @@ -1229,6 +1307,7 @@ private constructor( * .token() * .acquirerFee() * .amount() + * .amounts() * .authorizationAmount() * .avs() * .card() @@ -1251,6 +1330,7 @@ private constructor( checkRequired("token", token), checkRequired("acquirerFee", acquirerFee), checkRequired("amount", amount), + checkRequired("amounts", amounts), checkRequired("authorizationAmount", authorizationAmount), checkRequired("avs", avs), checkRequired("card", card), @@ -1291,6 +1371,7 @@ private constructor( token() acquirerFee() amount() + amounts().validate() authorizationAmount() avs().validate() card().validate() @@ -1338,6 +1419,7 @@ private constructor( (if (token.asKnown().isPresent) 1 else 0) + (if (acquirerFee.asKnown().isPresent) 1 else 0) + (if (amount.asKnown().isPresent) 1 else 0) + + (amounts.asKnown().getOrNull()?.validity() ?: 0) + (if (authorizationAmount.asKnown().isPresent) 1 else 0) + (avs.asKnown().getOrNull()?.validity() ?: 0) + (card.asKnown().getOrNull()?.validity() ?: 0) + @@ -1365,6 +1447,755 @@ private constructor( (tokenInfo.asKnown().getOrNull()?.validity() ?: 0) + (if (ttl.asKnown().isPresent) 1 else 0) + /** + * Structured amounts for this authorization. The `cardholder` and `merchant` amounts reflect + * the original network authorization values. For programs with hold adjustments enabled (e.g., + * automated fuel dispensers or tipping MCCs), the `hold` amount may exceed the `cardholder` and + * `merchant` amounts to account for anticipated final transaction amounts such as tips or fuel + * fill-ups + */ + class Amounts + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val cardholder: JsonField, + private val hold: JsonField, + private val merchant: JsonField, + private val settlement: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("cardholder") + @ExcludeMissing + cardholder: JsonField = JsonMissing.of(), + @JsonProperty("hold") @ExcludeMissing hold: JsonField = JsonMissing.of(), + @JsonProperty("merchant") + @ExcludeMissing + merchant: JsonField = JsonMissing.of(), + @JsonProperty("settlement") + @ExcludeMissing + settlement: JsonField = JsonMissing.of(), + ) : this(cardholder, hold, merchant, settlement, mutableMapOf()) + + /** + * @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 cardholder(): ConvertedAmount = cardholder.getRequired("cardholder") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun hold(): Optional = hold.getOptional("hold") + + /** + * @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 merchant(): Amount = merchant.getRequired("merchant") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun settlement(): Optional = settlement.getOptional("settlement") + + /** + * Returns the raw JSON value of [cardholder]. + * + * Unlike [cardholder], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cardholder") + @ExcludeMissing + fun _cardholder(): JsonField = cardholder + + /** + * Returns the raw JSON value of [hold]. + * + * Unlike [hold], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("hold") @ExcludeMissing fun _hold(): JsonField = hold + + /** + * Returns the raw JSON value of [merchant]. + * + * Unlike [merchant], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("merchant") @ExcludeMissing fun _merchant(): JsonField = merchant + + /** + * Returns the raw JSON value of [settlement]. + * + * Unlike [settlement], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("settlement") + @ExcludeMissing + fun _settlement(): JsonField = settlement + + @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 [Amounts]. + * + * The following fields are required: + * ```java + * .cardholder() + * .hold() + * .merchant() + * .settlement() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Amounts]. */ + class Builder internal constructor() { + + private var cardholder: JsonField? = null + private var hold: JsonField? = null + private var merchant: JsonField? = null + private var settlement: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(amounts: Amounts) = apply { + cardholder = amounts.cardholder + hold = amounts.hold + merchant = amounts.merchant + settlement = amounts.settlement + additionalProperties = amounts.additionalProperties.toMutableMap() + } + + fun cardholder(cardholder: ConvertedAmount) = cardholder(JsonField.of(cardholder)) + + /** + * Sets [Builder.cardholder] to an arbitrary JSON value. + * + * You should usually call [Builder.cardholder] with a well-typed [ConvertedAmount] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun cardholder(cardholder: JsonField) = apply { + this.cardholder = cardholder + } + + fun hold(hold: Amount?) = hold(JsonField.ofNullable(hold)) + + /** Alias for calling [Builder.hold] with `hold.orElse(null)`. */ + fun hold(hold: Optional) = hold(hold.getOrNull()) + + /** + * Sets [Builder.hold] to an arbitrary JSON value. + * + * You should usually call [Builder.hold] with a well-typed [Amount] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun hold(hold: JsonField) = apply { this.hold = hold } + + fun merchant(merchant: Amount) = merchant(JsonField.of(merchant)) + + /** + * Sets [Builder.merchant] to an arbitrary JSON value. + * + * You should usually call [Builder.merchant] with a well-typed [Amount] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun merchant(merchant: JsonField) = apply { this.merchant = merchant } + + fun settlement(settlement: Amount?) = settlement(JsonField.ofNullable(settlement)) + + /** Alias for calling [Builder.settlement] with `settlement.orElse(null)`. */ + fun settlement(settlement: Optional) = settlement(settlement.getOrNull()) + + /** + * Sets [Builder.settlement] to an arbitrary JSON value. + * + * You should usually call [Builder.settlement] with a well-typed [Amount] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun settlement(settlement: JsonField) = apply { this.settlement = settlement } + + 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 [Amounts]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .cardholder() + * .hold() + * .merchant() + * .settlement() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Amounts = + Amounts( + checkRequired("cardholder", cardholder), + checkRequired("hold", hold), + checkRequired("merchant", merchant), + checkRequired("settlement", settlement), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Amounts = apply { + if (validated) { + return@apply + } + + cardholder().validate() + hold().ifPresent { it.validate() } + merchant().validate() + settlement().ifPresent { it.validate() } + 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 = + (cardholder.asKnown().getOrNull()?.validity() ?: 0) + + (hold.asKnown().getOrNull()?.validity() ?: 0) + + (merchant.asKnown().getOrNull()?.validity() ?: 0) + + (settlement.asKnown().getOrNull()?.validity() ?: 0) + + class ConvertedAmount + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val amount: JsonField, + private val conversionRate: JsonField, + private val currency: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("amount") @ExcludeMissing amount: JsonField = JsonMissing.of(), + @JsonProperty("conversion_rate") + @ExcludeMissing + conversionRate: JsonField = JsonMissing.of(), + @JsonProperty("currency") + @ExcludeMissing + currency: JsonField = JsonMissing.of(), + ) : this(amount, conversionRate, currency, mutableMapOf()) + + /** + * Amount in the smallest unit of the applicable currency (e.g., cents) + * + * @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 amount(): Long = amount.getRequired("amount") + + /** + * Exchange rate used for currency conversion + * + * @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 conversionRate(): String = conversionRate.getRequired("conversion_rate") + + /** + * 3-character alphabetic ISO 4217 currency + * + * @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 currency(): String = currency.getRequired("currency") + + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + + /** + * Returns the raw JSON value of [conversionRate]. + * + * Unlike [conversionRate], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("conversion_rate") + @ExcludeMissing + fun _conversionRate(): JsonField = conversionRate + + /** + * Returns the raw JSON value of [currency]. + * + * Unlike [currency], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("currency") @ExcludeMissing fun _currency(): JsonField = currency + + @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 [ConvertedAmount]. + * + * The following fields are required: + * ```java + * .amount() + * .conversionRate() + * .currency() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ConvertedAmount]. */ + class Builder internal constructor() { + + private var amount: JsonField? = null + private var conversionRate: JsonField? = null + private var currency: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(convertedAmount: ConvertedAmount) = apply { + amount = convertedAmount.amount + conversionRate = convertedAmount.conversionRate + currency = convertedAmount.currency + additionalProperties = convertedAmount.additionalProperties.toMutableMap() + } + + /** Amount in the smallest unit of the applicable currency (e.g., cents) */ + fun amount(amount: Long) = amount(JsonField.of(amount)) + + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } + + /** Exchange rate used for currency conversion */ + fun conversionRate(conversionRate: String) = + conversionRate(JsonField.of(conversionRate)) + + /** + * Sets [Builder.conversionRate] to an arbitrary JSON value. + * + * You should usually call [Builder.conversionRate] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun conversionRate(conversionRate: JsonField) = apply { + this.conversionRate = conversionRate + } + + /** 3-character alphabetic ISO 4217 currency */ + fun currency(currency: String) = currency(JsonField.of(currency)) + + /** + * Sets [Builder.currency] to an arbitrary JSON value. + * + * You should usually call [Builder.currency] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun currency(currency: JsonField) = apply { this.currency = currency } + + 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 [ConvertedAmount]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .amount() + * .conversionRate() + * .currency() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ConvertedAmount = + ConvertedAmount( + checkRequired("amount", amount), + checkRequired("conversionRate", conversionRate), + checkRequired("currency", currency), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ConvertedAmount = apply { + if (validated) { + return@apply + } + + amount() + conversionRate() + currency() + 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 (amount.asKnown().isPresent) 1 else 0) + + (if (conversionRate.asKnown().isPresent) 1 else 0) + + (if (currency.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ConvertedAmount && + amount == other.amount && + conversionRate == other.conversionRate && + currency == other.currency && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(amount, conversionRate, currency, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ConvertedAmount{amount=$amount, conversionRate=$conversionRate, currency=$currency, additionalProperties=$additionalProperties}" + } + + class Amount + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val amount: JsonField, + private val currency: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("amount") @ExcludeMissing amount: JsonField = JsonMissing.of(), + @JsonProperty("currency") + @ExcludeMissing + currency: JsonField = JsonMissing.of(), + ) : this(amount, currency, mutableMapOf()) + + /** + * Amount in the smallest unit of the applicable currency (e.g., cents) + * + * @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 amount(): Long = amount.getRequired("amount") + + /** + * 3-character alphabetic ISO 4217 currency + * + * @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 currency(): String = currency.getRequired("currency") + + /** + * Returns the raw JSON value of [amount]. + * + * Unlike [amount], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("amount") @ExcludeMissing fun _amount(): JsonField = amount + + /** + * Returns the raw JSON value of [currency]. + * + * Unlike [currency], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("currency") @ExcludeMissing fun _currency(): JsonField = currency + + @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 [Amount]. + * + * The following fields are required: + * ```java + * .amount() + * .currency() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Amount]. */ + class Builder internal constructor() { + + private var amount: JsonField? = null + private var currency: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(amount: Amount) = apply { + this.amount = amount.amount + currency = amount.currency + additionalProperties = amount.additionalProperties.toMutableMap() + } + + /** Amount in the smallest unit of the applicable currency (e.g., cents) */ + fun amount(amount: Long) = amount(JsonField.of(amount)) + + /** + * Sets [Builder.amount] to an arbitrary JSON value. + * + * You should usually call [Builder.amount] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun amount(amount: JsonField) = apply { this.amount = amount } + + /** 3-character alphabetic ISO 4217 currency */ + fun currency(currency: String) = currency(JsonField.of(currency)) + + /** + * Sets [Builder.currency] to an arbitrary JSON value. + * + * You should usually call [Builder.currency] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun currency(currency: JsonField) = apply { this.currency = currency } + + 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 [Amount]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .amount() + * .currency() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Amount = + Amount( + checkRequired("amount", amount), + checkRequired("currency", currency), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Amount = apply { + if (validated) { + return@apply + } + + amount() + currency() + 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 (amount.asKnown().isPresent) 1 else 0) + + (if (currency.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Amount && + amount == other.amount && + currency == other.currency && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(amount, currency, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Amount{amount=$amount, currency=$currency, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Amounts && + cardholder == other.cardholder && + hold == other.hold && + merchant == other.merchant && + settlement == other.settlement && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(cardholder, hold, merchant, settlement, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Amounts{cardholder=$cardholder, hold=$hold, merchant=$merchant, settlement=$settlement, additionalProperties=$additionalProperties}" + } + class Avs @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( @@ -7410,6 +8241,7 @@ private constructor( token == other.token && acquirerFee == other.acquirerFee && amount == other.amount && + amounts == other.amounts && authorizationAmount == other.authorizationAmount && avs == other.avs && card == other.card && @@ -7444,6 +8276,7 @@ private constructor( token, acquirerFee, amount, + amounts, authorizationAmount, avs, card, @@ -7477,5 +8310,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "CardAuthorizationApprovalRequestWebhookEvent{token=$token, acquirerFee=$acquirerFee, amount=$amount, authorizationAmount=$authorizationAmount, avs=$avs, card=$card, cardholderCurrency=$cardholderCurrency, cashAmount=$cashAmount, created=$created, eventType=$eventType, merchant=$merchant, merchantAmount=$merchantAmount, merchantCurrency=$merchantCurrency, settledAmount=$settledAmount, status=$status, transactionInitiator=$transactionInitiator, accountType=$accountType, cardholderAuthentication=$cardholderAuthentication, cashback=$cashback, conversionRate=$conversionRate, eventToken=$eventToken, fleetInfo=$fleetInfo, latestChallenge=$latestChallenge, network=$network, networkRiskScore=$networkRiskScore, networkSpecificData=$networkSpecificData, pos=$pos, tokenInfo=$tokenInfo, ttl=$ttl, additionalProperties=$additionalProperties}" + "CardAuthorizationApprovalRequestWebhookEvent{token=$token, acquirerFee=$acquirerFee, amount=$amount, amounts=$amounts, authorizationAmount=$authorizationAmount, avs=$avs, card=$card, cardholderCurrency=$cardholderCurrency, cashAmount=$cashAmount, created=$created, eventType=$eventType, merchant=$merchant, merchantAmount=$merchantAmount, merchantCurrency=$merchantCurrency, settledAmount=$settledAmount, status=$status, transactionInitiator=$transactionInitiator, accountType=$accountType, cardholderAuthentication=$cardholderAuthentication, cashback=$cashback, conversionRate=$conversionRate, eventToken=$eventToken, fleetInfo=$fleetInfo, latestChallenge=$latestChallenge, network=$network, networkRiskScore=$networkRiskScore, networkSpecificData=$networkSpecificData, pos=$pos, tokenInfo=$tokenInfo, ttl=$ttl, additionalProperties=$additionalProperties}" } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Conditional3dsActionParameters.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Conditional3dsActionParameters.kt index dac7a079..df68c5f7 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Conditional3dsActionParameters.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Conditional3dsActionParameters.kt @@ -23,14 +23,16 @@ import kotlin.jvm.optionals.getOrNull class Conditional3dsActionParameters @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val action: JsonField, + private val action: JsonField, private val conditions: JsonField>, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("action") @ExcludeMissing action: JsonField = JsonMissing.of(), + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), @JsonProperty("conditions") @ExcludeMissing conditions: JsonField> = JsonMissing.of(), @@ -42,7 +44,7 @@ private constructor( * @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 action(): Action = action.getRequired("action") + fun action(): Authentication3dsAction = action.getRequired("action") /** * @throws LithicInvalidDataException if the JSON field has an unexpected type or is @@ -55,7 +57,9 @@ private constructor( * * Unlike [action], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + @JsonProperty("action") + @ExcludeMissing + fun _action(): JsonField = action /** * Returns the raw JSON value of [conditions]. @@ -96,7 +100,7 @@ private constructor( /** A builder for [Conditional3dsActionParameters]. */ class Builder internal constructor() { - private var action: JsonField? = null + private var action: JsonField? = null private var conditions: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @@ -109,15 +113,16 @@ private constructor( } /** The action to take if the conditions are met. */ - fun action(action: Action) = action(JsonField.of(action)) + fun action(action: Authentication3dsAction) = action(JsonField.of(action)) /** * Sets [Builder.action] to an arbitrary JSON value. * - * You should usually call [Builder.action] with a well-typed [Action] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * You should usually call [Builder.action] with a well-typed [Authentication3dsAction] + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. */ - fun action(action: JsonField) = apply { this.action = action } + fun action(action: JsonField) = apply { this.action = action } fun conditions(conditions: List) = conditions(JsonField.of(conditions)) @@ -215,7 +220,9 @@ private constructor( (conditions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) /** The action to take if the conditions are met. */ - class Action @JsonCreator private constructor(private val value: JsonField) : Enum { + class Authentication3dsAction + @JsonCreator + private constructor(private val value: JsonField) : Enum { /** * Returns this class instance's raw value. @@ -233,19 +240,21 @@ private constructor( @JvmField val CHALLENGE = of("CHALLENGE") - @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + @JvmStatic fun of(value: String) = Authentication3dsAction(JsonField.of(value)) } - /** An enum containing [Action]'s known values. */ + /** An enum containing [Authentication3dsAction]'s known values. */ enum class Known { DECLINE, CHALLENGE, } /** - * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * An enum containing [Authentication3dsAction]'s known values, as well as an [_UNKNOWN] + * member. * - * An instance of [Action] can contain an unknown value in a couple of cases: + * An instance of [Authentication3dsAction] 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. @@ -254,7 +263,10 @@ private constructor( enum class Value { DECLINE, CHALLENGE, - /** An enum member indicating that [Action] was instantiated with an unknown value. */ + /** + * An enum member indicating that [Authentication3dsAction] was instantiated with an + * unknown value. + */ _UNKNOWN, } @@ -285,7 +297,7 @@ private constructor( when (this) { DECLINE -> Known.DECLINE CHALLENGE -> Known.CHALLENGE - else -> throw LithicInvalidDataException("Unknown Action: $value") + else -> throw LithicInvalidDataException("Unknown Authentication3dsAction: $value") } /** @@ -302,7 +314,7 @@ private constructor( private var validated: Boolean = false - fun validate(): Action = apply { + fun validate(): Authentication3dsAction = apply { if (validated) { return@apply } @@ -332,7 +344,7 @@ private constructor( return true } - return other is Action && value == other.value + return other is Authentication3dsAction && value == other.value } override fun hashCode() = value.hashCode() diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAchActionParameters.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAchActionParameters.kt index cebf84be..a1bb64f6 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAchActionParameters.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAchActionParameters.kt @@ -49,7 +49,7 @@ private constructor( ) : this(action, conditions, mutableMapOf()) /** - * The action to take if the conditions are met + * The action to take if the conditions are met. * * @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). @@ -120,7 +120,7 @@ private constructor( conditionalAchActionParameters.additionalProperties.toMutableMap() } - /** The action to take if the conditions are met */ + /** The action to take if the conditions are met. */ fun action(action: Action) = action(JsonField.of(action)) /** @@ -232,7 +232,7 @@ private constructor( (action.asKnown().getOrNull()?.validity() ?: 0) + (conditions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) - /** The action to take if the conditions are met */ + /** The action to take if the conditions are met. */ @JsonDeserialize(using = Action.Deserializer::class) @JsonSerialize(using = Action.Serializer::class) class Action diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParameters.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParameters.kt index 183eefd7..95e9bcdc 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParameters.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParameters.kt @@ -23,14 +23,16 @@ import kotlin.jvm.optionals.getOrNull class ConditionalAuthorizationActionParameters @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( - private val action: JsonField, + private val action: JsonField, private val conditions: JsonField>, private val additionalProperties: MutableMap, ) { @JsonCreator private constructor( - @JsonProperty("action") @ExcludeMissing action: JsonField = JsonMissing.of(), + @JsonProperty("action") + @ExcludeMissing + action: JsonField = JsonMissing.of(), @JsonProperty("conditions") @ExcludeMissing conditions: JsonField> = JsonMissing.of(), @@ -42,7 +44,7 @@ private constructor( * @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 action(): Action = action.getRequired("action") + fun action(): AuthorizationAction = action.getRequired("action") /** * @throws LithicInvalidDataException if the JSON field has an unexpected type or is @@ -55,7 +57,7 @@ private constructor( * * Unlike [action], this method doesn't throw if the JSON field has an unexpected type. */ - @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action + @JsonProperty("action") @ExcludeMissing fun _action(): JsonField = action /** * Returns the raw JSON value of [conditions]. @@ -96,7 +98,7 @@ private constructor( /** A builder for [ConditionalAuthorizationActionParameters]. */ class Builder internal constructor() { - private var action: JsonField? = null + private var action: JsonField? = null private var conditions: JsonField>? = null private var additionalProperties: MutableMap = mutableMapOf() @@ -112,15 +114,16 @@ private constructor( } /** The action to take if the conditions are met. */ - fun action(action: Action) = action(JsonField.of(action)) + fun action(action: AuthorizationAction) = action(JsonField.of(action)) /** * Sets [Builder.action] to an arbitrary JSON value. * - * You should usually call [Builder.action] with a well-typed [Action] value instead. This - * method is primarily for setting the field to an undocumented or not yet supported value. + * You should usually call [Builder.action] with a well-typed [AuthorizationAction] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. */ - fun action(action: JsonField) = apply { this.action = action } + fun action(action: JsonField) = apply { this.action = action } fun conditions(conditions: List) = conditions(JsonField.of(conditions)) @@ -218,7 +221,9 @@ private constructor( (conditions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) /** The action to take if the conditions are met. */ - class Action @JsonCreator private constructor(private val value: JsonField) : Enum { + class AuthorizationAction + @JsonCreator + private constructor(private val value: JsonField) : Enum { /** * Returns this class instance's raw value. @@ -236,19 +241,19 @@ private constructor( @JvmField val CHALLENGE = of("CHALLENGE") - @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + @JvmStatic fun of(value: String) = AuthorizationAction(JsonField.of(value)) } - /** An enum containing [Action]'s known values. */ + /** An enum containing [AuthorizationAction]'s known values. */ enum class Known { DECLINE, CHALLENGE, } /** - * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * An enum containing [AuthorizationAction]'s known values, as well as an [_UNKNOWN] member. * - * An instance of [Action] can contain an unknown value in a couple of cases: + * An instance of [AuthorizationAction] 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. @@ -257,7 +262,10 @@ private constructor( enum class Value { DECLINE, CHALLENGE, - /** An enum member indicating that [Action] was instantiated with an unknown value. */ + /** + * An enum member indicating that [AuthorizationAction] was instantiated with an unknown + * value. + */ _UNKNOWN, } @@ -288,7 +296,7 @@ private constructor( when (this) { DECLINE -> Known.DECLINE CHALLENGE -> Known.CHALLENGE - else -> throw LithicInvalidDataException("Unknown Action: $value") + else -> throw LithicInvalidDataException("Unknown AuthorizationAction: $value") } /** @@ -305,7 +313,7 @@ private constructor( private var validated: Boolean = false - fun validate(): Action = apply { + fun validate(): AuthorizationAction = apply { if (validated) { return@apply } @@ -335,7 +343,7 @@ private constructor( return true } - return other is Action && value == other.value + return other is AuthorizationAction && value == other.value } override fun hashCode() = value.hashCode() diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalTokenizationActionParameters.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalTokenizationActionParameters.kt index 9d9781ec..b7d6aa59 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalTokenizationActionParameters.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ConditionalTokenizationActionParameters.kt @@ -49,7 +49,7 @@ private constructor( ) : this(action, conditions, mutableMapOf()) /** - * The action to take if the conditions are met + * The action to take if the conditions are met. * * @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). @@ -123,7 +123,7 @@ private constructor( conditionalTokenizationActionParameters.additionalProperties.toMutableMap() } - /** The action to take if the conditions are met */ + /** The action to take if the conditions are met. */ fun action(action: Action) = action(JsonField.of(action)) /** @@ -235,7 +235,7 @@ private constructor( (action.asKnown().getOrNull()?.validity() ?: 0) + (conditions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) - /** The action to take if the conditions are met */ + /** The action to take if the conditions are met. */ @JsonDeserialize(using = Action.Deserializer::class) @JsonSerialize(using = Action.Serializer::class) class Action @@ -1501,8 +1501,10 @@ private constructor( * The following attributes may be targeted: * * `TIMESTAMP`: The timestamp of the tokenization request in ISO 8601 format. * * `TOKENIZATION_CHANNEL`: The channel through which the tokenization request was - * initiated (e.g., DIGITAL_WALLET, ECOMMERCE). - * * `TOKENIZATION_SOURCE`: The source of the tokenization request. + * initiated. Valid values are `DIGITAL_WALLET`, `MERCHANT`. + * * `TOKENIZATION_SOURCE`: The source of the tokenization request. Valid values are + * `ACCOUNT_ON_FILE`, `MANUAL_PROVISION`, `PUSH_PROVISION`, `CHIP_DIP`, `CONTACTLESS_TAP`, + * `TOKEN`, `UNKNOWN`. * * `TOKEN_REQUESTOR_NAME`: The name of the entity requesting the token. Valid values are * `ALT_ID`, `AMAZON_ONE`, `AMERICAN_EXPRESS_TOKEN_SERVICE`, `ANDROID_PAY`, `APPLE_PAY`, * `FACEBOOK`, `FITBIT_PAY`, `GARMIN_PAY`, `GOOGLE_PAY`, `GOOGLE_VCN`, `ISSUER_HCE`, @@ -1514,12 +1516,21 @@ private constructor( * * `WALLET_RECOMMENDED_DECISION`: The decision recommended by the digital wallet provider. * Valid values include APPROVE, DECLINE, REQUIRE_ADDITIONAL_AUTHENTICATION. * * `WALLET_RECOMMENDATION_REASONS`: List of reasons provided by the digital wallet - * provider for the recommended decision. Valid values are `ACCOUNT_CARD_TOO_NEW`, - * `ACCOUNT_RECENTLY_CHANGED`, `ACCOUNT_TOO_NEW`, `ACCOUNT_TOO_NEW_SINCE_LAUNCH`, - * `DEVICE_RECENTLY_LOST`, `HAS_SUSPENDED_TOKENS`, `HIGH_RISK`, `INACTIVE_ACCOUNT`, - * `LOW_ACCOUNT_SCORE`, `LOW_DEVICE_SCORE`, `OUTSIDE_HOME_TERRITORY`, - * `SUSPICIOUS_ACTIVITY`, `TOO_MANY_DIFFERENT_CARDHOLDERS`, `TOO_MANY_RECENT_ATTEMPTS`, - * `TOO_MANY_RECENT_TOKENS`, `UNABLE_TO_ASSESS`. + * provider for the recommended decision. Valid values are: + * - Common: `ACCOUNT_CARD_TOO_NEW`, `ACCOUNT_RECENTLY_CHANGED`, `ACCOUNT_TOO_NEW`, + * `ACCOUNT_TOO_NEW_SINCE_LAUNCH`, `DEVICE_RECENTLY_LOST`, `HAS_SUSPENDED_TOKENS`, + * `HIGH_RISK`, `INACTIVE_ACCOUNT`, `LOW_ACCOUNT_SCORE`, `LOW_DEVICE_SCORE`, + * `OUTSIDE_HOME_TERRITORY`, `SUSPICIOUS_ACTIVITY`, `TOO_MANY_DIFFERENT_CARDHOLDERS`, + * `TOO_MANY_RECENT_ATTEMPTS`, `TOO_MANY_RECENT_TOKENS`, `UNABLE_TO_ASSESS` + * - Visa only: `ACCOUNT_DATA_RECENTLY_CHANGED`, `ACCOUNT_PAN_PAIRING_TOO_NEW`, + * `LOW_TRANSACTION_VOLUME`, `USER_ACCOUNT_DEVICE_TOO_NEW`, `WALLET_ACCOUNT_TOO_NEW` + * - Amex only: `DEVICE_USING_VPN_PROXY`, `EXCESSIVE_BILLING_NAME_ATTEMPTS_MODERATE`, + * `EXCESSIVE_BILLING_NAME_ATTEMPTS_SEVERE`, + * `EXCESSIVE_CARD_PROVISION_ATTEMPTS_MODERATE`, + * `EXCESSIVE_CARD_PROVISION_ATTEMPTS_SEVERE`, `EXCESSIVE_WALLET_RESETS`, + * `EXCESSIVE_ZIP_ATTEMPTS_MODERATE`, `EXCESSIVE_ZIP_ATTEMPTS_SEVERE`, + * `USER_ID_CARD_PAIRING_TOO_NEW`, `USER_ID_DEVICE_ID_PAIRING_TOO_NEW`, + * `USER_ID_OS_ID_PAIRING_TOO_NEW`, `USER_ID_TOO_NEW` * * `TOKEN_REQUESTOR_ID`: Unique identifier for the entity requesting the token. * * `WALLET_TOKEN_STATUS`: The current status of the wallet token. * * `CARD_STATE`: The state of the card being tokenized. Valid values are `CLOSED`, `OPEN`, @@ -1620,8 +1631,10 @@ private constructor( * The following attributes may be targeted: * * `TIMESTAMP`: The timestamp of the tokenization request in ISO 8601 format. * * `TOKENIZATION_CHANNEL`: The channel through which the tokenization request was - * initiated (e.g., DIGITAL_WALLET, ECOMMERCE). - * * `TOKENIZATION_SOURCE`: The source of the tokenization request. + * initiated. Valid values are `DIGITAL_WALLET`, `MERCHANT`. + * * `TOKENIZATION_SOURCE`: The source of the tokenization request. Valid values are + * `ACCOUNT_ON_FILE`, `MANUAL_PROVISION`, `PUSH_PROVISION`, `CHIP_DIP`, + * `CONTACTLESS_TAP`, `TOKEN`, `UNKNOWN`. * * `TOKEN_REQUESTOR_NAME`: The name of the entity requesting the token. Valid values * are `ALT_ID`, `AMAZON_ONE`, `AMERICAN_EXPRESS_TOKEN_SERVICE`, `ANDROID_PAY`, * `APPLE_PAY`, `FACEBOOK`, `FITBIT_PAY`, `GARMIN_PAY`, `GOOGLE_PAY`, `GOOGLE_VCN`, @@ -1636,12 +1649,24 @@ private constructor( * * `WALLET_RECOMMENDED_DECISION`: The decision recommended by the digital wallet * provider. Valid values include APPROVE, DECLINE, REQUIRE_ADDITIONAL_AUTHENTICATION. * * `WALLET_RECOMMENDATION_REASONS`: List of reasons provided by the digital wallet - * provider for the recommended decision. Valid values are `ACCOUNT_CARD_TOO_NEW`, - * `ACCOUNT_RECENTLY_CHANGED`, `ACCOUNT_TOO_NEW`, `ACCOUNT_TOO_NEW_SINCE_LAUNCH`, - * `DEVICE_RECENTLY_LOST`, `HAS_SUSPENDED_TOKENS`, `HIGH_RISK`, `INACTIVE_ACCOUNT`, - * `LOW_ACCOUNT_SCORE`, `LOW_DEVICE_SCORE`, `OUTSIDE_HOME_TERRITORY`, - * `SUSPICIOUS_ACTIVITY`, `TOO_MANY_DIFFERENT_CARDHOLDERS`, - * `TOO_MANY_RECENT_ATTEMPTS`, `TOO_MANY_RECENT_TOKENS`, `UNABLE_TO_ASSESS`. + * provider for the recommended decision. Valid values are: + * - Common: `ACCOUNT_CARD_TOO_NEW`, `ACCOUNT_RECENTLY_CHANGED`, `ACCOUNT_TOO_NEW`, + * `ACCOUNT_TOO_NEW_SINCE_LAUNCH`, `DEVICE_RECENTLY_LOST`, `HAS_SUSPENDED_TOKENS`, + * `HIGH_RISK`, `INACTIVE_ACCOUNT`, `LOW_ACCOUNT_SCORE`, `LOW_DEVICE_SCORE`, + * `OUTSIDE_HOME_TERRITORY`, `SUSPICIOUS_ACTIVITY`, + * `TOO_MANY_DIFFERENT_CARDHOLDERS`, `TOO_MANY_RECENT_ATTEMPTS`, + * `TOO_MANY_RECENT_TOKENS`, `UNABLE_TO_ASSESS` + * - Visa only: `ACCOUNT_DATA_RECENTLY_CHANGED`, `ACCOUNT_PAN_PAIRING_TOO_NEW`, + * `LOW_TRANSACTION_VOLUME`, `USER_ACCOUNT_DEVICE_TOO_NEW`, + * `WALLET_ACCOUNT_TOO_NEW` + * - Amex only: `DEVICE_USING_VPN_PROXY`, + * `EXCESSIVE_BILLING_NAME_ATTEMPTS_MODERATE`, + * `EXCESSIVE_BILLING_NAME_ATTEMPTS_SEVERE`, + * `EXCESSIVE_CARD_PROVISION_ATTEMPTS_MODERATE`, + * `EXCESSIVE_CARD_PROVISION_ATTEMPTS_SEVERE`, `EXCESSIVE_WALLET_RESETS`, + * `EXCESSIVE_ZIP_ATTEMPTS_MODERATE`, `EXCESSIVE_ZIP_ATTEMPTS_SEVERE`, + * `USER_ID_CARD_PAIRING_TOO_NEW`, `USER_ID_DEVICE_ID_PAIRING_TOO_NEW`, + * `USER_ID_OS_ID_PAIRING_TOO_NEW`, `USER_ID_TOO_NEW` * * `TOKEN_REQUESTOR_ID`: Unique identifier for the entity requesting the token. * * `WALLET_TOKEN_STATUS`: The current status of the wallet token. * * `CARD_STATE`: The state of the card being tokenized. Valid values are `CLOSED`, @@ -1778,8 +1803,10 @@ private constructor( * The following attributes may be targeted: * * `TIMESTAMP`: The timestamp of the tokenization request in ISO 8601 format. * * `TOKENIZATION_CHANNEL`: The channel through which the tokenization request was - * initiated (e.g., DIGITAL_WALLET, ECOMMERCE). - * * `TOKENIZATION_SOURCE`: The source of the tokenization request. + * initiated. Valid values are `DIGITAL_WALLET`, `MERCHANT`. + * * `TOKENIZATION_SOURCE`: The source of the tokenization request. Valid values are + * `ACCOUNT_ON_FILE`, `MANUAL_PROVISION`, `PUSH_PROVISION`, `CHIP_DIP`, `CONTACTLESS_TAP`, + * `TOKEN`, `UNKNOWN`. * * `TOKEN_REQUESTOR_NAME`: The name of the entity requesting the token. Valid values are * `ALT_ID`, `AMAZON_ONE`, `AMERICAN_EXPRESS_TOKEN_SERVICE`, `ANDROID_PAY`, `APPLE_PAY`, * `FACEBOOK`, `FITBIT_PAY`, `GARMIN_PAY`, `GOOGLE_PAY`, `GOOGLE_VCN`, `ISSUER_HCE`, @@ -1791,12 +1818,21 @@ private constructor( * * `WALLET_RECOMMENDED_DECISION`: The decision recommended by the digital wallet provider. * Valid values include APPROVE, DECLINE, REQUIRE_ADDITIONAL_AUTHENTICATION. * * `WALLET_RECOMMENDATION_REASONS`: List of reasons provided by the digital wallet - * provider for the recommended decision. Valid values are `ACCOUNT_CARD_TOO_NEW`, - * `ACCOUNT_RECENTLY_CHANGED`, `ACCOUNT_TOO_NEW`, `ACCOUNT_TOO_NEW_SINCE_LAUNCH`, - * `DEVICE_RECENTLY_LOST`, `HAS_SUSPENDED_TOKENS`, `HIGH_RISK`, `INACTIVE_ACCOUNT`, - * `LOW_ACCOUNT_SCORE`, `LOW_DEVICE_SCORE`, `OUTSIDE_HOME_TERRITORY`, - * `SUSPICIOUS_ACTIVITY`, `TOO_MANY_DIFFERENT_CARDHOLDERS`, `TOO_MANY_RECENT_ATTEMPTS`, - * `TOO_MANY_RECENT_TOKENS`, `UNABLE_TO_ASSESS`. + * provider for the recommended decision. Valid values are: + * - Common: `ACCOUNT_CARD_TOO_NEW`, `ACCOUNT_RECENTLY_CHANGED`, `ACCOUNT_TOO_NEW`, + * `ACCOUNT_TOO_NEW_SINCE_LAUNCH`, `DEVICE_RECENTLY_LOST`, `HAS_SUSPENDED_TOKENS`, + * `HIGH_RISK`, `INACTIVE_ACCOUNT`, `LOW_ACCOUNT_SCORE`, `LOW_DEVICE_SCORE`, + * `OUTSIDE_HOME_TERRITORY`, `SUSPICIOUS_ACTIVITY`, `TOO_MANY_DIFFERENT_CARDHOLDERS`, + * `TOO_MANY_RECENT_ATTEMPTS`, `TOO_MANY_RECENT_TOKENS`, `UNABLE_TO_ASSESS` + * - Visa only: `ACCOUNT_DATA_RECENTLY_CHANGED`, `ACCOUNT_PAN_PAIRING_TOO_NEW`, + * `LOW_TRANSACTION_VOLUME`, `USER_ACCOUNT_DEVICE_TOO_NEW`, `WALLET_ACCOUNT_TOO_NEW` + * - Amex only: `DEVICE_USING_VPN_PROXY`, `EXCESSIVE_BILLING_NAME_ATTEMPTS_MODERATE`, + * `EXCESSIVE_BILLING_NAME_ATTEMPTS_SEVERE`, + * `EXCESSIVE_CARD_PROVISION_ATTEMPTS_MODERATE`, + * `EXCESSIVE_CARD_PROVISION_ATTEMPTS_SEVERE`, `EXCESSIVE_WALLET_RESETS`, + * `EXCESSIVE_ZIP_ATTEMPTS_MODERATE`, `EXCESSIVE_ZIP_ATTEMPTS_SEVERE`, + * `USER_ID_CARD_PAIRING_TOO_NEW`, `USER_ID_DEVICE_ID_PAIRING_TOO_NEW`, + * `USER_ID_OS_ID_PAIRING_TOO_NEW`, `USER_ID_TOO_NEW` * * `TOKEN_REQUESTOR_ID`: Unique identifier for the entity requesting the token. * * `WALLET_TOKEN_STATUS`: The current status of the wallet token. * * `CARD_STATE`: The state of the card being tokenized. Valid values are `CLOSED`, `OPEN`, diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ExternalBankAccountCreateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ExternalBankAccountCreateParams.kt index b0ffa075..acc4f7a8 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ExternalBankAccountCreateParams.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ExternalBankAccountCreateParams.kt @@ -35,12 +35,12 @@ import kotlin.jvm.optionals.getOrNull /** Creates an external bank account within a program or Lithic account. */ class ExternalBankAccountCreateParams private constructor( - private val body: Body?, + private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, ) : Params { - fun body(): Optional = Optional.ofNullable(body) + fun body(): Body = body /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -52,11 +52,14 @@ private constructor( companion object { - @JvmStatic fun none(): ExternalBankAccountCreateParams = builder().build() - /** * Returns a mutable builder for constructing an instance of * [ExternalBankAccountCreateParams]. + * + * The following fields are required: + * ```java + * .body() + * ``` */ @JvmStatic fun builder() = Builder() } @@ -77,10 +80,7 @@ private constructor( externalBankAccountCreateParams.additionalQueryParams.toBuilder() } - fun body(body: Body?) = apply { this.body = body } - - /** Alias for calling [Builder.body] with `body.orElse(null)`. */ - fun body(body: Optional) = body(body.getOrNull()) + fun body(body: Body) = apply { this.body = body } /** * Alias for calling [body] with @@ -205,16 +205,23 @@ private constructor( * Returns an immutable instance of [ExternalBankAccountCreateParams]. * * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .body() + * ``` + * + * @throws IllegalStateException if any required field is unset. */ fun build(): ExternalBankAccountCreateParams = ExternalBankAccountCreateParams( - body, + checkRequired("body", body), additionalHeaders.build(), additionalQueryParams.build(), ) } - fun _body(): Optional = Optional.ofNullable(body) + fun _body(): Body = body override fun _headers(): Headers = additionalHeaders diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Kyb.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Kyb.kt index 7a476160..34e9a22b 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Kyb.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Kyb.kt @@ -32,6 +32,7 @@ private constructor( private val beneficialOwnerEntities: JsonField>, private val externalId: JsonField, private val kybPassedTimestamp: JsonField, + private val naicsCode: JsonField, private val websiteUrl: JsonField, private val additionalProperties: MutableMap, ) { @@ -63,6 +64,7 @@ private constructor( @JsonProperty("kyb_passed_timestamp") @ExcludeMissing kybPassedTimestamp: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") @ExcludeMissing naicsCode: JsonField = JsonMissing.of(), @JsonProperty("website_url") @ExcludeMissing websiteUrl: JsonField = JsonMissing.of(), @@ -76,6 +78,7 @@ private constructor( beneficialOwnerEntities, externalId, kybPassedTimestamp, + naicsCode, websiteUrl, mutableMapOf(), ) @@ -171,6 +174,14 @@ private constructor( fun kybPassedTimestamp(): Optional = kybPassedTimestamp.getOptional("kyb_passed_timestamp") + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Company website URL. * @@ -261,6 +272,13 @@ private constructor( @ExcludeMissing fun _kybPassedTimestamp(): JsonField = kybPassedTimestamp + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("naics_code") @ExcludeMissing fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [websiteUrl]. * @@ -310,6 +328,7 @@ private constructor( private var beneficialOwnerEntities: JsonField>? = null private var externalId: JsonField = JsonMissing.of() private var kybPassedTimestamp: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var websiteUrl: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -324,6 +343,7 @@ private constructor( beneficialOwnerEntities = kyb.beneficialOwnerEntities.map { it.toMutableList() } externalId = kyb.externalId kybPassedTimestamp = kyb.kybPassedTimestamp + naicsCode = kyb.naicsCode websiteUrl = kyb.websiteUrl additionalProperties = kyb.additionalProperties.toMutableMap() } @@ -511,6 +531,18 @@ private constructor( this.kybPassedTimestamp = kybPassedTimestamp } + /** 6-digit North American Industry Classification System (NAICS) code for the business. */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** Company website URL. */ fun websiteUrl(websiteUrl: String) = websiteUrl(JsonField.of(websiteUrl)) @@ -572,6 +604,7 @@ private constructor( (beneficialOwnerEntities ?: JsonMissing.of()).map { it.toImmutable() }, externalId, kybPassedTimestamp, + naicsCode, websiteUrl, additionalProperties.toMutableMap(), ) @@ -593,6 +626,7 @@ private constructor( beneficialOwnerEntities().ifPresent { it.forEach { it.validate() } } externalId() kybPassedTimestamp() + naicsCode() websiteUrl() validated = true } @@ -621,6 +655,7 @@ private constructor( (beneficialOwnerEntities.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + (if (kybPassedTimestamp.asKnown().isPresent) 1 else 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (websiteUrl.asKnown().isPresent) 1 else 0) /** Individuals associated with a KYB application. Phone number is optional. */ @@ -1621,6 +1656,7 @@ private constructor( beneficialOwnerEntities == other.beneficialOwnerEntities && externalId == other.externalId && kybPassedTimestamp == other.kybPassedTimestamp && + naicsCode == other.naicsCode && websiteUrl == other.websiteUrl && additionalProperties == other.additionalProperties } @@ -1636,6 +1672,7 @@ private constructor( beneficialOwnerEntities, externalId, kybPassedTimestamp, + naicsCode, websiteUrl, additionalProperties, ) @@ -1644,5 +1681,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Kyb{beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessEntity=$businessEntity, controlPerson=$controlPerson, natureOfBusiness=$natureOfBusiness, tosTimestamp=$tosTimestamp, workflow=$workflow, beneficialOwnerEntities=$beneficialOwnerEntities, externalId=$externalId, kybPassedTimestamp=$kybPassedTimestamp, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "Kyb{beneficialOwnerIndividuals=$beneficialOwnerIndividuals, businessEntity=$businessEntity, controlPerson=$controlPerson, natureOfBusiness=$natureOfBusiness, tosTimestamp=$tosTimestamp, workflow=$workflow, beneficialOwnerEntities=$beneficialOwnerEntities, externalId=$externalId, kybPassedTimestamp=$kybPassedTimestamp, naicsCode=$naicsCode, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ParsedWebhookEvent.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ParsedWebhookEvent.kt index 9444b8ad..1f4257ba 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/ParsedWebhookEvent.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/ParsedWebhookEvent.kt @@ -2615,6 +2615,7 @@ private constructor( private val updateRequest: JsonField, private val eventType: JsonField, private val externalId: JsonField, + private val naicsCode: JsonField, private val natureOfBusiness: JsonField, private val websiteUrl: JsonField, private val additionalProperties: MutableMap, @@ -2632,6 +2633,9 @@ private constructor( @JsonProperty("external_id") @ExcludeMissing externalId: JsonField = JsonMissing.of(), + @JsonProperty("naics_code") + @ExcludeMissing + naicsCode: JsonField = JsonMissing.of(), @JsonProperty("nature_of_business") @ExcludeMissing natureOfBusiness: JsonField = JsonMissing.of(), @@ -2643,6 +2647,7 @@ private constructor( updateRequest, eventType, externalId, + naicsCode, natureOfBusiness, websiteUrl, mutableMapOf(), @@ -2680,6 +2685,15 @@ private constructor( */ fun externalId(): Optional = externalId.getOptional("external_id") + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. Only + * present if naics_code was included in the update request. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun naicsCode(): Optional = naicsCode.getOptional("naics_code") + /** * Short description of the company's line of business (i.e., what does the company do?). * @@ -2732,6 +2746,13 @@ private constructor( @ExcludeMissing fun _externalId(): JsonField = externalId + /** + * Returns the raw JSON value of [naicsCode]. + * + * Unlike [naicsCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("naics_code") @ExcludeMissing fun _naicsCode(): JsonField = naicsCode + /** * Returns the raw JSON value of [natureOfBusiness]. * @@ -2784,6 +2805,7 @@ private constructor( private var updateRequest: JsonField? = null private var eventType: JsonField = JsonMissing.of() private var externalId: JsonField = JsonMissing.of() + private var naicsCode: JsonField = JsonMissing.of() private var natureOfBusiness: JsonField = JsonMissing.of() private var websiteUrl: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @@ -2794,6 +2816,7 @@ private constructor( updateRequest = kybPayload.updateRequest eventType = kybPayload.eventType externalId = kybPayload.externalId + naicsCode = kybPayload.naicsCode natureOfBusiness = kybPayload.natureOfBusiness websiteUrl = kybPayload.websiteUrl additionalProperties = kybPayload.additionalProperties.toMutableMap() @@ -2852,6 +2875,21 @@ private constructor( */ fun externalId(externalId: JsonField) = apply { this.externalId = externalId } + /** + * 6-digit North American Industry Classification System (NAICS) code for the business. + * Only present if naics_code was included in the update request. + */ + fun naicsCode(naicsCode: String) = naicsCode(JsonField.of(naicsCode)) + + /** + * Sets [Builder.naicsCode] to an arbitrary JSON value. + * + * You should usually call [Builder.naicsCode] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun naicsCode(naicsCode: JsonField) = apply { this.naicsCode = naicsCode } + /** * Short description of the company's line of business (i.e., what does the company * do?). @@ -2920,6 +2958,7 @@ private constructor( checkRequired("updateRequest", updateRequest), eventType, externalId, + naicsCode, natureOfBusiness, websiteUrl, additionalProperties.toMutableMap(), @@ -2937,6 +2976,7 @@ private constructor( updateRequest().validate() eventType().ifPresent { it.validate() } externalId() + naicsCode() natureOfBusiness() websiteUrl() validated = true @@ -2962,6 +3002,7 @@ private constructor( (updateRequest.asKnown().getOrNull()?.validity() ?: 0) + (eventType.asKnown().getOrNull()?.validity() ?: 0) + (if (externalId.asKnown().isPresent) 1 else 0) + + (if (naicsCode.asKnown().isPresent) 1 else 0) + (if (natureOfBusiness.asKnown().isPresent) 1 else 0) + (if (websiteUrl.asKnown().isPresent) 1 else 0) @@ -4331,6 +4372,7 @@ private constructor( updateRequest == other.updateRequest && eventType == other.eventType && externalId == other.externalId && + naicsCode == other.naicsCode && natureOfBusiness == other.natureOfBusiness && websiteUrl == other.websiteUrl && additionalProperties == other.additionalProperties @@ -4342,6 +4384,7 @@ private constructor( updateRequest, eventType, externalId, + naicsCode, natureOfBusiness, websiteUrl, additionalProperties, @@ -4351,7 +4394,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "KybPayload{token=$token, updateRequest=$updateRequest, eventType=$eventType, externalId=$externalId, natureOfBusiness=$natureOfBusiness, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" + "KybPayload{token=$token, updateRequest=$updateRequest, eventType=$eventType, externalId=$externalId, naicsCode=$naicsCode, natureOfBusiness=$natureOfBusiness, websiteUrl=$websiteUrl, additionalProperties=$additionalProperties}" } /** KYC payload for an updated account holder. */ diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/V2ListResultsResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/V2ListResultsResponse.kt new file mode 100644 index 00000000..b6f7b2a6 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/V2ListResultsResponse.kt @@ -0,0 +1,6762 @@ +// 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.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.ObjectCodec +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.BaseDeserializer +import com.lithic.api.core.BaseSerializer +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.allMaxBy +import com.lithic.api.core.checkKnown +import com.lithic.api.core.checkRequired +import com.lithic.api.core.getOrThrow +import com.lithic.api.core.toImmutable +import com.lithic.api.errors.LithicInvalidDataException +import java.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Result of an Auth Rule evaluation */ +@JsonDeserialize(using = V2ListResultsResponse.Deserializer::class) +@JsonSerialize(using = V2ListResultsResponse.Serializer::class) +class V2ListResultsResponse +private constructor( + private val authorizationResult: AuthorizationResult? = null, + private val authentication3dsResult: Authentication3dsResult? = null, + private val tokenizationResult: TokenizationResult? = null, + private val achResult: AchResult? = null, + private val _json: JsonValue? = null, +) { + + fun authorizationResult(): Optional = + Optional.ofNullable(authorizationResult) + + fun authentication3dsResult(): Optional = + Optional.ofNullable(authentication3dsResult) + + fun tokenizationResult(): Optional = Optional.ofNullable(tokenizationResult) + + fun achResult(): Optional = Optional.ofNullable(achResult) + + fun isAuthorizationResult(): Boolean = authorizationResult != null + + fun isAuthentication3dsResult(): Boolean = authentication3dsResult != null + + fun isTokenizationResult(): Boolean = tokenizationResult != null + + fun isAchResult(): Boolean = achResult != null + + fun asAuthorizationResult(): AuthorizationResult = + authorizationResult.getOrThrow("authorizationResult") + + fun asAuthentication3dsResult(): Authentication3dsResult = + authentication3dsResult.getOrThrow("authentication3dsResult") + + fun asTokenizationResult(): TokenizationResult = + tokenizationResult.getOrThrow("tokenizationResult") + + fun asAchResult(): AchResult = achResult.getOrThrow("achResult") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + authorizationResult != null -> visitor.visitAuthorizationResult(authorizationResult) + authentication3dsResult != null -> + visitor.visitAuthentication3dsResult(authentication3dsResult) + tokenizationResult != null -> visitor.visitTokenizationResult(tokenizationResult) + achResult != null -> visitor.visitAchResult(achResult) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): V2ListResultsResponse = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitAuthorizationResult(authorizationResult: AuthorizationResult) { + authorizationResult.validate() + } + + override fun visitAuthentication3dsResult( + authentication3dsResult: Authentication3dsResult + ) { + authentication3dsResult.validate() + } + + override fun visitTokenizationResult(tokenizationResult: TokenizationResult) { + tokenizationResult.validate() + } + + override fun visitAchResult(achResult: AchResult) { + achResult.validate() + } + } + ) + 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 = + accept( + object : Visitor { + override fun visitAuthorizationResult(authorizationResult: AuthorizationResult) = + authorizationResult.validity() + + override fun visitAuthentication3dsResult( + authentication3dsResult: Authentication3dsResult + ) = authentication3dsResult.validity() + + override fun visitTokenizationResult(tokenizationResult: TokenizationResult) = + tokenizationResult.validity() + + override fun visitAchResult(achResult: AchResult) = achResult.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is V2ListResultsResponse && + authorizationResult == other.authorizationResult && + authentication3dsResult == other.authentication3dsResult && + tokenizationResult == other.tokenizationResult && + achResult == other.achResult + } + + override fun hashCode(): Int = + Objects.hash(authorizationResult, authentication3dsResult, tokenizationResult, achResult) + + override fun toString(): String = + when { + authorizationResult != null -> + "V2ListResultsResponse{authorizationResult=$authorizationResult}" + authentication3dsResult != null -> + "V2ListResultsResponse{authentication3dsResult=$authentication3dsResult}" + tokenizationResult != null -> + "V2ListResultsResponse{tokenizationResult=$tokenizationResult}" + achResult != null -> "V2ListResultsResponse{achResult=$achResult}" + _json != null -> "V2ListResultsResponse{_unknown=$_json}" + else -> throw IllegalStateException("Invalid V2ListResultsResponse") + } + + companion object { + + @JvmStatic + fun ofAuthorizationResult(authorizationResult: AuthorizationResult) = + V2ListResultsResponse(authorizationResult = authorizationResult) + + @JvmStatic + fun ofAuthentication3dsResult(authentication3dsResult: Authentication3dsResult) = + V2ListResultsResponse(authentication3dsResult = authentication3dsResult) + + @JvmStatic + fun ofTokenizationResult(tokenizationResult: TokenizationResult) = + V2ListResultsResponse(tokenizationResult = tokenizationResult) + + @JvmStatic + fun ofAchResult(achResult: AchResult) = V2ListResultsResponse(achResult = achResult) + } + + /** + * An interface that defines how to map each variant of [V2ListResultsResponse] to a value of + * type [T]. + */ + interface Visitor { + + fun visitAuthorizationResult(authorizationResult: AuthorizationResult): T + + fun visitAuthentication3dsResult(authentication3dsResult: Authentication3dsResult): T + + fun visitTokenizationResult(tokenizationResult: TokenizationResult): T + + fun visitAchResult(achResult: AchResult): T + + /** + * Maps an unknown variant of [V2ListResultsResponse] to a value of type [T]. + * + * An instance of [V2ListResultsResponse] can contain an unknown variant if it was + * deserialized from data that doesn't match any known variant. For example, if the SDK is + * on an older version than the API, then the API may respond with new variants that the SDK + * is unaware of. + * + * @throws LithicInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw LithicInvalidDataException("Unknown V2ListResultsResponse: $json") + } + } + + internal class Deserializer : + BaseDeserializer(V2ListResultsResponse::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): V2ListResultsResponse { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + V2ListResultsResponse(authorizationResult = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + V2ListResultsResponse(authentication3dsResult = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + V2ListResultsResponse(tokenizationResult = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + V2ListResultsResponse(achResult = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible with all + // the possible variants (e.g. deserializing from boolean). + 0 -> V2ListResultsResponse(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the first + // completely valid match, or simply the first match if none are completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : + BaseSerializer(V2ListResultsResponse::class) { + + override fun serialize( + value: V2ListResultsResponse, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.authorizationResult != null -> + generator.writeObject(value.authorizationResult) + value.authentication3dsResult != null -> + generator.writeObject(value.authentication3dsResult) + value.tokenizationResult != null -> generator.writeObject(value.tokenizationResult) + value.achResult != null -> generator.writeObject(value.achResult) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid V2ListResultsResponse") + } + } + } + + class AuthorizationResult + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val token: JsonField, + private val actions: JsonField>, + private val authRuleToken: JsonField, + private val evaluationTime: JsonField, + private val eventStream: JsonField, + private val eventToken: JsonField, + private val mode: JsonField, + private val ruleVersion: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of(), + @JsonProperty("actions") + @ExcludeMissing + actions: JsonField> = JsonMissing.of(), + @JsonProperty("auth_rule_token") + @ExcludeMissing + authRuleToken: JsonField = JsonMissing.of(), + @JsonProperty("evaluation_time") + @ExcludeMissing + evaluationTime: JsonField = JsonMissing.of(), + @JsonProperty("event_stream") + @ExcludeMissing + eventStream: JsonField = JsonMissing.of(), + @JsonProperty("event_token") + @ExcludeMissing + eventToken: JsonField = JsonMissing.of(), + @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of(), + @JsonProperty("rule_version") + @ExcludeMissing + ruleVersion: JsonField = JsonMissing.of(), + ) : this( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + mutableMapOf(), + ) + + /** + * Globally unique identifier for the evaluation + * + * @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 token(): String = token.getRequired("token") + + /** + * Actions returned by the rule evaluation + * + * @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 actions(): List = actions.getRequired("actions") + + /** + * The Auth Rule token + * + * @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 authRuleToken(): String = authRuleToken.getRequired("auth_rule_token") + + /** + * Timestamp of the rule evaluation + * + * @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 evaluationTime(): OffsetDateTime = evaluationTime.getRequired("evaluation_time") + + /** + * The event stream during which the rule was evaluated + * + * @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 eventStream(): EventStream = eventStream.getRequired("event_stream") + + /** + * Token of the event that triggered the evaluation + * + * @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 eventToken(): String = eventToken.getRequired("event_token") + + /** + * The state of the Auth Rule + * + * @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 mode(): AuthRuleState = mode.getRequired("mode") + + /** + * Version of the rule that was evaluated + * + * @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 ruleVersion(): Long = ruleVersion.getRequired("rule_version") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + /** + * Returns the raw JSON value of [actions]. + * + * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actions") @ExcludeMissing fun _actions(): JsonField> = actions + + /** + * Returns the raw JSON value of [authRuleToken]. + * + * Unlike [authRuleToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("auth_rule_token") + @ExcludeMissing + fun _authRuleToken(): JsonField = authRuleToken + + /** + * Returns the raw JSON value of [evaluationTime]. + * + * Unlike [evaluationTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("evaluation_time") + @ExcludeMissing + fun _evaluationTime(): JsonField = evaluationTime + + /** + * Returns the raw JSON value of [eventStream]. + * + * Unlike [eventStream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_stream") + @ExcludeMissing + fun _eventStream(): JsonField = eventStream + + /** + * Returns the raw JSON value of [eventToken]. + * + * Unlike [eventToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_token") + @ExcludeMissing + fun _eventToken(): JsonField = eventToken + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + /** + * Returns the raw JSON value of [ruleVersion]. + * + * Unlike [ruleVersion], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rule_version") + @ExcludeMissing + fun _ruleVersion(): JsonField = ruleVersion + + @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 [AuthorizationResult]. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthorizationResult]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var actions: JsonField>? = null + private var authRuleToken: JsonField? = null + private var evaluationTime: JsonField? = null + private var eventStream: JsonField? = null + private var eventToken: JsonField? = null + private var mode: JsonField? = null + private var ruleVersion: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(authorizationResult: AuthorizationResult) = apply { + token = authorizationResult.token + actions = authorizationResult.actions.map { it.toMutableList() } + authRuleToken = authorizationResult.authRuleToken + evaluationTime = authorizationResult.evaluationTime + eventStream = authorizationResult.eventStream + eventToken = authorizationResult.eventToken + mode = authorizationResult.mode + ruleVersion = authorizationResult.ruleVersion + additionalProperties = authorizationResult.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for the evaluation */ + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + /** Actions returned by the rule evaluation */ + fun actions(actions: List) = actions(JsonField.of(actions)) + + /** + * Sets [Builder.actions] to an arbitrary JSON value. + * + * You should usually call [Builder.actions] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actions(actions: JsonField>) = apply { + this.actions = actions.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [actions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAction(action: Action) = apply { + actions = + (actions ?: JsonField.of(mutableListOf())).also { + checkKnown("actions", it).add(action) + } + } + + /** The Auth Rule token */ + fun authRuleToken(authRuleToken: String) = authRuleToken(JsonField.of(authRuleToken)) + + /** + * Sets [Builder.authRuleToken] to an arbitrary JSON value. + * + * You should usually call [Builder.authRuleToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun authRuleToken(authRuleToken: JsonField) = apply { + this.authRuleToken = authRuleToken + } + + /** Timestamp of the rule evaluation */ + fun evaluationTime(evaluationTime: OffsetDateTime) = + evaluationTime(JsonField.of(evaluationTime)) + + /** + * Sets [Builder.evaluationTime] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationTime] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun evaluationTime(evaluationTime: JsonField) = apply { + this.evaluationTime = evaluationTime + } + + /** The event stream during which the rule was evaluated */ + fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) + + /** + * Sets [Builder.eventStream] to an arbitrary JSON value. + * + * You should usually call [Builder.eventStream] with a well-typed [EventStream] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventStream(eventStream: JsonField) = apply { + this.eventStream = eventStream + } + + /** Token of the event that triggered the evaluation */ + fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) + + /** + * Sets [Builder.eventToken] to an arbitrary JSON value. + * + * You should usually call [Builder.eventToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventToken(eventToken: JsonField) = apply { this.eventToken = eventToken } + + /** The state of the Auth Rule */ + fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [AuthRuleState] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + /** Version of the rule that was evaluated */ + fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) + + /** + * Sets [Builder.ruleVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.ruleVersion] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ruleVersion(ruleVersion: JsonField) = apply { this.ruleVersion = ruleVersion } + + 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 [AuthorizationResult]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AuthorizationResult = + AuthorizationResult( + checkRequired("token", token), + checkRequired("actions", actions).map { it.toImmutable() }, + checkRequired("authRuleToken", authRuleToken), + checkRequired("evaluationTime", evaluationTime), + checkRequired("eventStream", eventStream), + checkRequired("eventToken", eventToken), + checkRequired("mode", mode), + checkRequired("ruleVersion", ruleVersion), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AuthorizationResult = apply { + if (validated) { + return@apply + } + + token() + actions().forEach { it.validate() } + authRuleToken() + evaluationTime() + eventStream().validate() + eventToken() + mode().validate() + ruleVersion() + 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 (token.asKnown().isPresent) 1 else 0) + + (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (authRuleToken.asKnown().isPresent) 1 else 0) + + (if (evaluationTime.asKnown().isPresent) 1 else 0) + + (eventStream.asKnown().getOrNull()?.validity() ?: 0) + + (if (eventToken.asKnown().isPresent) 1 else 0) + + (mode.asKnown().getOrNull()?.validity() ?: 0) + + (if (ruleVersion.asKnown().isPresent) 1 else 0) + + class Action + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val explanation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of(), + ) : this(type, explanation, mutableMapOf()) + + /** + * @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 type(): AuthorizationAction = type.getRequired("type") + + /** + * Optional explanation for why this action was taken + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun explanation(): Optional = explanation.getOptional("explanation") + + /** + * 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 + + /** + * Returns the raw JSON value of [explanation]. + * + * Unlike [explanation], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("explanation") + @ExcludeMissing + fun _explanation(): JsonField = explanation + + @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 [Action]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Action]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var explanation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(action: Action) = apply { + type = action.type + explanation = action.explanation + additionalProperties = action.additionalProperties.toMutableMap() + } + + fun type(type: AuthorizationAction) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [AuthorizationAction] + * 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 } + + /** Optional explanation for why this action was taken */ + fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + + /** + * Sets [Builder.explanation] to an arbitrary JSON value. + * + * You should usually call [Builder.explanation] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun explanation(explanation: JsonField) = apply { + this.explanation = explanation + } + + 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 [Action]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Action = + Action( + checkRequired("type", type), + explanation, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + type().validate() + explanation() + 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 = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + class AuthorizationAction + @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 DECLINE = of("DECLINE") + + @JvmField val CHALLENGE = of("CHALLENGE") + + @JvmStatic fun of(value: String) = AuthorizationAction(JsonField.of(value)) + } + + /** An enum containing [AuthorizationAction]'s known values. */ + enum class Known { + DECLINE, + CHALLENGE, + } + + /** + * An enum containing [AuthorizationAction]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [AuthorizationAction] 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 { + DECLINE, + CHALLENGE, + /** + * An enum member indicating that [AuthorizationAction] 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) { + DECLINE -> Value.DECLINE + CHALLENGE -> Value.CHALLENGE + 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) { + DECLINE -> Known.DECLINE + CHALLENGE -> Known.CHALLENGE + else -> + throw LithicInvalidDataException("Unknown AuthorizationAction: $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(): AuthorizationAction = 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 AuthorizationAction && 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 Action && + type == other.type && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, explanation, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Action{type=$type, explanation=$explanation, additionalProperties=$additionalProperties}" + } + + /** The event stream during which the rule was evaluated */ + class EventStream @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 AUTHORIZATION = of("AUTHORIZATION") + + @JvmStatic fun of(value: String) = EventStream(JsonField.of(value)) + } + + /** An enum containing [EventStream]'s known values. */ + enum class Known { + AUTHORIZATION + } + + /** + * An enum containing [EventStream]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EventStream] 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 { + AUTHORIZATION, + /** + * An enum member indicating that [EventStream] 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) { + AUTHORIZATION -> Value.AUTHORIZATION + 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) { + AUTHORIZATION -> Known.AUTHORIZATION + else -> throw LithicInvalidDataException("Unknown EventStream: $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(): EventStream = 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 EventStream && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The state of the Auth Rule */ + class AuthRuleState @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 ACTIVE = of("ACTIVE") + + @JvmField val INACTIVE = of("INACTIVE") + + @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) + } + + /** An enum containing [AuthRuleState]'s known values. */ + enum class Known { + ACTIVE, + INACTIVE, + } + + /** + * An enum containing [AuthRuleState]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AuthRuleState] 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 { + ACTIVE, + INACTIVE, + /** + * An enum member indicating that [AuthRuleState] 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) { + ACTIVE -> Value.ACTIVE + INACTIVE -> Value.INACTIVE + 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) { + ACTIVE -> Known.ACTIVE + INACTIVE -> Known.INACTIVE + else -> throw LithicInvalidDataException("Unknown AuthRuleState: $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(): AuthRuleState = 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 AuthRuleState && 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 AuthorizationResult && + token == other.token && + actions == other.actions && + authRuleToken == other.authRuleToken && + evaluationTime == other.evaluationTime && + eventStream == other.eventStream && + eventToken == other.eventToken && + mode == other.mode && + ruleVersion == other.ruleVersion && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AuthorizationResult{token=$token, actions=$actions, authRuleToken=$authRuleToken, evaluationTime=$evaluationTime, eventStream=$eventStream, eventToken=$eventToken, mode=$mode, ruleVersion=$ruleVersion, additionalProperties=$additionalProperties}" + } + + class Authentication3dsResult + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val token: JsonField, + private val actions: JsonField>, + private val authRuleToken: JsonField, + private val evaluationTime: JsonField, + private val eventStream: JsonField, + private val eventToken: JsonField, + private val mode: JsonField, + private val ruleVersion: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of(), + @JsonProperty("actions") + @ExcludeMissing + actions: JsonField> = JsonMissing.of(), + @JsonProperty("auth_rule_token") + @ExcludeMissing + authRuleToken: JsonField = JsonMissing.of(), + @JsonProperty("evaluation_time") + @ExcludeMissing + evaluationTime: JsonField = JsonMissing.of(), + @JsonProperty("event_stream") + @ExcludeMissing + eventStream: JsonField = JsonMissing.of(), + @JsonProperty("event_token") + @ExcludeMissing + eventToken: JsonField = JsonMissing.of(), + @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of(), + @JsonProperty("rule_version") + @ExcludeMissing + ruleVersion: JsonField = JsonMissing.of(), + ) : this( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + mutableMapOf(), + ) + + /** + * Globally unique identifier for the evaluation + * + * @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 token(): String = token.getRequired("token") + + /** + * Actions returned by the rule evaluation + * + * @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 actions(): List = actions.getRequired("actions") + + /** + * The Auth Rule token + * + * @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 authRuleToken(): String = authRuleToken.getRequired("auth_rule_token") + + /** + * Timestamp of the rule evaluation + * + * @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 evaluationTime(): OffsetDateTime = evaluationTime.getRequired("evaluation_time") + + /** + * The event stream during which the rule was evaluated + * + * @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 eventStream(): EventStream = eventStream.getRequired("event_stream") + + /** + * Token of the event that triggered the evaluation + * + * @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 eventToken(): String = eventToken.getRequired("event_token") + + /** + * The state of the Auth Rule + * + * @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 mode(): AuthRuleState = mode.getRequired("mode") + + /** + * Version of the rule that was evaluated + * + * @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 ruleVersion(): Long = ruleVersion.getRequired("rule_version") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + /** + * Returns the raw JSON value of [actions]. + * + * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actions") @ExcludeMissing fun _actions(): JsonField> = actions + + /** + * Returns the raw JSON value of [authRuleToken]. + * + * Unlike [authRuleToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("auth_rule_token") + @ExcludeMissing + fun _authRuleToken(): JsonField = authRuleToken + + /** + * Returns the raw JSON value of [evaluationTime]. + * + * Unlike [evaluationTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("evaluation_time") + @ExcludeMissing + fun _evaluationTime(): JsonField = evaluationTime + + /** + * Returns the raw JSON value of [eventStream]. + * + * Unlike [eventStream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_stream") + @ExcludeMissing + fun _eventStream(): JsonField = eventStream + + /** + * Returns the raw JSON value of [eventToken]. + * + * Unlike [eventToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_token") + @ExcludeMissing + fun _eventToken(): JsonField = eventToken + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + /** + * Returns the raw JSON value of [ruleVersion]. + * + * Unlike [ruleVersion], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rule_version") + @ExcludeMissing + fun _ruleVersion(): JsonField = ruleVersion + + @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 [Authentication3dsResult]. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Authentication3dsResult]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var actions: JsonField>? = null + private var authRuleToken: JsonField? = null + private var evaluationTime: JsonField? = null + private var eventStream: JsonField? = null + private var eventToken: JsonField? = null + private var mode: JsonField? = null + private var ruleVersion: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(authentication3dsResult: Authentication3dsResult) = apply { + token = authentication3dsResult.token + actions = authentication3dsResult.actions.map { it.toMutableList() } + authRuleToken = authentication3dsResult.authRuleToken + evaluationTime = authentication3dsResult.evaluationTime + eventStream = authentication3dsResult.eventStream + eventToken = authentication3dsResult.eventToken + mode = authentication3dsResult.mode + ruleVersion = authentication3dsResult.ruleVersion + additionalProperties = authentication3dsResult.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for the evaluation */ + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + /** Actions returned by the rule evaluation */ + fun actions(actions: List) = actions(JsonField.of(actions)) + + /** + * Sets [Builder.actions] to an arbitrary JSON value. + * + * You should usually call [Builder.actions] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actions(actions: JsonField>) = apply { + this.actions = actions.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [actions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAction(action: Action) = apply { + actions = + (actions ?: JsonField.of(mutableListOf())).also { + checkKnown("actions", it).add(action) + } + } + + /** The Auth Rule token */ + fun authRuleToken(authRuleToken: String) = authRuleToken(JsonField.of(authRuleToken)) + + /** + * Sets [Builder.authRuleToken] to an arbitrary JSON value. + * + * You should usually call [Builder.authRuleToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun authRuleToken(authRuleToken: JsonField) = apply { + this.authRuleToken = authRuleToken + } + + /** Timestamp of the rule evaluation */ + fun evaluationTime(evaluationTime: OffsetDateTime) = + evaluationTime(JsonField.of(evaluationTime)) + + /** + * Sets [Builder.evaluationTime] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationTime] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun evaluationTime(evaluationTime: JsonField) = apply { + this.evaluationTime = evaluationTime + } + + /** The event stream during which the rule was evaluated */ + fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) + + /** + * Sets [Builder.eventStream] to an arbitrary JSON value. + * + * You should usually call [Builder.eventStream] with a well-typed [EventStream] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventStream(eventStream: JsonField) = apply { + this.eventStream = eventStream + } + + /** Token of the event that triggered the evaluation */ + fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) + + /** + * Sets [Builder.eventToken] to an arbitrary JSON value. + * + * You should usually call [Builder.eventToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventToken(eventToken: JsonField) = apply { this.eventToken = eventToken } + + /** The state of the Auth Rule */ + fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [AuthRuleState] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + /** Version of the rule that was evaluated */ + fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) + + /** + * Sets [Builder.ruleVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.ruleVersion] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ruleVersion(ruleVersion: JsonField) = apply { this.ruleVersion = ruleVersion } + + 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 [Authentication3dsResult]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Authentication3dsResult = + Authentication3dsResult( + checkRequired("token", token), + checkRequired("actions", actions).map { it.toImmutable() }, + checkRequired("authRuleToken", authRuleToken), + checkRequired("evaluationTime", evaluationTime), + checkRequired("eventStream", eventStream), + checkRequired("eventToken", eventToken), + checkRequired("mode", mode), + checkRequired("ruleVersion", ruleVersion), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Authentication3dsResult = apply { + if (validated) { + return@apply + } + + token() + actions().forEach { it.validate() } + authRuleToken() + evaluationTime() + eventStream().validate() + eventToken() + mode().validate() + ruleVersion() + 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 (token.asKnown().isPresent) 1 else 0) + + (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (authRuleToken.asKnown().isPresent) 1 else 0) + + (if (evaluationTime.asKnown().isPresent) 1 else 0) + + (eventStream.asKnown().getOrNull()?.validity() ?: 0) + + (if (eventToken.asKnown().isPresent) 1 else 0) + + (mode.asKnown().getOrNull()?.validity() ?: 0) + + (if (ruleVersion.asKnown().isPresent) 1 else 0) + + class Action + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val explanation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") + @ExcludeMissing + type: JsonField = JsonMissing.of(), + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of(), + ) : this(type, explanation, mutableMapOf()) + + /** + * @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 type(): Authentication3dsAction = type.getRequired("type") + + /** + * Optional explanation for why this action was taken + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun explanation(): Optional = explanation.getOptional("explanation") + + /** + * 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 + + /** + * Returns the raw JSON value of [explanation]. + * + * Unlike [explanation], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("explanation") + @ExcludeMissing + fun _explanation(): JsonField = explanation + + @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 [Action]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Action]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var explanation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(action: Action) = apply { + type = action.type + explanation = action.explanation + additionalProperties = action.additionalProperties.toMutableMap() + } + + fun type(type: Authentication3dsAction) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed + * [Authentication3dsAction] 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 } + + /** Optional explanation for why this action was taken */ + fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + + /** + * Sets [Builder.explanation] to an arbitrary JSON value. + * + * You should usually call [Builder.explanation] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun explanation(explanation: JsonField) = apply { + this.explanation = explanation + } + + 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 [Action]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Action = + Action( + checkRequired("type", type), + explanation, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + type().validate() + explanation() + 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 = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + class Authentication3dsAction + @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 DECLINE = of("DECLINE") + + @JvmField val CHALLENGE = of("CHALLENGE") + + @JvmStatic fun of(value: String) = Authentication3dsAction(JsonField.of(value)) + } + + /** An enum containing [Authentication3dsAction]'s known values. */ + enum class Known { + DECLINE, + CHALLENGE, + } + + /** + * An enum containing [Authentication3dsAction]'s known values, as well as an + * [_UNKNOWN] member. + * + * An instance of [Authentication3dsAction] 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 { + DECLINE, + CHALLENGE, + /** + * An enum member indicating that [Authentication3dsAction] 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) { + DECLINE -> Value.DECLINE + CHALLENGE -> Value.CHALLENGE + 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) { + DECLINE -> Known.DECLINE + CHALLENGE -> Known.CHALLENGE + else -> + throw LithicInvalidDataException( + "Unknown Authentication3dsAction: $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(): Authentication3dsAction = 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 Authentication3dsAction && 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 Action && + type == other.type && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, explanation, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Action{type=$type, explanation=$explanation, additionalProperties=$additionalProperties}" + } + + /** The event stream during which the rule was evaluated */ + class EventStream @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 THREE_DS_AUTHENTICATION = of("THREE_DS_AUTHENTICATION") + + @JvmStatic fun of(value: String) = EventStream(JsonField.of(value)) + } + + /** An enum containing [EventStream]'s known values. */ + enum class Known { + THREE_DS_AUTHENTICATION + } + + /** + * An enum containing [EventStream]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EventStream] 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 { + THREE_DS_AUTHENTICATION, + /** + * An enum member indicating that [EventStream] 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) { + THREE_DS_AUTHENTICATION -> Value.THREE_DS_AUTHENTICATION + 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) { + THREE_DS_AUTHENTICATION -> Known.THREE_DS_AUTHENTICATION + else -> throw LithicInvalidDataException("Unknown EventStream: $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(): EventStream = 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 EventStream && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The state of the Auth Rule */ + class AuthRuleState @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 ACTIVE = of("ACTIVE") + + @JvmField val INACTIVE = of("INACTIVE") + + @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) + } + + /** An enum containing [AuthRuleState]'s known values. */ + enum class Known { + ACTIVE, + INACTIVE, + } + + /** + * An enum containing [AuthRuleState]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AuthRuleState] 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 { + ACTIVE, + INACTIVE, + /** + * An enum member indicating that [AuthRuleState] 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) { + ACTIVE -> Value.ACTIVE + INACTIVE -> Value.INACTIVE + 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) { + ACTIVE -> Known.ACTIVE + INACTIVE -> Known.INACTIVE + else -> throw LithicInvalidDataException("Unknown AuthRuleState: $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(): AuthRuleState = 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 AuthRuleState && 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 Authentication3dsResult && + token == other.token && + actions == other.actions && + authRuleToken == other.authRuleToken && + evaluationTime == other.evaluationTime && + eventStream == other.eventStream && + eventToken == other.eventToken && + mode == other.mode && + ruleVersion == other.ruleVersion && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Authentication3dsResult{token=$token, actions=$actions, authRuleToken=$authRuleToken, evaluationTime=$evaluationTime, eventStream=$eventStream, eventToken=$eventToken, mode=$mode, ruleVersion=$ruleVersion, additionalProperties=$additionalProperties}" + } + + class TokenizationResult + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val token: JsonField, + private val actions: JsonField>, + private val authRuleToken: JsonField, + private val evaluationTime: JsonField, + private val eventStream: JsonField, + private val eventToken: JsonField, + private val mode: JsonField, + private val ruleVersion: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of(), + @JsonProperty("actions") + @ExcludeMissing + actions: JsonField> = JsonMissing.of(), + @JsonProperty("auth_rule_token") + @ExcludeMissing + authRuleToken: JsonField = JsonMissing.of(), + @JsonProperty("evaluation_time") + @ExcludeMissing + evaluationTime: JsonField = JsonMissing.of(), + @JsonProperty("event_stream") + @ExcludeMissing + eventStream: JsonField = JsonMissing.of(), + @JsonProperty("event_token") + @ExcludeMissing + eventToken: JsonField = JsonMissing.of(), + @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of(), + @JsonProperty("rule_version") + @ExcludeMissing + ruleVersion: JsonField = JsonMissing.of(), + ) : this( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + mutableMapOf(), + ) + + /** + * Globally unique identifier for the evaluation + * + * @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 token(): String = token.getRequired("token") + + /** + * Actions returned by the rule evaluation + * + * @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 actions(): List = actions.getRequired("actions") + + /** + * The Auth Rule token + * + * @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 authRuleToken(): String = authRuleToken.getRequired("auth_rule_token") + + /** + * Timestamp of the rule evaluation + * + * @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 evaluationTime(): OffsetDateTime = evaluationTime.getRequired("evaluation_time") + + /** + * The event stream during which the rule was evaluated + * + * @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 eventStream(): EventStream = eventStream.getRequired("event_stream") + + /** + * Token of the event that triggered the evaluation + * + * @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 eventToken(): String = eventToken.getRequired("event_token") + + /** + * The state of the Auth Rule + * + * @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 mode(): AuthRuleState = mode.getRequired("mode") + + /** + * Version of the rule that was evaluated + * + * @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 ruleVersion(): Long = ruleVersion.getRequired("rule_version") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + /** + * Returns the raw JSON value of [actions]. + * + * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actions") @ExcludeMissing fun _actions(): JsonField> = actions + + /** + * Returns the raw JSON value of [authRuleToken]. + * + * Unlike [authRuleToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("auth_rule_token") + @ExcludeMissing + fun _authRuleToken(): JsonField = authRuleToken + + /** + * Returns the raw JSON value of [evaluationTime]. + * + * Unlike [evaluationTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("evaluation_time") + @ExcludeMissing + fun _evaluationTime(): JsonField = evaluationTime + + /** + * Returns the raw JSON value of [eventStream]. + * + * Unlike [eventStream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_stream") + @ExcludeMissing + fun _eventStream(): JsonField = eventStream + + /** + * Returns the raw JSON value of [eventToken]. + * + * Unlike [eventToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_token") + @ExcludeMissing + fun _eventToken(): JsonField = eventToken + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + /** + * Returns the raw JSON value of [ruleVersion]. + * + * Unlike [ruleVersion], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rule_version") + @ExcludeMissing + fun _ruleVersion(): JsonField = ruleVersion + + @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 [TokenizationResult]. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [TokenizationResult]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var actions: JsonField>? = null + private var authRuleToken: JsonField? = null + private var evaluationTime: JsonField? = null + private var eventStream: JsonField? = null + private var eventToken: JsonField? = null + private var mode: JsonField? = null + private var ruleVersion: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(tokenizationResult: TokenizationResult) = apply { + token = tokenizationResult.token + actions = tokenizationResult.actions.map { it.toMutableList() } + authRuleToken = tokenizationResult.authRuleToken + evaluationTime = tokenizationResult.evaluationTime + eventStream = tokenizationResult.eventStream + eventToken = tokenizationResult.eventToken + mode = tokenizationResult.mode + ruleVersion = tokenizationResult.ruleVersion + additionalProperties = tokenizationResult.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for the evaluation */ + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + /** Actions returned by the rule evaluation */ + fun actions(actions: List) = actions(JsonField.of(actions)) + + /** + * Sets [Builder.actions] to an arbitrary JSON value. + * + * You should usually call [Builder.actions] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actions(actions: JsonField>) = apply { + this.actions = actions.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [actions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAction(action: Action) = apply { + actions = + (actions ?: JsonField.of(mutableListOf())).also { + checkKnown("actions", it).add(action) + } + } + + /** Alias for calling [addAction] with `Action.ofDecline(decline)`. */ + fun addAction(decline: Action.DeclineAction) = addAction(Action.ofDecline(decline)) + + /** Alias for calling [addAction] with `Action.ofRequireTfa(requireTfa)`. */ + fun addAction(requireTfa: Action.RequireTfaAction) = + addAction(Action.ofRequireTfa(requireTfa)) + + /** The Auth Rule token */ + fun authRuleToken(authRuleToken: String) = authRuleToken(JsonField.of(authRuleToken)) + + /** + * Sets [Builder.authRuleToken] to an arbitrary JSON value. + * + * You should usually call [Builder.authRuleToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun authRuleToken(authRuleToken: JsonField) = apply { + this.authRuleToken = authRuleToken + } + + /** Timestamp of the rule evaluation */ + fun evaluationTime(evaluationTime: OffsetDateTime) = + evaluationTime(JsonField.of(evaluationTime)) + + /** + * Sets [Builder.evaluationTime] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationTime] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun evaluationTime(evaluationTime: JsonField) = apply { + this.evaluationTime = evaluationTime + } + + /** The event stream during which the rule was evaluated */ + fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) + + /** + * Sets [Builder.eventStream] to an arbitrary JSON value. + * + * You should usually call [Builder.eventStream] with a well-typed [EventStream] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventStream(eventStream: JsonField) = apply { + this.eventStream = eventStream + } + + /** Token of the event that triggered the evaluation */ + fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) + + /** + * Sets [Builder.eventToken] to an arbitrary JSON value. + * + * You should usually call [Builder.eventToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventToken(eventToken: JsonField) = apply { this.eventToken = eventToken } + + /** The state of the Auth Rule */ + fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [AuthRuleState] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + /** Version of the rule that was evaluated */ + fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) + + /** + * Sets [Builder.ruleVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.ruleVersion] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ruleVersion(ruleVersion: JsonField) = apply { this.ruleVersion = ruleVersion } + + 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 [TokenizationResult]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): TokenizationResult = + TokenizationResult( + checkRequired("token", token), + checkRequired("actions", actions).map { it.toImmutable() }, + checkRequired("authRuleToken", authRuleToken), + checkRequired("evaluationTime", evaluationTime), + checkRequired("eventStream", eventStream), + checkRequired("eventToken", eventToken), + checkRequired("mode", mode), + checkRequired("ruleVersion", ruleVersion), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): TokenizationResult = apply { + if (validated) { + return@apply + } + + token() + actions().forEach { it.validate() } + authRuleToken() + evaluationTime() + eventStream().validate() + eventToken() + mode().validate() + ruleVersion() + 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 (token.asKnown().isPresent) 1 else 0) + + (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (authRuleToken.asKnown().isPresent) 1 else 0) + + (if (evaluationTime.asKnown().isPresent) 1 else 0) + + (eventStream.asKnown().getOrNull()?.validity() ?: 0) + + (if (eventToken.asKnown().isPresent) 1 else 0) + + (mode.asKnown().getOrNull()?.validity() ?: 0) + + (if (ruleVersion.asKnown().isPresent) 1 else 0) + + @JsonDeserialize(using = Action.Deserializer::class) + @JsonSerialize(using = Action.Serializer::class) + class Action + private constructor( + private val decline: DeclineAction? = null, + private val requireTfa: RequireTfaAction? = null, + private val _json: JsonValue? = null, + ) { + + fun decline(): Optional = Optional.ofNullable(decline) + + fun requireTfa(): Optional = Optional.ofNullable(requireTfa) + + fun isDecline(): Boolean = decline != null + + fun isRequireTfa(): Boolean = requireTfa != null + + fun asDecline(): DeclineAction = decline.getOrThrow("decline") + + fun asRequireTfa(): RequireTfaAction = requireTfa.getOrThrow("requireTfa") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + decline != null -> visitor.visitDecline(decline) + requireTfa != null -> visitor.visitRequireTfa(requireTfa) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitDecline(decline: DeclineAction) { + decline.validate() + } + + override fun visitRequireTfa(requireTfa: RequireTfaAction) { + requireTfa.validate() + } + } + ) + 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 = + accept( + object : Visitor { + override fun visitDecline(decline: DeclineAction) = decline.validity() + + override fun visitRequireTfa(requireTfa: RequireTfaAction) = + requireTfa.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Action && decline == other.decline && requireTfa == other.requireTfa + } + + override fun hashCode(): Int = Objects.hash(decline, requireTfa) + + override fun toString(): String = + when { + decline != null -> "Action{decline=$decline}" + requireTfa != null -> "Action{requireTfa=$requireTfa}" + _json != null -> "Action{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Action") + } + + companion object { + + @JvmStatic fun ofDecline(decline: DeclineAction) = Action(decline = decline) + + @JvmStatic + fun ofRequireTfa(requireTfa: RequireTfaAction) = Action(requireTfa = requireTfa) + } + + /** + * An interface that defines how to map each variant of [Action] to a value of type [T]. + */ + interface Visitor { + + fun visitDecline(decline: DeclineAction): T + + fun visitRequireTfa(requireTfa: RequireTfaAction): T + + /** + * Maps an unknown variant of [Action] to a value of type [T]. + * + * An instance of [Action] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws LithicInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw LithicInvalidDataException("Unknown Action: $json") + } + } + + internal class Deserializer : BaseDeserializer(Action::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Action { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Action(decline = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Action(requireTfa = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from boolean). + 0 -> Action(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Action::class) { + + override fun serialize( + value: Action, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.decline != null -> generator.writeObject(value.decline) + value.requireTfa != null -> generator.writeObject(value.requireTfa) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Action") + } + } + } + + class DeclineAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val explanation: JsonField, + private val reason: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of(), + @JsonProperty("reason") + @ExcludeMissing + reason: JsonField = JsonMissing.of(), + ) : this(type, explanation, reason, mutableMapOf()) + + /** + * Decline the tokenization request + * + * @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 type(): Type = type.getRequired("type") + + /** + * Optional explanation for why this action was taken + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun explanation(): Optional = explanation.getOptional("explanation") + + /** + * Reason code for declining the tokenization request + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun reason(): Optional = reason.getOptional("reason") + + /** + * 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 + + /** + * Returns the raw JSON value of [explanation]. + * + * Unlike [explanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("explanation") + @ExcludeMissing + fun _explanation(): JsonField = explanation + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + @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 [DeclineAction]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [DeclineAction]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var explanation: JsonField = JsonMissing.of() + private var reason: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(declineAction: DeclineAction) = apply { + type = declineAction.type + explanation = declineAction.explanation + reason = declineAction.reason + additionalProperties = declineAction.additionalProperties.toMutableMap() + } + + /** Decline the tokenization request */ + 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 } + + /** Optional explanation for why this action was taken */ + fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + + /** + * Sets [Builder.explanation] to an arbitrary JSON value. + * + * You should usually call [Builder.explanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun explanation(explanation: JsonField) = apply { + this.explanation = explanation + } + + /** Reason code for declining the tokenization request */ + fun reason(reason: Reason) = reason(JsonField.of(reason)) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [Reason] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + 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 [DeclineAction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): DeclineAction = + DeclineAction( + checkRequired("type", type), + explanation, + reason, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DeclineAction = apply { + if (validated) { + return@apply + } + + type().validate() + explanation() + reason().ifPresent { it.validate() } + 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 = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + (reason.asKnown().getOrNull()?.validity() ?: 0) + + /** Decline the tokenization request */ + 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 DECLINE = of("DECLINE") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + DECLINE + } + + /** + * 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 { + DECLINE, + /** + * 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) { + DECLINE -> Value.DECLINE + 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) { + DECLINE -> Known.DECLINE + else -> throw LithicInvalidDataException("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 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(): Type = 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 Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Reason code for declining the tokenization request */ + class Reason + @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 ACCOUNT_SCORE_1 = of("ACCOUNT_SCORE_1") + + @JvmField val DEVICE_SCORE_1 = of("DEVICE_SCORE_1") + + @JvmField + val ALL_WALLET_DECLINE_REASONS_PRESENT = + of("ALL_WALLET_DECLINE_REASONS_PRESENT") + + @JvmField + val WALLET_RECOMMENDED_DECISION_RED = of("WALLET_RECOMMENDED_DECISION_RED") + + @JvmField val CVC_MISMATCH = of("CVC_MISMATCH") + + @JvmField val CARD_EXPIRY_MONTH_MISMATCH = of("CARD_EXPIRY_MONTH_MISMATCH") + + @JvmField val CARD_EXPIRY_YEAR_MISMATCH = of("CARD_EXPIRY_YEAR_MISMATCH") + + @JvmField val CARD_INVALID_STATE = of("CARD_INVALID_STATE") + + @JvmField val CUSTOMER_RED_PATH = of("CUSTOMER_RED_PATH") + + @JvmField val INVALID_CUSTOMER_RESPONSE = of("INVALID_CUSTOMER_RESPONSE") + + @JvmField val NETWORK_FAILURE = of("NETWORK_FAILURE") + + @JvmField val GENERIC_DECLINE = of("GENERIC_DECLINE") + + @JvmField val DIGITAL_CARD_ART_REQUIRED = of("DIGITAL_CARD_ART_REQUIRED") + + @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) + } + + /** An enum containing [Reason]'s known values. */ + enum class Known { + ACCOUNT_SCORE_1, + DEVICE_SCORE_1, + ALL_WALLET_DECLINE_REASONS_PRESENT, + WALLET_RECOMMENDED_DECISION_RED, + CVC_MISMATCH, + CARD_EXPIRY_MONTH_MISMATCH, + CARD_EXPIRY_YEAR_MISMATCH, + CARD_INVALID_STATE, + CUSTOMER_RED_PATH, + INVALID_CUSTOMER_RESPONSE, + NETWORK_FAILURE, + GENERIC_DECLINE, + DIGITAL_CARD_ART_REQUIRED, + } + + /** + * An enum containing [Reason]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Reason] 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 { + ACCOUNT_SCORE_1, + DEVICE_SCORE_1, + ALL_WALLET_DECLINE_REASONS_PRESENT, + WALLET_RECOMMENDED_DECISION_RED, + CVC_MISMATCH, + CARD_EXPIRY_MONTH_MISMATCH, + CARD_EXPIRY_YEAR_MISMATCH, + CARD_INVALID_STATE, + CUSTOMER_RED_PATH, + INVALID_CUSTOMER_RESPONSE, + NETWORK_FAILURE, + GENERIC_DECLINE, + DIGITAL_CARD_ART_REQUIRED, + /** + * An enum member indicating that [Reason] 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) { + ACCOUNT_SCORE_1 -> Value.ACCOUNT_SCORE_1 + DEVICE_SCORE_1 -> Value.DEVICE_SCORE_1 + ALL_WALLET_DECLINE_REASONS_PRESENT -> + Value.ALL_WALLET_DECLINE_REASONS_PRESENT + WALLET_RECOMMENDED_DECISION_RED -> Value.WALLET_RECOMMENDED_DECISION_RED + CVC_MISMATCH -> Value.CVC_MISMATCH + CARD_EXPIRY_MONTH_MISMATCH -> Value.CARD_EXPIRY_MONTH_MISMATCH + CARD_EXPIRY_YEAR_MISMATCH -> Value.CARD_EXPIRY_YEAR_MISMATCH + CARD_INVALID_STATE -> Value.CARD_INVALID_STATE + CUSTOMER_RED_PATH -> Value.CUSTOMER_RED_PATH + INVALID_CUSTOMER_RESPONSE -> Value.INVALID_CUSTOMER_RESPONSE + NETWORK_FAILURE -> Value.NETWORK_FAILURE + GENERIC_DECLINE -> Value.GENERIC_DECLINE + DIGITAL_CARD_ART_REQUIRED -> Value.DIGITAL_CARD_ART_REQUIRED + 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) { + ACCOUNT_SCORE_1 -> Known.ACCOUNT_SCORE_1 + DEVICE_SCORE_1 -> Known.DEVICE_SCORE_1 + ALL_WALLET_DECLINE_REASONS_PRESENT -> + Known.ALL_WALLET_DECLINE_REASONS_PRESENT + WALLET_RECOMMENDED_DECISION_RED -> Known.WALLET_RECOMMENDED_DECISION_RED + CVC_MISMATCH -> Known.CVC_MISMATCH + CARD_EXPIRY_MONTH_MISMATCH -> Known.CARD_EXPIRY_MONTH_MISMATCH + CARD_EXPIRY_YEAR_MISMATCH -> Known.CARD_EXPIRY_YEAR_MISMATCH + CARD_INVALID_STATE -> Known.CARD_INVALID_STATE + CUSTOMER_RED_PATH -> Known.CUSTOMER_RED_PATH + INVALID_CUSTOMER_RESPONSE -> Known.INVALID_CUSTOMER_RESPONSE + NETWORK_FAILURE -> Known.NETWORK_FAILURE + GENERIC_DECLINE -> Known.GENERIC_DECLINE + DIGITAL_CARD_ART_REQUIRED -> Known.DIGITAL_CARD_ART_REQUIRED + else -> throw LithicInvalidDataException("Unknown Reason: $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(): Reason = 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 Reason && 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 DeclineAction && + type == other.type && + explanation == other.explanation && + reason == other.reason && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, explanation, reason, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DeclineAction{type=$type, explanation=$explanation, reason=$reason, additionalProperties=$additionalProperties}" + } + + class RequireTfaAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val explanation: JsonField, + private val reason: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of(), + @JsonProperty("reason") + @ExcludeMissing + reason: JsonField = JsonMissing.of(), + ) : this(type, explanation, reason, mutableMapOf()) + + /** + * Require two-factor authentication for the tokenization request + * + * @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 type(): Type = type.getRequired("type") + + /** + * Optional explanation for why this action was taken + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun explanation(): Optional = explanation.getOptional("explanation") + + /** + * Reason code for requiring two-factor authentication + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun reason(): Optional = reason.getOptional("reason") + + /** + * 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 + + /** + * Returns the raw JSON value of [explanation]. + * + * Unlike [explanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("explanation") + @ExcludeMissing + fun _explanation(): JsonField = explanation + + /** + * Returns the raw JSON value of [reason]. + * + * Unlike [reason], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + + @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 [RequireTfaAction]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [RequireTfaAction]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var explanation: JsonField = JsonMissing.of() + private var reason: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(requireTfaAction: RequireTfaAction) = apply { + type = requireTfaAction.type + explanation = requireTfaAction.explanation + reason = requireTfaAction.reason + additionalProperties = requireTfaAction.additionalProperties.toMutableMap() + } + + /** Require two-factor authentication for the tokenization request */ + 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 } + + /** Optional explanation for why this action was taken */ + fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + + /** + * Sets [Builder.explanation] to an arbitrary JSON value. + * + * You should usually call [Builder.explanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun explanation(explanation: JsonField) = apply { + this.explanation = explanation + } + + /** Reason code for requiring two-factor authentication */ + fun reason(reason: Reason) = reason(JsonField.of(reason)) + + /** + * Sets [Builder.reason] to an arbitrary JSON value. + * + * You should usually call [Builder.reason] with a well-typed [Reason] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun reason(reason: JsonField) = apply { this.reason = reason } + + 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 [RequireTfaAction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): RequireTfaAction = + RequireTfaAction( + checkRequired("type", type), + explanation, + reason, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): RequireTfaAction = apply { + if (validated) { + return@apply + } + + type().validate() + explanation() + reason().ifPresent { it.validate() } + 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 = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + (reason.asKnown().getOrNull()?.validity() ?: 0) + + /** Require two-factor authentication for the tokenization request */ + 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 REQUIRE_TFA = of("REQUIRE_TFA") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + REQUIRE_TFA + } + + /** + * 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 { + REQUIRE_TFA, + /** + * 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) { + REQUIRE_TFA -> Value.REQUIRE_TFA + 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) { + REQUIRE_TFA -> Known.REQUIRE_TFA + else -> throw LithicInvalidDataException("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 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(): Type = 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 Type && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Reason code for requiring two-factor authentication */ + class Reason + @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 WALLET_RECOMMENDED_TFA = of("WALLET_RECOMMENDED_TFA") + + @JvmField val SUSPICIOUS_ACTIVITY = of("SUSPICIOUS_ACTIVITY") + + @JvmField val DEVICE_RECENTLY_LOST = of("DEVICE_RECENTLY_LOST") + + @JvmField val TOO_MANY_RECENT_ATTEMPTS = of("TOO_MANY_RECENT_ATTEMPTS") + + @JvmField val TOO_MANY_RECENT_TOKENS = of("TOO_MANY_RECENT_TOKENS") + + @JvmField + val TOO_MANY_DIFFERENT_CARDHOLDERS = of("TOO_MANY_DIFFERENT_CARDHOLDERS") + + @JvmField val OUTSIDE_HOME_TERRITORY = of("OUTSIDE_HOME_TERRITORY") + + @JvmField val HAS_SUSPENDED_TOKENS = of("HAS_SUSPENDED_TOKENS") + + @JvmField val HIGH_RISK = of("HIGH_RISK") + + @JvmField val ACCOUNT_SCORE_LOW = of("ACCOUNT_SCORE_LOW") + + @JvmField val DEVICE_SCORE_LOW = of("DEVICE_SCORE_LOW") + + @JvmField val CARD_STATE_TFA = of("CARD_STATE_TFA") + + @JvmField val HARDCODED_TFA = of("HARDCODED_TFA") + + @JvmField val CUSTOMER_RULE_TFA = of("CUSTOMER_RULE_TFA") + + @JvmField val DEVICE_HOST_CARD_EMULATION = of("DEVICE_HOST_CARD_EMULATION") + + @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) + } + + /** An enum containing [Reason]'s known values. */ + enum class Known { + WALLET_RECOMMENDED_TFA, + SUSPICIOUS_ACTIVITY, + DEVICE_RECENTLY_LOST, + TOO_MANY_RECENT_ATTEMPTS, + TOO_MANY_RECENT_TOKENS, + TOO_MANY_DIFFERENT_CARDHOLDERS, + OUTSIDE_HOME_TERRITORY, + HAS_SUSPENDED_TOKENS, + HIGH_RISK, + ACCOUNT_SCORE_LOW, + DEVICE_SCORE_LOW, + CARD_STATE_TFA, + HARDCODED_TFA, + CUSTOMER_RULE_TFA, + DEVICE_HOST_CARD_EMULATION, + } + + /** + * An enum containing [Reason]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Reason] 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 { + WALLET_RECOMMENDED_TFA, + SUSPICIOUS_ACTIVITY, + DEVICE_RECENTLY_LOST, + TOO_MANY_RECENT_ATTEMPTS, + TOO_MANY_RECENT_TOKENS, + TOO_MANY_DIFFERENT_CARDHOLDERS, + OUTSIDE_HOME_TERRITORY, + HAS_SUSPENDED_TOKENS, + HIGH_RISK, + ACCOUNT_SCORE_LOW, + DEVICE_SCORE_LOW, + CARD_STATE_TFA, + HARDCODED_TFA, + CUSTOMER_RULE_TFA, + DEVICE_HOST_CARD_EMULATION, + /** + * An enum member indicating that [Reason] 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) { + WALLET_RECOMMENDED_TFA -> Value.WALLET_RECOMMENDED_TFA + SUSPICIOUS_ACTIVITY -> Value.SUSPICIOUS_ACTIVITY + DEVICE_RECENTLY_LOST -> Value.DEVICE_RECENTLY_LOST + TOO_MANY_RECENT_ATTEMPTS -> Value.TOO_MANY_RECENT_ATTEMPTS + TOO_MANY_RECENT_TOKENS -> Value.TOO_MANY_RECENT_TOKENS + TOO_MANY_DIFFERENT_CARDHOLDERS -> Value.TOO_MANY_DIFFERENT_CARDHOLDERS + OUTSIDE_HOME_TERRITORY -> Value.OUTSIDE_HOME_TERRITORY + HAS_SUSPENDED_TOKENS -> Value.HAS_SUSPENDED_TOKENS + HIGH_RISK -> Value.HIGH_RISK + ACCOUNT_SCORE_LOW -> Value.ACCOUNT_SCORE_LOW + DEVICE_SCORE_LOW -> Value.DEVICE_SCORE_LOW + CARD_STATE_TFA -> Value.CARD_STATE_TFA + HARDCODED_TFA -> Value.HARDCODED_TFA + CUSTOMER_RULE_TFA -> Value.CUSTOMER_RULE_TFA + DEVICE_HOST_CARD_EMULATION -> Value.DEVICE_HOST_CARD_EMULATION + 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) { + WALLET_RECOMMENDED_TFA -> Known.WALLET_RECOMMENDED_TFA + SUSPICIOUS_ACTIVITY -> Known.SUSPICIOUS_ACTIVITY + DEVICE_RECENTLY_LOST -> Known.DEVICE_RECENTLY_LOST + TOO_MANY_RECENT_ATTEMPTS -> Known.TOO_MANY_RECENT_ATTEMPTS + TOO_MANY_RECENT_TOKENS -> Known.TOO_MANY_RECENT_TOKENS + TOO_MANY_DIFFERENT_CARDHOLDERS -> Known.TOO_MANY_DIFFERENT_CARDHOLDERS + OUTSIDE_HOME_TERRITORY -> Known.OUTSIDE_HOME_TERRITORY + HAS_SUSPENDED_TOKENS -> Known.HAS_SUSPENDED_TOKENS + HIGH_RISK -> Known.HIGH_RISK + ACCOUNT_SCORE_LOW -> Known.ACCOUNT_SCORE_LOW + DEVICE_SCORE_LOW -> Known.DEVICE_SCORE_LOW + CARD_STATE_TFA -> Known.CARD_STATE_TFA + HARDCODED_TFA -> Known.HARDCODED_TFA + CUSTOMER_RULE_TFA -> Known.CUSTOMER_RULE_TFA + DEVICE_HOST_CARD_EMULATION -> Known.DEVICE_HOST_CARD_EMULATION + else -> throw LithicInvalidDataException("Unknown Reason: $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(): Reason = 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 Reason && 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 RequireTfaAction && + type == other.type && + explanation == other.explanation && + reason == other.reason && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, explanation, reason, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RequireTfaAction{type=$type, explanation=$explanation, reason=$reason, additionalProperties=$additionalProperties}" + } + } + + /** The event stream during which the rule was evaluated */ + class EventStream @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 TOKENIZATION = of("TOKENIZATION") + + @JvmStatic fun of(value: String) = EventStream(JsonField.of(value)) + } + + /** An enum containing [EventStream]'s known values. */ + enum class Known { + TOKENIZATION + } + + /** + * An enum containing [EventStream]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EventStream] 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 { + TOKENIZATION, + /** + * An enum member indicating that [EventStream] 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) { + TOKENIZATION -> Value.TOKENIZATION + 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) { + TOKENIZATION -> Known.TOKENIZATION + else -> throw LithicInvalidDataException("Unknown EventStream: $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(): EventStream = 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 EventStream && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The state of the Auth Rule */ + class AuthRuleState @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 ACTIVE = of("ACTIVE") + + @JvmField val INACTIVE = of("INACTIVE") + + @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) + } + + /** An enum containing [AuthRuleState]'s known values. */ + enum class Known { + ACTIVE, + INACTIVE, + } + + /** + * An enum containing [AuthRuleState]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AuthRuleState] 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 { + ACTIVE, + INACTIVE, + /** + * An enum member indicating that [AuthRuleState] 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) { + ACTIVE -> Value.ACTIVE + INACTIVE -> Value.INACTIVE + 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) { + ACTIVE -> Known.ACTIVE + INACTIVE -> Known.INACTIVE + else -> throw LithicInvalidDataException("Unknown AuthRuleState: $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(): AuthRuleState = 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 AuthRuleState && 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 TokenizationResult && + token == other.token && + actions == other.actions && + authRuleToken == other.authRuleToken && + evaluationTime == other.evaluationTime && + eventStream == other.eventStream && + eventToken == other.eventToken && + mode == other.mode && + ruleVersion == other.ruleVersion && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "TokenizationResult{token=$token, actions=$actions, authRuleToken=$authRuleToken, evaluationTime=$evaluationTime, eventStream=$eventStream, eventToken=$eventToken, mode=$mode, ruleVersion=$ruleVersion, additionalProperties=$additionalProperties}" + } + + class AchResult + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val token: JsonField, + private val actions: JsonField>, + private val authRuleToken: JsonField, + private val evaluationTime: JsonField, + private val eventStream: JsonField, + private val eventToken: JsonField, + private val mode: JsonField, + private val ruleVersion: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of(), + @JsonProperty("actions") + @ExcludeMissing + actions: JsonField> = JsonMissing.of(), + @JsonProperty("auth_rule_token") + @ExcludeMissing + authRuleToken: JsonField = JsonMissing.of(), + @JsonProperty("evaluation_time") + @ExcludeMissing + evaluationTime: JsonField = JsonMissing.of(), + @JsonProperty("event_stream") + @ExcludeMissing + eventStream: JsonField = JsonMissing.of(), + @JsonProperty("event_token") + @ExcludeMissing + eventToken: JsonField = JsonMissing.of(), + @JsonProperty("mode") @ExcludeMissing mode: JsonField = JsonMissing.of(), + @JsonProperty("rule_version") + @ExcludeMissing + ruleVersion: JsonField = JsonMissing.of(), + ) : this( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + mutableMapOf(), + ) + + /** + * Globally unique identifier for the evaluation + * + * @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 token(): String = token.getRequired("token") + + /** + * Actions returned by the rule evaluation + * + * @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 actions(): List = actions.getRequired("actions") + + /** + * The Auth Rule token + * + * @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 authRuleToken(): String = authRuleToken.getRequired("auth_rule_token") + + /** + * Timestamp of the rule evaluation + * + * @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 evaluationTime(): OffsetDateTime = evaluationTime.getRequired("evaluation_time") + + /** + * The event stream during which the rule was evaluated + * + * @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 eventStream(): EventStream = eventStream.getRequired("event_stream") + + /** + * Token of the event that triggered the evaluation + * + * @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 eventToken(): String = eventToken.getRequired("event_token") + + /** + * The state of the Auth Rule + * + * @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 mode(): AuthRuleState = mode.getRequired("mode") + + /** + * Version of the rule that was evaluated + * + * @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 ruleVersion(): Long = ruleVersion.getRequired("rule_version") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + /** + * Returns the raw JSON value of [actions]. + * + * Unlike [actions], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("actions") @ExcludeMissing fun _actions(): JsonField> = actions + + /** + * Returns the raw JSON value of [authRuleToken]. + * + * Unlike [authRuleToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("auth_rule_token") + @ExcludeMissing + fun _authRuleToken(): JsonField = authRuleToken + + /** + * Returns the raw JSON value of [evaluationTime]. + * + * Unlike [evaluationTime], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("evaluation_time") + @ExcludeMissing + fun _evaluationTime(): JsonField = evaluationTime + + /** + * Returns the raw JSON value of [eventStream]. + * + * Unlike [eventStream], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_stream") + @ExcludeMissing + fun _eventStream(): JsonField = eventStream + + /** + * Returns the raw JSON value of [eventToken]. + * + * Unlike [eventToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("event_token") + @ExcludeMissing + fun _eventToken(): JsonField = eventToken + + /** + * Returns the raw JSON value of [mode]. + * + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + + /** + * Returns the raw JSON value of [ruleVersion]. + * + * Unlike [ruleVersion], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rule_version") + @ExcludeMissing + fun _ruleVersion(): JsonField = ruleVersion + + @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 [AchResult]. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AchResult]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var actions: JsonField>? = null + private var authRuleToken: JsonField? = null + private var evaluationTime: JsonField? = null + private var eventStream: JsonField? = null + private var eventToken: JsonField? = null + private var mode: JsonField? = null + private var ruleVersion: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(achResult: AchResult) = apply { + token = achResult.token + actions = achResult.actions.map { it.toMutableList() } + authRuleToken = achResult.authRuleToken + evaluationTime = achResult.evaluationTime + eventStream = achResult.eventStream + eventToken = achResult.eventToken + mode = achResult.mode + ruleVersion = achResult.ruleVersion + additionalProperties = achResult.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for the evaluation */ + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + /** Actions returned by the rule evaluation */ + fun actions(actions: List) = actions(JsonField.of(actions)) + + /** + * Sets [Builder.actions] to an arbitrary JSON value. + * + * You should usually call [Builder.actions] with a well-typed `List` value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun actions(actions: JsonField>) = apply { + this.actions = actions.map { it.toMutableList() } + } + + /** + * Adds a single [Action] to [actions]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addAction(action: Action) = apply { + actions = + (actions ?: JsonField.of(mutableListOf())).also { + checkKnown("actions", it).add(action) + } + } + + /** Alias for calling [addAction] with `Action.ofApprove(approve)`. */ + fun addAction(approve: Action.ApproveAction) = addAction(Action.ofApprove(approve)) + + /** Alias for calling [addAction] with `Action.ofReturnAction(returnAction)`. */ + fun addAction(returnAction: Action.ReturnAction) = + addAction(Action.ofReturnAction(returnAction)) + + /** The Auth Rule token */ + fun authRuleToken(authRuleToken: String) = authRuleToken(JsonField.of(authRuleToken)) + + /** + * Sets [Builder.authRuleToken] to an arbitrary JSON value. + * + * You should usually call [Builder.authRuleToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun authRuleToken(authRuleToken: JsonField) = apply { + this.authRuleToken = authRuleToken + } + + /** Timestamp of the rule evaluation */ + fun evaluationTime(evaluationTime: OffsetDateTime) = + evaluationTime(JsonField.of(evaluationTime)) + + /** + * Sets [Builder.evaluationTime] to an arbitrary JSON value. + * + * You should usually call [Builder.evaluationTime] with a well-typed [OffsetDateTime] + * value instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun evaluationTime(evaluationTime: JsonField) = apply { + this.evaluationTime = evaluationTime + } + + /** The event stream during which the rule was evaluated */ + fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) + + /** + * Sets [Builder.eventStream] to an arbitrary JSON value. + * + * You should usually call [Builder.eventStream] with a well-typed [EventStream] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventStream(eventStream: JsonField) = apply { + this.eventStream = eventStream + } + + /** Token of the event that triggered the evaluation */ + fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) + + /** + * Sets [Builder.eventToken] to an arbitrary JSON value. + * + * You should usually call [Builder.eventToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun eventToken(eventToken: JsonField) = apply { this.eventToken = eventToken } + + /** The state of the Auth Rule */ + fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) + + /** + * Sets [Builder.mode] to an arbitrary JSON value. + * + * You should usually call [Builder.mode] with a well-typed [AuthRuleState] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun mode(mode: JsonField) = apply { this.mode = mode } + + /** Version of the rule that was evaluated */ + fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) + + /** + * Sets [Builder.ruleVersion] to an arbitrary JSON value. + * + * You should usually call [Builder.ruleVersion] with a well-typed [Long] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun ruleVersion(ruleVersion: JsonField) = apply { this.ruleVersion = ruleVersion } + + 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 [AchResult]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AchResult = + AchResult( + checkRequired("token", token), + checkRequired("actions", actions).map { it.toImmutable() }, + checkRequired("authRuleToken", authRuleToken), + checkRequired("evaluationTime", evaluationTime), + checkRequired("eventStream", eventStream), + checkRequired("eventToken", eventToken), + checkRequired("mode", mode), + checkRequired("ruleVersion", ruleVersion), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AchResult = apply { + if (validated) { + return@apply + } + + token() + actions().forEach { it.validate() } + authRuleToken() + evaluationTime() + eventStream().validate() + eventToken() + mode().validate() + ruleVersion() + 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 (token.asKnown().isPresent) 1 else 0) + + (actions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (authRuleToken.asKnown().isPresent) 1 else 0) + + (if (evaluationTime.asKnown().isPresent) 1 else 0) + + (eventStream.asKnown().getOrNull()?.validity() ?: 0) + + (if (eventToken.asKnown().isPresent) 1 else 0) + + (mode.asKnown().getOrNull()?.validity() ?: 0) + + (if (ruleVersion.asKnown().isPresent) 1 else 0) + + @JsonDeserialize(using = Action.Deserializer::class) + @JsonSerialize(using = Action.Serializer::class) + class Action + private constructor( + private val approve: ApproveAction? = null, + private val returnAction: ReturnAction? = null, + private val _json: JsonValue? = null, + ) { + + fun approve(): Optional = Optional.ofNullable(approve) + + fun returnAction(): Optional = Optional.ofNullable(returnAction) + + fun isApprove(): Boolean = approve != null + + fun isReturnAction(): Boolean = returnAction != null + + fun asApprove(): ApproveAction = approve.getOrThrow("approve") + + fun asReturnAction(): ReturnAction = returnAction.getOrThrow("returnAction") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + approve != null -> visitor.visitApprove(approve) + returnAction != null -> visitor.visitReturnAction(returnAction) + else -> visitor.unknown(_json) + } + + private var validated: Boolean = false + + fun validate(): Action = apply { + if (validated) { + return@apply + } + + accept( + object : Visitor { + override fun visitApprove(approve: ApproveAction) { + approve.validate() + } + + override fun visitReturnAction(returnAction: ReturnAction) { + returnAction.validate() + } + } + ) + 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 = + accept( + object : Visitor { + override fun visitApprove(approve: ApproveAction) = approve.validity() + + override fun visitReturnAction(returnAction: ReturnAction) = + returnAction.validity() + + override fun unknown(json: JsonValue?) = 0 + } + ) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Action && + approve == other.approve && + returnAction == other.returnAction + } + + override fun hashCode(): Int = Objects.hash(approve, returnAction) + + override fun toString(): String = + when { + approve != null -> "Action{approve=$approve}" + returnAction != null -> "Action{returnAction=$returnAction}" + _json != null -> "Action{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Action") + } + + companion object { + + @JvmStatic fun ofApprove(approve: ApproveAction) = Action(approve = approve) + + @JvmStatic + fun ofReturnAction(returnAction: ReturnAction) = Action(returnAction = returnAction) + } + + /** + * An interface that defines how to map each variant of [Action] to a value of type [T]. + */ + interface Visitor { + + fun visitApprove(approve: ApproveAction): T + + fun visitReturnAction(returnAction: ReturnAction): T + + /** + * Maps an unknown variant of [Action] to a value of type [T]. + * + * An instance of [Action] can contain an unknown variant if it was deserialized + * from data that doesn't match any known variant. For example, if the SDK is on an + * older version than the API, then the API may respond with new variants that the + * SDK is unaware of. + * + * @throws LithicInvalidDataException in the default implementation. + */ + fun unknown(json: JsonValue?): T { + throw LithicInvalidDataException("Unknown Action: $json") + } + } + + internal class Deserializer : BaseDeserializer(Action::class) { + + override fun ObjectCodec.deserialize(node: JsonNode): Action { + val json = JsonValue.fromJsonNode(node) + + val bestMatches = + sequenceOf( + tryDeserialize(node, jacksonTypeRef())?.let { + Action(approve = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Action(returnAction = it, _json = json) + }, + ) + .filterNotNull() + .allMaxBy { it.validity() } + .toList() + return when (bestMatches.size) { + // This can happen if what we're deserializing is completely incompatible + // with all the possible variants (e.g. deserializing from boolean). + 0 -> Action(_json = json) + 1 -> bestMatches.single() + // If there's more than one match with the highest validity, then use the + // first completely valid match, or simply the first match if none are + // completely valid. + else -> bestMatches.firstOrNull { it.isValid() } ?: bestMatches.first() + } + } + } + + internal class Serializer : BaseSerializer(Action::class) { + + override fun serialize( + value: Action, + generator: JsonGenerator, + provider: SerializerProvider, + ) { + when { + value.approve != null -> generator.writeObject(value.approve) + value.returnAction != null -> generator.writeObject(value.returnAction) + value._json != null -> generator.writeObject(value._json) + else -> throw IllegalStateException("Invalid Action") + } + } + } + + class ApproveAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val explanation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of(), + ) : this(type, explanation, mutableMapOf()) + + /** + * Approve the ACH 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 type(): Type = type.getRequired("type") + + /** + * Optional explanation for why this action was taken + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun explanation(): Optional = explanation.getOptional("explanation") + + /** + * 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 + + /** + * Returns the raw JSON value of [explanation]. + * + * Unlike [explanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("explanation") + @ExcludeMissing + fun _explanation(): JsonField = explanation + + @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 [ApproveAction]. + * + * The following fields are required: + * ```java + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ApproveAction]. */ + class Builder internal constructor() { + + private var type: JsonField? = null + private var explanation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(approveAction: ApproveAction) = apply { + type = approveAction.type + explanation = approveAction.explanation + additionalProperties = approveAction.additionalProperties.toMutableMap() + } + + /** Approve the ACH transaction */ + 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 } + + /** Optional explanation for why this action was taken */ + fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + + /** + * Sets [Builder.explanation] to an arbitrary JSON value. + * + * You should usually call [Builder.explanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun explanation(explanation: JsonField) = apply { + this.explanation = explanation + } + + 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 [ApproveAction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ApproveAction = + ApproveAction( + checkRequired("type", type), + explanation, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ApproveAction = apply { + if (validated) { + return@apply + } + + type().validate() + explanation() + 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 = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + /** Approve the ACH transaction */ + 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 APPROVE = of("APPROVE") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + APPROVE + } + + /** + * 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 { + APPROVE, + /** + * 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) { + APPROVE -> Value.APPROVE + 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) { + APPROVE -> Known.APPROVE + else -> throw LithicInvalidDataException("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 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(): Type = 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 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 ApproveAction && + type == other.type && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(type, explanation, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ApproveAction{type=$type, explanation=$explanation, additionalProperties=$additionalProperties}" + } + + class ReturnAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val code: JsonField, + private val type: JsonField, + private val explanation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of(), + ) : this(code, type, explanation, mutableMapOf()) + + /** + * NACHA return code to use when returning the transaction. Note that the list of + * available return codes is subject to an allowlist configured at the program level + * + * @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 code(): Code = code.getRequired("code") + + /** + * Return the ACH 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 type(): Type = type.getRequired("type") + + /** + * Optional explanation for why this action was taken + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun explanation(): Optional = explanation.getOptional("explanation") + + /** + * Returns the raw JSON value of [code]. + * + * Unlike [code], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code + + /** + * 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 + + /** + * Returns the raw JSON value of [explanation]. + * + * Unlike [explanation], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("explanation") + @ExcludeMissing + fun _explanation(): JsonField = explanation + + @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 [ReturnAction]. + * + * The following fields are required: + * ```java + * .code() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ReturnAction]. */ + class Builder internal constructor() { + + private var code: JsonField? = null + private var type: JsonField? = null + private var explanation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(returnAction: ReturnAction) = apply { + code = returnAction.code + type = returnAction.type + explanation = returnAction.explanation + additionalProperties = returnAction.additionalProperties.toMutableMap() + } + + /** + * NACHA return code to use when returning the transaction. Note that the list + * of available return codes is subject to an allowlist configured at the + * program level + */ + fun code(code: Code) = code(JsonField.of(code)) + + /** + * Sets [Builder.code] to an arbitrary JSON value. + * + * You should usually call [Builder.code] with a well-typed [Code] value + * instead. This method is primarily for setting the field to an undocumented or + * not yet supported value. + */ + fun code(code: JsonField) = apply { this.code = code } + + /** Return the ACH transaction */ + 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 } + + /** Optional explanation for why this action was taken */ + fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + + /** + * Sets [Builder.explanation] to an arbitrary JSON value. + * + * You should usually call [Builder.explanation] with a well-typed [String] + * value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun explanation(explanation: JsonField) = apply { + this.explanation = explanation + } + + 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 [ReturnAction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .code() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): ReturnAction = + ReturnAction( + checkRequired("code", code), + checkRequired("type", type), + explanation, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ReturnAction = apply { + if (validated) { + return@apply + } + + code().validate() + type().validate() + explanation() + 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 = + (code.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + /** + * NACHA return code to use when returning the transaction. Note that the list of + * available return codes is subject to an allowlist configured at the program level + */ + class Code @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 R01 = of("R01") + + @JvmField val R02 = of("R02") + + @JvmField val R03 = of("R03") + + @JvmField val R04 = of("R04") + + @JvmField val R05 = of("R05") + + @JvmField val R06 = of("R06") + + @JvmField val R07 = of("R07") + + @JvmField val R08 = of("R08") + + @JvmField val R09 = of("R09") + + @JvmField val R10 = of("R10") + + @JvmField val R11 = of("R11") + + @JvmField val R12 = of("R12") + + @JvmField val R13 = of("R13") + + @JvmField val R14 = of("R14") + + @JvmField val R15 = of("R15") + + @JvmField val R16 = of("R16") + + @JvmField val R17 = of("R17") + + @JvmField val R18 = of("R18") + + @JvmField val R19 = of("R19") + + @JvmField val R20 = of("R20") + + @JvmField val R21 = of("R21") + + @JvmField val R22 = of("R22") + + @JvmField val R23 = of("R23") + + @JvmField val R24 = of("R24") + + @JvmField val R25 = of("R25") + + @JvmField val R26 = of("R26") + + @JvmField val R27 = of("R27") + + @JvmField val R28 = of("R28") + + @JvmField val R29 = of("R29") + + @JvmField val R30 = of("R30") + + @JvmField val R31 = of("R31") + + @JvmField val R32 = of("R32") + + @JvmField val R33 = of("R33") + + @JvmField val R34 = of("R34") + + @JvmField val R35 = of("R35") + + @JvmField val R36 = of("R36") + + @JvmField val R37 = of("R37") + + @JvmField val R38 = of("R38") + + @JvmField val R39 = of("R39") + + @JvmField val R40 = of("R40") + + @JvmField val R41 = of("R41") + + @JvmField val R42 = of("R42") + + @JvmField val R43 = of("R43") + + @JvmField val R44 = of("R44") + + @JvmField val R45 = of("R45") + + @JvmField val R46 = of("R46") + + @JvmField val R47 = of("R47") + + @JvmField val R50 = of("R50") + + @JvmField val R51 = of("R51") + + @JvmField val R52 = of("R52") + + @JvmField val R53 = of("R53") + + @JvmField val R61 = of("R61") + + @JvmField val R62 = of("R62") + + @JvmField val R67 = of("R67") + + @JvmField val R68 = of("R68") + + @JvmField val R69 = of("R69") + + @JvmField val R70 = of("R70") + + @JvmField val R71 = of("R71") + + @JvmField val R72 = of("R72") + + @JvmField val R73 = of("R73") + + @JvmField val R74 = of("R74") + + @JvmField val R75 = of("R75") + + @JvmField val R76 = of("R76") + + @JvmField val R77 = of("R77") + + @JvmField val R80 = of("R80") + + @JvmField val R81 = of("R81") + + @JvmField val R82 = of("R82") + + @JvmField val R83 = of("R83") + + @JvmField val R84 = of("R84") + + @JvmField val R85 = of("R85") + + @JvmStatic fun of(value: String) = Code(JsonField.of(value)) + } + + /** An enum containing [Code]'s known values. */ + enum class Known { + R01, + R02, + R03, + R04, + R05, + R06, + R07, + R08, + R09, + R10, + R11, + R12, + R13, + R14, + R15, + R16, + R17, + R18, + R19, + R20, + R21, + R22, + R23, + R24, + R25, + R26, + R27, + R28, + R29, + R30, + R31, + R32, + R33, + R34, + R35, + R36, + R37, + R38, + R39, + R40, + R41, + R42, + R43, + R44, + R45, + R46, + R47, + R50, + R51, + R52, + R53, + R61, + R62, + R67, + R68, + R69, + R70, + R71, + R72, + R73, + R74, + R75, + R76, + R77, + R80, + R81, + R82, + R83, + R84, + R85, + } + + /** + * An enum containing [Code]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [Code] 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 { + R01, + R02, + R03, + R04, + R05, + R06, + R07, + R08, + R09, + R10, + R11, + R12, + R13, + R14, + R15, + R16, + R17, + R18, + R19, + R20, + R21, + R22, + R23, + R24, + R25, + R26, + R27, + R28, + R29, + R30, + R31, + R32, + R33, + R34, + R35, + R36, + R37, + R38, + R39, + R40, + R41, + R42, + R43, + R44, + R45, + R46, + R47, + R50, + R51, + R52, + R53, + R61, + R62, + R67, + R68, + R69, + R70, + R71, + R72, + R73, + R74, + R75, + R76, + R77, + R80, + R81, + R82, + R83, + R84, + R85, + /** + * An enum member indicating that [Code] 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) { + R01 -> Value.R01 + R02 -> Value.R02 + R03 -> Value.R03 + R04 -> Value.R04 + R05 -> Value.R05 + R06 -> Value.R06 + R07 -> Value.R07 + R08 -> Value.R08 + R09 -> Value.R09 + R10 -> Value.R10 + R11 -> Value.R11 + R12 -> Value.R12 + R13 -> Value.R13 + R14 -> Value.R14 + R15 -> Value.R15 + R16 -> Value.R16 + R17 -> Value.R17 + R18 -> Value.R18 + R19 -> Value.R19 + R20 -> Value.R20 + R21 -> Value.R21 + R22 -> Value.R22 + R23 -> Value.R23 + R24 -> Value.R24 + R25 -> Value.R25 + R26 -> Value.R26 + R27 -> Value.R27 + R28 -> Value.R28 + R29 -> Value.R29 + R30 -> Value.R30 + R31 -> Value.R31 + R32 -> Value.R32 + R33 -> Value.R33 + R34 -> Value.R34 + R35 -> Value.R35 + R36 -> Value.R36 + R37 -> Value.R37 + R38 -> Value.R38 + R39 -> Value.R39 + R40 -> Value.R40 + R41 -> Value.R41 + R42 -> Value.R42 + R43 -> Value.R43 + R44 -> Value.R44 + R45 -> Value.R45 + R46 -> Value.R46 + R47 -> Value.R47 + R50 -> Value.R50 + R51 -> Value.R51 + R52 -> Value.R52 + R53 -> Value.R53 + R61 -> Value.R61 + R62 -> Value.R62 + R67 -> Value.R67 + R68 -> Value.R68 + R69 -> Value.R69 + R70 -> Value.R70 + R71 -> Value.R71 + R72 -> Value.R72 + R73 -> Value.R73 + R74 -> Value.R74 + R75 -> Value.R75 + R76 -> Value.R76 + R77 -> Value.R77 + R80 -> Value.R80 + R81 -> Value.R81 + R82 -> Value.R82 + R83 -> Value.R83 + R84 -> Value.R84 + R85 -> Value.R85 + 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) { + R01 -> Known.R01 + R02 -> Known.R02 + R03 -> Known.R03 + R04 -> Known.R04 + R05 -> Known.R05 + R06 -> Known.R06 + R07 -> Known.R07 + R08 -> Known.R08 + R09 -> Known.R09 + R10 -> Known.R10 + R11 -> Known.R11 + R12 -> Known.R12 + R13 -> Known.R13 + R14 -> Known.R14 + R15 -> Known.R15 + R16 -> Known.R16 + R17 -> Known.R17 + R18 -> Known.R18 + R19 -> Known.R19 + R20 -> Known.R20 + R21 -> Known.R21 + R22 -> Known.R22 + R23 -> Known.R23 + R24 -> Known.R24 + R25 -> Known.R25 + R26 -> Known.R26 + R27 -> Known.R27 + R28 -> Known.R28 + R29 -> Known.R29 + R30 -> Known.R30 + R31 -> Known.R31 + R32 -> Known.R32 + R33 -> Known.R33 + R34 -> Known.R34 + R35 -> Known.R35 + R36 -> Known.R36 + R37 -> Known.R37 + R38 -> Known.R38 + R39 -> Known.R39 + R40 -> Known.R40 + R41 -> Known.R41 + R42 -> Known.R42 + R43 -> Known.R43 + R44 -> Known.R44 + R45 -> Known.R45 + R46 -> Known.R46 + R47 -> Known.R47 + R50 -> Known.R50 + R51 -> Known.R51 + R52 -> Known.R52 + R53 -> Known.R53 + R61 -> Known.R61 + R62 -> Known.R62 + R67 -> Known.R67 + R68 -> Known.R68 + R69 -> Known.R69 + R70 -> Known.R70 + R71 -> Known.R71 + R72 -> Known.R72 + R73 -> Known.R73 + R74 -> Known.R74 + R75 -> Known.R75 + R76 -> Known.R76 + R77 -> Known.R77 + R80 -> Known.R80 + R81 -> Known.R81 + R82 -> Known.R82 + R83 -> Known.R83 + R84 -> Known.R84 + R85 -> Known.R85 + else -> throw LithicInvalidDataException("Unknown Code: $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(): Code = 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 Code && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Return the ACH transaction */ + 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 RETURN = of("RETURN") + + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } + + /** An enum containing [Type]'s known values. */ + enum class Known { + RETURN + } + + /** + * 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 { + RETURN, + /** + * 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) { + RETURN -> Value.RETURN + 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) { + RETURN -> Known.RETURN + else -> throw LithicInvalidDataException("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 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(): Type = 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 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 ReturnAction && + code == other.code && + type == other.type && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(code, type, explanation, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ReturnAction{code=$code, type=$type, explanation=$explanation, additionalProperties=$additionalProperties}" + } + } + + /** The event stream during which the rule was evaluated */ + class EventStream @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 ACH_CREDIT_RECEIPT = of("ACH_CREDIT_RECEIPT") + + @JvmField val ACH_DEBIT_RECEIPT = of("ACH_DEBIT_RECEIPT") + + @JvmStatic fun of(value: String) = EventStream(JsonField.of(value)) + } + + /** An enum containing [EventStream]'s known values. */ + enum class Known { + ACH_CREDIT_RECEIPT, + ACH_DEBIT_RECEIPT, + } + + /** + * An enum containing [EventStream]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EventStream] 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 { + ACH_CREDIT_RECEIPT, + ACH_DEBIT_RECEIPT, + /** + * An enum member indicating that [EventStream] 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) { + ACH_CREDIT_RECEIPT -> Value.ACH_CREDIT_RECEIPT + ACH_DEBIT_RECEIPT -> Value.ACH_DEBIT_RECEIPT + 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) { + ACH_CREDIT_RECEIPT -> Known.ACH_CREDIT_RECEIPT + ACH_DEBIT_RECEIPT -> Known.ACH_DEBIT_RECEIPT + else -> throw LithicInvalidDataException("Unknown EventStream: $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(): EventStream = 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 EventStream && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The state of the Auth Rule */ + class AuthRuleState @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 ACTIVE = of("ACTIVE") + + @JvmField val INACTIVE = of("INACTIVE") + + @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) + } + + /** An enum containing [AuthRuleState]'s known values. */ + enum class Known { + ACTIVE, + INACTIVE, + } + + /** + * An enum containing [AuthRuleState]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [AuthRuleState] 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 { + ACTIVE, + INACTIVE, + /** + * An enum member indicating that [AuthRuleState] 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) { + ACTIVE -> Value.ACTIVE + INACTIVE -> Value.INACTIVE + 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) { + ACTIVE -> Known.ACTIVE + INACTIVE -> Known.INACTIVE + else -> throw LithicInvalidDataException("Unknown AuthRuleState: $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(): AuthRuleState = 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 AuthRuleState && 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 AchResult && + token == other.token && + actions == other.actions && + authRuleToken == other.authRuleToken && + evaluationTime == other.evaluationTime && + eventStream == other.eventStream && + eventToken == other.eventToken && + mode == other.mode && + ruleVersion == other.ruleVersion && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AchResult{token=$token, actions=$actions, authRuleToken=$authRuleToken, evaluationTime=$evaluationTime, eventStream=$eventStream, eventToken=$eventToken, mode=$mode, ruleVersion=$ruleVersion, additionalProperties=$additionalProperties}" + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt index 6fa120ac..a2f1ff8a 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt @@ -21,6 +21,9 @@ import com.lithic.api.models.AccountHolderUpdateParams import com.lithic.api.models.AccountHolderUpdateResponse import com.lithic.api.models.AccountHolderUploadDocumentParams import com.lithic.api.models.Document +import com.lithic.api.models.Kyb +import com.lithic.api.models.Kyc +import com.lithic.api.models.KycExempt import java.util.concurrent.CompletableFuture import java.util.function.Consumer @@ -56,6 +59,63 @@ interface AccountHolderServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see create */ + fun create( + body: AccountHolderCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AccountHolderCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create( + body: AccountHolderCreateParams.Body + ): CompletableFuture = create(body, RequestOptions.none()) + + /** @see create */ + fun create( + kyb: Kyb, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AccountHolderCreateParams.Body.ofKyb(kyb), requestOptions) + + /** @see create */ + fun create(kyb: Kyb): CompletableFuture = + create(kyb, RequestOptions.none()) + + /** @see create */ + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AccountHolderCreateParams.Body.ofKybDelegated(kybDelegated), requestOptions) + + /** @see create */ + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated + ): CompletableFuture = create(kybDelegated, RequestOptions.none()) + + /** @see create */ + fun create( + kyc: Kyc, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AccountHolderCreateParams.Body.ofKyc(kyc), requestOptions) + + /** @see create */ + fun create(kyc: Kyc): CompletableFuture = + create(kyc, RequestOptions.none()) + + /** @see create */ + fun create( + kycExempt: KycExempt, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AccountHolderCreateParams.Body.ofKycExempt(kycExempt), requestOptions) + + /** @see create */ + fun create(kycExempt: KycExempt): CompletableFuture = + create(kycExempt, RequestOptions.none()) + /** Get an Individual or Business Account Holder and/or their KYC or KYB evaluation status. */ fun retrieve(accountHolderToken: String): CompletableFuture = retrieve(accountHolderToken, AccountHolderRetrieveParams.none()) @@ -356,6 +416,67 @@ interface AccountHolderServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see create */ + fun create( + body: AccountHolderCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AccountHolderCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create( + body: AccountHolderCreateParams.Body + ): CompletableFuture> = + create(body, RequestOptions.none()) + + /** @see create */ + fun create( + kyb: Kyb, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AccountHolderCreateParams.Body.ofKyb(kyb), requestOptions) + + /** @see create */ + fun create(kyb: Kyb): CompletableFuture> = + create(kyb, RequestOptions.none()) + + /** @see create */ + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AccountHolderCreateParams.Body.ofKybDelegated(kybDelegated), requestOptions) + + /** @see create */ + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated + ): CompletableFuture> = + create(kybDelegated, RequestOptions.none()) + + /** @see create */ + fun create( + kyc: Kyc, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AccountHolderCreateParams.Body.ofKyc(kyc), requestOptions) + + /** @see create */ + fun create(kyc: Kyc): CompletableFuture> = + create(kyc, RequestOptions.none()) + + /** @see create */ + fun create( + kycExempt: KycExempt, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AccountHolderCreateParams.Body.ofKycExempt(kycExempt), requestOptions) + + /** @see create */ + fun create( + kycExempt: KycExempt + ): CompletableFuture> = + create(kycExempt, RequestOptions.none()) + /** * Returns a raw HTTP response for `get /v1/account_holders/{account_holder_token}`, but is * otherwise the same as [AccountHolderServiceAsync.retrieve]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsync.kt index ad0625da..8dd832a5 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsync.kt @@ -39,25 +39,78 @@ interface ExternalBankAccountServiceAsync { fun microDeposits(): MicroDepositServiceAsync /** Creates an external bank account within a program or Lithic account. */ - fun create(): CompletableFuture = - create(ExternalBankAccountCreateParams.none()) + fun create( + params: ExternalBankAccountCreateParams + ): CompletableFuture = create(params, RequestOptions.none()) /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), + params: ExternalBankAccountCreateParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() - ): CompletableFuture = create(params, RequestOptions.none()) + body: ExternalBankAccountCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(ExternalBankAccountCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create( + body: ExternalBankAccountCreateParams.Body + ): CompletableFuture = create(body, RequestOptions.none()) + + /** @see create */ + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create( + ExternalBankAccountCreateParams.Body.ofBankVerifiedCreateBankAccountApiRequest( + bankVerifiedCreateBankAccountApiRequest + ), + requestOptions, + ) + + /** @see create */ + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + ): CompletableFuture = + create(bankVerifiedCreateBankAccountApiRequest, RequestOptions.none()) + + /** @see create */ + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create( + ExternalBankAccountCreateParams.Body.ofExternallyVerified(externallyVerified), + requestOptions, + ) + + /** @see create */ + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest + ): CompletableFuture = + create(externallyVerified, RequestOptions.none()) /** @see create */ fun create( - requestOptions: RequestOptions + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture = - create(ExternalBankAccountCreateParams.none(), requestOptions) + create(ExternalBankAccountCreateParams.Body.ofUnverified(unverified), requestOptions) + + /** @see create */ + fun create( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest + ): CompletableFuture = + create(unverified, RequestOptions.none()) /** Get the external bank account by token. */ fun retrieve( @@ -320,26 +373,80 @@ interface ExternalBankAccountServiceAsync { * Returns a raw HTTP response for `post /v1/external_bank_accounts`, but is otherwise the * same as [ExternalBankAccountServiceAsync.create]. */ - fun create(): CompletableFuture> = - create(ExternalBankAccountCreateParams.none()) + fun create( + params: ExternalBankAccountCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), + params: ExternalBankAccountCreateParams, requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() + body: ExternalBankAccountCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> = - create(params, RequestOptions.none()) + create(ExternalBankAccountCreateParams.builder().body(body).build(), requestOptions) /** @see create */ fun create( - requestOptions: RequestOptions + body: ExternalBankAccountCreateParams.Body + ): CompletableFuture> = + create(body, RequestOptions.none()) + + /** @see create */ + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create( + ExternalBankAccountCreateParams.Body.ofBankVerifiedCreateBankAccountApiRequest( + bankVerifiedCreateBankAccountApiRequest + ), + requestOptions, + ) + + /** @see create */ + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + ): CompletableFuture> = + create(bankVerifiedCreateBankAccountApiRequest, RequestOptions.none()) + + /** @see create */ + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create( + ExternalBankAccountCreateParams.Body.ofExternallyVerified(externallyVerified), + requestOptions, + ) + + /** @see create */ + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest + ): CompletableFuture> = + create(externallyVerified, RequestOptions.none()) + + /** @see create */ + fun create( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(ExternalBankAccountCreateParams.Body.ofUnverified(unverified), requestOptions) + + /** @see create */ + fun create( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest ): CompletableFuture> = - create(ExternalBankAccountCreateParams.none(), requestOptions) + create(unverified, RequestOptions.none()) /** * Returns a raw HTTP response for `get diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncImpl.kt index 92e745fc..9514f7e6 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncImpl.kt @@ -139,7 +139,7 @@ internal constructor(private val clientOptions: ClientOptions) : ExternalBankAcc .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) .addPathSegments("v1", "external_bank_accounts") - .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt index f283ca68..af65aaf2 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsyncImpl.kt @@ -7,7 +7,6 @@ import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicException -import com.lithic.api.errors.LithicInvalidDataException import com.lithic.api.models.ParsedWebhookEvent import com.lithic.api.services.blocking.WebhookServiceImpl import java.util.function.Consumer diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsync.kt index 0998d0b6..42b3f62d 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsync.kt @@ -12,6 +12,8 @@ import com.lithic.api.models.AuthRuleV2DeleteParams import com.lithic.api.models.AuthRuleV2DraftParams import com.lithic.api.models.AuthRuleV2ListPageAsync import com.lithic.api.models.AuthRuleV2ListParams +import com.lithic.api.models.AuthRuleV2ListResultsPageAsync +import com.lithic.api.models.AuthRuleV2ListResultsParams import com.lithic.api.models.AuthRuleV2PromoteParams import com.lithic.api.models.AuthRuleV2RetrieveFeaturesParams import com.lithic.api.models.AuthRuleV2RetrieveParams @@ -49,6 +51,53 @@ interface V2ServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see create */ + fun create( + body: AuthRuleV2CreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AuthRuleV2CreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create(body: AuthRuleV2CreateParams.Body): CompletableFuture = + create(body, RequestOptions.none()) + + /** @see create */ + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AuthRuleV2CreateParams.Body.ofAccountLevelRule(accountLevelRule), requestOptions) + + /** @see create */ + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule + ): CompletableFuture = create(accountLevelRule, RequestOptions.none()) + + /** @see create */ + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AuthRuleV2CreateParams.Body.ofCardLevelRule(cardLevelRule), requestOptions) + + /** @see create */ + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule + ): CompletableFuture = create(cardLevelRule, RequestOptions.none()) + + /** @see create */ + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(AuthRuleV2CreateParams.Body.ofProgramLevelRule(programLevelRule), requestOptions) + + /** @see create */ + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule + ): CompletableFuture = create(programLevelRule, RequestOptions.none()) + /** Fetches a V2 Auth rule by its token */ fun retrieve(authRuleToken: String): CompletableFuture = retrieve(authRuleToken, AuthRuleV2RetrieveParams.none()) @@ -198,6 +247,35 @@ interface V2ServiceAsync { fun draft(authRuleToken: String, requestOptions: RequestOptions): CompletableFuture = draft(authRuleToken, AuthRuleV2DraftParams.none(), requestOptions) + /** + * Lists Auth Rule evaluation results. + * + * **Limitations:** + * - Results are available for the past 3 months only + * - At least one filter (`event_token` or `auth_rule_token`) must be provided + * - When filtering by `event_token`, pagination is not supported + */ + fun listResults(): CompletableFuture = + listResults(AuthRuleV2ListResultsParams.none()) + + /** @see listResults */ + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see listResults */ + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none() + ): CompletableFuture = + listResults(params, RequestOptions.none()) + + /** @see listResults */ + fun listResults( + requestOptions: RequestOptions + ): CompletableFuture = + listResults(AuthRuleV2ListResultsParams.none(), requestOptions) + /** * Promotes the draft version of an Auth rule to the currently active version such that it is * enforced in the respective stream. @@ -345,6 +423,57 @@ interface V2ServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see create */ + fun create( + body: AuthRuleV2CreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AuthRuleV2CreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create( + body: AuthRuleV2CreateParams.Body + ): CompletableFuture> = create(body, RequestOptions.none()) + + /** @see create */ + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AuthRuleV2CreateParams.Body.ofAccountLevelRule(accountLevelRule), requestOptions) + + /** @see create */ + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule + ): CompletableFuture> = + create(accountLevelRule, RequestOptions.none()) + + /** @see create */ + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AuthRuleV2CreateParams.Body.ofCardLevelRule(cardLevelRule), requestOptions) + + /** @see create */ + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule + ): CompletableFuture> = + create(cardLevelRule, RequestOptions.none()) + + /** @see create */ + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create(AuthRuleV2CreateParams.Body.ofProgramLevelRule(programLevelRule), requestOptions) + + /** @see create */ + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule + ): CompletableFuture> = + create(programLevelRule, RequestOptions.none()) + /** * Returns a raw HTTP response for `get /v2/auth_rules/{auth_rule_token}`, but is otherwise * the same as [V2ServiceAsync.retrieve]. @@ -515,6 +644,31 @@ interface V2ServiceAsync { ): CompletableFuture> = draft(authRuleToken, AuthRuleV2DraftParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `get /v2/auth_rules/results`, but is otherwise the same + * as [V2ServiceAsync.listResults]. + */ + fun listResults(): CompletableFuture> = + listResults(AuthRuleV2ListResultsParams.none()) + + /** @see listResults */ + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see listResults */ + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none() + ): CompletableFuture> = + listResults(params, RequestOptions.none()) + + /** @see listResults */ + fun listResults( + requestOptions: RequestOptions + ): CompletableFuture> = + listResults(AuthRuleV2ListResultsParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /v2/auth_rules/{auth_rule_token}/promote`, but is * otherwise the same as [V2ServiceAsync.promote]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncImpl.kt index cdc0b2f2..0f667c25 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncImpl.kt @@ -24,6 +24,9 @@ import com.lithic.api.models.AuthRuleV2DraftParams import com.lithic.api.models.AuthRuleV2ListPageAsync import com.lithic.api.models.AuthRuleV2ListPageResponse import com.lithic.api.models.AuthRuleV2ListParams +import com.lithic.api.models.AuthRuleV2ListResultsPageAsync +import com.lithic.api.models.AuthRuleV2ListResultsPageResponse +import com.lithic.api.models.AuthRuleV2ListResultsParams import com.lithic.api.models.AuthRuleV2PromoteParams import com.lithic.api.models.AuthRuleV2RetrieveFeaturesParams import com.lithic.api.models.AuthRuleV2RetrieveParams @@ -95,6 +98,13 @@ class V2ServiceAsyncImpl internal constructor(private val clientOptions: ClientO // post /v2/auth_rules/{auth_rule_token}/draft withRawResponse().draft(params, requestOptions).thenApply { it.parse() } + override fun listResults( + params: AuthRuleV2ListResultsParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v2/auth_rules/results + withRawResponse().listResults(params, requestOptions).thenApply { it.parse() } + override fun promote( params: AuthRuleV2PromoteParams, requestOptions: RequestOptions, @@ -332,6 +342,44 @@ class V2ServiceAsyncImpl internal constructor(private val clientOptions: ClientO } } + private val listResultsHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun listResults( + params: AuthRuleV2ListResultsParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v2", "auth_rules", "results") + .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 { listResultsHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + AuthRuleV2ListResultsPageAsync.builder() + .service(V2ServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) + .params(params) + .response(it) + .build() + } + } + } + } + private val promoteHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt index 2b7500aa..b2f1c4af 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt @@ -22,6 +22,9 @@ import com.lithic.api.models.AccountHolderUpdateParams import com.lithic.api.models.AccountHolderUpdateResponse import com.lithic.api.models.AccountHolderUploadDocumentParams import com.lithic.api.models.Document +import com.lithic.api.models.Kyb +import com.lithic.api.models.Kyc +import com.lithic.api.models.KycExempt import java.util.function.Consumer interface AccountHolderService { @@ -56,6 +59,60 @@ interface AccountHolderService { requestOptions: RequestOptions = RequestOptions.none(), ): AccountHolderCreateResponse + /** @see create */ + fun create( + body: AccountHolderCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderCreateResponse = + create(AccountHolderCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create(body: AccountHolderCreateParams.Body): AccountHolderCreateResponse = + create(body, RequestOptions.none()) + + /** @see create */ + fun create( + kyb: Kyb, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderCreateResponse = + create(AccountHolderCreateParams.Body.ofKyb(kyb), requestOptions) + + /** @see create */ + fun create(kyb: Kyb): AccountHolderCreateResponse = create(kyb, RequestOptions.none()) + + /** @see create */ + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderCreateResponse = + create(AccountHolderCreateParams.Body.ofKybDelegated(kybDelegated), requestOptions) + + /** @see create */ + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated + ): AccountHolderCreateResponse = create(kybDelegated, RequestOptions.none()) + + /** @see create */ + fun create( + kyc: Kyc, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderCreateResponse = + create(AccountHolderCreateParams.Body.ofKyc(kyc), requestOptions) + + /** @see create */ + fun create(kyc: Kyc): AccountHolderCreateResponse = create(kyc, RequestOptions.none()) + + /** @see create */ + fun create( + kycExempt: KycExempt, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderCreateResponse = + create(AccountHolderCreateParams.Body.ofKycExempt(kycExempt), requestOptions) + + /** @see create */ + fun create(kycExempt: KycExempt): AccountHolderCreateResponse = + create(kycExempt, RequestOptions.none()) + /** Get an Individual or Business Account Holder and/or their KYC or KYB evaluation status. */ fun retrieve(accountHolderToken: String): AccountHolder = retrieve(accountHolderToken, AccountHolderRetrieveParams.none()) @@ -346,6 +403,74 @@ interface AccountHolderService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see create */ + @MustBeClosed + fun create( + body: AccountHolderCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AccountHolderCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + @MustBeClosed + fun create( + body: AccountHolderCreateParams.Body + ): HttpResponseFor = create(body, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + kyb: Kyb, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AccountHolderCreateParams.Body.ofKyb(kyb), requestOptions) + + /** @see create */ + @MustBeClosed + fun create(kyb: Kyb): HttpResponseFor = + create(kyb, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AccountHolderCreateParams.Body.ofKybDelegated(kybDelegated), requestOptions) + + /** @see create */ + @MustBeClosed + fun create( + kybDelegated: AccountHolderCreateParams.Body.KybDelegated + ): HttpResponseFor = + create(kybDelegated, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + kyc: Kyc, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AccountHolderCreateParams.Body.ofKyc(kyc), requestOptions) + + /** @see create */ + @MustBeClosed + fun create(kyc: Kyc): HttpResponseFor = + create(kyc, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + kycExempt: KycExempt, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AccountHolderCreateParams.Body.ofKycExempt(kycExempt), requestOptions) + + /** @see create */ + @MustBeClosed + fun create(kycExempt: KycExempt): HttpResponseFor = + create(kycExempt, RequestOptions.none()) + /** * Returns a raw HTTP response for `get /v1/account_holders/{account_holder_token}`, but is * otherwise the same as [AccountHolderService.retrieve]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountService.kt index b7ea69e4..968e9303 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountService.kt @@ -39,22 +39,74 @@ interface ExternalBankAccountService { fun microDeposits(): MicroDepositService /** Creates an external bank account within a program or Lithic account. */ - fun create(): ExternalBankAccountCreateResponse = create(ExternalBankAccountCreateParams.none()) + fun create(params: ExternalBankAccountCreateParams): ExternalBankAccountCreateResponse = + create(params, RequestOptions.none()) /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), + params: ExternalBankAccountCreateParams, requestOptions: RequestOptions = RequestOptions.none(), ): ExternalBankAccountCreateResponse /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() - ): ExternalBankAccountCreateResponse = create(params, RequestOptions.none()) + body: ExternalBankAccountCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): ExternalBankAccountCreateResponse = + create(ExternalBankAccountCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create(body: ExternalBankAccountCreateParams.Body): ExternalBankAccountCreateResponse = + create(body, RequestOptions.none()) + + /** @see create */ + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): ExternalBankAccountCreateResponse = + create( + ExternalBankAccountCreateParams.Body.ofBankVerifiedCreateBankAccountApiRequest( + bankVerifiedCreateBankAccountApiRequest + ), + requestOptions, + ) + + /** @see create */ + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + ): ExternalBankAccountCreateResponse = + create(bankVerifiedCreateBankAccountApiRequest, RequestOptions.none()) + + /** @see create */ + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): ExternalBankAccountCreateResponse = + create( + ExternalBankAccountCreateParams.Body.ofExternallyVerified(externallyVerified), + requestOptions, + ) /** @see create */ - fun create(requestOptions: RequestOptions): ExternalBankAccountCreateResponse = - create(ExternalBankAccountCreateParams.none(), requestOptions) + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest + ): ExternalBankAccountCreateResponse = create(externallyVerified, RequestOptions.none()) + + /** @see create */ + fun create( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): ExternalBankAccountCreateResponse = + create(ExternalBankAccountCreateParams.Body.ofUnverified(unverified), requestOptions) + + /** @see create */ + fun create( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest + ): ExternalBankAccountCreateResponse = create(unverified, RequestOptions.none()) /** Get the external bank account by token. */ fun retrieve(externalBankAccountToken: String): ExternalBankAccountRetrieveResponse = @@ -307,29 +359,88 @@ interface ExternalBankAccountService { * same as [ExternalBankAccountService.create]. */ @MustBeClosed - fun create(): HttpResponseFor = - create(ExternalBankAccountCreateParams.none()) + fun create( + params: ExternalBankAccountCreateParams + ): HttpResponseFor = + create(params, RequestOptions.none()) /** @see create */ @MustBeClosed fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), + params: ExternalBankAccountCreateParams, requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor /** @see create */ @MustBeClosed fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() + body: ExternalBankAccountCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor = - create(params, RequestOptions.none()) + create(ExternalBankAccountCreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + @MustBeClosed + fun create( + body: ExternalBankAccountCreateParams.Body + ): HttpResponseFor = create(body, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create( + ExternalBankAccountCreateParams.Body.ofBankVerifiedCreateBankAccountApiRequest( + bankVerifiedCreateBankAccountApiRequest + ), + requestOptions, + ) + + /** @see create */ + @MustBeClosed + fun create( + bankVerifiedCreateBankAccountApiRequest: + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + ): HttpResponseFor = + create(bankVerifiedCreateBankAccountApiRequest, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create( + ExternalBankAccountCreateParams.Body.ofExternallyVerified(externallyVerified), + requestOptions, + ) + + /** @see create */ + @MustBeClosed + fun create( + externallyVerified: + ExternalBankAccountCreateParams.Body.ExternallyVerifiedCreateBankAccountApiRequest + ): HttpResponseFor = + create(externallyVerified, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(ExternalBankAccountCreateParams.Body.ofUnverified(unverified), requestOptions) /** @see create */ @MustBeClosed fun create( - requestOptions: RequestOptions + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest ): HttpResponseFor = - create(ExternalBankAccountCreateParams.none(), requestOptions) + create(unverified, RequestOptions.none()) /** * Returns a raw HTTP response for `get diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceImpl.kt index 7001796c..01f0678b 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceImpl.kt @@ -135,7 +135,7 @@ internal constructor(private val clientOptions: ClientOptions) : ExternalBankAcc .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) .addPathSegments("v1", "external_bank_accounts") - .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt index 9b569841..1a09c069 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookServiceImpl.kt @@ -6,18 +6,13 @@ import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.module.kotlin.jacksonTypeRef import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue -import com.lithic.api.core.getRequiredHeader import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicException import com.lithic.api.errors.LithicInvalidDataException +import com.lithic.api.errors.LithicWebhookException import com.lithic.api.models.ParsedWebhookEvent -import java.security.MessageDigest -import java.time.Duration -import java.time.Instant -import java.util.Base64 +import com.standardwebhooks.Webhook import java.util.function.Consumer -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec import kotlin.jvm.optionals.getOrNull class WebhookServiceImpl internal constructor(private val clientOptions: ClientOptions) : @@ -49,53 +44,14 @@ class WebhookServiceImpl internal constructor(private val clientOptions: ClientO "The webhook secret must either be set using the env var, LITHIC_WEBHOOK_SECRET, on the client class, or passed to this method" ) - val whsecret = - try { - Base64.getDecoder().decode(webhookSecret.removePrefix("whsec_")) - } catch (e: RuntimeException) { - throw LithicException("Invalid webhook secret") - } - - val msgId = headers.getRequiredHeader("webhook-id") - val msgSignature = headers.getRequiredHeader("webhook-signature") - val msgTimestamp = headers.getRequiredHeader("webhook-timestamp") - - val timestamp = - try { - Instant.ofEpochSecond(msgTimestamp.toLong()) - } catch (e: RuntimeException) { - throw LithicException("Invalid signature headers", e) - } - val now = Instant.now(clientOptions.clock) - - if (timestamp.isBefore(now.minus(Duration.ofMinutes(5)))) { - throw LithicException("Webhook timestamp too old") - } - if (timestamp.isAfter(now.plus(Duration.ofMinutes(5)))) { - throw LithicException("Webhook timestamp too new") - } - - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(whsecret, "HmacSHA256")) - val expectedSignature = - mac.doFinal("$msgId.${timestamp.epochSecond}.$payload".toByteArray()) - - msgSignature.splitToSequence(" ").forEach { - val parts = it.split(",") - if (parts.size != 2) { - return@forEach - } - - if (parts[0] != "v1") { - return@forEach - } + try { + val headersMap = headers.names().associateWith { name -> headers.values(name) } - if (MessageDigest.isEqual(Base64.getDecoder().decode(parts[1]), expectedSignature)) { - return - } + val webhook = Webhook(webhookSecret) + webhook.verify(payload, headersMap) + } catch (e: Exception) { + throw LithicWebhookException("Could not verify webhook event signature", e) } - - throw LithicException("None of the given webhook signatures match the expected signature") } /** diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2Service.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2Service.kt index d7bbf237..b8fd41dc 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2Service.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2Service.kt @@ -13,6 +13,8 @@ import com.lithic.api.models.AuthRuleV2DeleteParams import com.lithic.api.models.AuthRuleV2DraftParams import com.lithic.api.models.AuthRuleV2ListPage import com.lithic.api.models.AuthRuleV2ListParams +import com.lithic.api.models.AuthRuleV2ListResultsPage +import com.lithic.api.models.AuthRuleV2ListResultsParams import com.lithic.api.models.AuthRuleV2PromoteParams import com.lithic.api.models.AuthRuleV2RetrieveFeaturesParams import com.lithic.api.models.AuthRuleV2RetrieveParams @@ -48,6 +50,47 @@ interface V2Service { requestOptions: RequestOptions = RequestOptions.none(), ): AuthRule + /** @see create */ + fun create( + body: AuthRuleV2CreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): AuthRule = create(AuthRuleV2CreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + fun create(body: AuthRuleV2CreateParams.Body): AuthRule = create(body, RequestOptions.none()) + + /** @see create */ + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): AuthRule = + create(AuthRuleV2CreateParams.Body.ofAccountLevelRule(accountLevelRule), requestOptions) + + /** @see create */ + fun create(accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule): AuthRule = + create(accountLevelRule, RequestOptions.none()) + + /** @see create */ + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): AuthRule = create(AuthRuleV2CreateParams.Body.ofCardLevelRule(cardLevelRule), requestOptions) + + /** @see create */ + fun create(cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule): AuthRule = + create(cardLevelRule, RequestOptions.none()) + + /** @see create */ + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): AuthRule = + create(AuthRuleV2CreateParams.Body.ofProgramLevelRule(programLevelRule), requestOptions) + + /** @see create */ + fun create(programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule): AuthRule = + create(programLevelRule, RequestOptions.none()) + /** Fetches a V2 Auth rule by its token */ fun retrieve(authRuleToken: String): AuthRule = retrieve(authRuleToken, AuthRuleV2RetrieveParams.none()) @@ -184,6 +227,31 @@ interface V2Service { fun draft(authRuleToken: String, requestOptions: RequestOptions): AuthRule = draft(authRuleToken, AuthRuleV2DraftParams.none(), requestOptions) + /** + * Lists Auth Rule evaluation results. + * + * **Limitations:** + * - Results are available for the past 3 months only + * - At least one filter (`event_token` or `auth_rule_token`) must be provided + * - When filtering by `event_token`, pagination is not supported + */ + fun listResults(): AuthRuleV2ListResultsPage = listResults(AuthRuleV2ListResultsParams.none()) + + /** @see listResults */ + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): AuthRuleV2ListResultsPage + + /** @see listResults */ + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none() + ): AuthRuleV2ListResultsPage = listResults(params, RequestOptions.none()) + + /** @see listResults */ + fun listResults(requestOptions: RequestOptions): AuthRuleV2ListResultsPage = + listResults(AuthRuleV2ListResultsParams.none(), requestOptions) + /** * Promotes the draft version of an Auth rule to the currently active version such that it is * enforced in the respective stream. @@ -323,6 +391,61 @@ interface V2Service { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see create */ + @MustBeClosed + fun create( + body: AuthRuleV2CreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AuthRuleV2CreateParams.builder().body(body).build(), requestOptions) + + /** @see create */ + @MustBeClosed + fun create(body: AuthRuleV2CreateParams.Body): HttpResponseFor = + create(body, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AuthRuleV2CreateParams.Body.ofAccountLevelRule(accountLevelRule), requestOptions) + + /** @see create */ + @MustBeClosed + fun create( + accountLevelRule: AuthRuleV2CreateParams.Body.AccountLevelRule + ): HttpResponseFor = create(accountLevelRule, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AuthRuleV2CreateParams.Body.ofCardLevelRule(cardLevelRule), requestOptions) + + /** @see create */ + @MustBeClosed + fun create( + cardLevelRule: AuthRuleV2CreateParams.Body.CardLevelRule + ): HttpResponseFor = create(cardLevelRule, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create(AuthRuleV2CreateParams.Body.ofProgramLevelRule(programLevelRule), requestOptions) + + /** @see create */ + @MustBeClosed + fun create( + programLevelRule: AuthRuleV2CreateParams.Body.ProgramLevelRule + ): HttpResponseFor = create(programLevelRule, RequestOptions.none()) + /** * Returns a raw HTTP response for `get /v2/auth_rules/{auth_rule_token}`, but is otherwise * the same as [V2Service.retrieve]. @@ -508,6 +631,34 @@ interface V2Service { ): HttpResponseFor = draft(authRuleToken, AuthRuleV2DraftParams.none(), requestOptions) + /** + * Returns a raw HTTP response for `get /v2/auth_rules/results`, but is otherwise the same + * as [V2Service.listResults]. + */ + @MustBeClosed + fun listResults(): HttpResponseFor = + listResults(AuthRuleV2ListResultsParams.none()) + + /** @see listResults */ + @MustBeClosed + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see listResults */ + @MustBeClosed + fun listResults( + params: AuthRuleV2ListResultsParams = AuthRuleV2ListResultsParams.none() + ): HttpResponseFor = listResults(params, RequestOptions.none()) + + /** @see listResults */ + @MustBeClosed + fun listResults( + requestOptions: RequestOptions + ): HttpResponseFor = + listResults(AuthRuleV2ListResultsParams.none(), requestOptions) + /** * Returns a raw HTTP response for `post /v2/auth_rules/{auth_rule_token}/promote`, but is * otherwise the same as [V2Service.promote]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceImpl.kt index 61a6e6c4..1b9b4b3f 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceImpl.kt @@ -24,6 +24,9 @@ import com.lithic.api.models.AuthRuleV2DraftParams import com.lithic.api.models.AuthRuleV2ListPage import com.lithic.api.models.AuthRuleV2ListPageResponse import com.lithic.api.models.AuthRuleV2ListParams +import com.lithic.api.models.AuthRuleV2ListResultsPage +import com.lithic.api.models.AuthRuleV2ListResultsPageResponse +import com.lithic.api.models.AuthRuleV2ListResultsParams import com.lithic.api.models.AuthRuleV2PromoteParams import com.lithic.api.models.AuthRuleV2RetrieveFeaturesParams import com.lithic.api.models.AuthRuleV2RetrieveParams @@ -82,6 +85,13 @@ class V2ServiceImpl internal constructor(private val clientOptions: ClientOption // post /v2/auth_rules/{auth_rule_token}/draft withRawResponse().draft(params, requestOptions).parse() + override fun listResults( + params: AuthRuleV2ListResultsParams, + requestOptions: RequestOptions, + ): AuthRuleV2ListResultsPage = + // get /v2/auth_rules/results + withRawResponse().listResults(params, requestOptions).parse() + override fun promote( params: AuthRuleV2PromoteParams, requestOptions: RequestOptions, @@ -300,6 +310,40 @@ class V2ServiceImpl internal constructor(private val clientOptions: ClientOption } } + private val listResultsHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun listResults( + params: AuthRuleV2ListResultsParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v2", "auth_rules", "results") + .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 { listResultsHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + AuthRuleV2ListResultsPage.builder() + .service(V2ServiceImpl(clientOptions)) + .params(params) + .response(it) + .build() + } + } + } + private val promoteHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/TestServerExtension.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/TestServerExtension.kt index 23bb2ab9..308d5694 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/TestServerExtension.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/TestServerExtension.kt @@ -15,25 +15,12 @@ class TestServerExtension : BeforeAllCallback, ExecutionCondition { } catch (e: Exception) { throw RuntimeException( """ - The test suite will not run without a mock Prism server running against your OpenAPI spec. + The test suite will not run without a mock server running against your OpenAPI spec. You can set the environment variable `SKIP_MOCK_TESTS` to `true` to skip running any tests that require the mock server. - To fix: - - 1. Install Prism (requires Node 16+): - - With npm: - $ npm install -g @stoplight/prism-cli - - With yarn: - $ yarn global add @stoplight/prism-cli - - 2. Run the mock server - - To run the server, pass in the path of your OpenAPI spec to the prism command: - $ prism mock path/to/your.openapi.yml + To fix run `./scripts/mock` in a separate terminal. """ .trimIndent(), e, diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderCreateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderCreateParamsTest.kt index 41cf0349..c5b3e4f0 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderCreateParamsTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderCreateParamsTest.kt @@ -97,6 +97,7 @@ internal class AccountHolderCreateParamsTest { ) .externalId("external_id") .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") .websiteUrl("https://www.mybusiness.com") .build() ) @@ -194,6 +195,7 @@ internal class AccountHolderCreateParamsTest { ) .externalId("external_id") .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") .websiteUrl("https://www.mybusiness.com") .build() ) @@ -290,6 +292,7 @@ internal class AccountHolderCreateParamsTest { ) .externalId("external_id") .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") .websiteUrl("https://www.mybusiness.com") .build() ) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderListPageResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderListPageResponseTest.kt index 3a8e72f6..998a0625 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderListPageResponseTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderListPageResponseTest.kt @@ -123,6 +123,7 @@ internal class AccountHolderListPageResponseTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("+15555555555") .addRequiredDocument( @@ -265,6 +266,7 @@ internal class AccountHolderListPageResponseTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("+15555555555") .addRequiredDocument( @@ -410,6 +412,7 @@ internal class AccountHolderListPageResponseTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("+15555555555") .addRequiredDocument( diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponseTest.kt index a735a637..0a8832f0 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponseTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderSimulateEnrollmentReviewResponseTest.kt @@ -52,6 +52,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -92,6 +93,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -118,10 +120,12 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("phone_number") .addRequiredDocument( @@ -203,6 +207,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -245,6 +250,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -272,10 +278,12 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) + assertThat(accountHolderSimulateEnrollmentReviewResponse.naicsCode()).contains("naics_code") assertThat(accountHolderSimulateEnrollmentReviewResponse.natureOfBusiness()) .contains("nature_of_business") assertThat(accountHolderSimulateEnrollmentReviewResponse.phoneNumber()) @@ -360,6 +368,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -400,6 +409,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -426,10 +436,12 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("phone_number") .addRequiredDocument( diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderTest.kt index f668dde1..151331ef 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderTest.kt @@ -122,6 +122,7 @@ internal class AccountHolderTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("+15555555555") .addRequiredDocument( @@ -263,6 +264,7 @@ internal class AccountHolderTest { .phoneNumber("+15555555555") .build() ) + assertThat(accountHolder.naicsCode()).contains("naics_code") assertThat(accountHolder.natureOfBusiness()).contains("nature_of_business") assertThat(accountHolder.phoneNumber()).contains("+15555555555") assertThat(accountHolder.requiredDocuments().getOrNull()) @@ -404,6 +406,7 @@ internal class AccountHolderTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("+15555555555") .addRequiredDocument( diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateParamsTest.kt index d3953760..ed955519 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateParamsTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateParamsTest.kt @@ -50,6 +50,7 @@ internal class AccountHolderUpdateParamsTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -91,11 +92,13 @@ internal class AccountHolderUpdateParamsTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) @@ -162,6 +165,7 @@ internal class AccountHolderUpdateParamsTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -203,11 +207,13 @@ internal class AccountHolderUpdateParamsTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) @@ -259,6 +265,7 @@ internal class AccountHolderUpdateParamsTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -300,11 +307,13 @@ internal class AccountHolderUpdateParamsTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateResponseTest.kt index bbb82a46..61938f69 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateResponseTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdateResponseTest.kt @@ -56,6 +56,7 @@ internal class AccountHolderUpdateResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -96,6 +97,7 @@ internal class AccountHolderUpdateResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -122,10 +124,12 @@ internal class AccountHolderUpdateResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("phone_number") .addRequiredDocument( @@ -211,6 +215,7 @@ internal class AccountHolderUpdateResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -251,6 +256,7 @@ internal class AccountHolderUpdateResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -278,10 +284,12 @@ internal class AccountHolderUpdateResponseTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("phone_number") .addRequiredDocument( diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEventTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEventTest.kt index 648947d4..0b07e515 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEventTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderUpdatedWebhookEventTest.kt @@ -60,6 +60,7 @@ internal class AccountHolderUpdatedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -102,6 +103,7 @@ internal class AccountHolderUpdatedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -112,6 +114,7 @@ internal class AccountHolderUpdatedWebhookEventTest { AccountHolderUpdatedWebhookEvent.KybPayload.EventType.ACCOUNT_HOLDER_UPDATED ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness("Software company selling solutions to the restaurant industry") .websiteUrl("www.mybusiness.com") .build() @@ -171,6 +174,7 @@ internal class AccountHolderUpdatedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -213,6 +217,7 @@ internal class AccountHolderUpdatedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -223,6 +228,7 @@ internal class AccountHolderUpdatedWebhookEventTest { AccountHolderUpdatedWebhookEvent.KybPayload.EventType.ACCOUNT_HOLDER_UPDATED ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) @@ -266,6 +272,7 @@ internal class AccountHolderUpdatedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -314,6 +321,7 @@ internal class AccountHolderUpdatedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt new file mode 100644 index 00000000..94471084 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt @@ -0,0 +1,112 @@ +// 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 java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AuthRuleV2ListResultsPageResponseTest { + + @Test + fun create() { + val authRuleV2ListResultsPageResponse = + AuthRuleV2ListResultsPageResponse.builder() + .addData( + V2ListResultsResponse.AuthorizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AuthorizationResult.Action.builder() + .type( + V2ListResultsResponse.AuthorizationResult.Action + .AuthorizationAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream( + V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION + ) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + .hasMore(true) + .build() + + assertThat(authRuleV2ListResultsPageResponse.data()) + .containsExactly( + V2ListResultsResponse.ofAuthorizationResult( + V2ListResultsResponse.AuthorizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AuthorizationResult.Action.builder() + .type( + V2ListResultsResponse.AuthorizationResult.Action + .AuthorizationAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream( + V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION + ) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + ) + assertThat(authRuleV2ListResultsPageResponse.hasMore()).isEqualTo(true) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val authRuleV2ListResultsPageResponse = + AuthRuleV2ListResultsPageResponse.builder() + .addData( + V2ListResultsResponse.AuthorizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AuthorizationResult.Action.builder() + .type( + V2ListResultsResponse.AuthorizationResult.Action + .AuthorizationAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream( + V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION + ) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + .hasMore(true) + .build() + + val roundtrippedAuthRuleV2ListResultsPageResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(authRuleV2ListResultsPageResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedAuthRuleV2ListResultsPageResponse) + .isEqualTo(authRuleV2ListResultsPageResponse) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParamsTest.kt new file mode 100644 index 00000000..0a1326fa --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParamsTest.kt @@ -0,0 +1,58 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.http.QueryParams +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AuthRuleV2ListResultsParamsTest { + + @Test + fun create() { + AuthRuleV2ListResultsParams.builder() + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .hasActions(true) + .pageSize(1L) + .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + } + + @Test + fun queryParams() { + val params = + AuthRuleV2ListResultsParams.builder() + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .hasActions(true) + .pageSize(1L) + .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("auth_rule_token", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("event_token", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .put("has_actions", "true") + .put("page_size", "1") + .put("starting_after", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = AuthRuleV2ListResultsParams.builder().build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/BookTransferCreateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/BookTransferCreateParamsTest.kt index 7455f87c..e8f03230 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/BookTransferCreateParamsTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/BookTransferCreateParamsTest.kt @@ -18,6 +18,7 @@ internal class BookTransferCreateParamsTest { .type(BookTransferCreateParams.BookTransferType.ATM_BALANCE_INQUIRY) .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .externalId("external_id") + .holdToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .memo("memo") .onClosedAccount(BookTransferCreateParams.OnClosedAccount.FAIL) .build() @@ -35,6 +36,7 @@ internal class BookTransferCreateParamsTest { .type(BookTransferCreateParams.BookTransferType.ATM_BALANCE_INQUIRY) .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .externalId("external_id") + .holdToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .memo("memo") .onClosedAccount(BookTransferCreateParams.OnClosedAccount.FAIL) .build() @@ -52,6 +54,7 @@ internal class BookTransferCreateParamsTest { .isEqualTo(BookTransferCreateParams.BookTransferType.ATM_BALANCE_INQUIRY) assertThat(body.token()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.externalId()).contains("external_id") + assertThat(body.holdToken()).contains("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(body.memo()).contains("memo") assertThat(body.onClosedAccount()).contains(BookTransferCreateParams.OnClosedAccount.FAIL) } diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEventTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEventTest.kt index 7196fb57..af86743c 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEventTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/CardAuthorizationApprovalRequestWebhookEventTest.kt @@ -17,6 +17,36 @@ internal class CardAuthorizationApprovalRequestWebhookEventTest { .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .acquirerFee(0L) .amount(0L) + .amounts( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.builder() + .cardholder( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.ConvertedAmount + .builder() + .amount(0L) + .conversionRate("1.000000") + .currency("USD") + .build() + ) + .hold( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .merchant( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .settlement( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .build() + ) .authorizationAmount(0L) .avs( CardAuthorizationApprovalRequestWebhookEvent.Avs.builder() @@ -208,6 +238,37 @@ internal class CardAuthorizationApprovalRequestWebhookEventTest { .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") assertThat(cardAuthorizationApprovalRequestWebhookEvent.acquirerFee()).isEqualTo(0L) assertThat(cardAuthorizationApprovalRequestWebhookEvent.amount()).isEqualTo(0L) + assertThat(cardAuthorizationApprovalRequestWebhookEvent.amounts()) + .isEqualTo( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.builder() + .cardholder( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.ConvertedAmount + .builder() + .amount(0L) + .conversionRate("1.000000") + .currency("USD") + .build() + ) + .hold( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .merchant( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .settlement( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .build() + ) assertThat(cardAuthorizationApprovalRequestWebhookEvent.authorizationAmount()).isEqualTo(0L) assertThat(cardAuthorizationApprovalRequestWebhookEvent.avs()) .isEqualTo( @@ -413,6 +474,36 @@ internal class CardAuthorizationApprovalRequestWebhookEventTest { .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .acquirerFee(0L) .amount(0L) + .amounts( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.builder() + .cardholder( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.ConvertedAmount + .builder() + .amount(0L) + .conversionRate("1.000000") + .currency("USD") + .build() + ) + .hold( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .merchant( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .settlement( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .build() + ) .authorizationAmount(0L) .avs( CardAuthorizationApprovalRequestWebhookEvent.Avs.builder() diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/Conditional3dsActionParametersTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/Conditional3dsActionParametersTest.kt index 0788cb82..a579bb0b 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/Conditional3dsActionParametersTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/Conditional3dsActionParametersTest.kt @@ -13,7 +13,7 @@ internal class Conditional3dsActionParametersTest { fun create() { val conditional3dsActionParameters = Conditional3dsActionParameters.builder() - .action(Conditional3dsActionParameters.Action.DECLINE) + .action(Conditional3dsActionParameters.Authentication3dsAction.DECLINE) .addCondition( Conditional3dsActionParameters.Condition.builder() .attribute(Conditional3dsActionParameters.Condition.Attribute.MCC) @@ -24,7 +24,7 @@ internal class Conditional3dsActionParametersTest { .build() assertThat(conditional3dsActionParameters.action()) - .isEqualTo(Conditional3dsActionParameters.Action.DECLINE) + .isEqualTo(Conditional3dsActionParameters.Authentication3dsAction.DECLINE) assertThat(conditional3dsActionParameters.conditions()) .containsExactly( Conditional3dsActionParameters.Condition.builder() @@ -40,7 +40,7 @@ internal class Conditional3dsActionParametersTest { val jsonMapper = jsonMapper() val conditional3dsActionParameters = Conditional3dsActionParameters.builder() - .action(Conditional3dsActionParameters.Action.DECLINE) + .action(Conditional3dsActionParameters.Authentication3dsAction.DECLINE) .addCondition( Conditional3dsActionParameters.Condition.builder() .attribute(Conditional3dsActionParameters.Condition.Attribute.MCC) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParametersTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParametersTest.kt index 9ada3b0a..d30700c4 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParametersTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ConditionalAuthorizationActionParametersTest.kt @@ -13,7 +13,7 @@ internal class ConditionalAuthorizationActionParametersTest { fun create() { val conditionalAuthorizationActionParameters = ConditionalAuthorizationActionParameters.builder() - .action(ConditionalAuthorizationActionParameters.Action.DECLINE) + .action(ConditionalAuthorizationActionParameters.AuthorizationAction.DECLINE) .addCondition( ConditionalAuthorizationActionParameters.Condition.builder() .attribute(ConditionalAuthorizationActionParameters.Condition.Attribute.MCC) @@ -24,7 +24,7 @@ internal class ConditionalAuthorizationActionParametersTest { .build() assertThat(conditionalAuthorizationActionParameters.action()) - .isEqualTo(ConditionalAuthorizationActionParameters.Action.DECLINE) + .isEqualTo(ConditionalAuthorizationActionParameters.AuthorizationAction.DECLINE) assertThat(conditionalAuthorizationActionParameters.conditions()) .containsExactly( ConditionalAuthorizationActionParameters.Condition.builder() @@ -40,7 +40,7 @@ internal class ConditionalAuthorizationActionParametersTest { val jsonMapper = jsonMapper() val conditionalAuthorizationActionParameters = ConditionalAuthorizationActionParameters.builder() - .action(ConditionalAuthorizationActionParameters.Action.DECLINE) + .action(ConditionalAuthorizationActionParameters.AuthorizationAction.DECLINE) .addCondition( ConditionalAuthorizationActionParameters.Condition.builder() .attribute(ConditionalAuthorizationActionParameters.Condition.Attribute.MCC) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/ExternalBankAccountCreateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ExternalBankAccountCreateParamsTest.kt index 6e389c43..17af898d 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/ExternalBankAccountCreateParamsTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ExternalBankAccountCreateParamsTest.kt @@ -3,7 +3,6 @@ package com.lithic.api.models import java.time.LocalDate -import kotlin.jvm.optionals.getOrNull import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test @@ -92,7 +91,7 @@ internal class ExternalBankAccountCreateParamsTest { ) .build() - val body = params._body().getOrNull() + val body = params._body() assertThat(body) .isEqualTo( @@ -137,8 +136,52 @@ internal class ExternalBankAccountCreateParamsTest { @Test fun bodyWithoutOptionalFields() { - val params = ExternalBankAccountCreateParams.builder().build() + val params = + ExternalBankAccountCreateParams.builder() + .body( + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + .builder() + .accountNumber("13719713158835300") + .country("USA") + .currency("USD") + .financialAccountToken("dabadb3b-700c-41e3-8801-d5dfc84ebea0") + .owner("John Doe") + .ownerType(OwnerType.BUSINESS) + .routingNumber("011103093") + .type( + ExternalBankAccountCreateParams.Body + .BankVerifiedCreateBankAccountApiRequest + .AccountType + .CHECKING + ) + .verificationMethod(VerificationMethod.MICRO_DEPOSIT) + .build() + ) + .build() + + val body = params._body() - val body = params._body().getOrNull() + assertThat(body) + .isEqualTo( + ExternalBankAccountCreateParams.Body.ofBankVerifiedCreateBankAccountApiRequest( + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + .builder() + .accountNumber("13719713158835300") + .country("USA") + .currency("USD") + .financialAccountToken("dabadb3b-700c-41e3-8801-d5dfc84ebea0") + .owner("John Doe") + .ownerType(OwnerType.BUSINESS) + .routingNumber("011103093") + .type( + ExternalBankAccountCreateParams.Body + .BankVerifiedCreateBankAccountApiRequest + .AccountType + .CHECKING + ) + .verificationMethod(VerificationMethod.MICRO_DEPOSIT) + .build() + ) + ) } } diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/KybTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/KybTest.kt index 26a23ee1..ba2defb1 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/KybTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/KybTest.kt @@ -97,6 +97,7 @@ internal class KybTest { ) .externalId("external_id") .kybPassedTimestamp("2018-05-29T21:16:05Z") + .naicsCode("541512") .websiteUrl("www.mybusiness.com") .build() @@ -188,6 +189,7 @@ internal class KybTest { ) assertThat(kyb.externalId()).contains("external_id") assertThat(kyb.kybPassedTimestamp()).contains("2018-05-29T21:16:05Z") + assertThat(kyb.naicsCode()).contains("541512") assertThat(kyb.websiteUrl()).contains("www.mybusiness.com") } @@ -279,6 +281,7 @@ internal class KybTest { ) .externalId("external_id") .kybPassedTimestamp("2018-05-29T21:16:05Z") + .naicsCode("541512") .websiteUrl("www.mybusiness.com") .build() diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/ParsedWebhookEventTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ParsedWebhookEventTest.kt index 92718683..9628e2ad 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/models/ParsedWebhookEventTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ParsedWebhookEventTest.kt @@ -172,6 +172,7 @@ internal class ParsedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -211,6 +212,7 @@ internal class ParsedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -219,6 +221,7 @@ internal class ParsedWebhookEventTest { ) .eventType(ParsedWebhookEvent.KybPayload.EventType.ACCOUNT_HOLDER_UPDATED) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness("Software company selling solutions to the restaurant industry") .websiteUrl("www.mybusiness.com") .build() @@ -332,6 +335,7 @@ internal class ParsedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -372,6 +376,7 @@ internal class ParsedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -380,6 +385,7 @@ internal class ParsedWebhookEventTest { ) .eventType(ParsedWebhookEvent.KybPayload.EventType.ACCOUNT_HOLDER_UPDATED) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) @@ -419,6 +425,7 @@ internal class ParsedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -519,6 +526,7 @@ internal class ParsedWebhookEventTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -910,6 +918,36 @@ internal class ParsedWebhookEventTest { .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .acquirerFee(0L) .amount(0L) + .amounts( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.builder() + .cardholder( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.ConvertedAmount + .builder() + .amount(0L) + .conversionRate("1.000000") + .currency("USD") + .build() + ) + .hold( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .merchant( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .settlement( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount.builder() + .amount(0L) + .currency("USD") + .build() + ) + .build() + ) .authorizationAmount(0L) .avs( CardAuthorizationApprovalRequestWebhookEvent.Avs.builder() @@ -1172,6 +1210,39 @@ internal class ParsedWebhookEventTest { .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .acquirerFee(0L) .amount(0L) + .amounts( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.builder() + .cardholder( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.ConvertedAmount + .builder() + .amount(0L) + .conversionRate("1.000000") + .currency("USD") + .build() + ) + .hold( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount + .builder() + .amount(0L) + .currency("USD") + .build() + ) + .merchant( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount + .builder() + .amount(0L) + .currency("USD") + .build() + ) + .settlement( + CardAuthorizationApprovalRequestWebhookEvent.Amounts.Amount + .builder() + .amount(0L) + .currency("USD") + .build() + ) + .build() + ) .authorizationAmount(0L) .avs( CardAuthorizationApprovalRequestWebhookEvent.Avs.builder() diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/V2ListResultsResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/V2ListResultsResponseTest.kt new file mode 100644 index 00000000..251ecab8 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/V2ListResultsResponseTest.kt @@ -0,0 +1,305 @@ +// 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.JsonValue +import com.lithic.api.core.jsonMapper +import com.lithic.api.errors.LithicInvalidDataException +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource + +internal class V2ListResultsResponseTest { + + @Test + fun ofAuthorizationResult() { + val authorizationResult = + V2ListResultsResponse.AuthorizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AuthorizationResult.Action.builder() + .type( + V2ListResultsResponse.AuthorizationResult.Action.AuthorizationAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + + val v2ListResultsResponse = V2ListResultsResponse.ofAuthorizationResult(authorizationResult) + + assertThat(v2ListResultsResponse.authorizationResult()).contains(authorizationResult) + assertThat(v2ListResultsResponse.authentication3dsResult()).isEmpty + assertThat(v2ListResultsResponse.tokenizationResult()).isEmpty + assertThat(v2ListResultsResponse.achResult()).isEmpty + } + + @Test + fun ofAuthorizationResultRoundtrip() { + val jsonMapper = jsonMapper() + val v2ListResultsResponse = + V2ListResultsResponse.ofAuthorizationResult( + V2ListResultsResponse.AuthorizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AuthorizationResult.Action.builder() + .type( + V2ListResultsResponse.AuthorizationResult.Action.AuthorizationAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream( + V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION + ) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + + val roundtrippedV2ListResultsResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(v2ListResultsResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedV2ListResultsResponse).isEqualTo(v2ListResultsResponse) + } + + @Test + fun ofAuthentication3dsResult() { + val authentication3dsResult = + V2ListResultsResponse.Authentication3dsResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Authentication3dsResult.Action.builder() + .type( + V2ListResultsResponse.Authentication3dsResult.Action + .Authentication3dsAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream( + V2ListResultsResponse.Authentication3dsResult.EventStream + .THREE_DS_AUTHENTICATION + ) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.Authentication3dsResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + + val v2ListResultsResponse = + V2ListResultsResponse.ofAuthentication3dsResult(authentication3dsResult) + + assertThat(v2ListResultsResponse.authorizationResult()).isEmpty + assertThat(v2ListResultsResponse.authentication3dsResult()) + .contains(authentication3dsResult) + assertThat(v2ListResultsResponse.tokenizationResult()).isEmpty + assertThat(v2ListResultsResponse.achResult()).isEmpty + } + + @Test + fun ofAuthentication3dsResultRoundtrip() { + val jsonMapper = jsonMapper() + val v2ListResultsResponse = + V2ListResultsResponse.ofAuthentication3dsResult( + V2ListResultsResponse.Authentication3dsResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Authentication3dsResult.Action.builder() + .type( + V2ListResultsResponse.Authentication3dsResult.Action + .Authentication3dsAction + .DECLINE + ) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream( + V2ListResultsResponse.Authentication3dsResult.EventStream + .THREE_DS_AUTHENTICATION + ) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.Authentication3dsResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + + val roundtrippedV2ListResultsResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(v2ListResultsResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedV2ListResultsResponse).isEqualTo(v2ListResultsResponse) + } + + @Test + fun ofTokenizationResult() { + val tokenizationResult = + V2ListResultsResponse.TokenizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.TokenizationResult.Action.DeclineAction.builder() + .type( + V2ListResultsResponse.TokenizationResult.Action.DeclineAction.Type + .DECLINE + ) + .explanation("explanation") + .reason( + V2ListResultsResponse.TokenizationResult.Action.DeclineAction.Reason + .ACCOUNT_SCORE_1 + ) + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(V2ListResultsResponse.TokenizationResult.EventStream.TOKENIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.TokenizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + + val v2ListResultsResponse = V2ListResultsResponse.ofTokenizationResult(tokenizationResult) + + assertThat(v2ListResultsResponse.authorizationResult()).isEmpty + assertThat(v2ListResultsResponse.authentication3dsResult()).isEmpty + assertThat(v2ListResultsResponse.tokenizationResult()).contains(tokenizationResult) + assertThat(v2ListResultsResponse.achResult()).isEmpty + } + + @Test + fun ofTokenizationResultRoundtrip() { + val jsonMapper = jsonMapper() + val v2ListResultsResponse = + V2ListResultsResponse.ofTokenizationResult( + V2ListResultsResponse.TokenizationResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.TokenizationResult.Action.DeclineAction.builder() + .type( + V2ListResultsResponse.TokenizationResult.Action.DeclineAction.Type + .DECLINE + ) + .explanation("explanation") + .reason( + V2ListResultsResponse.TokenizationResult.Action.DeclineAction.Reason + .ACCOUNT_SCORE_1 + ) + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(V2ListResultsResponse.TokenizationResult.EventStream.TOKENIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.TokenizationResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + + val roundtrippedV2ListResultsResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(v2ListResultsResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedV2ListResultsResponse).isEqualTo(v2ListResultsResponse) + } + + @Test + fun ofAchResult() { + val achResult = + V2ListResultsResponse.AchResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AchResult.Action.ApproveAction.builder() + .type(V2ListResultsResponse.AchResult.Action.ApproveAction.Type.APPROVE) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(V2ListResultsResponse.AchResult.EventStream.ACH_CREDIT_RECEIPT) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AchResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + + val v2ListResultsResponse = V2ListResultsResponse.ofAchResult(achResult) + + assertThat(v2ListResultsResponse.authorizationResult()).isEmpty + assertThat(v2ListResultsResponse.authentication3dsResult()).isEmpty + assertThat(v2ListResultsResponse.tokenizationResult()).isEmpty + assertThat(v2ListResultsResponse.achResult()).contains(achResult) + } + + @Test + fun ofAchResultRoundtrip() { + val jsonMapper = jsonMapper() + val v2ListResultsResponse = + V2ListResultsResponse.ofAchResult( + V2ListResultsResponse.AchResult.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.AchResult.Action.ApproveAction.builder() + .type(V2ListResultsResponse.AchResult.Action.ApproveAction.Type.APPROVE) + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(V2ListResultsResponse.AchResult.EventStream.ACH_CREDIT_RECEIPT) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AchResult.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + + val roundtrippedV2ListResultsResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(v2ListResultsResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedV2ListResultsResponse).isEqualTo(v2ListResultsResponse) + } + + enum class IncompatibleJsonShapeTestCase(val value: JsonValue) { + BOOLEAN(JsonValue.from(false)), + STRING(JsonValue.from("invalid")), + INTEGER(JsonValue.from(-1)), + FLOAT(JsonValue.from(3.14)), + ARRAY(JsonValue.from(listOf("invalid", "array"))), + } + + @ParameterizedTest + @EnumSource + fun incompatibleJsonShapeDeserializesToUnknown(testCase: IncompatibleJsonShapeTestCase) { + val v2ListResultsResponse = + jsonMapper().convertValue(testCase.value, jacksonTypeRef()) + + val e = assertThrows { v2ListResultsResponse.validate() } + assertThat(e).hasMessageStartingWith("Unknown ") + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncTest.kt index 16db460e..1c50429e 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncTest.kt @@ -4,7 +4,6 @@ package com.lithic.api.services.async import com.lithic.api.TestServerExtension import com.lithic.api.client.okhttp.LithicOkHttpClientAsync -import com.lithic.api.models.AccountHolderCreateParams import com.lithic.api.models.AccountHolderRetrieveDocumentParams import com.lithic.api.models.AccountHolderSimulateEnrollmentDocumentReviewParams import com.lithic.api.models.AccountHolderSimulateEnrollmentReviewParams @@ -30,97 +29,94 @@ internal class AccountHolderServiceAsyncTest { val accountHolderFuture = accountHolderServiceAsync.create( - AccountHolderCreateParams.builder() - .body( - Kyb.builder() - .addBeneficialOwnerIndividual( - Kyb.KybIndividual.builder() - .address( - Address.builder() - .address1("300 Normal Forest Way") - .city("Portland") - .country("USA") - .postalCode("90210") - .state("OR") - .address2("address2") - .build() - ) - .dob("1991-03-08T08:00:00Z") - .email("tim@left-earth.com") - .firstName("Timmy") - .governmentId("211-23-1412") - .lastName("Turner") - .phoneNumber("+15555555555") + Kyb.builder() + .addBeneficialOwnerIndividual( + Kyb.KybIndividual.builder() + .address( + Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") .build() ) - .businessEntity( - Kyb.BusinessEntity.builder() - .address( - Address.builder() - .address1("123 Old Forest Way") - .city("Omaha") - .country("USA") - .postalCode("61022") - .state("NE") - .address2("address2") - .build() - ) - .governmentId("12-3456789") - .legalBusinessName("Busy Business, Inc.") - .addPhoneNumber("+15555555555") - .dbaBusinessName("Example Business Solutions") - .parentCompany("parent_company") + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .build() + ) + .businessEntity( + Kyb.BusinessEntity.builder() + .address( + Address.builder() + .address1("123 Old Forest Way") + .city("Omaha") + .country("USA") + .postalCode("61022") + .state("NE") + .address2("address2") .build() ) - .controlPerson( - Kyb.KybIndividual.builder() - .address( - Address.builder() - .address1("451 New Forest Way") - .city("Springfield") - .country("USA") - .postalCode("68022") - .state("IL") - .address2("address2") - .build() - ) - .dob("1991-03-08T08:00:00Z") - .email("tom@middle-pluto.com") - .firstName("Tom") - .governmentId("111-23-1412") - .lastName("Timothy") - .phoneNumber("+15555555555") + .governmentId("12-3456789") + .legalBusinessName("Busy Business, Inc.") + .addPhoneNumber("+15555555555") + .dbaBusinessName("Example Business Solutions") + .parentCompany("parent_company") + .build() + ) + .controlPerson( + Kyb.KybIndividual.builder() + .address( + Address.builder() + .address1("451 New Forest Way") + .city("Springfield") + .country("USA") + .postalCode("68022") + .state("IL") + .address2("address2") .build() ) - .natureOfBusiness( - "Software company selling solutions to the restaurant industry" - ) - .tosTimestamp("2022-03-08T08:00:00Z") - .workflow(Kyb.Workflow.KYB_BYO) - .addBeneficialOwnerEntity( - Kyb.BusinessEntity.builder() - .address( - Address.builder() - .address1("300 Normal Forest Way") - .city("Portland") - .country("USA") - .postalCode("90210") - .state("OR") - .address2("address2") - .build() - ) - .governmentId("98-7654321") - .legalBusinessName("Majority Holdings LLC") - .addPhoneNumber("+15555555555") - .dbaBusinessName("MHoldings") - .parentCompany("parent_company") + .dob("1991-03-08T08:00:00Z") + .email("tom@middle-pluto.com") + .firstName("Tom") + .governmentId("111-23-1412") + .lastName("Timothy") + .phoneNumber("+15555555555") + .build() + ) + .natureOfBusiness( + "Software company selling solutions to the restaurant industry" + ) + .tosTimestamp("2022-03-08T08:00:00Z") + .workflow(Kyb.Workflow.KYB_BYO) + .addBeneficialOwnerEntity( + Kyb.BusinessEntity.builder() + .address( + Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") .build() ) - .externalId("external_id") - .kybPassedTimestamp("2022-03-08T08:00:00Z") - .websiteUrl("https://www.mybusiness.com") + .governmentId("98-7654321") + .legalBusinessName("Majority Holdings LLC") + .addPhoneNumber("+15555555555") + .dbaBusinessName("MHoldings") + .parentCompany("parent_company") .build() ) + .externalId("external_id") + .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") + .websiteUrl("https://www.mybusiness.com") .build() ) @@ -198,6 +194,7 @@ internal class AccountHolderServiceAsyncTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -241,11 +238,13 @@ internal class AccountHolderServiceAsyncTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/BookTransferServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/BookTransferServiceAsyncTest.kt index 0c1900ec..c0db3936 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/BookTransferServiceAsyncTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/BookTransferServiceAsyncTest.kt @@ -33,6 +33,7 @@ internal class BookTransferServiceAsyncTest { .type(BookTransferCreateParams.BookTransferType.ATM_BALANCE_INQUIRY) .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .externalId("external_id") + .holdToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .memo("memo") .onClosedAccount(BookTransferCreateParams.OnClosedAccount.FAIL) .build() diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncTest.kt index 0f695a6f..857fe26c 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsyncTest.kt @@ -29,43 +29,38 @@ internal class ExternalBankAccountServiceAsyncTest { val externalBankAccountFuture = externalBankAccountServiceAsync.create( - ExternalBankAccountCreateParams.builder() - .body( + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + .builder() + .accountNumber("13719713158835300") + .country("USA") + .currency("USD") + .financialAccountToken("dabadb3b-700c-41e3-8801-d5dfc84ebea0") + .owner("John Doe") + .ownerType(OwnerType.BUSINESS) + .routingNumber("011103093") + .type( ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest - .builder() - .accountNumber("13719713158835300") + .AccountType + .CHECKING + ) + .verificationMethod(VerificationMethod.MICRO_DEPOSIT) + .accountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + ExternalBankAccountAddress.builder() + .address1("5 Broad Street") + .city("New York") .country("USA") - .currency("USD") - .financialAccountToken("dabadb3b-700c-41e3-8801-d5dfc84ebea0") - .owner("John Doe") - .ownerType(OwnerType.BUSINESS) - .routingNumber("011103093") - .type( - ExternalBankAccountCreateParams.Body - .BankVerifiedCreateBankAccountApiRequest - .AccountType - .CHECKING - ) - .verificationMethod(VerificationMethod.MICRO_DEPOSIT) - .accountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .address( - ExternalBankAccountAddress.builder() - .address1("5 Broad Street") - .city("New York") - .country("USA") - .postalCode("10001") - .state("NY") - .address2("x") - .build() - ) - .companyId("sq") - .dob(LocalDate.parse("2019-12-27")) - .doingBusinessAs("x") - .name("John Does Checking") - .userDefinedId("x") - .verificationEnforcement(true) + .postalCode("10001") + .state("NY") + .address2("x") .build() ) + .companyId("sq") + .dob(LocalDate.parse("2019-12-27")) + .doingBusinessAs("x") + .name("John Does Checking") + .userDefinedId("x") + .verificationEnforcement(true) .build() ) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/WebhookServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/WebhookServiceAsyncTest.kt new file mode 100644 index 00000000..66876aec --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/WebhookServiceAsyncTest.kt @@ -0,0 +1,89 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async + +import com.lithic.api.client.okhttp.LithicOkHttpClientAsync +import com.lithic.api.core.http.Headers +import com.lithic.api.errors.LithicWebhookException +import com.standardwebhooks.Webhook +import java.time.Instant +import org.assertj.core.api.Assertions.assertThatCode +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test + +internal class WebhookServiceAsyncTest { + + private val webhookSecret = "whsec_c2VjcmV0Cg==" + + @Test + fun verifySignature() { + val client = + LithicOkHttpClientAsync.builder() + .apiKey("test-api-key") + .webhookSecret(webhookSecret) + .build() + + val payload = + "{\"event_type\":\"account_holder.created\",\"token\":\"00000000-0000-0000-0000-000000000001\"}" + val messageId = "msg_1" + val timestampSeconds = Instant.now().epochSecond + val webhook = Webhook(webhookSecret) + val signature = webhook.sign(messageId, timestampSeconds, payload) + val headers = + Headers.builder() + .put("webhook-id", messageId) + .put("webhook-timestamp", timestampSeconds.toString()) + .put("webhook-signature", signature) + .build() + + // Valid signature should not throw + assertThatCode { client.webhooks().verifySignature(payload, headers, null) } + .doesNotThrowAnyException() + + // Wrong key should throw + assertThatThrownBy { + client.webhooks().verifySignature(payload, headers, "whsec_aaaaaaaaaa") + } + .isInstanceOf(LithicWebhookException::class.java) + + // Bad signature should throw + val badSignature = webhook.sign(messageId, timestampSeconds, "some other payload") + assertThatThrownBy { + client + .webhooks() + .verifySignature( + payload, + headers + .toBuilder() + .replace("webhook-signature", listOf(badSignature)) + .build(), + null, + ) + } + .isInstanceOf(LithicWebhookException::class.java) + + // Old timestamp should throw + assertThatThrownBy { + client + .webhooks() + .verifySignature( + payload, + headers.toBuilder().replace("webhook-timestamp", listOf("5")).build(), + null, + ) + } + .isInstanceOf(LithicWebhookException::class.java) + + // Wrong message ID should throw + assertThatThrownBy { + client + .webhooks() + .verifySignature( + payload, + headers.toBuilder().replace("webhook-id", listOf("wrong")).build(), + null, + ) + } + .isInstanceOf(LithicWebhookException::class.java) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncTest.kt index 59bfc5ee..202f019d 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncTest.kt @@ -32,30 +32,25 @@ internal class V2ServiceAsyncTest { val authRuleFuture = v2ServiceAsync.create( - AuthRuleV2CreateParams.builder() - .body( - AuthRuleV2CreateParams.Body.AccountLevelRule.builder() - .parameters( - ConditionalBlockParameters.builder() - .addCondition( - AuthRuleCondition.builder() - .attribute(ConditionalAttribute.MCC) - .operation(ConditionalOperation.IS_ONE_OF) - .value("string") - .build() - ) + AuthRuleV2CreateParams.Body.AccountLevelRule.builder() + .parameters( + ConditionalBlockParameters.builder() + .addCondition( + AuthRuleCondition.builder() + .attribute(ConditionalAttribute.MCC) + .operation(ConditionalOperation.IS_ONE_OF) + .value("string") .build() ) - .type( - AuthRuleV2CreateParams.Body.AccountLevelRule.AuthRuleType - .CONDITIONAL_BLOCK - ) - .addAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addBusinessAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .eventStream(EventStream.AUTHORIZATION) - .name("name") .build() ) + .type( + AuthRuleV2CreateParams.Body.AccountLevelRule.AuthRuleType.CONDITIONAL_BLOCK + ) + .addAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addBusinessAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .eventStream(EventStream.AUTHORIZATION) + .name("name") .build() ) @@ -166,6 +161,21 @@ internal class V2ServiceAsyncTest { authRule.validate() } + @Test + fun listResults() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val v2ServiceAsync = client.authRules().v2() + + val pageFuture = v2ServiceAsync.listResults() + + val page = pageFuture.get() + page.response().validate() + } + @Test fun promote() { val client = diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/AccountHolderServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/AccountHolderServiceTest.kt index 62807a33..b39ad8b9 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/AccountHolderServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/AccountHolderServiceTest.kt @@ -4,7 +4,6 @@ package com.lithic.api.services.blocking import com.lithic.api.TestServerExtension import com.lithic.api.client.okhttp.LithicOkHttpClient -import com.lithic.api.models.AccountHolderCreateParams import com.lithic.api.models.AccountHolderRetrieveDocumentParams import com.lithic.api.models.AccountHolderSimulateEnrollmentDocumentReviewParams import com.lithic.api.models.AccountHolderSimulateEnrollmentReviewParams @@ -30,97 +29,94 @@ internal class AccountHolderServiceTest { val accountHolder = accountHolderService.create( - AccountHolderCreateParams.builder() - .body( - Kyb.builder() - .addBeneficialOwnerIndividual( - Kyb.KybIndividual.builder() - .address( - Address.builder() - .address1("300 Normal Forest Way") - .city("Portland") - .country("USA") - .postalCode("90210") - .state("OR") - .address2("address2") - .build() - ) - .dob("1991-03-08T08:00:00Z") - .email("tim@left-earth.com") - .firstName("Timmy") - .governmentId("211-23-1412") - .lastName("Turner") - .phoneNumber("+15555555555") + Kyb.builder() + .addBeneficialOwnerIndividual( + Kyb.KybIndividual.builder() + .address( + Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") .build() ) - .businessEntity( - Kyb.BusinessEntity.builder() - .address( - Address.builder() - .address1("123 Old Forest Way") - .city("Omaha") - .country("USA") - .postalCode("61022") - .state("NE") - .address2("address2") - .build() - ) - .governmentId("12-3456789") - .legalBusinessName("Busy Business, Inc.") - .addPhoneNumber("+15555555555") - .dbaBusinessName("Example Business Solutions") - .parentCompany("parent_company") + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .build() + ) + .businessEntity( + Kyb.BusinessEntity.builder() + .address( + Address.builder() + .address1("123 Old Forest Way") + .city("Omaha") + .country("USA") + .postalCode("61022") + .state("NE") + .address2("address2") .build() ) - .controlPerson( - Kyb.KybIndividual.builder() - .address( - Address.builder() - .address1("451 New Forest Way") - .city("Springfield") - .country("USA") - .postalCode("68022") - .state("IL") - .address2("address2") - .build() - ) - .dob("1991-03-08T08:00:00Z") - .email("tom@middle-pluto.com") - .firstName("Tom") - .governmentId("111-23-1412") - .lastName("Timothy") - .phoneNumber("+15555555555") + .governmentId("12-3456789") + .legalBusinessName("Busy Business, Inc.") + .addPhoneNumber("+15555555555") + .dbaBusinessName("Example Business Solutions") + .parentCompany("parent_company") + .build() + ) + .controlPerson( + Kyb.KybIndividual.builder() + .address( + Address.builder() + .address1("451 New Forest Way") + .city("Springfield") + .country("USA") + .postalCode("68022") + .state("IL") + .address2("address2") .build() ) - .natureOfBusiness( - "Software company selling solutions to the restaurant industry" - ) - .tosTimestamp("2022-03-08T08:00:00Z") - .workflow(Kyb.Workflow.KYB_BYO) - .addBeneficialOwnerEntity( - Kyb.BusinessEntity.builder() - .address( - Address.builder() - .address1("300 Normal Forest Way") - .city("Portland") - .country("USA") - .postalCode("90210") - .state("OR") - .address2("address2") - .build() - ) - .governmentId("98-7654321") - .legalBusinessName("Majority Holdings LLC") - .addPhoneNumber("+15555555555") - .dbaBusinessName("MHoldings") - .parentCompany("parent_company") + .dob("1991-03-08T08:00:00Z") + .email("tom@middle-pluto.com") + .firstName("Tom") + .governmentId("111-23-1412") + .lastName("Timothy") + .phoneNumber("+15555555555") + .build() + ) + .natureOfBusiness( + "Software company selling solutions to the restaurant industry" + ) + .tosTimestamp("2022-03-08T08:00:00Z") + .workflow(Kyb.Workflow.KYB_BYO) + .addBeneficialOwnerEntity( + Kyb.BusinessEntity.builder() + .address( + Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") .build() ) - .externalId("external_id") - .kybPassedTimestamp("2022-03-08T08:00:00Z") - .websiteUrl("https://www.mybusiness.com") + .governmentId("98-7654321") + .legalBusinessName("Majority Holdings LLC") + .addPhoneNumber("+15555555555") + .dbaBusinessName("MHoldings") + .parentCompany("parent_company") .build() ) + .externalId("external_id") + .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") + .websiteUrl("https://www.mybusiness.com") .build() ) @@ -195,6 +191,7 @@ internal class AccountHolderServiceTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() @@ -238,11 +235,13 @@ internal class AccountHolderServiceTest { .dob("1991-03-08 08:00:00") .email("tom@middle-earth.com") .firstName("Tom") + .governmentId("111-23-1412") .lastName("Bombadil") .phoneNumber("+15555555555") .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/BookTransferServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/BookTransferServiceTest.kt index 57d19f31..eeaa8f24 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/BookTransferServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/BookTransferServiceTest.kt @@ -33,6 +33,7 @@ internal class BookTransferServiceTest { .type(BookTransferCreateParams.BookTransferType.ATM_BALANCE_INQUIRY) .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .externalId("external_id") + .holdToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .memo("memo") .onClosedAccount(BookTransferCreateParams.OnClosedAccount.FAIL) .build() diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceTest.kt index 6b141dfa..a659b745 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/ExternalBankAccountServiceTest.kt @@ -29,43 +29,38 @@ internal class ExternalBankAccountServiceTest { val externalBankAccount = externalBankAccountService.create( - ExternalBankAccountCreateParams.builder() - .body( + ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest + .builder() + .accountNumber("13719713158835300") + .country("USA") + .currency("USD") + .financialAccountToken("dabadb3b-700c-41e3-8801-d5dfc84ebea0") + .owner("John Doe") + .ownerType(OwnerType.BUSINESS) + .routingNumber("011103093") + .type( ExternalBankAccountCreateParams.Body.BankVerifiedCreateBankAccountApiRequest - .builder() - .accountNumber("13719713158835300") + .AccountType + .CHECKING + ) + .verificationMethod(VerificationMethod.MICRO_DEPOSIT) + .accountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + ExternalBankAccountAddress.builder() + .address1("5 Broad Street") + .city("New York") .country("USA") - .currency("USD") - .financialAccountToken("dabadb3b-700c-41e3-8801-d5dfc84ebea0") - .owner("John Doe") - .ownerType(OwnerType.BUSINESS) - .routingNumber("011103093") - .type( - ExternalBankAccountCreateParams.Body - .BankVerifiedCreateBankAccountApiRequest - .AccountType - .CHECKING - ) - .verificationMethod(VerificationMethod.MICRO_DEPOSIT) - .accountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .address( - ExternalBankAccountAddress.builder() - .address1("5 Broad Street") - .city("New York") - .country("USA") - .postalCode("10001") - .state("NY") - .address2("x") - .build() - ) - .companyId("sq") - .dob(LocalDate.parse("2019-12-27")) - .doingBusinessAs("x") - .name("John Does Checking") - .userDefinedId("x") - .verificationEnforcement(true) + .postalCode("10001") + .state("NY") + .address2("x") .build() ) + .companyId("sq") + .dob(LocalDate.parse("2019-12-27")) + .doingBusinessAs("x") + .name("John Does Checking") + .userDefinedId("x") + .verificationEnforcement(true) .build() ) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt index e647cb95..fe43f36f 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt @@ -4,54 +4,38 @@ package com.lithic.api.services.blocking import com.lithic.api.client.okhttp.LithicOkHttpClient import com.lithic.api.core.http.Headers -import com.lithic.api.errors.LithicException +import com.lithic.api.errors.LithicWebhookException import com.lithic.api.models.* -import java.time.Clock +import com.standardwebhooks.Webhook import java.time.Instant -import java.time.ZoneOffset -import java.util.Base64 -import javax.crypto.Mac -import javax.crypto.spec.SecretKeySpec import org.assertj.core.api.Assertions.* import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test class WebhookServiceTest { - private fun generateSignature( - secret: String, - msgId: String, - timestamp: Long, - payload: String, - ): String { - val whsecret = Base64.getDecoder().decode(secret.removePrefix("whsec_")) - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(whsecret, "HmacSHA256")) - val signature = mac.doFinal("$msgId.$timestamp.$payload".toByteArray()) - return Base64.getEncoder().encodeToString(signature) + private val webhookSecret = "whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst" + + private fun signPayload(msgId: String, timestamp: Long, payload: String): String { + val webhook = Webhook(webhookSecret) + return webhook.sign(msgId, timestamp, payload) } @Test fun unwrap() { - val now = Instant.now() - val timestamp = now.epochSecond + val timestamp = Instant.now().epochSecond val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst") - .clock(Clock.fixed(now, ZoneOffset.UTC)) - .build() + LithicOkHttpClient.builder().apiKey("test-api-key").webhookSecret(webhookSecret).build() val payload = "{\"card_token\":\"sit Lorem ipsum, accusantium repellendus possimus\",\"created_at\":\"elit. placeat libero architecto molestias, sit\",\"account_token\":\"elit.\",\"issuer_decision\":\"magnam, libero esse Lorem ipsum magnam, magnam,\",\"tokenization_attempt_id\":\"illum dolor repellendus libero esse accusantium\",\"wallet_decisioning_info\":{\"device_score\":\"placeat architecto\"},\"digital_wallet_token_metadata\":{\"status\":\"reprehenderit dolor\",\"token_requestor_id\":\"possimus\",\"payment_account_info\":{\"account_holder_data\":{\"phone_number\":\"libero\",\"email_address\":\"nobis molestias, veniam culpa! quas elit. quas libero esse architecto placeat\"},\"pan_unique_reference\":\"adipisicing odit magnam, odit\"}}}" val msgId = "msg_2Lh9KRb0pzN4LePd3XiA4v12Axj" - val signature = - generateSignature("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst", msgId, timestamp, payload) + val signature = signPayload(msgId, timestamp, payload) val headers = Headers.builder() .put("webhook-id", msgId) .put("webhook-timestamp", timestamp.toString()) - .put("webhook-signature", "v1,$signature") + .put("webhook-signature", signature) .build() val event = client.webhooks().unwrap(payload, headers, null) @@ -61,42 +45,29 @@ class WebhookServiceTest { @Test fun verifySignature() { - val now = Instant.now() - val timestamp = now.epochSecond + val timestamp = Instant.now().epochSecond val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst") - .clock(Clock.fixed(now, ZoneOffset.UTC)) - .build() + LithicOkHttpClient.builder().apiKey("test-api-key").webhookSecret(webhookSecret).build() val payload = "{\"card_token\":\"sit Lorem ipsum, accusantium repellendus possimus\",\"created_at\":\"elit. placeat libero architecto molestias, sit\",\"account_token\":\"elit.\",\"issuer_decision\":\"magnam, libero esse Lorem ipsum magnam, magnam,\",\"tokenization_attempt_id\":\"illum dolor repellendus libero esse accusantium\",\"wallet_decisioning_info\":{\"device_score\":\"placeat architecto\"},\"digital_wallet_token_metadata\":{\"status\":\"reprehenderit dolor\",\"token_requestor_id\":\"possimus\",\"payment_account_info\":{\"account_holder_data\":{\"phone_number\":\"libero\",\"email_address\":\"nobis molestias, veniam culpa! quas elit. quas libero esse architecto placeat\"},\"pan_unique_reference\":\"adipisicing odit magnam, odit\"}}}" val webhookId = "msg_2Lh9KRb0pzN4LePd3XiA4v12Axj" val webhookTimestamp = timestamp.toString() - val webhookSignature = - generateSignature( - "whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst", - webhookId, - timestamp, - payload, - ) + val signature = signPayload(webhookId, timestamp, payload) val headers = Headers.builder() .put("webhook-id", webhookId) .put("webhook-timestamp", webhookTimestamp) - .put("webhook-signature", "v1,$webhookSignature") + .put("webhook-signature", signature) .build() - // Test timestamp too old (> 5 minutes) - val oldTimestamp = timestamp - 360 // 6 minutes ago - val oldSignature = - generateSignature( - "whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst", - webhookId, - oldTimestamp, - payload, - ) + // Valid signature should not throw + assertThatCode { client.webhooks().verifySignature(payload, headers, null) } + .doesNotThrowAnyException() + + // Timestamp too old (> 5 minutes) + val oldTimestamp = timestamp - 360 + val oldSignature = signPayload(webhookId, oldTimestamp, payload) assertThatThrownBy { client .webhooks() @@ -105,23 +76,16 @@ class WebhookServiceTest { Headers.builder() .put("webhook-id", webhookId) .put("webhook-timestamp", oldTimestamp.toString()) - .put("webhook-signature", "v1,$oldSignature") + .put("webhook-signature", oldSignature) .build(), null, ) } - .isInstanceOf(LithicException::class.java) - .hasMessage("Webhook timestamp too old") + .isInstanceOf(LithicWebhookException::class.java) - // Test timestamp too new (> 5 minutes in future) - val futureTimestamp = timestamp + 360 // 6 minutes from now - val futureSignature = - generateSignature( - "whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst", - webhookId, - futureTimestamp, - payload, - ) + // Timestamp too new (> 5 minutes in future) + val futureTimestamp = timestamp + 360 + val futureSignature = signPayload(webhookId, futureTimestamp, payload) assertThatThrownBy { client .webhooks() @@ -130,60 +94,22 @@ class WebhookServiceTest { Headers.builder() .put("webhook-id", webhookId) .put("webhook-timestamp", futureTimestamp.toString()) - .put("webhook-signature", "v1,$futureSignature") - .build(), - null, - ) - } - .isInstanceOf(LithicException::class.java) - .hasMessage("Webhook timestamp too new") - - // Test invalid secret format - assertThatThrownBy { client.webhooks().verifySignature(payload, headers, "invalid-secret") } - .isInstanceOf(LithicException::class.java) - .hasMessage("Invalid webhook secret") - - // Test incorrect signature with valid secret - assertThatThrownBy { client.webhooks().verifySignature(payload, headers, "Zm9v") } - .isInstanceOf(LithicException::class.java) - .hasMessage("None of the given webhook signatures match the expected signature") - - // Test multiple signatures where one is valid - assertThatCode { - client - .webhooks() - .verifySignature( - payload, - Headers.builder() - .put("webhook-id", webhookId) - .put("webhook-timestamp", webhookTimestamp) - .put("webhook-signature", "v1,$webhookSignature v1,Zm9v") + .put("webhook-signature", futureSignature) .build(), null, ) } - .doesNotThrowAnyException() + .isInstanceOf(LithicWebhookException::class.java) - // Test wrong signature version + // Wrong secret should throw assertThatThrownBy { - client - .webhooks() - .verifySignature( - payload, - Headers.builder() - .put("webhook-id", webhookId) - .put("webhook-timestamp", webhookTimestamp) - .put("webhook-signature", "v2,$webhookSignature") - .build(), - null, - ) + client.webhooks().verifySignature(payload, headers, "whsec_aaaaaaaaaa") } - .isInstanceOf(LithicException::class.java) - .hasMessage("None of the given webhook signatures match the expected signature") + .isInstanceOf(LithicWebhookException::class.java) - // Test multiple signatures where the first is valid (should succeed even if later ones are - // wrong version) - assertThatCode { + // Bad signature (signed with different payload) should throw + val badSignature = signPayload(webhookId, timestamp, "some other payload") + assertThatThrownBy { client .webhooks() .verifySignature( @@ -191,51 +117,40 @@ class WebhookServiceTest { Headers.builder() .put("webhook-id", webhookId) .put("webhook-timestamp", webhookTimestamp) - .put("webhook-signature", "v1,$webhookSignature v2,$webhookSignature") + .put("webhook-signature", badSignature) .build(), null, ) } - .doesNotThrowAnyException() + .isInstanceOf(LithicWebhookException::class.java) - // Test signature without version prefix + // Wrong message ID should throw assertThatThrownBy { client .webhooks() .verifySignature( payload, - Headers.builder() - .put("webhook-id", webhookId) - .put("webhook-timestamp", webhookTimestamp) - .put("webhook-signature", webhookSignature) - .build(), + headers.toBuilder().replace("webhook-id", listOf("wrong")).build(), null, ) } - .isInstanceOf(LithicException::class.java) - .hasMessage("None of the given webhook signatures match the expected signature") + .isInstanceOf(LithicWebhookException::class.java) } @Test fun parse() { - val now = Instant.now() - val timestamp = now.epochSecond + val timestamp = Instant.now().epochSecond val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst") - .clock(Clock.fixed(now, ZoneOffset.UTC)) - .build() + LithicOkHttpClient.builder().apiKey("test-api-key").webhookSecret(webhookSecret).build() val payload = """{"card_token":"card_Ao6kQgjenC6H2bSd","event_type":"card.created"}""" val msgId = "msg_2Lh9KRb0pzN4LePd3XiA4v12Axj" - val signature = - generateSignature("whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst", msgId, timestamp, payload) + val signature = signPayload(msgId, timestamp, payload) val headers = Headers.builder() .put("webhook-id", msgId) .put("webhook-timestamp", timestamp.toString()) - .put("webhook-signature", "v1,$signature") + .put("webhook-signature", signature) .build() val event = client.webhooks().parse(payload, headers, null) diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceTest.kt index 7ec49bf4..b703c864 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceTest.kt @@ -32,30 +32,25 @@ internal class V2ServiceTest { val authRule = v2Service.create( - AuthRuleV2CreateParams.builder() - .body( - AuthRuleV2CreateParams.Body.AccountLevelRule.builder() - .parameters( - ConditionalBlockParameters.builder() - .addCondition( - AuthRuleCondition.builder() - .attribute(ConditionalAttribute.MCC) - .operation(ConditionalOperation.IS_ONE_OF) - .value("string") - .build() - ) + AuthRuleV2CreateParams.Body.AccountLevelRule.builder() + .parameters( + ConditionalBlockParameters.builder() + .addCondition( + AuthRuleCondition.builder() + .attribute(ConditionalAttribute.MCC) + .operation(ConditionalOperation.IS_ONE_OF) + .value("string") .build() ) - .type( - AuthRuleV2CreateParams.Body.AccountLevelRule.AuthRuleType - .CONDITIONAL_BLOCK - ) - .addAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addBusinessAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .eventStream(EventStream.AUTHORIZATION) - .name("name") .build() ) + .type( + AuthRuleV2CreateParams.Body.AccountLevelRule.AuthRuleType.CONDITIONAL_BLOCK + ) + .addAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addBusinessAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .eventStream(EventStream.AUTHORIZATION) + .name("name") .build() ) @@ -159,6 +154,20 @@ internal class V2ServiceTest { authRule.validate() } + @Test + fun listResults() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val v2Service = client.authRules().v2() + + val page = v2Service.listResults() + + page.response().validate() + } + @Test fun promote() { val client = diff --git a/lithic-java-proguard-test/build.gradle.kts b/lithic-java-proguard-test/build.gradle.kts index 9f9c7fba..09a7df21 100644 --- a/lithic-java-proguard-test/build.gradle.kts +++ b/lithic-java-proguard-test/build.gradle.kts @@ -18,7 +18,7 @@ dependencies { testImplementation(project(":lithic-java")) testImplementation(kotlin("test")) testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") - testImplementation("org.assertj:assertj-core:3.25.3") + testImplementation("org.assertj:assertj-core:3.27.7") testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.0") } diff --git a/scripts/build b/scripts/build index f4063482..16a2b00d 100755 --- a/scripts/build +++ b/scripts/build @@ -5,4 +5,4 @@ set -e cd "$(dirname "$0")/.." echo "==> Building classes" -./gradlew build testClasses -x test +./gradlew build testClasses "$@" -x test