From b075f58683c40bd097d18490992744526f74161a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:02:53 +0000 Subject: [PATCH 01/26] fix: add missing fields --- .../AccountHolderSimulateEnrollmentReviewResponseTest.kt | 9 +++++++++ .../lithic/api/models/AccountHolderUpdateParamsTest.kt | 6 ++++++ .../lithic/api/models/AccountHolderUpdateResponseTest.kt | 6 ++++++ .../api/models/AccountHolderUpdatedWebhookEventTest.kt | 6 ++++++ .../com/lithic/api/models/ParsedWebhookEventTest.kt | 6 ++++++ .../api/services/async/AccountHolderServiceAsyncTest.kt | 2 ++ .../api/services/blocking/AccountHolderServiceTest.kt | 2 ++ 7 files changed, 37 insertions(+) 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..5f5b4ee2 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,6 +120,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() @@ -203,6 +206,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 +249,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,6 +277,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() @@ -360,6 +366,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 +407,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,6 +434,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() 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..8ed2e868 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,6 +92,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() @@ -162,6 +164,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,6 +206,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() @@ -259,6 +263,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,6 +305,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() 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..56bd8155 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,6 +124,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() @@ -211,6 +214,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 +255,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,6 +283,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() 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..538d2c69 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() @@ -171,6 +173,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 +216,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() @@ -266,6 +270,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 +319,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/ParsedWebhookEventTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ParsedWebhookEventTest.kt index 92718683..a8a3cc4f 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() @@ -332,6 +334,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 +375,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() @@ -419,6 +423,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 +524,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() 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..c310b240 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 @@ -198,6 +198,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,6 +242,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() 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..475f1248 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 @@ -195,6 +195,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,6 +239,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() From 2ddf82360b21d85b57231fafc022f10ef909df40 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:19:18 +0000 Subject: [PATCH 02/26] chore: configure new SDK language --- .stats.yml | 2 +- README.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 0080147f..6c50cded 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 +config_hash: 03116d920ed711085fce266148733bcc diff --git a/README.md b/README.md index 7829b853..2a8289b1 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,15 @@ 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=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImxpdGhpYy1tY3AiXSwiZW52Ijp7IkxJVEhJQ19BUElfS0VZIjoiTXkgTGl0aGljIEFQSSBLZXkiLCJMSVRISUNfV0VCSE9PS19TRUNSRVQiOiJNeSBXZWJob29rIFNlY3JldCJ9fQ) +[![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%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22lithic-mcp%22%5D%2C%22env%22%3A%7B%22LITHIC_API_KEY%22%3A%22My%20Lithic%20API%20Key%22%2C%22LITHIC_WEBHOOK_SECRET%22%3A%22My%20Webhook%20Secret%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). From 2f605c19967c7c77dec0358e1ccbacbadf9fc632 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:34:33 +0000 Subject: [PATCH 03/26] chore: Enable stainless MCP in config --- .stats.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 6c50cded..5ae1eda0 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: 03116d920ed711085fce266148733bcc +config_hash: faacaff68ffb3a4d051f0a7b8442e099 diff --git a/README.md b/README.md index 2a8289b1..d6195437 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ The Lithic Java SDK is similar to the Lithic Kotlin SDK but with minor differenc 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=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImxpdGhpYy1tY3AiXSwiZW52Ijp7IkxJVEhJQ19BUElfS0VZIjoiTXkgTGl0aGljIEFQSSBLZXkiLCJMSVRISUNfV0VCSE9PS19TRUNSRVQiOiJNeSBXZWJob29rIFNlY3JldCJ9fQ) -[![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%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22lithic-mcp%22%5D%2C%22env%22%3A%7B%22LITHIC_API_KEY%22%3A%22My%20Lithic%20API%20Key%22%2C%22LITHIC_WEBHOOK_SECRET%22%3A%22My%20Webhook%20Secret%22%7D%7D) +[![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. From c9ff6daa033e4022ac9208f4ff81d18346f53695 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:35:55 +0000 Subject: [PATCH 04/26] feat(api): Add naics_code to account holder requests/responses --- .stats.yml | 4 +- .../com/lithic/api/models/AccountHolder.kt | 55 +++++++++++++++--- .../api/models/AccountHolderCreateParams.kt | 47 ++++++++++++++- ...tHolderSimulateEnrollmentReviewResponse.kt | 55 +++++++++++++++--- .../api/models/AccountHolderUpdateParams.kt | 47 ++++++++++++++- .../api/models/AccountHolderUpdateResponse.kt | 57 ++++++++++++++++--- .../AccountHolderUpdatedWebhookEvent.kt | 45 ++++++++++++++- .../main/kotlin/com/lithic/api/models/Kyb.kt | 39 ++++++++++++- .../lithic/api/models/ParsedWebhookEvent.kt | 45 ++++++++++++++- .../models/AccountHolderCreateParamsTest.kt | 3 + .../AccountHolderListPageResponseTest.kt | 3 + ...derSimulateEnrollmentReviewResponseTest.kt | 3 + .../lithic/api/models/AccountHolderTest.kt | 3 + .../models/AccountHolderUpdateParamsTest.kt | 3 + .../models/AccountHolderUpdateResponseTest.kt | 2 + .../AccountHolderUpdatedWebhookEventTest.kt | 2 + .../kotlin/com/lithic/api/models/KybTest.kt | 3 + .../api/models/ParsedWebhookEventTest.kt | 2 + .../async/AccountHolderServiceAsyncTest.kt | 2 + .../blocking/AccountHolderServiceTest.kt | 2 + 20 files changed, 394 insertions(+), 28 deletions(-) diff --git a/.stats.yml b/.stats.yml index 5ae1eda0..2c43cb20 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 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-05d665e9c7e81d85c0d6629bf3898e2eb221268d677b772ef3da3891b25d8346.yml +openapi_spec_hash: fd8900412ab9a393719dba3669d44d3a config_hash: faacaff68ffb3a4d051f0a7b8442e099 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/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/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/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 5f5b4ee2..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 @@ -125,6 +125,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("phone_number") .addRequiredDocument( @@ -282,6 +283,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .phoneNumber("+15555555555") .build() ) + assertThat(accountHolderSimulateEnrollmentReviewResponse.naicsCode()).contains("naics_code") assertThat(accountHolderSimulateEnrollmentReviewResponse.natureOfBusiness()) .contains("nature_of_business") assertThat(accountHolderSimulateEnrollmentReviewResponse.phoneNumber()) @@ -439,6 +441,7 @@ internal class AccountHolderSimulateEnrollmentReviewResponseTest { .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 8ed2e868..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 @@ -98,6 +98,7 @@ internal class AccountHolderUpdateParamsTest { .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) @@ -212,6 +213,7 @@ internal class AccountHolderUpdateParamsTest { .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) @@ -311,6 +313,7 @@ internal class AccountHolderUpdateParamsTest { .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 56bd8155..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 @@ -129,6 +129,7 @@ internal class AccountHolderUpdateResponseTest { .phoneNumber("+15555555555") .build() ) + .naicsCode("naics_code") .natureOfBusiness("nature_of_business") .phoneNumber("phone_number") .addRequiredDocument( @@ -288,6 +289,7 @@ internal class AccountHolderUpdateResponseTest { .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 538d2c69..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 @@ -114,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() @@ -227,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" ) 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 a8a3cc4f..f2c08fec 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 @@ -221,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() @@ -384,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" ) 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 c310b240..cde7d409 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 @@ -118,6 +118,7 @@ internal class AccountHolderServiceAsyncTest { ) .externalId("external_id") .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") .websiteUrl("https://www.mybusiness.com") .build() ) @@ -248,6 +249,7 @@ internal class AccountHolderServiceAsyncTest { .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/AccountHolderServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/AccountHolderServiceTest.kt index 475f1248..e4a902fc 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 @@ -118,6 +118,7 @@ internal class AccountHolderServiceTest { ) .externalId("external_id") .kybPassedTimestamp("2022-03-08T08:00:00Z") + .naicsCode("541512") .websiteUrl("https://www.mybusiness.com") .build() ) @@ -245,6 +246,7 @@ internal class AccountHolderServiceTest { .build() ) .externalId("external_id") + .naicsCode("541512") .natureOfBusiness( "Software company selling solutions to the restaurant industry" ) From b327fb6b7736803c3fd6a0806fe528aeeb96f428 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 22:45:07 +0000 Subject: [PATCH 05/26] chore(internal): allow passing args to `./scripts/test` --- scripts/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From c8632283a23548a67d038da60a064d70ef03d017 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 17:03:10 +0000 Subject: [PATCH 06/26] docs: Fix documentation of tokenization channel and tokenization source for tokenization rules --- .stats.yml | 4 ++-- .../ConditionalTokenizationActionParameters.kt | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2c43cb20..3bc0021a 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-05d665e9c7e81d85c0d6629bf3898e2eb221268d677b772ef3da3891b25d8346.yml -openapi_spec_hash: fd8900412ab9a393719dba3669d44d3a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-6f5bac5a5738304da24f077b52afd3c309c0fc4719176d26fb6eddd598e20eb2.yml +openapi_spec_hash: cc4e56e4325643c3342bcd80a082e16e config_hash: faacaff68ffb3a4d051f0a7b8442e099 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..9fcd9469 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 @@ -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`, @@ -1620,8 +1622,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`, @@ -1778,8 +1782,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`, From d91bef9d101200a475da93aa5e961a0ce40589a0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 20:24:21 +0000 Subject: [PATCH 07/26] codegen metadata --- .stats.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3bc0021a..237cf435 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-6f5bac5a5738304da24f077b52afd3c309c0fc4719176d26fb6eddd598e20eb2.yml -openapi_spec_hash: cc4e56e4325643c3342bcd80a082e16e -config_hash: faacaff68ffb3a4d051f0a7b8442e099 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fbdac41d84b5679c659e324345bc4101b056b5f5ed4ddefcd6680afe20db41dc.yml +openapi_spec_hash: 37834cd63d604a528d0467c1cfb01919 +config_hash: 61652458521692cd0b88976827c42c25 From 4e26f350ebf038f7fa0562a484a6fea5a2d85de4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 20:01:23 +0000 Subject: [PATCH 08/26] feat(api): add webhook signature verification --- lithic-java-core/build.gradle.kts | 1 + .../lithic/api/core/UnwrapWebhookParams.kt | 102 ++++++++++++++++++ .../api/errors/LithicWebhookException.kt | 5 + .../api/services/async/WebhookServiceAsync.kt | 10 ++ .../services/async/WebhookServiceAsyncImpl.kt | 5 +- .../api/services/blocking/WebhookService.kt | 10 ++ .../services/blocking/WebhookServiceImpl.kt | 27 +++++ .../services/async/WebhookServiceAsyncTest.kt | 98 +++++++++++++++++ 8 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/core/UnwrapWebhookParams.kt create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/errors/LithicWebhookException.kt create mode 100644 lithic-java-core/src/test/kotlin/com/lithic/api/services/async/WebhookServiceAsyncTest.kt diff --git a/lithic-java-core/build.gradle.kts b/lithic-java-core/build.gradle.kts index 151c17eb..4c30bb62 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") 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/services/async/WebhookServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt index 407346b2..77c315ef 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt @@ -4,8 +4,10 @@ package com.lithic.api.services.async import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue +import com.lithic.api.core.UnwrapWebhookParams import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicInvalidDataException +import com.lithic.api.errors.LithicWebhookException import com.lithic.api.models.ParsedWebhookEvent import java.util.function.Consumer @@ -41,6 +43,14 @@ interface WebhookServiceAsync { */ fun parseUnsafe(body: String): ParsedWebhookEvent + /** + * Unwraps a webhook event from its JSON representation. + * + * @throws LithicInvalidDataException if the body could not be parsed. + * @throws LithicWebhookException if the webhook signature could not be verified + */ + fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent + /** * A view of [WebhookServiceAsync] that provides access to raw HTTP responses for each method. */ 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..8493fb3a 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 @@ -5,9 +5,9 @@ package com.lithic.api.services.async import com.fasterxml.jackson.core.JsonProcessingException import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue +import com.lithic.api.core.UnwrapWebhookParams 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 @@ -53,6 +53,9 @@ class WebhookServiceAsyncImpl internal constructor(private val clientOptions: Cl override fun parseUnsafe(body: String): ParsedWebhookEvent = WebhookServiceImpl(clientOptions).parseUnsafe(body) + override fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent = + WebhookServiceImpl(clientOptions).parsed(unwrapParams) + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : WebhookServiceAsync.WithRawResponse { diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt index 17e80d0d..8d93e620 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt @@ -4,8 +4,10 @@ package com.lithic.api.services.blocking import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue +import com.lithic.api.core.UnwrapWebhookParams import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicInvalidDataException +import com.lithic.api.errors.LithicWebhookException import com.lithic.api.models.ParsedWebhookEvent import java.util.function.Consumer @@ -41,6 +43,14 @@ interface WebhookService { */ fun parseUnsafe(body: String): ParsedWebhookEvent + /** + * Unwraps a webhook event from its JSON representation. + * + * @throws LithicInvalidDataException if the body could not be parsed. + * @throws LithicWebhookException if the webhook signature could not be verified + */ + fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent + /** A view of [WebhookService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { 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..3f5800ba 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,11 +6,16 @@ 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.UnwrapWebhookParams +import com.lithic.api.core.checkRequired 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 com.standardwebhooks.Webhook +import com.standardwebhooks.exceptions.WebhookVerificationException import java.security.MessageDigest import java.time.Duration import java.time.Instant @@ -124,6 +129,28 @@ class WebhookServiceImpl internal constructor(private val clientOptions: ClientO throw LithicInvalidDataException("Error parsing body", e) } + override fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent { + val headers = unwrapParams.headers().getOrNull() + if (headers != null) { + try { + val webhookSecret = + checkRequired( + "webhookSecret", + unwrapParams.secret().getOrNull() + ?: clientOptions.webhookSecret().getOrNull(), + ) + val headersMap = + headers.names().associateWith { name -> headers.values(name) }.toMap() + + val webhook = Webhook(webhookSecret) + webhook.verify(unwrapParams.body(), headersMap) + } catch (e: WebhookVerificationException) { + throw LithicWebhookException("Could not verify webhook event signature", e) + } + } + return parsed(unwrapParams.body()) + } + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : WebhookService.WithRawResponse { 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..078239a1 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/WebhookServiceAsyncTest.kt @@ -0,0 +1,98 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClientAsync +import com.lithic.api.core.UnwrapWebhookParams +import com.lithic.api.core.http.Headers +import com.lithic.api.errors.LithicWebhookException +import com.standardwebhooks.Webhook +import java.time.Instant +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class WebhookServiceAsyncTest { + + @Test + fun parsed() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val webhookServiceAsync = client.webhooks() + + val payload = + "{\"event_type\":\"account_holder.created\",\"token\":\"00000000-0000-0000-0000-000000000001\",\"account_token\":\"00000000-0000-0000-0000-000000000001\",\"created\":\"2019-12-27T18:11:19.117Z\",\"required_documents\":[{\"entity_token\":\"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e\",\"status_reasons\":[\"string\"],\"valid_documents\":[\"string\"]}],\"status\":\"ACCEPTED\",\"status_reason\":[\"string\"]}" + val webhookSecret = "whsec_c2VjcmV0Cg==" + val messageId = "1" + val timestampSeconds = Instant.now().epochSecond + val webhook = Webhook(webhookSecret) + val signature = webhook.sign(messageId, timestampSeconds, payload) + val headers = + Headers.builder() + .putAll( + mapOf( + "webhook-signature" to listOf(signature), + "webhook-id" to listOf(messageId), + "webhook-timestamp" to listOf(timestampSeconds.toString()), + ) + ) + .build() + + webhookServiceAsync.parsed(payload).validate() + + // Wrong key should throw + assertThrows { + val wrongKey = "whsec_aaaaaaaaaa" + webhookServiceAsync.parsed( + UnwrapWebhookParams.builder() + .body(payload) + .headers(headers) + .secret(wrongKey) + .build() + ) + } + + // Bad signature should throw + assertThrows { + val badSig = webhook.sign(messageId, timestampSeconds, "some other payload") + val badHeaders = + headers.toBuilder().replace("webhook-signature", listOf(badSig)).build() + webhookServiceAsync.parsed( + UnwrapWebhookParams.builder() + .body(payload) + .headers(badHeaders) + .secret(webhookSecret) + .build() + ) + } + + // Old timestamp should throw + assertThrows { + val oldHeaders = headers.toBuilder().replace("webhook-timestamp", listOf("5")).build() + webhookServiceAsync.parsed( + UnwrapWebhookParams.builder() + .body(payload) + .headers(oldHeaders) + .secret(webhookSecret) + .build() + ) + } + + // Wrong message ID should throw + assertThrows { + val wrongIdHeaders = headers.toBuilder().replace("webhook-id", listOf("wrong")).build() + webhookServiceAsync.parsed( + UnwrapWebhookParams.builder() + .body(payload) + .headers(wrongIdHeaders) + .secret(webhookSecret) + .build() + ) + } + } +} From 71b1a8bb689d8740ddf53c0b85745d240ea83981 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 20:58:01 +0000 Subject: [PATCH 09/26] chore(internal): upgrade AssertJ --- lithic-java-client-okhttp/build.gradle.kts | 2 +- lithic-java-core/build.gradle.kts | 2 +- lithic-java-proguard-test/build.gradle.kts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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-core/build.gradle.kts b/lithic-java-core/build.gradle.kts index 4c30bb62..dc2ea195 100644 --- a/lithic-java-core/build.gradle.kts +++ b/lithic-java-core/build.gradle.kts @@ -34,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-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") } From 6064b3a6c4481eeee5dd71091b9a8362134277f6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 06:06:07 +0000 Subject: [PATCH 10/26] feat(api): Add /v2/auth_rules/results endpoint for listing rule evaluation data --- .stats.yml | 8 +- .../api/models/AuthRuleV2ListResultsPage.kt | 135 + .../models/AuthRuleV2ListResultsPageAsync.kt | 151 + .../AuthRuleV2ListResultsPageResponse.kt | 233 ++ .../api/models/AuthRuleV2ListResultsParams.kt | 323 ++ .../models/Conditional3dsActionParameters.kt | 41 +- .../models/ConditionalAchActionParameters.kt | 6 +- ...onditionalAuthorizationActionParameters.kt | 44 +- ...ConditionalTokenizationActionParameters.kt | 6 +- .../api/models/V2ListResultsResponse.kt | 3473 +++++++++++++++++ .../async/authRules/V2ServiceAsync.kt | 56 + .../async/authRules/V2ServiceAsyncImpl.kt | 48 + .../services/blocking/authRules/V2Service.kt | 55 + .../blocking/authRules/V2ServiceImpl.kt | 44 + .../AuthRuleV2ListResultsPageResponseTest.kt | 89 + .../models/AuthRuleV2ListResultsParamsTest.kt | 58 + .../Conditional3dsActionParametersTest.kt | 6 +- ...tionalAuthorizationActionParametersTest.kt | 6 +- .../api/models/V2ListResultsResponseTest.kt | 79 + .../async/authRules/V2ServiceAsyncTest.kt | 15 + .../blocking/authRules/V2ServiceTest.kt | 14 + 21 files changed, 4838 insertions(+), 52 deletions(-) create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPage.kt create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageAsync.kt create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponse.kt create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParams.kt create mode 100644 lithic-java-core/src/main/kotlin/com/lithic/api/models/V2ListResultsResponse.kt create mode 100644 lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt create mode 100644 lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsParamsTest.kt create mode 100644 lithic-java-core/src/test/kotlin/com/lithic/api/models/V2ListResultsResponseTest.kt diff --git a/.stats.yml b/.stats.yml index 237cf435..dc20d41b 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-fbdac41d84b5679c659e324345bc4101b056b5f5ed4ddefcd6680afe20db41dc.yml -openapi_spec_hash: 37834cd63d604a528d0467c1cfb01919 -config_hash: 61652458521692cd0b88976827c42c25 +configured_endpoints: 177 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-32c9a538495a2c820a7ca28c4f09cc1226642b8f7c9422ce1889aebd15e225ca.yml +openapi_spec_hash: b6403689900263b73d4054a548f00285 +config_hash: 693dddc4721eef512d75ab6c60897794 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..d27dc602 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPage.kt @@ -0,0 +1,135 @@ +// 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()._token().getOptional("token")).build() + } else { + params.toBuilder().startingAfter(items().last()._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..ed123272 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageAsync.kt @@ -0,0 +1,151 @@ +// 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()._token().getOptional("token")).build() + } else { + params.toBuilder().startingAfter(items().last()._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..c91830e4 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponse.kt @@ -0,0 +1,233 @@ +// 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) + } + } + + /** + * 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..a52a889b --- /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_uuid` or `auth_rule_token`) must be provided + * - When filtering by `event_uuid`, pagination is not supported + */ +class AuthRuleV2ListResultsParams +private constructor( + private val authRuleToken: String?, + private val endingBefore: String?, + private val eventUuid: 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 UUID */ + fun eventUuid(): Optional = Optional.ofNullable(eventUuid) + + /** + * 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 eventUuid: 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 + eventUuid = authRuleV2ListResultsParams.eventUuid + 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 UUID */ + fun eventUuid(eventUuid: String?) = apply { this.eventUuid = eventUuid } + + /** Alias for calling [Builder.eventUuid] with `eventUuid.orElse(null)`. */ + fun eventUuid(eventUuid: Optional) = eventUuid(eventUuid.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, + eventUuid, + 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) } + eventUuid?.let { put("event_uuid", 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 && + eventUuid == other.eventUuid && + hasActions == other.hasActions && + pageSize == other.pageSize && + startingAfter == other.startingAfter && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + authRuleToken, + endingBefore, + eventUuid, + hasActions, + pageSize, + startingAfter, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "AuthRuleV2ListResultsParams{authRuleToken=$authRuleToken, endingBefore=$endingBefore, eventUuid=$eventUuid, hasActions=$hasActions, pageSize=$pageSize, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} 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..cde4605d 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,14 @@ 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 +42,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(): ThreeDSAction = action.getRequired("action") /** * @throws LithicInvalidDataException if the JSON field has an unexpected type or is @@ -55,7 +55,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 +96,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 +109,16 @@ private constructor( } /** The action to take if the conditions are met. */ - fun action(action: Action) = action(JsonField.of(action)) + fun action(action: ThreeDSAction) = 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 [ThreeDSAction] 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 +216,8 @@ 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 ThreeDSAction @JsonCreator private constructor(private val value: JsonField) : + Enum { /** * Returns this class instance's raw value. @@ -233,19 +235,19 @@ private constructor( @JvmField val CHALLENGE = of("CHALLENGE") - @JvmStatic fun of(value: String) = Action(JsonField.of(value)) + @JvmStatic fun of(value: String) = ThreeDSAction(JsonField.of(value)) } - /** An enum containing [Action]'s known values. */ + /** An enum containing [ThreeDSAction]'s known values. */ enum class Known { DECLINE, CHALLENGE, } /** - * An enum containing [Action]'s known values, as well as an [_UNKNOWN] member. + * An enum containing [ThreeDSAction]'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 [ThreeDSAction] 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 +256,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 [ThreeDSAction] was instantiated with an unknown + * value. + */ _UNKNOWN, } @@ -285,7 +290,7 @@ private constructor( when (this) { DECLINE -> Known.DECLINE CHALLENGE -> Known.CHALLENGE - else -> throw LithicInvalidDataException("Unknown Action: $value") + else -> throw LithicInvalidDataException("Unknown ThreeDSAction: $value") } /** @@ -302,7 +307,7 @@ private constructor( private var validated: Boolean = false - fun validate(): Action = apply { + fun validate(): ThreeDSAction = apply { if (validated) { return@apply } @@ -332,7 +337,7 @@ private constructor( return true } - return other is Action && value == other.value + return other is ThreeDSAction && 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 9fcd9469..33a8fc5d 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 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..b6d72b88 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/V2ListResultsResponse.kt @@ -0,0 +1,3473 @@ +// 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 */ +class V2ListResultsResponse +@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 [V2ListResultsResponse]. + * + * The following fields are required: + * ```java + * .token() + * .actions() + * .authRuleToken() + * .evaluationTime() + * .eventStream() + * .eventToken() + * .mode() + * .ruleVersion() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [V2ListResultsResponse]. */ + 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(v2ListResultsResponse: V2ListResultsResponse) = apply { + token = v2ListResultsResponse.token + actions = v2ListResultsResponse.actions.map { it.toMutableList() } + authRuleToken = v2ListResultsResponse.authRuleToken + evaluationTime = v2ListResultsResponse.evaluationTime + eventStream = v2ListResultsResponse.eventStream + eventToken = v2ListResultsResponse.eventToken + mode = v2ListResultsResponse.mode + ruleVersion = v2ListResultsResponse.ruleVersion + additionalProperties = v2ListResultsResponse.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.ofAuthorization(authorization)`. */ + fun addAction(authorization: Action.AuthorizationAction) = + addAction(Action.ofAuthorization(authorization)) + + /** Alias for calling [addAction] with `Action.ofThreeDS(threeDS)`. */ + fun addAction(threeDS: Action.ThreeDSAction) = addAction(Action.ofThreeDS(threeDS)) + + /** 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)) + + /** 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 [V2ListResultsResponse]. + * + * 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(): V2ListResultsResponse = + V2ListResultsResponse( + 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(): V2ListResultsResponse = 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 authorization: AuthorizationAction? = null, + private val threeDS: ThreeDSAction? = null, + private val decline: DeclineAction? = null, + private val requireTfa: RequireTfaAction? = null, + private val approve: ApproveAction? = null, + private val returnAction: ReturnAction? = null, + private val _json: JsonValue? = null, + ) { + + fun authorization(): Optional = Optional.ofNullable(authorization) + + fun threeDS(): Optional = Optional.ofNullable(threeDS) + + fun decline(): Optional = Optional.ofNullable(decline) + + fun requireTfa(): Optional = Optional.ofNullable(requireTfa) + + fun approve(): Optional = Optional.ofNullable(approve) + + fun returnAction(): Optional = Optional.ofNullable(returnAction) + + fun isAuthorization(): Boolean = authorization != null + + fun isThreeDS(): Boolean = threeDS != null + + fun isDecline(): Boolean = decline != null + + fun isRequireTfa(): Boolean = requireTfa != null + + fun isApprove(): Boolean = approve != null + + fun isReturnAction(): Boolean = returnAction != null + + fun asAuthorization(): AuthorizationAction = authorization.getOrThrow("authorization") + + fun asThreeDS(): ThreeDSAction = threeDS.getOrThrow("threeDS") + + fun asDecline(): DeclineAction = decline.getOrThrow("decline") + + fun asRequireTfa(): RequireTfaAction = requireTfa.getOrThrow("requireTfa") + + fun asApprove(): ApproveAction = approve.getOrThrow("approve") + + fun asReturnAction(): ReturnAction = returnAction.getOrThrow("returnAction") + + fun _json(): Optional = Optional.ofNullable(_json) + + fun accept(visitor: Visitor): T = + when { + authorization != null -> visitor.visitAuthorization(authorization) + threeDS != null -> visitor.visitThreeDS(threeDS) + decline != null -> visitor.visitDecline(decline) + requireTfa != null -> visitor.visitRequireTfa(requireTfa) + 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 visitAuthorization(authorization: AuthorizationAction) { + authorization.validate() + } + + override fun visitThreeDS(threeDS: ThreeDSAction) { + threeDS.validate() + } + + override fun visitDecline(decline: DeclineAction) { + decline.validate() + } + + override fun visitRequireTfa(requireTfa: RequireTfaAction) { + requireTfa.validate() + } + + 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 visitAuthorization(authorization: AuthorizationAction) = + authorization.validity() + + override fun visitThreeDS(threeDS: ThreeDSAction) = threeDS.validity() + + override fun visitDecline(decline: DeclineAction) = decline.validity() + + override fun visitRequireTfa(requireTfa: RequireTfaAction) = + requireTfa.validity() + + 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 && + authorization == other.authorization && + threeDS == other.threeDS && + decline == other.decline && + requireTfa == other.requireTfa && + approve == other.approve && + returnAction == other.returnAction + } + + override fun hashCode(): Int = + Objects.hash(authorization, threeDS, decline, requireTfa, approve, returnAction) + + override fun toString(): String = + when { + authorization != null -> "Action{authorization=$authorization}" + threeDS != null -> "Action{threeDS=$threeDS}" + decline != null -> "Action{decline=$decline}" + requireTfa != null -> "Action{requireTfa=$requireTfa}" + approve != null -> "Action{approve=$approve}" + returnAction != null -> "Action{returnAction=$returnAction}" + _json != null -> "Action{_unknown=$_json}" + else -> throw IllegalStateException("Invalid Action") + } + + companion object { + + @JvmStatic + fun ofAuthorization(authorization: AuthorizationAction) = + Action(authorization = authorization) + + @JvmStatic fun ofThreeDS(threeDS: ThreeDSAction) = Action(threeDS = threeDS) + + @JvmStatic fun ofDecline(decline: DeclineAction) = Action(decline = decline) + + @JvmStatic + fun ofRequireTfa(requireTfa: RequireTfaAction) = Action(requireTfa = requireTfa) + + @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 visitAuthorization(authorization: AuthorizationAction): T + + fun visitThreeDS(threeDS: ThreeDSAction): T + + fun visitDecline(decline: DeclineAction): T + + fun visitRequireTfa(requireTfa: RequireTfaAction): T + + 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(authorization = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Action(threeDS = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Action(decline = it, _json = json) + }, + tryDeserialize(node, jacksonTypeRef())?.let { + Action(requireTfa = it, _json = json) + }, + 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.authorization != null -> generator.writeObject(value.authorization) + value.threeDS != null -> generator.writeObject(value.threeDS) + value.decline != null -> generator.writeObject(value.decline) + value.requireTfa != null -> generator.writeObject(value.requireTfa) + 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 AuthorizationAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val explanation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of() + ) : this(explanation, mutableMapOf()) + + /** + * 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 [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 [AuthorizationAction]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AuthorizationAction]. */ + class Builder internal constructor() { + + private var explanation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(authorizationAction: AuthorizationAction) = apply { + explanation = authorizationAction.explanation + additionalProperties = authorizationAction.additionalProperties.toMutableMap() + } + + /** 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 [AuthorizationAction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): AuthorizationAction = + AuthorizationAction(explanation, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): AuthorizationAction = apply { + if (validated) { + return@apply + } + + 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 = (if (explanation.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AuthorizationAction && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(explanation, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AuthorizationAction{explanation=$explanation, additionalProperties=$additionalProperties}" + } + + class ThreeDSAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val explanation: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("explanation") + @ExcludeMissing + explanation: JsonField = JsonMissing.of() + ) : this(explanation, mutableMapOf()) + + /** + * 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 [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 [ThreeDSAction]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [ThreeDSAction]. */ + class Builder internal constructor() { + + private var explanation: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(threeDSAction: ThreeDSAction) = apply { + explanation = threeDSAction.explanation + additionalProperties = threeDSAction.additionalProperties.toMutableMap() + } + + /** 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 [ThreeDSAction]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): ThreeDSAction = + ThreeDSAction(explanation, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): ThreeDSAction = apply { + if (validated) { + return@apply + } + + 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 = (if (explanation.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ThreeDSAction && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(explanation, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ThreeDSAction{explanation=$explanation, additionalProperties=$additionalProperties}" + } + + class DeclineAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val reason: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), + ) : this(type, 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") + + /** + * 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 [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 reason: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(declineAction: DeclineAction) = apply { + type = declineAction.type + 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 } + + /** 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), + reason, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): DeclineAction = apply { + if (validated) { + return@apply + } + + type().validate() + 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) + + (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 && + reason == other.reason && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, reason, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "DeclineAction{type=$type, reason=$reason, additionalProperties=$additionalProperties}" + } + + class RequireTfaAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val reason: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), + ) : this(type, 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") + + /** + * 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 [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 reason: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(requireTfaAction: RequireTfaAction) = apply { + type = requireTfaAction.type + 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 } + + /** 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), + reason, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): RequireTfaAction = apply { + if (validated) { + return@apply + } + + type().validate() + 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) + + (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 && + reason == other.reason && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, reason, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "RequireTfaAction{type=$type, reason=$reason, additionalProperties=$additionalProperties}" + } + + class ApproveAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of() + ) : this(type, 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") + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [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 additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(approveAction: ApproveAction) = apply { + type = approveAction.type + 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 } + + 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), additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): ApproveAction = apply { + if (validated) { + return@apply + } + + type().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) + + /** 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 && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ApproveAction{type=$type, additionalProperties=$additionalProperties}" + } + + class ReturnAction + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val code: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this(code, type, 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") + + /** + * 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 + + @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 additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(returnAction: ReturnAction) = apply { + code = returnAction.code + type = returnAction.type + 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 } + + 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), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): ReturnAction = apply { + if (validated) { + return@apply + } + + code().validate() + type().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 = + (code.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 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 && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(code, type, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "ReturnAction{code=$code, type=$type, additionalProperties=$additionalProperties}" + } + } + + /** 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 V2ListResultsResponse && + 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() = + "V2ListResultsResponse{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/authRules/V2ServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsync.kt index 0998d0b6..03573361 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 @@ -198,6 +200,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_uuid` or `auth_rule_token`) must be provided + * - When filtering by `event_uuid`, 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. @@ -515,6 +546,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/authRules/V2Service.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/authRules/V2Service.kt index d7bbf237..a1fa9816 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 @@ -184,6 +186,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_uuid` or `auth_rule_token`) must be provided + * - When filtering by `event_uuid`, 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. @@ -508,6 +535,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/models/AuthRuleV2ListResultsPageResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt new file mode 100644 index 00000000..a0a6264f --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt @@ -0,0 +1,89 @@ +// 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.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Action.AuthorizationAction.builder() + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(EventStream.AUTHORIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + .hasMore(true) + .build() + + assertThat(authRuleV2ListResultsPageResponse.data()) + .containsExactly( + V2ListResultsResponse.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Action.AuthorizationAction.builder() + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(EventStream.AUTHORIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + ) + assertThat(authRuleV2ListResultsPageResponse.hasMore()).isEqualTo(true) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val authRuleV2ListResultsPageResponse = + AuthRuleV2ListResultsPageResponse.builder() + .addData( + V2ListResultsResponse.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Action.AuthorizationAction.builder() + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(EventStream.AUTHORIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.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..31cfec17 --- /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") + .eventUuid("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") + .eventUuid("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_uuid", "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/Conditional3dsActionParametersTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/Conditional3dsActionParametersTest.kt index 0788cb82..af9d5436 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.ThreeDSAction.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.ThreeDSAction.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.ThreeDSAction.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/V2ListResultsResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/V2ListResultsResponseTest.kt new file mode 100644 index 00000000..4c43d13a --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/V2ListResultsResponseTest.kt @@ -0,0 +1,79 @@ +// 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 V2ListResultsResponseTest { + + @Test + fun create() { + val v2ListResultsResponse = + V2ListResultsResponse.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Action.AuthorizationAction.builder() + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(EventStream.AUTHORIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + + assertThat(v2ListResultsResponse.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(v2ListResultsResponse.actions()) + .containsExactly( + V2ListResultsResponse.Action.ofAuthorization( + V2ListResultsResponse.Action.AuthorizationAction.builder() + .explanation("explanation") + .build() + ) + ) + assertThat(v2ListResultsResponse.authRuleToken()) + .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(v2ListResultsResponse.evaluationTime()) + .isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(v2ListResultsResponse.eventStream()).isEqualTo(EventStream.AUTHORIZATION) + assertThat(v2ListResultsResponse.eventToken()) + .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(v2ListResultsResponse.mode()) + .isEqualTo(V2ListResultsResponse.AuthRuleState.ACTIVE) + assertThat(v2ListResultsResponse.ruleVersion()).isEqualTo(0L) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val v2ListResultsResponse = + V2ListResultsResponse.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addAction( + V2ListResultsResponse.Action.AuthorizationAction.builder() + .explanation("explanation") + .build() + ) + .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .eventStream(EventStream.AUTHORIZATION) + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .ruleVersion(0L) + .build() + + val roundtrippedV2ListResultsResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(v2ListResultsResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedV2ListResultsResponse).isEqualTo(v2ListResultsResponse) + } +} 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..84c9a0d4 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 @@ -166,6 +166,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/authRules/V2ServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceTest.kt index 7ec49bf4..4bc38503 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 @@ -159,6 +159,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 = From 74dcc48075f54e964f4c8179a6121c53e6a28283 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 08:05:21 +0000 Subject: [PATCH 11/26] fix(api): Update /v2/auth_rules/results endpoint parameter naming and action types --- .stats.yml | 4 +- .../api/models/AuthRuleV2ListResultsParams.kt | 32 ++++---- .../models/Conditional3dsActionParameters.kt | 49 ++++++----- .../api/models/V2ListResultsResponse.kt | 81 ++++++++++++------- .../async/authRules/V2ServiceAsync.kt | 4 +- .../services/blocking/authRules/V2Service.kt | 4 +- .../models/AuthRuleV2ListResultsParamsTest.kt | 6 +- .../Conditional3dsActionParametersTest.kt | 6 +- 8 files changed, 107 insertions(+), 79 deletions(-) diff --git a/.stats.yml b/.stats.yml index dc20d41b..811d5e92 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-32c9a538495a2c820a7ca28c4f09cc1226642b8f7c9422ce1889aebd15e225ca.yml -openapi_spec_hash: b6403689900263b73d4054a548f00285 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fe39002b6b38eb33ba43532f28e317bdd4dbb5b0efd46fa098178cb6a544d585.yml +openapi_spec_hash: 8ee7b837e77df089ca3359b5502c7525 config_hash: 693dddc4721eef512d75ab6c60897794 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 index a52a889b..99101e4b 100644 --- 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 @@ -14,14 +14,14 @@ import kotlin.jvm.optionals.getOrNull * * **Limitations:** * - Results are available for the past 3 months only - * - At least one filter (`event_uuid` or `auth_rule_token`) must be provided - * - When filtering by `event_uuid`, pagination is not supported + * - 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 eventUuid: String?, + private val eventToken: String?, private val hasActions: Boolean?, private val pageSize: Long?, private val startingAfter: String?, @@ -38,8 +38,8 @@ private constructor( */ fun endingBefore(): Optional = Optional.ofNullable(endingBefore) - /** Filter by event UUID */ - fun eventUuid(): Optional = Optional.ofNullable(eventUuid) + /** Filter by event token */ + fun eventToken(): Optional = Optional.ofNullable(eventToken) /** * Filter by whether the rule evaluation produced any actions. When not provided, all results @@ -79,7 +79,7 @@ private constructor( private var authRuleToken: String? = null private var endingBefore: String? = null - private var eventUuid: String? = null + private var eventToken: String? = null private var hasActions: Boolean? = null private var pageSize: Long? = null private var startingAfter: String? = null @@ -90,7 +90,7 @@ private constructor( internal fun from(authRuleV2ListResultsParams: AuthRuleV2ListResultsParams) = apply { authRuleToken = authRuleV2ListResultsParams.authRuleToken endingBefore = authRuleV2ListResultsParams.endingBefore - eventUuid = authRuleV2ListResultsParams.eventUuid + eventToken = authRuleV2ListResultsParams.eventToken hasActions = authRuleV2ListResultsParams.hasActions pageSize = authRuleV2ListResultsParams.pageSize startingAfter = authRuleV2ListResultsParams.startingAfter @@ -114,11 +114,11 @@ private constructor( /** Alias for calling [Builder.endingBefore] with `endingBefore.orElse(null)`. */ fun endingBefore(endingBefore: Optional) = endingBefore(endingBefore.getOrNull()) - /** Filter by event UUID */ - fun eventUuid(eventUuid: String?) = apply { this.eventUuid = eventUuid } + /** Filter by event token */ + fun eventToken(eventToken: String?) = apply { this.eventToken = eventToken } - /** Alias for calling [Builder.eventUuid] with `eventUuid.orElse(null)`. */ - fun eventUuid(eventUuid: Optional) = eventUuid(eventUuid.getOrNull()) + /** 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 @@ -266,7 +266,7 @@ private constructor( AuthRuleV2ListResultsParams( authRuleToken, endingBefore, - eventUuid, + eventToken, hasActions, pageSize, startingAfter, @@ -282,7 +282,7 @@ private constructor( .apply { authRuleToken?.let { put("auth_rule_token", it) } endingBefore?.let { put("ending_before", it) } - eventUuid?.let { put("event_uuid", 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) } @@ -298,7 +298,7 @@ private constructor( return other is AuthRuleV2ListResultsParams && authRuleToken == other.authRuleToken && endingBefore == other.endingBefore && - eventUuid == other.eventUuid && + eventToken == other.eventToken && hasActions == other.hasActions && pageSize == other.pageSize && startingAfter == other.startingAfter && @@ -310,7 +310,7 @@ private constructor( Objects.hash( authRuleToken, endingBefore, - eventUuid, + eventToken, hasActions, pageSize, startingAfter, @@ -319,5 +319,5 @@ private constructor( ) override fun toString() = - "AuthRuleV2ListResultsParams{authRuleToken=$authRuleToken, endingBefore=$endingBefore, eventUuid=$eventUuid, hasActions=$hasActions, pageSize=$pageSize, startingAfter=$startingAfter, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" + "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/Conditional3dsActionParameters.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Conditional3dsActionParameters.kt index cde4605d..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(): ThreeDSAction = 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,16 +113,16 @@ private constructor( } /** The action to take if the conditions are met. */ - fun action(action: ThreeDSAction) = 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 [ThreeDSAction] 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)) @@ -216,8 +220,9 @@ private constructor( (conditions.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) /** The action to take if the conditions are met. */ - class ThreeDSAction @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. @@ -235,19 +240,21 @@ private constructor( @JvmField val CHALLENGE = of("CHALLENGE") - @JvmStatic fun of(value: String) = ThreeDSAction(JsonField.of(value)) + @JvmStatic fun of(value: String) = Authentication3dsAction(JsonField.of(value)) } - /** An enum containing [ThreeDSAction]'s known values. */ + /** An enum containing [Authentication3dsAction]'s known values. */ enum class Known { DECLINE, CHALLENGE, } /** - * An enum containing [ThreeDSAction]'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 [ThreeDSAction] 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. @@ -257,8 +264,8 @@ private constructor( DECLINE, CHALLENGE, /** - * An enum member indicating that [ThreeDSAction] was instantiated with an unknown - * value. + * An enum member indicating that [Authentication3dsAction] was instantiated with an + * unknown value. */ _UNKNOWN, } @@ -290,7 +297,7 @@ private constructor( when (this) { DECLINE -> Known.DECLINE CHALLENGE -> Known.CHALLENGE - else -> throw LithicInvalidDataException("Unknown ThreeDSAction: $value") + else -> throw LithicInvalidDataException("Unknown Authentication3dsAction: $value") } /** @@ -307,7 +314,7 @@ private constructor( private var validated: Boolean = false - fun validate(): ThreeDSAction = apply { + fun validate(): Authentication3dsAction = apply { if (validated) { return@apply } @@ -337,7 +344,7 @@ private constructor( return true } - return other is ThreeDSAction && 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/V2ListResultsResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/V2ListResultsResponse.kt index b6d72b88..d1648ad6 100644 --- 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 @@ -306,8 +306,9 @@ private constructor( fun addAction(authorization: Action.AuthorizationAction) = addAction(Action.ofAuthorization(authorization)) - /** Alias for calling [addAction] with `Action.ofThreeDS(threeDS)`. */ - fun addAction(threeDS: Action.ThreeDSAction) = addAction(Action.ofThreeDS(threeDS)) + /** Alias for calling [addAction] with `Action.ofAuthentication3ds(authentication3ds)`. */ + fun addAction(authentication3ds: Action.Authentication3dsAction) = + addAction(Action.ofAuthentication3ds(authentication3ds)) /** Alias for calling [addAction] with `Action.ofDecline(decline)`. */ fun addAction(decline: Action.DeclineAction) = addAction(Action.ofDecline(decline)) @@ -501,7 +502,7 @@ private constructor( class Action private constructor( private val authorization: AuthorizationAction? = null, - private val threeDS: ThreeDSAction? = null, + private val authentication3ds: Authentication3dsAction? = null, private val decline: DeclineAction? = null, private val requireTfa: RequireTfaAction? = null, private val approve: ApproveAction? = null, @@ -511,7 +512,8 @@ private constructor( fun authorization(): Optional = Optional.ofNullable(authorization) - fun threeDS(): Optional = Optional.ofNullable(threeDS) + fun authentication3ds(): Optional = + Optional.ofNullable(authentication3ds) fun decline(): Optional = Optional.ofNullable(decline) @@ -523,7 +525,7 @@ private constructor( fun isAuthorization(): Boolean = authorization != null - fun isThreeDS(): Boolean = threeDS != null + fun isAuthentication3ds(): Boolean = authentication3ds != null fun isDecline(): Boolean = decline != null @@ -535,7 +537,8 @@ private constructor( fun asAuthorization(): AuthorizationAction = authorization.getOrThrow("authorization") - fun asThreeDS(): ThreeDSAction = threeDS.getOrThrow("threeDS") + fun asAuthentication3ds(): Authentication3dsAction = + authentication3ds.getOrThrow("authentication3ds") fun asDecline(): DeclineAction = decline.getOrThrow("decline") @@ -550,7 +553,7 @@ private constructor( fun accept(visitor: Visitor): T = when { authorization != null -> visitor.visitAuthorization(authorization) - threeDS != null -> visitor.visitThreeDS(threeDS) + authentication3ds != null -> visitor.visitAuthentication3ds(authentication3ds) decline != null -> visitor.visitDecline(decline) requireTfa != null -> visitor.visitRequireTfa(requireTfa) approve != null -> visitor.visitApprove(approve) @@ -571,8 +574,10 @@ private constructor( authorization.validate() } - override fun visitThreeDS(threeDS: ThreeDSAction) { - threeDS.validate() + override fun visitAuthentication3ds( + authentication3ds: Authentication3dsAction + ) { + authentication3ds.validate() } override fun visitDecline(decline: DeclineAction) { @@ -616,7 +621,9 @@ private constructor( override fun visitAuthorization(authorization: AuthorizationAction) = authorization.validity() - override fun visitThreeDS(threeDS: ThreeDSAction) = threeDS.validity() + override fun visitAuthentication3ds( + authentication3ds: Authentication3dsAction + ) = authentication3ds.validity() override fun visitDecline(decline: DeclineAction) = decline.validity() @@ -639,7 +646,7 @@ private constructor( return other is Action && authorization == other.authorization && - threeDS == other.threeDS && + authentication3ds == other.authentication3ds && decline == other.decline && requireTfa == other.requireTfa && approve == other.approve && @@ -647,12 +654,19 @@ private constructor( } override fun hashCode(): Int = - Objects.hash(authorization, threeDS, decline, requireTfa, approve, returnAction) + Objects.hash( + authorization, + authentication3ds, + decline, + requireTfa, + approve, + returnAction, + ) override fun toString(): String = when { authorization != null -> "Action{authorization=$authorization}" - threeDS != null -> "Action{threeDS=$threeDS}" + authentication3ds != null -> "Action{authentication3ds=$authentication3ds}" decline != null -> "Action{decline=$decline}" requireTfa != null -> "Action{requireTfa=$requireTfa}" approve != null -> "Action{approve=$approve}" @@ -667,7 +681,9 @@ private constructor( fun ofAuthorization(authorization: AuthorizationAction) = Action(authorization = authorization) - @JvmStatic fun ofThreeDS(threeDS: ThreeDSAction) = Action(threeDS = threeDS) + @JvmStatic + fun ofAuthentication3ds(authentication3ds: Authentication3dsAction) = + Action(authentication3ds = authentication3ds) @JvmStatic fun ofDecline(decline: DeclineAction) = Action(decline = decline) @@ -685,7 +701,7 @@ private constructor( fun visitAuthorization(authorization: AuthorizationAction): T - fun visitThreeDS(threeDS: ThreeDSAction): T + fun visitAuthentication3ds(authentication3ds: Authentication3dsAction): T fun visitDecline(decline: DeclineAction): T @@ -720,8 +736,8 @@ private constructor( tryDeserialize(node, jacksonTypeRef())?.let { Action(authorization = it, _json = json) }, - tryDeserialize(node, jacksonTypeRef())?.let { - Action(threeDS = it, _json = json) + tryDeserialize(node, jacksonTypeRef())?.let { + Action(authentication3ds = it, _json = json) }, tryDeserialize(node, jacksonTypeRef())?.let { Action(decline = it, _json = json) @@ -761,7 +777,8 @@ private constructor( ) { when { value.authorization != null -> generator.writeObject(value.authorization) - value.threeDS != null -> generator.writeObject(value.threeDS) + value.authentication3ds != null -> + generator.writeObject(value.authentication3ds) value.decline != null -> generator.writeObject(value.decline) value.requireTfa != null -> generator.writeObject(value.requireTfa) value.approve != null -> generator.writeObject(value.approve) @@ -927,7 +944,7 @@ private constructor( "AuthorizationAction{explanation=$explanation, additionalProperties=$additionalProperties}" } - class ThreeDSAction + class Authentication3dsAction @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val explanation: JsonField, @@ -973,20 +990,24 @@ private constructor( companion object { - /** Returns a mutable builder for constructing an instance of [ThreeDSAction]. */ + /** + * Returns a mutable builder for constructing an instance of + * [Authentication3dsAction]. + */ @JvmStatic fun builder() = Builder() } - /** A builder for [ThreeDSAction]. */ + /** A builder for [Authentication3dsAction]. */ class Builder internal constructor() { private var explanation: JsonField = JsonMissing.of() private var additionalProperties: MutableMap = mutableMapOf() @JvmSynthetic - internal fun from(threeDSAction: ThreeDSAction) = apply { - explanation = threeDSAction.explanation - additionalProperties = threeDSAction.additionalProperties.toMutableMap() + internal fun from(authentication3dsAction: Authentication3dsAction) = apply { + explanation = authentication3dsAction.explanation + additionalProperties = + authentication3dsAction.additionalProperties.toMutableMap() } /** Optional explanation for why this action was taken */ @@ -1026,17 +1047,17 @@ private constructor( } /** - * Returns an immutable instance of [ThreeDSAction]. + * Returns an immutable instance of [Authentication3dsAction]. * * Further updates to this [Builder] will not mutate the returned instance. */ - fun build(): ThreeDSAction = - ThreeDSAction(explanation, additionalProperties.toMutableMap()) + fun build(): Authentication3dsAction = + Authentication3dsAction(explanation, additionalProperties.toMutableMap()) } private var validated: Boolean = false - fun validate(): ThreeDSAction = apply { + fun validate(): Authentication3dsAction = apply { if (validated) { return@apply } @@ -1067,7 +1088,7 @@ private constructor( return true } - return other is ThreeDSAction && + return other is Authentication3dsAction && explanation == other.explanation && additionalProperties == other.additionalProperties } @@ -1077,7 +1098,7 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "ThreeDSAction{explanation=$explanation, additionalProperties=$additionalProperties}" + "Authentication3dsAction{explanation=$explanation, additionalProperties=$additionalProperties}" } class DeclineAction 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 03573361..07174ba4 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 @@ -205,8 +205,8 @@ interface V2ServiceAsync { * * **Limitations:** * - Results are available for the past 3 months only - * - At least one filter (`event_uuid` or `auth_rule_token`) must be provided - * - When filtering by `event_uuid`, pagination is not supported + * - 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()) 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 a1fa9816..b8ae5450 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 @@ -191,8 +191,8 @@ interface V2Service { * * **Limitations:** * - Results are available for the past 3 months only - * - At least one filter (`event_uuid` or `auth_rule_token`) must be provided - * - When filtering by `event_uuid`, pagination is not supported + * - 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()) 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 index 31cfec17..0a1326fa 100644 --- 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 @@ -13,7 +13,7 @@ internal class AuthRuleV2ListResultsParamsTest { AuthRuleV2ListResultsParams.builder() .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .eventUuid("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .hasActions(true) .pageSize(1L) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -26,7 +26,7 @@ internal class AuthRuleV2ListResultsParamsTest { AuthRuleV2ListResultsParams.builder() .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .endingBefore("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .eventUuid("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .hasActions(true) .pageSize(1L) .startingAfter("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") @@ -39,7 +39,7 @@ internal class AuthRuleV2ListResultsParamsTest { QueryParams.builder() .put("auth_rule_token", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .put("ending_before", "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .put("event_uuid", "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") 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 af9d5436..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.ThreeDSAction.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.ThreeDSAction.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.ThreeDSAction.DECLINE) + .action(Conditional3dsActionParameters.Authentication3dsAction.DECLINE) .addCondition( Conditional3dsActionParameters.Condition.builder() .attribute(Conditional3dsActionParameters.Condition.Attribute.MCC) From bce1e00834c884f5b930821c7a7949fad1f38f56 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 02:54:17 +0000 Subject: [PATCH 12/26] fix(client): mark request body as required --- .../models/ExternalBankAccountCreateParams.kt | 27 ++++++---- .../async/ExternalBankAccountServiceAsync.kt | 36 +++---------- .../ExternalBankAccountServiceAsyncImpl.kt | 2 +- .../blocking/ExternalBankAccountService.kt | 34 +++---------- .../ExternalBankAccountServiceImpl.kt | 2 +- .../ExternalBankAccountCreateParamsTest.kt | 51 +++++++++++++++++-- 6 files changed, 81 insertions(+), 71 deletions(-) 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/services/async/ExternalBankAccountServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/ExternalBankAccountServiceAsync.kt index ad0625da..fdd12ea8 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,15 @@ interface ExternalBankAccountServiceAsync { fun microDeposits(): MicroDepositServiceAsync /** Creates an external bank account within a program or Lithic account. */ - fun create(): CompletableFuture = - create(ExternalBankAccountCreateParams.none()) - - /** @see create */ - fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture - - /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() + params: ExternalBankAccountCreateParams ): CompletableFuture = create(params, RequestOptions.none()) /** @see create */ fun create( - requestOptions: RequestOptions - ): CompletableFuture = - create(ExternalBankAccountCreateParams.none(), requestOptions) + params: ExternalBankAccountCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture /** Get the external bank account by token. */ fun retrieve( @@ -320,26 +310,16 @@ 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()) - - /** @see create */ - fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): CompletableFuture> - - /** @see create */ fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() + params: ExternalBankAccountCreateParams ): CompletableFuture> = create(params, RequestOptions.none()) /** @see create */ fun create( - requestOptions: RequestOptions - ): CompletableFuture> = - create(ExternalBankAccountCreateParams.none(), requestOptions) + params: ExternalBankAccountCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> /** * 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/blocking/ExternalBankAccountService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/ExternalBankAccountService.kt index b7ea69e4..edb88351 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,23 +39,15 @@ 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()) - - /** @see create */ - fun create(requestOptions: RequestOptions): ExternalBankAccountCreateResponse = - create(ExternalBankAccountCreateParams.none(), requestOptions) - /** Get the external bank account by token. */ fun retrieve(externalBankAccountToken: String): ExternalBankAccountRetrieveResponse = retrieve(externalBankAccountToken, ExternalBankAccountRetrieveParams.none()) @@ -307,29 +299,17 @@ interface ExternalBankAccountService { * same as [ExternalBankAccountService.create]. */ @MustBeClosed - fun create(): HttpResponseFor = - create(ExternalBankAccountCreateParams.none()) - - /** @see create */ - @MustBeClosed fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none(), - requestOptions: RequestOptions = RequestOptions.none(), - ): HttpResponseFor - - /** @see create */ - @MustBeClosed - fun create( - params: ExternalBankAccountCreateParams = ExternalBankAccountCreateParams.none() + params: ExternalBankAccountCreateParams ): HttpResponseFor = create(params, RequestOptions.none()) /** @see create */ @MustBeClosed fun create( - requestOptions: RequestOptions - ): HttpResponseFor = - create(ExternalBankAccountCreateParams.none(), requestOptions) + params: ExternalBankAccountCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor /** * 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/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() + ) + ) } } From 61d743af0994d360aab6b9700c620809e0372bf3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 08:12:06 +0000 Subject: [PATCH 13/26] feat(api): Add result schemas for Authorization and Authentication (3DS) actions --- .stats.yml | 4 +- .../api/models/AuthRuleV2ListResultsPage.kt | 62 +- .../models/AuthRuleV2ListResultsPageAsync.kt | 62 +- .../AuthRuleV2ListResultsPageResponse.kt | 25 + .../api/models/V2ListResultsResponse.kt | 8372 ++++++++++++----- .../AuthRuleV2ListResultsPageResponseTest.kt | 67 +- .../api/models/V2ListResultsResponseTest.kt | 278 +- 7 files changed, 6264 insertions(+), 2606 deletions(-) diff --git a/.stats.yml b/.stats.yml index 811d5e92..d1ffb6fa 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-fe39002b6b38eb33ba43532f28e317bdd4dbb5b0efd46fa098178cb6a544d585.yml -openapi_spec_hash: 8ee7b837e77df089ca3359b5502c7525 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-a4803fcc96eac3196b6763e16264cc1b3292394102f3645a986a575c57d0a290.yml +openapi_spec_hash: 8a62dfde46b1749196575f2879f54d77 config_hash: 693dddc4721eef512d75ab6c60897794 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 index d27dc602..80a97926 100644 --- 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 @@ -39,9 +39,67 @@ private constructor( fun nextPageParams(): AuthRuleV2ListResultsParams = if (params.endingBefore().isPresent) { - params.toBuilder().endingBefore(items().first()._token().getOptional("token")).build() + 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()._token().getOptional("token")).build() + 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()) 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 index ed123272..bf7822cf 100644 --- 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 @@ -42,9 +42,67 @@ private constructor( fun nextPageParams(): AuthRuleV2ListResultsParams = if (params.endingBefore().isPresent) { - params.toBuilder().endingBefore(items().first()._token().getOptional("token")).build() + 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()._token().getOptional("token")).build() + 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 = 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 index c91830e4..4276fd48 100644 --- 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 @@ -130,6 +130,31 @@ private constructor( } } + /** + * 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. */ 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 index d1648ad6..b6f7b2a6 100644 --- 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 @@ -33,570 +33,676 @@ 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 -@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, + 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, ) { - @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(), - ) + fun authorizationResult(): Optional = + Optional.ofNullable(authorizationResult) - /** - * 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") + fun authentication3dsResult(): Optional = + Optional.ofNullable(authentication3dsResult) - /** - * 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") + fun tokenizationResult(): Optional = Optional.ofNullable(tokenizationResult) - /** - * 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") + fun achResult(): Optional = Optional.ofNullable(achResult) - /** - * 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") + fun isAuthorizationResult(): Boolean = authorizationResult != null - /** - * 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") + fun isAuthentication3dsResult(): Boolean = authentication3dsResult != null - /** - * 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") + fun isTokenizationResult(): Boolean = tokenizationResult != null - /** - * 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") + fun isAchResult(): Boolean = achResult != null - /** - * 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") + fun asAuthorizationResult(): AuthorizationResult = + authorizationResult.getOrThrow("authorizationResult") - /** - * 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 + fun asAuthentication3dsResult(): Authentication3dsResult = + authentication3dsResult.getOrThrow("authentication3dsResult") - /** - * 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 + fun asTokenizationResult(): TokenizationResult = + tokenizationResult.getOrThrow("tokenizationResult") - /** - * 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 + fun asAchResult(): AchResult = achResult.getOrThrow("achResult") - /** - * 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 + fun _json(): Optional = Optional.ofNullable(_json) - /** - * 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 + 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) + } - /** - * 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 + 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 the raw JSON value of [mode]. + * Returns a score indicating how many valid values are contained in this object recursively. * - * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. + * Used for best match union deserialization. */ - @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode + @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) + } /** - * Returns the raw JSON value of [ruleVersion]. - * - * Unlike [ruleVersion], this method doesn't throw if the JSON field has an unexpected type. + * An interface that defines how to map each variant of [V2ListResultsResponse] to a value of + * type [T]. */ - @JsonProperty("rule_version") @ExcludeMissing fun _ruleVersion(): JsonField = ruleVersion + interface Visitor { - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + fun visitAuthorizationResult(authorizationResult: AuthorizationResult): T - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + fun visitAuthentication3dsResult(authentication3dsResult: Authentication3dsResult): T - fun toBuilder() = Builder().from(this) + fun visitTokenizationResult(tokenizationResult: TokenizationResult): T - companion object { + fun visitAchResult(achResult: AchResult): T /** - * Returns a mutable builder for constructing an instance of [V2ListResultsResponse]. + * 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. * - * The following fields are required: - * ```java - * .token() - * .actions() - * .authRuleToken() - * .evaluationTime() - * .eventStream() - * .eventToken() - * .mode() - * .ruleVersion() - * ``` + * @throws LithicInvalidDataException in the default implementation. */ - @JvmStatic fun builder() = Builder() + fun unknown(json: JsonValue?): T { + throw LithicInvalidDataException("Unknown V2ListResultsResponse: $json") + } } - /** A builder for [V2ListResultsResponse]. */ - class Builder internal constructor() { + 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() + } + } + } - 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() + internal class Serializer : + BaseSerializer(V2ListResultsResponse::class) { - @JvmSynthetic - internal fun from(v2ListResultsResponse: V2ListResultsResponse) = apply { - token = v2ListResultsResponse.token - actions = v2ListResultsResponse.actions.map { it.toMutableList() } - authRuleToken = v2ListResultsResponse.authRuleToken - evaluationTime = v2ListResultsResponse.evaluationTime - eventStream = v2ListResultsResponse.eventStream - eventToken = v2ListResultsResponse.eventToken - mode = v2ListResultsResponse.mode - ruleVersion = v2ListResultsResponse.ruleVersion - additionalProperties = v2ListResultsResponse.additionalProperties.toMutableMap() + 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, + ) { - /** Globally unique identifier for the evaluation */ - fun token(token: String) = token(JsonField.of(token)) + @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(), + ) /** - * Sets [Builder.token] to an arbitrary JSON value. + * Globally unique identifier for the evaluation * - * 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. + * @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(token: JsonField) = apply { this.token = token } - - /** Actions returned by the rule evaluation */ - fun actions(actions: List) = actions(JsonField.of(actions)) + fun token(): String = token.getRequired("token") /** - * Sets [Builder.actions] to an arbitrary JSON value. + * Actions returned by the rule evaluation * - * 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. + * @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(actions: JsonField>) = apply { - this.actions = actions.map { it.toMutableList() } - } + fun actions(): List = actions.getRequired("actions") /** - * Adds a single [Action] to [actions]. + * The Auth Rule token * - * @throws IllegalStateException if the field was previously set to a non-list. + * @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 addAction(action: Action) = apply { - actions = - (actions ?: JsonField.of(mutableListOf())).also { - checkKnown("actions", it).add(action) - } - } - - /** Alias for calling [addAction] with `Action.ofAuthorization(authorization)`. */ - fun addAction(authorization: Action.AuthorizationAction) = - addAction(Action.ofAuthorization(authorization)) - - /** Alias for calling [addAction] with `Action.ofAuthentication3ds(authentication3ds)`. */ - fun addAction(authentication3ds: Action.Authentication3dsAction) = - addAction(Action.ofAuthentication3ds(authentication3ds)) - - /** Alias for calling [addAction] with `Action.ofDecline(decline)`. */ - fun addAction(decline: Action.DeclineAction) = addAction(Action.ofDecline(decline)) + fun authRuleToken(): String = authRuleToken.getRequired("auth_rule_token") - /** Alias for calling [addAction] with `Action.ofRequireTfa(requireTfa)`. */ - fun addAction(requireTfa: Action.RequireTfaAction) = - addAction(Action.ofRequireTfa(requireTfa)) - - /** 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)) + /** + * 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") /** - * Sets [Builder.authRuleToken] to an arbitrary JSON value. + * The event stream during which the rule was evaluated * - * 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. + * @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(authRuleToken: JsonField) = apply { - this.authRuleToken = authRuleToken - } + fun eventStream(): EventStream = eventStream.getRequired("event_stream") - /** Timestamp of the rule evaluation */ - fun evaluationTime(evaluationTime: OffsetDateTime) = - evaluationTime(JsonField.of(evaluationTime)) + /** + * 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") /** - * Sets [Builder.evaluationTime] to an arbitrary JSON value. + * The state of the Auth Rule * - * 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. + * @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(evaluationTime: JsonField) = apply { - this.evaluationTime = evaluationTime - } + fun mode(): AuthRuleState = mode.getRequired("mode") - /** The event stream during which the rule was evaluated */ - fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) + /** + * 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") /** - * Sets [Builder.eventStream] to an arbitrary JSON value. + * Returns the raw JSON value of [token]. * - * 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. + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. */ - fun eventStream(eventStream: JsonField) = apply { - this.eventStream = eventStream - } + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token - /** Token of the event that triggered the evaluation */ - fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) + /** + * 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 /** - * Sets [Builder.eventToken] to an arbitrary JSON value. + * Returns the raw JSON value of [authRuleToken]. * - * 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. + * Unlike [authRuleToken], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun eventToken(eventToken: JsonField) = apply { this.eventToken = eventToken } + @JsonProperty("auth_rule_token") + @ExcludeMissing + fun _authRuleToken(): JsonField = authRuleToken - /** The state of the Auth Rule */ - fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) + /** + * 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 /** - * Sets [Builder.mode] to an arbitrary JSON value. + * Returns the raw JSON value of [eventStream]. * - * 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. + * Unlike [eventStream], this method doesn't throw if the JSON field has an unexpected type. */ - fun mode(mode: JsonField) = apply { this.mode = mode } + @JsonProperty("event_stream") + @ExcludeMissing + fun _eventStream(): JsonField = eventStream - /** Version of the rule that was evaluated */ - fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) + /** + * 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 /** - * Sets [Builder.ruleVersion] to an arbitrary JSON value. + * Returns the raw JSON value of [mode]. * - * 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. + * Unlike [mode], this method doesn't throw if the JSON field has an unexpected type. */ - fun ruleVersion(ruleVersion: JsonField) = apply { this.ruleVersion = ruleVersion } + @JsonProperty("mode") @ExcludeMissing fun _mode(): JsonField = mode - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * 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 - fun putAdditionalProperty(key: String, value: JsonValue) = apply { + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { 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 [V2ListResultsResponse]. - * - * 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(): V2ListResultsResponse = - V2ListResultsResponse( - 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 + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - fun validate(): V2ListResultsResponse = apply { - if (validated) { - return@apply - } + fun toBuilder() = Builder().from(this) - token() - actions().forEach { it.validate() } - authRuleToken() - evaluationTime() - eventStream().validate() - eventToken() - mode().validate() - ruleVersion() - validated = true - } + companion object { - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false + /** + * 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() } - /** - * 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 authorization: AuthorizationAction? = null, - private val authentication3ds: Authentication3dsAction? = null, - private val decline: DeclineAction? = null, - private val requireTfa: RequireTfaAction? = null, - private val approve: ApproveAction? = null, - private val returnAction: ReturnAction? = null, - private val _json: JsonValue? = null, - ) { + /** A builder for [AuthorizationResult]. */ + class Builder internal constructor() { - fun authorization(): Optional = Optional.ofNullable(authorization) + 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() - fun authentication3ds(): Optional = - Optional.ofNullable(authentication3ds) + @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() + } - fun decline(): Optional = Optional.ofNullable(decline) + /** Globally unique identifier for the evaluation */ + fun token(token: String) = token(JsonField.of(token)) - fun requireTfa(): Optional = Optional.ofNullable(requireTfa) + /** + * 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 } - fun approve(): Optional = Optional.ofNullable(approve) + /** Actions returned by the rule evaluation */ + fun actions(actions: List) = actions(JsonField.of(actions)) - fun returnAction(): Optional = Optional.ofNullable(returnAction) + /** + * 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() } + } - fun isAuthorization(): Boolean = authorization != null + /** + * 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) + } + } - fun isAuthentication3ds(): Boolean = authentication3ds != null + /** The Auth Rule token */ + fun authRuleToken(authRuleToken: String) = authRuleToken(JsonField.of(authRuleToken)) - fun isDecline(): Boolean = decline != null + /** + * 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 + } - fun isRequireTfa(): Boolean = requireTfa != null + /** Timestamp of the rule evaluation */ + fun evaluationTime(evaluationTime: OffsetDateTime) = + evaluationTime(JsonField.of(evaluationTime)) - fun isApprove(): Boolean = approve != null + /** + * 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 + } - fun isReturnAction(): Boolean = returnAction != null + /** The event stream during which the rule was evaluated */ + fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) - fun asAuthorization(): AuthorizationAction = authorization.getOrThrow("authorization") + /** + * 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 + } - fun asAuthentication3ds(): Authentication3dsAction = - authentication3ds.getOrThrow("authentication3ds") + /** Token of the event that triggered the evaluation */ + fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) - fun asDecline(): DeclineAction = decline.getOrThrow("decline") + /** + * 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 } - fun asRequireTfa(): RequireTfaAction = requireTfa.getOrThrow("requireTfa") + /** The state of the Auth Rule */ + fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) - fun asApprove(): ApproveAction = approve.getOrThrow("approve") + /** + * 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 } - fun asReturnAction(): ReturnAction = returnAction.getOrThrow("returnAction") + /** Version of the rule that was evaluated */ + fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) - fun _json(): Optional = Optional.ofNullable(_json) + /** + * 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 accept(visitor: Visitor): T = - when { - authorization != null -> visitor.visitAuthorization(authorization) - authentication3ds != null -> visitor.visitAuthentication3ds(authentication3ds) - decline != null -> visitor.visitDecline(decline) - requireTfa != null -> visitor.visitRequireTfa(requireTfa) - approve != null -> visitor.visitApprove(approve) - returnAction != null -> visitor.visitReturnAction(returnAction) - else -> visitor.unknown(_json) + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) } - private var validated: Boolean = false + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } - fun validate(): Action = apply { - if (validated) { - return@apply + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) } - accept( - object : Visitor { - override fun visitAuthorization(authorization: AuthorizationAction) { - authorization.validate() - } + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - override fun visitAuthentication3ds( - authentication3ds: Authentication3dsAction - ) { - authentication3ds.validate() - } + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - override fun visitDecline(decline: DeclineAction) { - decline.validate() - } + /** + * 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(), + ) + } - override fun visitRequireTfa(requireTfa: RequireTfaAction) { - requireTfa.validate() - } + private var validated: Boolean = false - override fun visitApprove(approve: ApproveAction) { - approve.validate() - } + fun validate(): AuthorizationResult = apply { + if (validated) { + return@apply + } - override fun visitReturnAction(returnAction: ReturnAction) { - returnAction.validate() - } - } - ) + token() + actions().forEach { it.validate() } + authRuleToken() + evaluationTime() + eventStream().validate() + eventToken() + mode().validate() + ruleVersion() validated = true } @@ -616,192 +722,39 @@ private constructor( */ @JvmSynthetic internal fun validity(): Int = - accept( - object : Visitor { - override fun visitAuthorization(authorization: AuthorizationAction) = - authorization.validity() - - override fun visitAuthentication3ds( - authentication3ds: Authentication3dsAction - ) = authentication3ds.validity() - - override fun visitDecline(decline: DeclineAction) = decline.validity() - - override fun visitRequireTfa(requireTfa: RequireTfaAction) = - requireTfa.validity() - - 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 && - authorization == other.authorization && - authentication3ds == other.authentication3ds && - decline == other.decline && - requireTfa == other.requireTfa && - approve == other.approve && - returnAction == other.returnAction - } - - override fun hashCode(): Int = - Objects.hash( - authorization, - authentication3ds, - decline, - requireTfa, - approve, - returnAction, - ) - - override fun toString(): String = - when { - authorization != null -> "Action{authorization=$authorization}" - authentication3ds != null -> "Action{authentication3ds=$authentication3ds}" - decline != null -> "Action{decline=$decline}" - requireTfa != null -> "Action{requireTfa=$requireTfa}" - approve != null -> "Action{approve=$approve}" - returnAction != null -> "Action{returnAction=$returnAction}" - _json != null -> "Action{_unknown=$_json}" - else -> throw IllegalStateException("Invalid Action") - } - - companion object { - - @JvmStatic - fun ofAuthorization(authorization: AuthorizationAction) = - Action(authorization = authorization) - - @JvmStatic - fun ofAuthentication3ds(authentication3ds: Authentication3dsAction) = - Action(authentication3ds = authentication3ds) - - @JvmStatic fun ofDecline(decline: DeclineAction) = Action(decline = decline) - - @JvmStatic - fun ofRequireTfa(requireTfa: RequireTfaAction) = Action(requireTfa = requireTfa) - - @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 visitAuthorization(authorization: AuthorizationAction): T - - fun visitAuthentication3ds(authentication3ds: Authentication3dsAction): T - - fun visitDecline(decline: DeclineAction): T - - fun visitRequireTfa(requireTfa: RequireTfaAction): T - - 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(authorization = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Action(authentication3ds = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Action(decline = it, _json = json) - }, - tryDeserialize(node, jacksonTypeRef())?.let { - Action(requireTfa = it, _json = json) - }, - 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.authorization != null -> generator.writeObject(value.authorization) - value.authentication3ds != null -> - generator.writeObject(value.authentication3ds) - value.decline != null -> generator.writeObject(value.decline) - value.requireTfa != null -> generator.writeObject(value.requireTfa) - 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 AuthorizationAction + (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(explanation, mutableMapOf()) + 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 @@ -811,6 +764,13 @@ private constructor( */ 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]. * @@ -836,23 +796,41 @@ private constructor( companion object { /** - * Returns a mutable builder for constructing an instance of [AuthorizationAction]. + * Returns a mutable builder for constructing an instance of [Action]. + * + * The following fields are required: + * ```java + * .type() + * ``` */ @JvmStatic fun builder() = Builder() } - /** A builder for [AuthorizationAction]. */ + /** 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(authorizationAction: AuthorizationAction) = apply { - explanation = authorizationAction.explanation - additionalProperties = authorizationAction.additionalProperties.toMutableMap() + 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)) @@ -890,21 +868,33 @@ private constructor( } /** - * Returns an immutable instance of [AuthorizationAction]. + * 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(): AuthorizationAction = - AuthorizationAction(explanation, additionalProperties.toMutableMap()) + fun build(): Action = + Action( + checkRequired("type", type), + explanation, + additionalProperties.toMutableMap(), + ) } private var validated: Boolean = false - fun validate(): AuthorizationAction = apply { + fun validate(): Action = apply { if (validated) { return@apply } + type().validate() explanation() validated = true } @@ -924,342 +914,392 @@ private constructor( * Used for best match union deserialization. */ @JvmSynthetic - internal fun validity(): Int = (if (explanation.asKnown().isPresent) 1 else 0) - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - - return other is AuthorizationAction && - explanation == other.explanation && - additionalProperties == other.additionalProperties - } - - private val hashCode: Int by lazy { Objects.hash(explanation, additionalProperties) } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "AuthorizationAction{explanation=$explanation, additionalProperties=$additionalProperties}" - } - - class Authentication3dsAction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val explanation: JsonField, - private val additionalProperties: MutableMap, - ) { + internal fun validity(): Int = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + class AuthorizationAction @JsonCreator - private constructor( - @JsonProperty("explanation") - @ExcludeMissing - explanation: JsonField = JsonMissing.of() - ) : this(explanation, mutableMapOf()) - - /** - * 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 [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 { + private constructor(private val value: JsonField) : Enum { /** - * Returns a mutable builder for constructing an instance of - * [Authentication3dsAction]. + * 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. */ - @JvmStatic fun builder() = Builder() - } + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value - /** A builder for [Authentication3dsAction]. */ - class Builder internal constructor() { + companion object { - private var explanation: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + @JvmField val DECLINE = of("DECLINE") - @JvmSynthetic - internal fun from(authentication3dsAction: Authentication3dsAction) = apply { - explanation = authentication3dsAction.explanation - additionalProperties = - authentication3dsAction.additionalProperties.toMutableMap() + @JvmField val CHALLENGE = of("CHALLENGE") + + @JvmStatic fun of(value: String) = AuthorizationAction(JsonField.of(value)) } - /** Optional explanation for why this action was taken */ - fun explanation(explanation: String) = explanation(JsonField.of(explanation)) + /** An enum containing [AuthorizationAction]'s known values. */ + enum class Known { + DECLINE, + CHALLENGE, + } /** - * Sets [Builder.explanation] to an arbitrary JSON value. + * An enum containing [AuthorizationAction]'s known values, as well as an [_UNKNOWN] + * member. * - * 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. + * 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. */ - 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) + enum class Value { + DECLINE, + CHALLENGE, + /** + * An enum member indicating that [AuthorizationAction] was instantiated with an + * unknown value. + */ + _UNKNOWN, } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + /** + * 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 } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } - - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) - } - /** - * Returns an immutable instance of [Authentication3dsAction]. + * Returns an enum member corresponding to this class instance's value. * - * Further updates to this [Builder] will not mutate the returned instance. + * 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 build(): Authentication3dsAction = - Authentication3dsAction(explanation, additionalProperties.toMutableMap()) - } - - private var validated: Boolean = false + fun known(): Known = + when (this) { + DECLINE -> Known.DECLINE + CHALLENGE -> Known.CHALLENGE + else -> + throw LithicInvalidDataException("Unknown AuthorizationAction: $value") + } - fun validate(): Authentication3dsAction = apply { - if (validated) { - return@apply + /** + * 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 } - explanation() - validated = true - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - 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 } - /** - * 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 (explanation.asKnown().isPresent) 1 else 0) + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Authentication3dsAction && + return other is Action && + type == other.type && explanation == other.explanation && additionalProperties == other.additionalProperties } - private val hashCode: Int by lazy { Objects.hash(explanation, additionalProperties) } + private val hashCode: Int by lazy { + Objects.hash(type, explanation, additionalProperties) + } override fun hashCode(): Int = hashCode override fun toString() = - "Authentication3dsAction{explanation=$explanation, additionalProperties=$additionalProperties}" + "Action{type=$type, explanation=$explanation, additionalProperties=$additionalProperties}" } - class DeclineAction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val type: JsonField, - private val reason: JsonField, - private val additionalProperties: MutableMap, - ) { + /** The event stream during which the rule was evaluated */ + class EventStream @JsonCreator private constructor(private val value: JsonField) : + Enum { - @JsonCreator - private constructor( - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), - ) : this(type, reason, mutableMapOf()) + /** + * 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 + } /** - * Decline the tokenization request + * An enum containing [EventStream]'s known values, as well as an [_UNKNOWN] member. * - * @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). + * 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. */ - fun type(): Type = type.getRequired("type") + enum class Value { + AUTHORIZATION, + /** + * An enum member indicating that [EventStream] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } /** - * Reason code for declining the tokenization request + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. * - * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected 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 reason(): Optional = reason.getOptional("reason") + fun value(): Value = + when (this) { + AUTHORIZATION -> Value.AUTHORIZATION + else -> Value._UNKNOWN + } /** - * Returns the raw JSON value of [type]. + * Returns an enum member corresponding to this class instance's value. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * 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. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + fun known(): Known = + when (this) { + AUTHORIZATION -> Known.AUTHORIZATION + else -> throw LithicInvalidDataException("Unknown EventStream: $value") + } /** - * Returns the raw JSON value of [reason]. + * Returns this class instance's primitive wire representation. * - * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + * 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. */ - @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + fun asString(): String = + _value().asString().orElseThrow { + LithicInvalidDataException("Value is not a String") + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) + private var validated: Boolean = false + + fun validate(): EventStream = apply { + if (validated) { + return@apply + } + + known() + validated = true } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - fun toBuilder() = Builder().from(this) + /** + * 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 - companion object { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns a mutable builder for constructing an instance of [DeclineAction]. - * - * The following fields are required: - * ```java - * .type() - * ``` - */ - @JvmStatic fun builder() = Builder() + return other is EventStream && value == other.value } - /** A builder for [DeclineAction]. */ - class Builder internal constructor() { + override fun hashCode() = value.hashCode() - private var type: JsonField? = null - private var reason: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + override fun toString() = value.toString() + } - @JvmSynthetic - internal fun from(declineAction: DeclineAction) = apply { - type = declineAction.type - reason = declineAction.reason - additionalProperties = declineAction.additionalProperties.toMutableMap() - } + /** The state of the Auth Rule */ + class AuthRuleState @JsonCreator private constructor(private val value: JsonField) : + Enum { - /** Decline the tokenization request */ - fun type(type: Type) = type(JsonField.of(type)) + /** + * 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 - /** - * 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 } + companion object { - /** Reason code for declining the tokenization request */ - fun reason(reason: Reason) = reason(JsonField.of(reason)) + @JvmField val ACTIVE = of("ACTIVE") - /** - * 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 } + @JvmField val INACTIVE = of("INACTIVE") - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** An enum containing [AuthRuleState]'s known values. */ + enum class Known { + ACTIVE, + INACTIVE, + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * 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, + } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + /** + * 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 } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + /** + * 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 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), - reason, - additionalProperties.toMutableMap(), - ) - } + /** + * 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(): DeclineAction = apply { + fun validate(): AuthRuleState = apply { if (validated) { return@apply } - type().validate() - reason().ifPresent { it.validate() } + known() validated = true } @@ -1277,104 +1317,2566 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic - internal fun validity(): Int = - (type.asKnown().getOrNull()?.validity() ?: 0) + - (reason.asKnown().getOrNull()?.validity() ?: 0) + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - /** Decline the tokenization request */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * 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 + return other is AuthRuleState && value == other.value + } - companion object { + override fun hashCode() = value.hashCode() - @JvmField val DECLINE = of("DECLINE") + override fun toString() = value.toString() + } - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** An enum containing [Type]'s known values. */ - enum class Known { - DECLINE - } + 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 + } - /** - * 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, - } + 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()) /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * Require two-factor authentication for the tokenization request * - * Use the [known] method instead if you're certain the value is always known or if - * you want to throw for the unknown case. + * @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 value(): Value = - when (this) { - DECLINE -> Value.DECLINE - else -> Value._UNKNOWN - } + fun type(): Type = type.getRequired("type") /** - * Returns an enum member corresponding to this class instance's value. + * Optional explanation for why this action was taken * - * 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 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 this class instance's value is a not a - * known member. + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). */ - fun known(): Known = - when (this) { - DECLINE -> Known.DECLINE - else -> throw LithicInvalidDataException("Unknown Type: $value") - } + fun reason(): Optional = reason.getOptional("reason") /** - * Returns this class instance's primitive wire representation. + * Returns the raw JSON value of [type]. * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. + * 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]. * - * @throws LithicInvalidDataException if this class instance's value does not have - * the expected primitive type. + * Unlike [explanation], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun asString(): String = - _value().asString().orElseThrow { - LithicInvalidDataException("Value is not a String") + @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(): Type = apply { + fun validate(): RequireTfaAction = apply { if (validated) { return@apply } - known() + type().validate() + explanation() + reason().ifPresent { it.validate() } validated = true } @@ -1392,402 +3894,603 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + @JvmSynthetic + internal fun validity(): Int = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) + + (reason.asKnown().getOrNull()?.validity() ?: 0) - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + /** 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)) } - return other is Type && value == other.value - } + /** An enum containing [Type]'s known values. */ + enum class Known { + REQUIRE_TFA + } - override fun hashCode() = value.hashCode() + /** + * 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, + } - override fun toString() = value.toString() - } + /** + * 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 + } - /** Reason code for declining the tokenization request */ - class Reason @JsonCreator private constructor(private val value: JsonField) : - Enum { + /** + * 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 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 + /** + * 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") + } - companion object { + private var validated: Boolean = false - @JvmField val ACCOUNT_SCORE_1 = of("ACCOUNT_SCORE_1") + fun validate(): Type = apply { + if (validated) { + return@apply + } - @JvmField val DEVICE_SCORE_1 = of("DEVICE_SCORE_1") + known() + validated = true + } - @JvmField - val ALL_WALLET_DECLINE_REASONS_PRESENT = - of("ALL_WALLET_DECLINE_REASONS_PRESENT") + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - @JvmField - val WALLET_RECOMMENDED_DECISION_RED = of("WALLET_RECOMMENDED_DECISION_RED") + /** + * 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 - @JvmField val CVC_MISMATCH = of("CVC_MISMATCH") + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JvmField val CARD_EXPIRY_MONTH_MISMATCH = of("CARD_EXPIRY_MONTH_MISMATCH") + return other is Type && value == other.value + } - @JvmField val CARD_EXPIRY_YEAR_MISMATCH = of("CARD_EXPIRY_YEAR_MISMATCH") + override fun hashCode() = value.hashCode() - @JvmField val CARD_INVALID_STATE = of("CARD_INVALID_STATE") + override fun toString() = value.toString() + } - @JvmField val CUSTOMER_RED_PATH = of("CUSTOMER_RED_PATH") + /** Reason code for requiring two-factor authentication */ + class Reason + @JsonCreator + private constructor(private val value: JsonField) : Enum { - @JvmField val INVALID_CUSTOMER_RESPONSE = of("INVALID_CUSTOMER_RESPONSE") + /** + * 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 - @JvmField val NETWORK_FAILURE = of("NETWORK_FAILURE") + companion object { - @JvmField val GENERIC_DECLINE = of("GENERIC_DECLINE") + @JvmField val WALLET_RECOMMENDED_TFA = of("WALLET_RECOMMENDED_TFA") - @JvmField val DIGITAL_CARD_ART_REQUIRED = of("DIGITAL_CARD_ART_REQUIRED") + @JvmField val SUSPICIOUS_ACTIVITY = of("SUSPICIOUS_ACTIVITY") - @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) - } + @JvmField val DEVICE_RECENTLY_LOST = of("DEVICE_RECENTLY_LOST") - /** 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, - } + @JvmField val TOO_MANY_RECENT_ATTEMPTS = of("TOO_MANY_RECENT_ATTEMPTS") - /** - * 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, - } + @JvmField val TOO_MANY_RECENT_TOKENS = of("TOO_MANY_RECENT_TOKENS") - /** - * 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 + @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)) } - /** - * 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") + /** 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, } - /** - * 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") + /** + * 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, } - private var validated: Boolean = false + /** + * 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 + } - fun validate(): Reason = apply { - if (validated) { - return@apply + /** + * 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 } - known() - validated = true - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - 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 } - /** - * 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 hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Reason && value == other.value + return other is RequireTfaAction && + type == other.type && + explanation == other.explanation && + reason == other.reason && + additionalProperties == other.additionalProperties } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + private val hashCode: Int by lazy { + Objects.hash(type, explanation, reason, additionalProperties) } - return other is DeclineAction && - type == other.type && - reason == other.reason && - additionalProperties == other.additionalProperties + override fun hashCode(): Int = hashCode + + override fun toString() = + "RequireTfaAction{type=$type, explanation=$explanation, reason=$reason, additionalProperties=$additionalProperties}" } + } - private val hashCode: Int by lazy { Objects.hash(type, reason, additionalProperties) } + /** The event stream during which the rule was evaluated */ + class EventStream @JsonCreator private constructor(private val value: JsonField) : + Enum { - override fun hashCode(): Int = hashCode + /** + * 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 - override fun toString() = - "DeclineAction{type=$type, reason=$reason, additionalProperties=$additionalProperties}" - } + companion object { - class RequireTfaAction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val type: JsonField, - private val reason: JsonField, - private val additionalProperties: MutableMap, - ) { + @JvmField val TOKENIZATION = of("TOKENIZATION") + + @JvmStatic fun of(value: String) = EventStream(JsonField.of(value)) + } - @JsonCreator - private constructor( - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - @JsonProperty("reason") @ExcludeMissing reason: JsonField = JsonMissing.of(), - ) : this(type, reason, mutableMapOf()) + /** An enum containing [EventStream]'s known values. */ + enum class Known { + TOKENIZATION + } /** - * Require two-factor authentication for the tokenization request + * An enum containing [EventStream]'s known values, as well as an [_UNKNOWN] member. * - * @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). + * 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. */ - fun type(): Type = type.getRequired("type") + enum class Value { + TOKENIZATION, + /** + * An enum member indicating that [EventStream] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } /** - * Reason code for requiring two-factor authentication + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. * - * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if - * the server responded with an unexpected 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 reason(): Optional = reason.getOptional("reason") + fun value(): Value = + when (this) { + TOKENIZATION -> Value.TOKENIZATION + else -> Value._UNKNOWN + } /** - * Returns the raw JSON value of [type]. + * Returns an enum member corresponding to this class instance's value. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * 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. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + fun known(): Known = + when (this) { + TOKENIZATION -> Known.TOKENIZATION + else -> throw LithicInvalidDataException("Unknown EventStream: $value") + } /** - * Returns the raw JSON value of [reason]. + * 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. * - * Unlike [reason], this method doesn't throw if the JSON field has an unexpected type. + * @throws LithicInvalidDataException if this class instance's value does not have the + * expected primitive type. */ - @JsonProperty("reason") @ExcludeMissing fun _reason(): JsonField = reason + fun asString(): String = + _value().asString().orElseThrow { + LithicInvalidDataException("Value is not a String") + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) + private var validated: Boolean = false + + fun validate(): EventStream = apply { + if (validated) { + return@apply + } + + known() + validated = true } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - fun toBuilder() = Builder().from(this) + /** + * 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 - companion object { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - /** - * Returns a mutable builder for constructing an instance of [RequireTfaAction]. - * - * The following fields are required: - * ```java - * .type() - * ``` - */ - @JvmStatic fun builder() = Builder() + return other is EventStream && value == other.value } - /** A builder for [RequireTfaAction]. */ - class Builder internal constructor() { + override fun hashCode() = value.hashCode() - private var type: JsonField? = null - private var reason: JsonField = JsonMissing.of() - private var additionalProperties: MutableMap = mutableMapOf() + override fun toString() = value.toString() + } - @JvmSynthetic - internal fun from(requireTfaAction: RequireTfaAction) = apply { - type = requireTfaAction.type - reason = requireTfaAction.reason - additionalProperties = requireTfaAction.additionalProperties.toMutableMap() - } + /** The state of the Auth Rule */ + class AuthRuleState @JsonCreator private constructor(private val value: JsonField) : + Enum { - /** Require two-factor authentication for the tokenization request */ - fun type(type: Type) = type(JsonField.of(type)) + /** + * 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 - /** - * 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 } + companion object { - /** Reason code for requiring two-factor authentication */ - fun reason(reason: Reason) = reason(JsonField.of(reason)) + @JvmField val ACTIVE = of("ACTIVE") - /** - * 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 } + @JvmField val INACTIVE = of("INACTIVE") - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) + } - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + /** An enum containing [AuthRuleState]'s known values. */ + enum class Known { + ACTIVE, + INACTIVE, + } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + /** + * 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, + } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + /** + * 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 } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + /** + * 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 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), - reason, - additionalProperties.toMutableMap(), - ) - } + /** + * 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(): RequireTfaAction = apply { + fun validate(): AuthRuleState = apply { if (validated) { return@apply } - type().validate() - reason().ifPresent { it.validate() } + known() validated = true } @@ -1805,489 +4508,563 @@ private constructor( * * Used for best match union deserialization. */ - @JvmSynthetic - internal fun validity(): Int = - (type.asKnown().getOrNull()?.validity() ?: 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 - } + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 - /** - * 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, + override fun equals(other: Any?): Boolean { + if (this === other) { + return true } - /** - * 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") - } + return other is AuthRuleState && value == other.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") - } + override fun hashCode() = value.hashCode() - private var validated: Boolean = false + override fun toString() = value.toString() + } - fun validate(): Type = apply { - if (validated) { - return@apply - } + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - known() - validated = 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 + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false - } + private val hashCode: Int by lazy { + Objects.hash( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + additionalProperties, + ) + } - /** - * 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 hashCode(): Int = hashCode - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + override fun toString() = + "TokenizationResult{token=$token, actions=$actions, authRuleToken=$authRuleToken, evaluationTime=$evaluationTime, eventStream=$eventStream, eventToken=$eventToken, mode=$mode, ruleVersion=$ruleVersion, additionalProperties=$additionalProperties}" + } - return other is Type && value == other.value - } + 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, + ) { - override fun hashCode() = value.hashCode() + @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(), + ) - override fun toString() = value.toString() - } + /** + * 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") - /** Reason code for requiring two-factor authentication */ - class Reason @JsonCreator private constructor(private val value: JsonField) : - Enum { + /** + * 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") - /** - * 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 + /** + * 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") - companion object { + /** + * 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") - @JvmField val WALLET_RECOMMENDED_TFA = of("WALLET_RECOMMENDED_TFA") + /** + * 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") - @JvmField val SUSPICIOUS_ACTIVITY = of("SUSPICIOUS_ACTIVITY") + /** + * 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") - @JvmField val DEVICE_RECENTLY_LOST = of("DEVICE_RECENTLY_LOST") + /** + * 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") - @JvmField val TOO_MANY_RECENT_ATTEMPTS = of("TOO_MANY_RECENT_ATTEMPTS") + /** + * 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") - @JvmField val TOO_MANY_RECENT_TOKENS = of("TOO_MANY_RECENT_TOKENS") + /** + * 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 - @JvmField - val TOO_MANY_DIFFERENT_CARDHOLDERS = of("TOO_MANY_DIFFERENT_CARDHOLDERS") + /** + * 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 - @JvmField val OUTSIDE_HOME_TERRITORY = of("OUTSIDE_HOME_TERRITORY") + /** + * 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 - @JvmField val HAS_SUSPENDED_TOKENS = of("HAS_SUSPENDED_TOKENS") + /** + * 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 - @JvmField val HIGH_RISK = of("HIGH_RISK") + /** + * 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 - @JvmField val ACCOUNT_SCORE_LOW = of("ACCOUNT_SCORE_LOW") + /** + * 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 - @JvmField val DEVICE_SCORE_LOW = of("DEVICE_SCORE_LOW") + /** + * 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 - @JvmField val CARD_STATE_TFA = of("CARD_STATE_TFA") + /** + * 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 - @JvmField val HARDCODED_TFA = of("HARDCODED_TFA") + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } - @JvmField val CUSTOMER_RULE_TFA = of("CUSTOMER_RULE_TFA") + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) - @JvmField val DEVICE_HOST_CARD_EMULATION = of("DEVICE_HOST_CARD_EMULATION") + fun toBuilder() = Builder().from(this) - @JvmStatic fun of(value: String) = Reason(JsonField.of(value)) - } + companion object { - /** 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, - } + /** + * 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() + } - /** - * 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, - } + /** A builder for [AchResult]. */ + class Builder internal constructor() { - /** - * 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 - } + 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() - /** - * 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") - } + @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() + } - /** - * 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") - } + /** Globally unique identifier for the evaluation */ + fun token(token: String) = token(JsonField.of(token)) - private var validated: Boolean = false + /** + * 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 } - fun validate(): Reason = apply { - if (validated) { - return@apply - } + /** Actions returned by the rule evaluation */ + fun actions(actions: List) = actions(JsonField.of(actions)) - known() - validated = true - } + /** + * 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() } + } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false + /** + * 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) } + } - /** - * 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 - } + /** Alias for calling [addAction] with `Action.ofApprove(approve)`. */ + fun addAction(approve: Action.ApproveAction) = addAction(Action.ofApprove(approve)) - return other is Reason && value == other.value - } + /** Alias for calling [addAction] with `Action.ofReturnAction(returnAction)`. */ + fun addAction(returnAction: Action.ReturnAction) = + addAction(Action.ofReturnAction(returnAction)) - override fun hashCode() = value.hashCode() + /** The Auth Rule token */ + fun authRuleToken(authRuleToken: String) = authRuleToken(JsonField.of(authRuleToken)) - override fun toString() = value.toString() + /** + * 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 } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + /** Timestamp of the rule evaluation */ + fun evaluationTime(evaluationTime: OffsetDateTime) = + evaluationTime(JsonField.of(evaluationTime)) - return other is RequireTfaAction && - type == other.type && - reason == other.reason && - additionalProperties == other.additionalProperties + /** + * 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 } - private val hashCode: Int by lazy { Objects.hash(type, reason, additionalProperties) } + /** The event stream during which the rule was evaluated */ + fun eventStream(eventStream: EventStream) = eventStream(JsonField.of(eventStream)) - override fun hashCode(): Int = hashCode + /** + * 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 + } - override fun toString() = - "RequireTfaAction{type=$type, reason=$reason, additionalProperties=$additionalProperties}" - } + /** Token of the event that triggered the evaluation */ + fun eventToken(eventToken: String) = eventToken(JsonField.of(eventToken)) - class ApproveAction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * 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 } - @JsonCreator - private constructor( - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of() - ) : this(type, mutableMapOf()) + /** The state of the Auth Rule */ + fun mode(mode: AuthRuleState) = mode(JsonField.of(mode)) /** - * Approve the ACH transaction + * Sets [Builder.mode] to an arbitrary JSON value. * - * @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). + * 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 type(): Type = type.getRequired("type") + fun mode(mode: JsonField) = apply { this.mode = mode } + + /** Version of the rule that was evaluated */ + fun ruleVersion(ruleVersion: Long) = ruleVersion(JsonField.of(ruleVersion)) /** - * Returns the raw JSON value of [type]. + * Sets [Builder.ruleVersion] to an arbitrary JSON value. * - * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + * 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. */ - @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + fun ruleVersion(ruleVersion: JsonField) = apply { this.ruleVersion = ruleVersion } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { additionalProperties.put(key, value) } - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } - fun toBuilder() = Builder().from(this) + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } - companion object { + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } - /** - * Returns a mutable builder for constructing an instance of [ApproveAction]. - * - * The following fields are required: - * ```java - * .type() - * ``` - */ - @JvmStatic fun builder() = Builder() + /** + * 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 } - /** A builder for [ApproveAction]. */ - class Builder internal constructor() { + token() + actions().forEach { it.validate() } + authRuleToken() + evaluationTime() + eventStream().validate() + eventToken() + mode().validate() + ruleVersion() + validated = true + } - private var type: JsonField? = null - private var additionalProperties: MutableMap = mutableMapOf() + 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, + ) { - @JvmSynthetic - internal fun from(approveAction: ApproveAction) = apply { - type = approveAction.type - additionalProperties = approveAction.additionalProperties.toMutableMap() - } + fun approve(): Optional = Optional.ofNullable(approve) - /** Approve the ACH transaction */ - fun type(type: Type) = type(JsonField.of(type)) + fun returnAction(): Optional = Optional.ofNullable(returnAction) - /** - * Sets [Builder.type] to an arbitrary JSON value. - * - * You should usually call [Builder.type] with a well-typed [Type] value instead. - * This method is primarily for setting the field to an undocumented or not yet - * supported value. - */ - fun type(type: JsonField) = apply { this.type = type } + fun isApprove(): Boolean = approve != null - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + fun isReturnAction(): Boolean = returnAction != null - fun putAdditionalProperty(key: String, value: JsonValue) = apply { - additionalProperties.put(key, value) - } + fun asApprove(): ApproveAction = approve.getOrThrow("approve") - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) - } + fun asReturnAction(): ReturnAction = returnAction.getOrThrow("returnAction") - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) - } + fun _json(): Optional = Optional.ofNullable(_json) - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + fun accept(visitor: Visitor): T = + when { + approve != null -> visitor.visitApprove(approve) + returnAction != null -> visitor.visitReturnAction(returnAction) + else -> visitor.unknown(_json) } - /** - * 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), additionalProperties.toMutableMap()) - } - private var validated: Boolean = false - fun validate(): ApproveAction = apply { + fun validate(): Action = apply { if (validated) { return@apply } - type().validate() + accept( + object : Visitor { + override fun visitApprove(approve: ApproveAction) { + approve.validate() + } + + override fun visitReturnAction(returnAction: ReturnAction) { + returnAction.validate() + } + } + ) validated = true } @@ -2306,101 +5083,283 @@ private constructor( * Used for best match union deserialization. */ @JvmSynthetic - internal fun validity(): Int = (type.asKnown().getOrNull()?.validity() ?: 0) + internal fun validity(): Int = + accept( + object : Visitor { + override fun visitApprove(approve: ApproveAction) = approve.validity() - /** Approve the ACH transaction */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { + override fun visitReturnAction(returnAction: ReturnAction) = + returnAction.validity() - /** - * 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 + override fun unknown(json: JsonValue?) = 0 + } + ) - companion object { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - @JvmField val APPROVE = of("APPROVE") + return other is Action && + approve == other.approve && + returnAction == other.returnAction + } - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } + override fun hashCode(): Int = Objects.hash(approve, returnAction) - /** An enum containing [Type]'s known values. */ - enum class Known { - APPROVE + 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 + /** - * An enum containing [Type]'s known values, as well as an [_UNKNOWN] member. + * Maps an unknown variant of [Action] to a value of type [T]. * - * 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. + * 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. */ - enum class Value { - APPROVE, - /** - * An enum member indicating that [Type] was instantiated with an unknown value. - */ - _UNKNOWN, + 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()) /** - * Returns an enum member corresponding to this class instance's value, or - * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * Approve the ACH transaction * - * Use the [known] method instead if you're certain the value is always known or if - * you want to throw for the unknown case. + * @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 value(): Value = - when (this) { - APPROVE -> Value.APPROVE - else -> Value._UNKNOWN - } + fun type(): Type = type.getRequired("type") /** - * 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. + * Optional explanation for why this action was taken * - * @throws LithicInvalidDataException if this class instance's value is a not a - * known member. + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). */ - fun known(): Known = - when (this) { - APPROVE -> Known.APPROVE - else -> throw LithicInvalidDataException("Unknown Type: $value") - } + fun explanation(): Optional = explanation.getOptional("explanation") /** - * Returns this class instance's primitive wire representation. + * Returns the raw JSON value of [type]. * - * This differs from the [toString] method because that method is primarily for - * debugging and generally doesn't throw. + * 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]. * - * @throws LithicInvalidDataException if this class instance's value does not have - * the expected primitive type. + * Unlike [explanation], this method doesn't throw if the JSON field has an + * unexpected type. */ - fun asString(): String = - _value().asString().orElseThrow { - LithicInvalidDataException("Value is not a String") + @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(): Type = apply { + fun validate(): ApproveAction = apply { if (validated) { return@apply } - known() + type().validate() + explanation() validated = true } @@ -2418,1077 +5377,1386 @@ private constructor( * * 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 - } + @JvmSynthetic + internal fun validity(): Int = + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) - return other is Type && value == other.value - } + /** Approve the ACH transaction */ + class Type @JsonCreator private constructor(private val value: JsonField) : + Enum { - override fun hashCode() = value.hashCode() + /** + * 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 - override fun toString() = value.toString() - } + companion object { - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + @JvmField val APPROVE = of("APPROVE") - return other is ApproveAction && - type == other.type && - additionalProperties == other.additionalProperties - } + @JvmStatic fun of(value: String) = Type(JsonField.of(value)) + } - private val hashCode: Int by lazy { Objects.hash(type, additionalProperties) } + /** An enum containing [Type]'s known values. */ + enum class Known { + APPROVE + } - override fun hashCode(): Int = hashCode + /** + * 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, + } - override fun toString() = - "ApproveAction{type=$type, additionalProperties=$additionalProperties}" - } + /** + * 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 + } - class ReturnAction - @JsonCreator(mode = JsonCreator.Mode.DISABLED) - private constructor( - private val code: JsonField, - private val type: JsonField, - private val additionalProperties: MutableMap, - ) { + /** + * 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") + } - @JsonCreator - private constructor( - @JsonProperty("code") @ExcludeMissing code: JsonField = JsonMissing.of(), - @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), - ) : this(code, type, mutableMapOf()) + /** + * 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") + } - /** - * 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") + private var validated: Boolean = false - /** - * 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") + fun validate(): Type = apply { + if (validated) { + return@apply + } - /** - * 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 + known() + validated = true + } - /** - * 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 + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - @JsonAnySetter - private fun putAdditionalProperty(key: String, value: JsonValue) { - additionalProperties.put(key, value) - } + /** + * 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 - @JsonAnyGetter - @ExcludeMissing - fun _additionalProperties(): Map = - Collections.unmodifiableMap(additionalProperties) + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - fun toBuilder() = Builder().from(this) + return other is Type && value == other.value + } - companion object { + override fun hashCode() = value.hashCode() - /** - * Returns a mutable builder for constructing an instance of [ReturnAction]. - * - * The following fields are required: - * ```java - * .code() - * .type() - * ``` - */ - @JvmStatic fun builder() = Builder() - } + override fun toString() = value.toString() + } - /** A builder for [ReturnAction]. */ - class Builder internal constructor() { + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } - private var code: JsonField? = null - private var type: JsonField? = null - private var additionalProperties: MutableMap = mutableMapOf() + return other is ApproveAction && + type == other.type && + explanation == other.explanation && + additionalProperties == other.additionalProperties + } - @JvmSynthetic - internal fun from(returnAction: ReturnAction) = apply { - code = returnAction.code - type = returnAction.type - additionalProperties = returnAction.additionalProperties.toMutableMap() + 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) = code(JsonField.of(code)) + fun code(): Code = code.getRequired("code") /** - * Sets [Builder.code] to an arbitrary JSON value. + * Return the ACH transaction * - * 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. + * @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: JsonField) = apply { this.code = code } + fun type(): Type = type.getRequired("type") - /** Return the ACH transaction */ - fun type(type: Type) = type(JsonField.of(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") /** - * Sets [Builder.type] to an arbitrary JSON value. + * Returns the raw JSON value of [code]. * - * 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. + * Unlike [code], this method doesn't throw if the JSON field has an unexpected + * type. */ - fun type(type: JsonField) = apply { this.type = type } + @JsonProperty("code") @ExcludeMissing fun _code(): JsonField = code - fun additionalProperties(additionalProperties: Map) = apply { - this.additionalProperties.clear() - putAllAdditionalProperties(additionalProperties) - } + /** + * 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 - fun putAdditionalProperty(key: String, value: JsonValue) = apply { + /** + * 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) } - fun putAllAdditionalProperties(additionalProperties: Map) = - apply { - this.additionalProperties.putAll(additionalProperties) + @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() } - fun removeAdditionalProperty(key: String) = apply { - additionalProperties.remove(key) + /** + * 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(), + ) } - fun removeAllAdditionalProperties(keys: Set) = apply { - keys.forEach(::removeAdditionalProperty) + 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 an immutable instance of [ReturnAction]. - * - * Further updates to this [Builder] will not mutate the returned instance. - * - * The following fields are required: - * ```java - * .code() - * .type() - * ``` + * Returns a score indicating how many valid values are contained in this object + * recursively. * - * @throws IllegalStateException if any required field is unset. + * Used for best match union deserialization. */ - fun build(): ReturnAction = - ReturnAction( - checkRequired("code", code), - checkRequired("type", type), - additionalProperties.toMutableMap(), - ) - } + @JvmSynthetic + internal fun validity(): Int = + (code.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + (if (explanation.asKnown().isPresent) 1 else 0) - private var validated: Boolean = false + /** + * 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 { - fun validate(): ReturnAction = apply { - if (validated) { - return@apply - } + /** + * 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 - code().validate() - type().validate() - validated = true - } + companion object { - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false - } + @JvmField val R01 = of("R01") - /** - * 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) + @JvmField val R02 = of("R02") - /** - * 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 { + @JvmField val R03 = of("R03") - /** - * 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 + @JvmField val R04 = of("R04") - companion object { + @JvmField val R05 = of("R05") - @JvmField val R01 = of("R01") + @JvmField val R06 = of("R06") - @JvmField val R02 = of("R02") + @JvmField val R07 = of("R07") - @JvmField val R03 = of("R03") + @JvmField val R08 = of("R08") - @JvmField val R04 = of("R04") + @JvmField val R09 = of("R09") - @JvmField val R05 = of("R05") + @JvmField val R10 = of("R10") - @JvmField val R06 = of("R06") + @JvmField val R11 = of("R11") - @JvmField val R07 = of("R07") + @JvmField val R12 = of("R12") - @JvmField val R08 = of("R08") + @JvmField val R13 = of("R13") - @JvmField val R09 = of("R09") + @JvmField val R14 = of("R14") - @JvmField val R10 = of("R10") + @JvmField val R15 = of("R15") - @JvmField val R11 = of("R11") + @JvmField val R16 = of("R16") - @JvmField val R12 = of("R12") + @JvmField val R17 = of("R17") - @JvmField val R13 = of("R13") + @JvmField val R18 = of("R18") - @JvmField val R14 = of("R14") + @JvmField val R19 = of("R19") - @JvmField val R15 = of("R15") + @JvmField val R20 = of("R20") - @JvmField val R16 = of("R16") + @JvmField val R21 = of("R21") - @JvmField val R17 = of("R17") + @JvmField val R22 = of("R22") - @JvmField val R18 = of("R18") + @JvmField val R23 = of("R23") - @JvmField val R19 = of("R19") + @JvmField val R24 = of("R24") - @JvmField val R20 = of("R20") + @JvmField val R25 = of("R25") - @JvmField val R21 = of("R21") + @JvmField val R26 = of("R26") - @JvmField val R22 = of("R22") + @JvmField val R27 = of("R27") - @JvmField val R23 = of("R23") + @JvmField val R28 = of("R28") - @JvmField val R24 = of("R24") + @JvmField val R29 = of("R29") - @JvmField val R25 = of("R25") + @JvmField val R30 = of("R30") - @JvmField val R26 = of("R26") + @JvmField val R31 = of("R31") - @JvmField val R27 = of("R27") + @JvmField val R32 = of("R32") - @JvmField val R28 = of("R28") + @JvmField val R33 = of("R33") - @JvmField val R29 = of("R29") + @JvmField val R34 = of("R34") - @JvmField val R30 = of("R30") + @JvmField val R35 = of("R35") - @JvmField val R31 = of("R31") + @JvmField val R36 = of("R36") - @JvmField val R32 = of("R32") + @JvmField val R37 = of("R37") - @JvmField val R33 = of("R33") + @JvmField val R38 = of("R38") - @JvmField val R34 = of("R34") + @JvmField val R39 = of("R39") - @JvmField val R35 = of("R35") + @JvmField val R40 = of("R40") - @JvmField val R36 = of("R36") + @JvmField val R41 = of("R41") - @JvmField val R37 = of("R37") + @JvmField val R42 = of("R42") - @JvmField val R38 = of("R38") + @JvmField val R43 = of("R43") - @JvmField val R39 = of("R39") + @JvmField val R44 = of("R44") - @JvmField val R40 = of("R40") + @JvmField val R45 = of("R45") - @JvmField val R41 = of("R41") + @JvmField val R46 = of("R46") - @JvmField val R42 = of("R42") + @JvmField val R47 = of("R47") - @JvmField val R43 = of("R43") + @JvmField val R50 = of("R50") - @JvmField val R44 = of("R44") + @JvmField val R51 = of("R51") - @JvmField val R45 = of("R45") + @JvmField val R52 = of("R52") - @JvmField val R46 = of("R46") + @JvmField val R53 = of("R53") - @JvmField val R47 = of("R47") + @JvmField val R61 = of("R61") - @JvmField val R50 = of("R50") + @JvmField val R62 = of("R62") - @JvmField val R51 = of("R51") + @JvmField val R67 = of("R67") - @JvmField val R52 = of("R52") + @JvmField val R68 = of("R68") - @JvmField val R53 = of("R53") + @JvmField val R69 = of("R69") - @JvmField val R61 = of("R61") + @JvmField val R70 = of("R70") - @JvmField val R62 = of("R62") + @JvmField val R71 = of("R71") - @JvmField val R67 = of("R67") + @JvmField val R72 = of("R72") - @JvmField val R68 = of("R68") + @JvmField val R73 = of("R73") - @JvmField val R69 = of("R69") + @JvmField val R74 = of("R74") - @JvmField val R70 = of("R70") + @JvmField val R75 = of("R75") - @JvmField val R71 = of("R71") + @JvmField val R76 = of("R76") - @JvmField val R72 = of("R72") + @JvmField val R77 = of("R77") - @JvmField val R73 = of("R73") + @JvmField val R80 = of("R80") - @JvmField val R74 = of("R74") + @JvmField val R81 = of("R81") - @JvmField val R75 = of("R75") + @JvmField val R82 = of("R82") - @JvmField val R76 = of("R76") + @JvmField val R83 = of("R83") - @JvmField val R77 = of("R77") + @JvmField val R84 = of("R84") - @JvmField val R80 = of("R80") + @JvmField val R85 = of("R85") - @JvmField val R81 = of("R81") + @JvmStatic fun of(value: String) = Code(JsonField.of(value)) + } - @JvmField val R82 = of("R82") + /** 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, + } - @JvmField val R83 = of("R83") + /** + * 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, + } - @JvmField val R84 = of("R84") + /** + * 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 + } - @JvmField val R85 = of("R85") + /** + * 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") + } - @JvmStatic fun of(value: String) = Code(JsonField.of(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") + } - /** 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, - } + private var validated: Boolean = false - /** - * 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. + 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. */ - _UNKNOWN, + @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() } - /** - * 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 + /** 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)) } - /** - * 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") + /** An enum containing [Type]'s known values. */ + enum class Known { + RETURN } - /** - * 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") + /** + * 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, } - private var validated: Boolean = false + /** + * 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 + } - fun validate(): Code = apply { - if (validated) { - return@apply + /** + * 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 } - known() - validated = true - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - 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 } - /** - * 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 hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is Code && value == other.value + return other is ReturnAction && + code == other.code && + type == other.type && + explanation == other.explanation && + additionalProperties == other.additionalProperties } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } + private val hashCode: Int by lazy { + Objects.hash(code, type, explanation, additionalProperties) + } - /** Return the ACH transaction */ - class Type @JsonCreator private constructor(private val value: JsonField) : - Enum { + override fun hashCode(): Int = hashCode - /** - * 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 + override fun toString() = + "ReturnAction{code=$code, type=$type, explanation=$explanation, additionalProperties=$additionalProperties}" + } + } - companion object { + /** The event stream during which the rule was evaluated */ + class EventStream @JsonCreator private constructor(private val value: JsonField) : + Enum { - @JvmField val RETURN = of("RETURN") + /** + * 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 - @JvmStatic fun of(value: String) = Type(JsonField.of(value)) - } + companion object { - /** An enum containing [Type]'s known values. */ - enum class Known { - RETURN - } + @JvmField val ACH_CREDIT_RECEIPT = of("ACH_CREDIT_RECEIPT") - /** - * 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, - } + @JvmField val ACH_DEBIT_RECEIPT = of("ACH_DEBIT_RECEIPT") - /** - * 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 - } + @JvmStatic fun of(value: String) = EventStream(JsonField.of(value)) + } - /** - * 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") - } + /** 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, /** - * 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. + * An enum member indicating that [EventStream] was instantiated with an unknown + * value. */ - fun asString(): String = - _value().asString().orElseThrow { - LithicInvalidDataException("Value is not a String") - } + _UNKNOWN, + } - private var validated: Boolean = false + /** + * 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 + } - fun validate(): Type = apply { - if (validated) { - return@apply - } + /** + * 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") + } - known() - validated = true + /** + * 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") } - fun isValid(): Boolean = - try { - validate() - true - } catch (e: LithicInvalidDataException) { - false - } + private var validated: Boolean = 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 + fun validate(): EventStream = apply { + if (validated) { + return@apply + } - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } + known() + validated = true + } - return other is Type && value == other.value + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } + /** + * 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 ReturnAction && - code == other.code && - type == other.type && - additionalProperties == other.additionalProperties + return other is EventStream && value == other.value } - private val hashCode: Int by lazy { Objects.hash(code, type, additionalProperties) } - - override fun hashCode(): Int = hashCode + override fun hashCode() = value.hashCode() - override fun toString() = - "ReturnAction{code=$code, type=$type, additionalProperties=$additionalProperties}" + override fun toString() = value.toString() } - } - /** The state of the Auth Rule */ - class AuthRuleState @JsonCreator private constructor(private val value: JsonField) : - Enum { + /** 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 + /** + * 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 { + companion object { - @JvmField val ACTIVE = of("ACTIVE") + @JvmField val ACTIVE = of("ACTIVE") - @JvmField val INACTIVE = of("INACTIVE") + @JvmField val INACTIVE = of("INACTIVE") - @JvmStatic fun of(value: String) = AuthRuleState(JsonField.of(value)) - } + @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. */ + 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. + * 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. */ - _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 + 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. - * - * 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 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 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") } + /** + * 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") + } - private var validated: Boolean = false + /** + * 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") + } - fun validate(): AuthRuleState = apply { - if (validated) { - return@apply + private var validated: Boolean = false + + fun validate(): AuthRuleState = apply { + if (validated) { + return@apply + } + + known() + validated = true } - known() - validated = true - } + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } - 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 } - /** - * 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 hashCode() = value.hashCode() + + override fun toString() = value.toString() + } override fun equals(other: Any?): Boolean { if (this === other) { return true } - return other is AuthRuleState && value == other.value + 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 } - override fun hashCode() = value.hashCode() - - override fun toString() = value.toString() - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true + private val hashCode: Int by lazy { + Objects.hash( + token, + actions, + authRuleToken, + evaluationTime, + eventStream, + eventToken, + mode, + ruleVersion, + additionalProperties, + ) } - return other is V2ListResultsResponse && - 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 - } + override fun hashCode(): Int = hashCode - private val hashCode: Int by lazy { - Objects.hash( - token, - actions, - authRuleToken, - evaluationTime, - eventStream, - eventToken, - mode, - ruleVersion, - additionalProperties, - ) + override fun toString() = + "AchResult{token=$token, actions=$actions, authRuleToken=$authRuleToken, evaluationTime=$evaluationTime, eventStream=$eventStream, eventToken=$eventToken, mode=$mode, ruleVersion=$ruleVersion, additionalProperties=$additionalProperties}" } - - override fun hashCode(): Int = hashCode - - override fun toString() = - "V2ListResultsResponse{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/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AuthRuleV2ListResultsPageResponseTest.kt index a0a6264f..94471084 100644 --- 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 @@ -15,18 +15,25 @@ internal class AuthRuleV2ListResultsPageResponseTest { val authRuleV2ListResultsPageResponse = AuthRuleV2ListResultsPageResponse.builder() .addData( - V2ListResultsResponse.builder() + V2ListResultsResponse.AuthorizationResult.builder() .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .addAction( - V2ListResultsResponse.Action.AuthorizationAction.builder() + 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(EventStream.AUTHORIZATION) + .eventStream( + V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION + ) .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) .ruleVersion(0L) .build() ) @@ -35,20 +42,29 @@ internal class AuthRuleV2ListResultsPageResponseTest { assertThat(authRuleV2ListResultsPageResponse.data()) .containsExactly( - V2ListResultsResponse.builder() - .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .addAction( - V2ListResultsResponse.Action.AuthorizationAction.builder() - .explanation("explanation") - .build() - ) - .authRuleToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .evaluationTime(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - .eventStream(EventStream.AUTHORIZATION) - .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) - .ruleVersion(0L) - .build() + 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) } @@ -59,18 +75,25 @@ internal class AuthRuleV2ListResultsPageResponseTest { val authRuleV2ListResultsPageResponse = AuthRuleV2ListResultsPageResponse.builder() .addData( - V2ListResultsResponse.builder() + V2ListResultsResponse.AuthorizationResult.builder() .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .addAction( - V2ListResultsResponse.Action.AuthorizationAction.builder() + 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(EventStream.AUTHORIZATION) + .eventStream( + V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION + ) .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) .ruleVersion(0L) .build() ) 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 index 4c43d13a..251ecab8 100644 --- 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 @@ -3,71 +3,279 @@ 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 create() { - val v2ListResultsResponse = - V2ListResultsResponse.builder() + fun ofAuthorizationResult() { + val authorizationResult = + V2ListResultsResponse.AuthorizationResult.builder() .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") .addAction( - V2ListResultsResponse.Action.AuthorizationAction.builder() + 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(EventStream.AUTHORIZATION) + .eventStream(V2ListResultsResponse.AuthorizationResult.EventStream.AUTHORIZATION) .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .mode(V2ListResultsResponse.AuthorizationResult.AuthRuleState.ACTIVE) .ruleVersion(0L) .build() - assertThat(v2ListResultsResponse.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(v2ListResultsResponse.actions()) - .containsExactly( - V2ListResultsResponse.Action.ofAuthorization( - V2ListResultsResponse.Action.AuthorizationAction.builder() + 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(v2ListResultsResponse.authRuleToken()) - .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(v2ListResultsResponse.evaluationTime()) - .isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) - assertThat(v2ListResultsResponse.eventStream()).isEqualTo(EventStream.AUTHORIZATION) - assertThat(v2ListResultsResponse.eventToken()) - .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - assertThat(v2ListResultsResponse.mode()) - .isEqualTo(V2ListResultsResponse.AuthRuleState.ACTIVE) - assertThat(v2ListResultsResponse.ruleVersion()).isEqualTo(0L) + + assertThat(roundtrippedV2ListResultsResponse).isEqualTo(v2ListResultsResponse) } @Test - fun roundtrip() { + 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.builder() + 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.Action.AuthorizationAction.builder() + 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(EventStream.AUTHORIZATION) + .eventStream(V2ListResultsResponse.AchResult.EventStream.ACH_CREDIT_RECEIPT) .eventToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") - .mode(V2ListResultsResponse.AuthRuleState.ACTIVE) + .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), @@ -76,4 +284,22 @@ internal class V2ListResultsResponseTest { 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 ") + } } From 0dc4d7ff3e44c45c5d55a952a3f22446bdcb6f48 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 09:02:17 +0000 Subject: [PATCH 14/26] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index d1ffb6fa..c9948bb5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-a4803fcc96eac3196b6763e16264cc1b3292394102f3645a986a575c57d0a290.yml -openapi_spec_hash: 8a62dfde46b1749196575f2879f54d77 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-cf14cb6b172fa5b0674b4d1b9c183c0776bc03e1c71808aa5b655a4302a44940.yml +openapi_spec_hash: 9a72138012f47d97fac1827c5cf4f563 config_hash: 693dddc4721eef512d75ab6c60897794 From a0a4acc37ebbd6a40fc6769855f87e4b2e20ce30 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 15:31:57 +0000 Subject: [PATCH 15/26] feat(api): Add PENDING_REVIEW status to KYB enrollment simulation --- .stats.yml | 4 ++-- .../models/AccountHolderSimulateEnrollmentReviewParams.kt | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index c9948bb5..f3b8b1f2 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-cf14cb6b172fa5b0674b4d1b9c183c0776bc03e1c71808aa5b655a4302a44940.yml -openapi_spec_hash: 9a72138012f47d97fac1827c5cf4f563 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-da8525181ab7cccb66db674dd7243de54b28969c0395223f6dbec3c791f1e7b0.yml +openapi_spec_hash: f4f45e8ca906900f78f1c8aa0233fc20 config_hash: 693dddc4721eef512d75ab6c60897794 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") } From 7796bac615b7324cd9c50bc1c1b35c181d4ffce9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 17:38:36 +0000 Subject: [PATCH 16/26] feat(api): Add hold token field to book transfers --- .stats.yml | 4 +- .../api/models/BookTransferCreateParams.kt | 68 ++++++++++++++++++- .../models/BookTransferCreateParamsTest.kt | 3 + .../async/BookTransferServiceAsyncTest.kt | 1 + .../blocking/BookTransferServiceTest.kt | 1 + 5 files changed, 74 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index f3b8b1f2..7a570288 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-da8525181ab7cccb66db674dd7243de54b28969c0395223f6dbec3c791f1e7b0.yml -openapi_spec_hash: f4f45e8ca906900f78f1c8aa0233fc20 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-f137c504db2dbc70382232b1db7ed592a852bc58068a4e72d5ba7ce724110b3d.yml +openapi_spec_hash: 20abc9c95ee5814da6d7aeccec75e996 config_hash: 693dddc4721eef512d75ab6c60897794 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/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/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/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() From 56b15ffec613c66071c67444273dc8ffd569bce5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:39:18 +0000 Subject: [PATCH 17/26] feat(api): Add network specific wallet recommendation reasons --- .stats.yml | 4 +- ...ConditionalTokenizationActionParameters.kt | 66 ++++++++++++++----- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/.stats.yml b/.stats.yml index 7a570288..d24dcfcc 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-f137c504db2dbc70382232b1db7ed592a852bc58068a4e72d5ba7ce724110b3d.yml -openapi_spec_hash: 20abc9c95ee5814da6d7aeccec75e996 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-8382e530e5b258ec35781d1e167a9a0159bdade6a8fc28e309bdb3eadc0dcdef.yml +openapi_spec_hash: 6489eed734e9c836b16d0c5b4bbce4e4 config_hash: 693dddc4721eef512d75ab6c60897794 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 33a8fc5d..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 @@ -1516,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`, @@ -1640,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`, @@ -1797,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`, From b7d700661fd0c506e43229c04fd12d81cef3505c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:43:43 +0000 Subject: [PATCH 18/26] feat(api): Add amounts object to ASA request --- .stats.yml | 4 +- ...uthorizationApprovalRequestWebhookEvent.kt | 901 +++++++++++++++++- ...rizationApprovalRequestWebhookEventTest.kt | 91 ++ .../api/models/ParsedWebhookEventTest.kt | 63 ++ 4 files changed, 1023 insertions(+), 36 deletions(-) diff --git a/.stats.yml b/.stats.yml index d24dcfcc..5a93d129 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-8382e530e5b258ec35781d1e167a9a0159bdade6a8fc28e309bdb3eadc0dcdef.yml -openapi_spec_hash: 6489eed734e9c836b16d0c5b4bbce4e4 +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/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/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/ParsedWebhookEventTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/ParsedWebhookEventTest.kt index f2c08fec..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 @@ -918,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() @@ -1180,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() From 4b90adc68d18452eaeb38a501097242ce2278c98 Mon Sep 17 00:00:00 2001 From: Mirek Klimos Date: Tue, 17 Feb 2026 14:01:55 +0100 Subject: [PATCH 19/26] Migrate to stadardwebhooks for webhook signature verification --- .../api/services/async/WebhookServiceAsync.kt | 10 -- .../services/async/WebhookServiceAsyncImpl.kt | 4 - .../api/services/blocking/WebhookService.kt | 10 -- .../services/blocking/WebhookServiceImpl.kt | 84 +-------- .../services/async/WebhookServiceAsyncTest.kt | 114 ++++++------ .../services/blocking/WebhookServiceTest.kt | 162 +++++------------- 6 files changed, 105 insertions(+), 279 deletions(-) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt index 77c315ef..407346b2 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/WebhookServiceAsync.kt @@ -4,10 +4,8 @@ package com.lithic.api.services.async import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue -import com.lithic.api.core.UnwrapWebhookParams import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicInvalidDataException -import com.lithic.api.errors.LithicWebhookException import com.lithic.api.models.ParsedWebhookEvent import java.util.function.Consumer @@ -43,14 +41,6 @@ interface WebhookServiceAsync { */ fun parseUnsafe(body: String): ParsedWebhookEvent - /** - * Unwraps a webhook event from its JSON representation. - * - * @throws LithicInvalidDataException if the body could not be parsed. - * @throws LithicWebhookException if the webhook signature could not be verified - */ - fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent - /** * A view of [WebhookServiceAsync] that provides access to raw HTTP responses for each method. */ 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 8493fb3a..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 @@ -5,7 +5,6 @@ package com.lithic.api.services.async import com.fasterxml.jackson.core.JsonProcessingException import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue -import com.lithic.api.core.UnwrapWebhookParams import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicException import com.lithic.api.models.ParsedWebhookEvent @@ -53,9 +52,6 @@ class WebhookServiceAsyncImpl internal constructor(private val clientOptions: Cl override fun parseUnsafe(body: String): ParsedWebhookEvent = WebhookServiceImpl(clientOptions).parseUnsafe(body) - override fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent = - WebhookServiceImpl(clientOptions).parsed(unwrapParams) - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : WebhookServiceAsync.WithRawResponse { diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt index 8d93e620..17e80d0d 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/WebhookService.kt @@ -4,10 +4,8 @@ package com.lithic.api.services.blocking import com.lithic.api.core.ClientOptions import com.lithic.api.core.JsonValue -import com.lithic.api.core.UnwrapWebhookParams import com.lithic.api.core.http.Headers import com.lithic.api.errors.LithicInvalidDataException -import com.lithic.api.errors.LithicWebhookException import com.lithic.api.models.ParsedWebhookEvent import java.util.function.Consumer @@ -43,14 +41,6 @@ interface WebhookService { */ fun parseUnsafe(body: String): ParsedWebhookEvent - /** - * Unwraps a webhook event from its JSON representation. - * - * @throws LithicInvalidDataException if the body could not be parsed. - * @throws LithicWebhookException if the webhook signature could not be verified - */ - fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent - /** A view of [WebhookService] that provides access to raw HTTP responses for each method. */ interface WithRawResponse { 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 3f5800ba..7ac3ef9b 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,23 +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.UnwrapWebhookParams -import com.lithic.api.core.checkRequired -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 com.standardwebhooks.Webhook -import com.standardwebhooks.exceptions.WebhookVerificationException -import java.security.MessageDigest -import java.time.Duration -import java.time.Instant -import java.util.Base64 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) : @@ -54,53 +44,15 @@ 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") } /** @@ -129,28 +81,6 @@ class WebhookServiceImpl internal constructor(private val clientOptions: ClientO throw LithicInvalidDataException("Error parsing body", e) } - override fun parsed(unwrapParams: UnwrapWebhookParams): ParsedWebhookEvent { - val headers = unwrapParams.headers().getOrNull() - if (headers != null) { - try { - val webhookSecret = - checkRequired( - "webhookSecret", - unwrapParams.secret().getOrNull() - ?: clientOptions.webhookSecret().getOrNull(), - ) - val headersMap = - headers.names().associateWith { name -> headers.values(name) }.toMap() - - val webhook = Webhook(webhookSecret) - webhook.verify(unwrapParams.body(), headersMap) - } catch (e: WebhookVerificationException) { - throw LithicWebhookException("Could not verify webhook event signature", e) - } - } - return parsed(unwrapParams.body()) - } - class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : WebhookService.WithRawResponse { 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 index 078239a1..8df088be 100644 --- 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 @@ -2,97 +2,87 @@ package com.lithic.api.services.async -import com.lithic.api.TestServerExtension import com.lithic.api.client.okhttp.LithicOkHttpClientAsync -import com.lithic.api.core.UnwrapWebhookParams 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 -import org.junit.jupiter.api.assertThrows -import org.junit.jupiter.api.extension.ExtendWith -@ExtendWith(TestServerExtension::class) internal class WebhookServiceAsyncTest { + private val webhookSecret = "whsec_c2VjcmV0Cg==" + @Test - fun parsed() { + fun verifySignature() { val client = LithicOkHttpClientAsync.builder() - .baseUrl(TestServerExtension.BASE_URL) - .apiKey("My Lithic API Key") + .apiKey("test-api-key") + .webhookSecret(webhookSecret) .build() - val webhookServiceAsync = client.webhooks() val payload = - "{\"event_type\":\"account_holder.created\",\"token\":\"00000000-0000-0000-0000-000000000001\",\"account_token\":\"00000000-0000-0000-0000-000000000001\",\"created\":\"2019-12-27T18:11:19.117Z\",\"required_documents\":[{\"entity_token\":\"182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e\",\"status_reasons\":[\"string\"],\"valid_documents\":[\"string\"]}],\"status\":\"ACCEPTED\",\"status_reason\":[\"string\"]}" - val webhookSecret = "whsec_c2VjcmV0Cg==" - val messageId = "1" + "{\"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() - .putAll( - mapOf( - "webhook-signature" to listOf(signature), - "webhook-id" to listOf(messageId), - "webhook-timestamp" to listOf(timestampSeconds.toString()), - ) - ) + .put("webhook-id", messageId) + .put("webhook-timestamp", timestampSeconds.toString()) + .put("webhook-signature", signature) .build() - webhookServiceAsync.parsed(payload).validate() + // Valid signature should not throw + assertThatCode { + client.webhooks().verifySignature(payload, headers, null) + } + .doesNotThrowAnyException() // Wrong key should throw - assertThrows { - val wrongKey = "whsec_aaaaaaaaaa" - webhookServiceAsync.parsed( - UnwrapWebhookParams.builder() - .body(payload) - .headers(headers) - .secret(wrongKey) - .build() - ) - } + assertThatThrownBy { + client.webhooks().verifySignature(payload, headers, "whsec_aaaaaaaaaa") + } + .isInstanceOf(LithicWebhookException::class.java) // Bad signature should throw - assertThrows { - val badSig = webhook.sign(messageId, timestampSeconds, "some other payload") - val badHeaders = - headers.toBuilder().replace("webhook-signature", listOf(badSig)).build() - webhookServiceAsync.parsed( - UnwrapWebhookParams.builder() - .body(payload) - .headers(badHeaders) - .secret(webhookSecret) - .build() - ) - } + 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 - assertThrows { - val oldHeaders = headers.toBuilder().replace("webhook-timestamp", listOf("5")).build() - webhookServiceAsync.parsed( - UnwrapWebhookParams.builder() - .body(payload) - .headers(oldHeaders) - .secret(webhookSecret) - .build() - ) - } + assertThatThrownBy { + client + .webhooks() + .verifySignature( + payload, + headers.toBuilder().replace("webhook-timestamp", listOf("5")).build(), + null, + ) + } + .isInstanceOf(LithicWebhookException::class.java) // Wrong message ID should throw - assertThrows { - val wrongIdHeaders = headers.toBuilder().replace("webhook-id", listOf("wrong")).build() - webhookServiceAsync.parsed( - UnwrapWebhookParams.builder() - .body(payload) - .headers(wrongIdHeaders) - .secret(webhookSecret) - .build() - ) - } + 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/blocking/WebhookServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/WebhookServiceTest.kt index e647cb95..56b3636e 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,45 @@ 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, + private val webhookSecret = "whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst" + + private fun signPayload( 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) + 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)) + .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 +52,34 @@ 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)) + .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 +88,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 +106,22 @@ class WebhookServiceTest { Headers.builder() .put("webhook-id", webhookId) .put("webhook-timestamp", futureTimestamp.toString()) - .put("webhook-signature", "v1,$futureSignature") + .put("webhook-signature", 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") + .isInstanceOf(LithicWebhookException::class.java) - // 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") - .build(), - null, - ) - } - .doesNotThrowAnyException() - - // 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 +129,43 @@ 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)) + .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) From 4090241320c1a8deb1fef98244d5813dec537467 Mon Sep 17 00:00:00 2001 From: Mirek Klimos Date: Tue, 17 Feb 2026 14:07:54 +0100 Subject: [PATCH 20/26] fix format --- .../services/blocking/WebhookServiceImpl.kt | 3 +-- .../services/async/WebhookServiceAsyncTest.kt | 9 ++++--- .../services/blocking/WebhookServiceTest.kt | 25 ++++--------------- 3 files changed, 11 insertions(+), 26 deletions(-) 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 7ac3ef9b..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 @@ -45,8 +45,7 @@ class WebhookServiceImpl internal constructor(private val clientOptions: ClientO ) try { - val headersMap = - headers.names().associateWith { name -> headers.values(name) } + val headersMap = headers.names().associateWith { name -> headers.values(name) } val webhook = Webhook(webhookSecret) webhook.verify(payload, headersMap) 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 index 8df088be..66876aec 100644 --- 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 @@ -37,9 +37,7 @@ internal class WebhookServiceAsyncTest { .build() // Valid signature should not throw - assertThatCode { - client.webhooks().verifySignature(payload, headers, null) - } + assertThatCode { client.webhooks().verifySignature(payload, headers, null) } .doesNotThrowAnyException() // Wrong key should throw @@ -55,7 +53,10 @@ internal class WebhookServiceAsyncTest { .webhooks() .verifySignature( payload, - headers.toBuilder().replace("webhook-signature", listOf(badSignature)).build(), + headers + .toBuilder() + .replace("webhook-signature", listOf(badSignature)) + .build(), null, ) } 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 56b3636e..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 @@ -16,11 +16,7 @@ class WebhookServiceTest { private val webhookSecret = "whsec_zlFsbBZ8Xcodlpcu6NDTdSzZRLSdhkst" - private fun signPayload( - msgId: String, - timestamp: Long, - payload: String, - ): String { + private fun signPayload(msgId: String, timestamp: Long, payload: String): String { val webhook = Webhook(webhookSecret) return webhook.sign(msgId, timestamp, payload) } @@ -29,10 +25,7 @@ class WebhookServiceTest { fun unwrap() { val timestamp = Instant.now().epochSecond val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret(webhookSecret) - .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\"}}}" @@ -54,10 +47,7 @@ class WebhookServiceTest { fun verifySignature() { val timestamp = Instant.now().epochSecond val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret(webhookSecret) - .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\"}}}" @@ -72,9 +62,7 @@ class WebhookServiceTest { .build() // Valid signature should not throw - assertThatCode { - client.webhooks().verifySignature(payload, headers, null) - } + assertThatCode { client.webhooks().verifySignature(payload, headers, null) } .doesNotThrowAnyException() // Timestamp too old (> 5 minutes) @@ -153,10 +141,7 @@ class WebhookServiceTest { fun parse() { val timestamp = Instant.now().epochSecond val client = - LithicOkHttpClient.builder() - .apiKey("test-api-key") - .webhookSecret(webhookSecret) - .build() + LithicOkHttpClient.builder().apiKey("test-api-key").webhookSecret(webhookSecret).build() val payload = """{"card_token":"card_Ao6kQgjenC6H2bSd","event_type":"card.created"}""" val msgId = "msg_2Lh9KRb0pzN4LePd3XiA4v12Axj" From 1d44ad909ecfd24ab000cfcd3db3874bcf18e97e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:59:24 +0000 Subject: [PATCH 21/26] chore(internal): update `TestServerExtension` comment --- .../com/lithic/api/TestServerExtension.kt | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) 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, From 2146e4bb9d84df595bcc204ca589f6a0e861dff8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:18:37 +0000 Subject: [PATCH 22/26] chore(internal): remove unnecessary base URL From 92d0d62f76d7eac438e901813dbce1fcf32c22fc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:47:14 +0000 Subject: [PATCH 23/26] chore(internal): make `OkHttp` constructor internal --- .../main/kotlin/com/lithic/api/client/okhttp/OkHttpClient.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..23c0b1c1 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 @@ -33,7 +33,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) From 41826de4dac92b85774ea9dcdb754a1bb58ada93 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 22:02:04 +0000 Subject: [PATCH 24/26] feat(client): add more convenience service method overloads --- .../async/AccountHolderServiceAsync.kt | 121 +++++++++++++ .../async/ExternalBankAccountServiceAsync.kt | 127 ++++++++++++++ .../async/authRules/V2ServiceAsync.kt | 98 +++++++++++ .../services/blocking/AccountHolderService.kt | 125 ++++++++++++++ .../blocking/ExternalBankAccountService.kt | 131 ++++++++++++++ .../services/blocking/authRules/V2Service.kt | 96 +++++++++++ .../async/AccountHolderServiceAsyncTest.kt | 161 +++++++++--------- .../ExternalBankAccountServiceAsyncTest.kt | 61 +++---- .../async/authRules/V2ServiceAsyncTest.kt | 35 ++-- .../blocking/AccountHolderServiceTest.kt | 161 +++++++++--------- .../ExternalBankAccountServiceTest.kt | 61 +++---- .../blocking/authRules/V2ServiceTest.kt | 35 ++-- 12 files changed, 940 insertions(+), 272 deletions(-) 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 fdd12ea8..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 @@ -49,6 +49,69 @@ interface ExternalBankAccountServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture + /** @see create */ + fun create( + 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( + 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(unverified, RequestOptions.none()) + /** Get the external bank account by token. */ fun retrieve( externalBankAccountToken: String @@ -321,6 +384,70 @@ interface ExternalBankAccountServiceAsync { requestOptions: RequestOptions = RequestOptions.none(), ): CompletableFuture> + /** @see create */ + fun create( + 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( + 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(unverified, RequestOptions.none()) + /** * Returns a raw HTTP response for `get * /v1/external_bank_accounts/{external_bank_account_token}`, but is otherwise the same as 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 07174ba4..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 @@ -51,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()) @@ -376,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]. 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 edb88351..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 @@ -48,6 +48,66 @@ interface ExternalBankAccountService { requestOptions: RequestOptions = RequestOptions.none(), ): ExternalBankAccountCreateResponse + /** @see create */ + fun create( + 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( + 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 = retrieve(externalBankAccountToken, ExternalBankAccountRetrieveParams.none()) @@ -311,6 +371,77 @@ interface ExternalBankAccountService { requestOptions: RequestOptions = RequestOptions.none(), ): HttpResponseFor + /** @see create */ + @MustBeClosed + fun create( + body: ExternalBankAccountCreateParams.Body, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + 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( + unverified: ExternalBankAccountCreateParams.Body.UnverifiedCreateBankAccountApiRequest + ): HttpResponseFor = + create(unverified, RequestOptions.none()) + /** * Returns a raw HTTP response for `get * /v1/external_bank_accounts/{external_bank_account_token}`, but is otherwise the same as 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 b8ae5450..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 @@ -50,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()) @@ -350,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]. 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 cde7d409..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,98 +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") - .naicsCode("541512") - .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() ) 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/authRules/V2ServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/authRules/V2ServiceAsyncTest.kt index 84c9a0d4..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() ) 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 e4a902fc..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,98 +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") - .naicsCode("541512") - .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() ) 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/authRules/V2ServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/authRules/V2ServiceTest.kt index 4bc38503..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() ) From 2b5bf16839b77bd880a73a2c4211176accc27864 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 23:04:26 +0000 Subject: [PATCH 25/26] feat(client): add connection pooling option --- README.md | 19 ++++++++ .../api/client/okhttp/LithicOkHttpClient.kt | 44 +++++++++++++++++++ .../client/okhttp/LithicOkHttpClientAsync.kt | 44 +++++++++++++++++++ .../lithic/api/client/okhttp/OkHttpClient.kt | 42 ++++++++++++++++++ 4 files changed, 149 insertions(+) diff --git a/README.md b/README.md index d6195437..00ea2234 100644 --- a/README.md +++ b/README.md @@ -500,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/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 23c0b1c1..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 @@ -200,6 +202,8 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie 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 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie 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 @@ internal constructor(@JvmSynthetic internal val okHttpClient: okhttp3.OkHttpClie .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) { From 71377d6dc486788f9247c80a9d8c382125b53078 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 23:04:59 +0000 Subject: [PATCH 26/26] release: 0.117.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 40 +++++++++++++++++++++++++++++++++++ README.md | 10 ++++----- build.gradle.kts | 2 +- 4 files changed, 47 insertions(+), 7 deletions(-) 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/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 00ea2234..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) @@ -22,7 +22,7 @@ Use the Lithic MCP Server to enable AI assistants to interact with this API, all -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). @@ -33,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 @@ -42,7 +42,7 @@ implementation("com.lithic.api:lithic-java:0.116.0") com.lithic.api lithic-java - 0.116.0 + 0.117.0 ``` 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 {