Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.96.1"
".": "0.97.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 167
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-b9c76d077831114f1e4c5c15ff3f1d835ef3e9361b768af8468f8eb07a09ef3e.yml
openapi_spec_hash: 5f9bcf1afd68f962a870727c35628394
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-54e6f7955e86265bc870eaae7f4a9cd716292457a83e032567f22bbb9ce6ad0d.yml
openapi_spec_hash: 6adbff5e5aeda88504047fc2c87e3fa0
config_hash: e9a46eb8acb9dc2c236f3e1958a1c4dd
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 0.97.0 (2025-07-23)

Full Changelog: [v0.96.1...v0.97.0](https://github.com/lithic-com/lithic-java/compare/v0.96.1...v0.97.0)

### Features

* **api:** adds new Auth Rules Scope and Settlement Details type ([b94bfc2](https://github.com/lithic-com/lithic-java/commit/b94bfc2ecef5a07742f4f0e0bf36ccd8e38c2b9f))
* **client:** add `{QueryParams,Headers}#put(String, JsonValue)` methods ([ef6b26e](https://github.com/lithic-com/lithic-java/commit/ef6b26ea48e9ceca26ae7e4da2805bce7b99d363))
* **client:** add https config options ([ac2c55c](https://github.com/lithic-com/lithic-java/commit/ac2c55c13ad7fd93a14e5e64cb8acc548ad84c63))
* **client:** allow configuring env via system properties ([3b78f9e](https://github.com/lithic-com/lithic-java/commit/3b78f9e12ba76f1422339640ca3bac21eafa408d))


### Chores

* **docs:** update Account Holder deprecation formatting ([12496f2](https://github.com/lithic-com/lithic-java/commit/12496f2edfff93ed6a1bbfc72ecba34acf85365f))
* **internal:** refactor delegating from client to options ([f165926](https://github.com/lithic-com/lithic-java/commit/f165926b1e58f6119241fe908915d86de6161d8f))


### Documentation

* fix missing readme comment ([f1d5068](https://github.com/lithic-com/lithic-java/commit/f1d50687540c2435b14e058007f7bbbfb8025613))

## 0.96.1 (2025-07-18)

Full Changelog: [v0.96.0...v0.96.1](https://github.com/lithic-com/lithic-java/compare/v0.96.0...v0.96.1)
Expand Down
60 changes: 44 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<!-- x-release-please-start-version -->

[![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.96.1)
[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.96.1/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.96.1)
[![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.97.0)
[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.97.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.97.0)

<!-- x-release-please-end -->

Expand All @@ -13,7 +13,7 @@ The Lithic Java SDK is similar to the Lithic Kotlin SDK but with minor differenc

<!-- x-release-please-start-version -->

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.96.1).
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.97.0).

<!-- x-release-please-end -->

Expand All @@ -24,7 +24,7 @@ The REST API documentation can be found on [docs.lithic.com](https://docs.lithic
### Gradle

```kotlin
implementation("com.lithic.api:lithic-java:0.96.1")
implementation("com.lithic.api:lithic-java:0.97.0")
```

### Maven
Expand All @@ -33,7 +33,7 @@ implementation("com.lithic.api:lithic-java:0.96.1")
<dependency>
<groupId>com.lithic.api</groupId>
<artifactId>lithic-java</artifactId>
<version>0.96.1</version>
<version>0.97.0</version>
</dependency>
```

Expand All @@ -51,7 +51,8 @@ import com.lithic.api.client.okhttp.LithicOkHttpClient;
import com.lithic.api.models.Card;
import com.lithic.api.models.CardCreateParams;

// Configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
// Configures using the `lithic.apiKey`, `lithic.webhookSecret` and `lithic.baseUrl` system properties
// Or configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
LithicClient client = LithicOkHttpClient.fromEnv();

CardCreateParams params = CardCreateParams.builder()
Expand All @@ -62,13 +63,14 @@ Card card = client.cards().create(params);

## Client configuration

Configure the client using environment variables:
Configure the client using system properties or environment variables:

```java
import com.lithic.api.client.LithicClient;
import com.lithic.api.client.okhttp.LithicOkHttpClient;

// Configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
// Configures using the `lithic.apiKey`, `lithic.webhookSecret` and `lithic.baseUrl` system properties
// Or configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
LithicClient client = LithicOkHttpClient.fromEnv();
```

Expand All @@ -90,19 +92,22 @@ import com.lithic.api.client.LithicClient;
import com.lithic.api.client.okhttp.LithicOkHttpClient;

LithicClient client = LithicOkHttpClient.builder()
// Configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
// Configures using the `lithic.apiKey`, `lithic.webhookSecret` and `lithic.baseUrl` system properties
// Or configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
.fromEnv()
.apiKey("My Lithic API Key")
.build();
```

See this table for the available options:

| Setter | Environment variable | Required | Default value |
| --------------- | ----------------------- | -------- | -------------------------- |
| `apiKey` | `LITHIC_API_KEY` | true | - |
| `webhookSecret` | `LITHIC_WEBHOOK_SECRET` | false | - |
| `baseUrl` | `LITHIC_BASE_URL` | true | `"https://api.lithic.com"` |
| Setter | System property | Environment variable | Required | Default value |
| --------------- | ---------------------- | ----------------------- | -------- | -------------------------- |
| `apiKey` | `lithic.apiKey` | `LITHIC_API_KEY` | true | - |
| `webhookSecret` | `lithic.webhookSecret` | `LITHIC_WEBHOOK_SECRET` | false | - |
| `baseUrl` | `lithic.baseUrl` | `LITHIC_BASE_URL` | true | `"https://api.lithic.com"` |

System properties take precedence over environment variables.

> [!TIP]
> Don't create more than one client in the same application. Each client has a connection pool and
Expand Down Expand Up @@ -148,7 +153,8 @@ import com.lithic.api.models.Card;
import com.lithic.api.models.CardCreateParams;
import java.util.concurrent.CompletableFuture;

// Configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
// Configures using the `lithic.apiKey`, `lithic.webhookSecret` and `lithic.baseUrl` system properties
// Or configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
LithicClient client = LithicOkHttpClient.fromEnv();

CardCreateParams params = CardCreateParams.builder()
Expand All @@ -166,7 +172,8 @@ import com.lithic.api.models.Card;
import com.lithic.api.models.CardCreateParams;
import java.util.concurrent.CompletableFuture;

// Configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
// Configures using the `lithic.apiKey`, `lithic.webhookSecret` and `lithic.baseUrl` system properties
// Or configures using the `LITHIC_API_KEY`, `LITHIC_WEBHOOK_SECRET` and `LITHIC_BASE_URL` environment variables
LithicClientAsync client = LithicOkHttpClientAsync.fromEnv();

CardCreateParams params = CardCreateParams.builder()
Expand Down Expand Up @@ -441,6 +448,27 @@ LithicClient client = LithicOkHttpClient.builder()
.build();
```

### HTTPS

> [!NOTE]
> Most applications should not call these methods, and instead use the system defaults. The defaults include
> special optimizations that can be lost if the implementations are modified.

To configure how HTTPS connections are secured, configure the client using the `sslSocketFactory`, `trustManager`, and `hostnameVerifier` methods:

```java
import com.lithic.api.client.LithicClient;
import com.lithic.api.client.okhttp.LithicOkHttpClient;

LithicClient client = LithicOkHttpClient.builder()
.fromEnv()
// If `sslSocketFactory` is set, then `trustManager` must be set, and vice versa.
.sslSocketFactory(yourSSLSocketFactory)
.trustManager(yourTrustManager)
.hostnameVerifier(yourHostnameVerifier)
.build();
```

### Environments

The SDK sends requests to the production by default. To send requests to a different environment, configure the client like so:
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repositories {

allprojects {
group = "com.lithic.api"
version = "0.96.1" // x-release-please-version
version = "0.97.0" // x-release-please-version
}

subprojects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@ import com.lithic.api.core.ClientOptions
import com.lithic.api.core.Timeout
import com.lithic.api.core.http.Headers
import com.lithic.api.core.http.QueryParams
import com.lithic.api.core.jsonMapper
import java.net.Proxy
import java.time.Clock
import java.time.Duration
import java.util.Optional
import java.util.concurrent.Executor
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager
import kotlin.jvm.optionals.getOrNull

class LithicOkHttpClient private constructor() {
Expand All @@ -30,12 +34,63 @@ class LithicOkHttpClient private constructor() {
class Builder internal constructor() {

private var clientOptions: ClientOptions.Builder = ClientOptions.builder()
private var timeout: Timeout = Timeout.default()
private var proxy: Proxy? = null
private var sslSocketFactory: SSLSocketFactory? = null
private var trustManager: X509TrustManager? = null
private var hostnameVerifier: HostnameVerifier? = null

fun sandbox() = apply { baseUrl(ClientOptions.SANDBOX_URL) }
fun proxy(proxy: Proxy?) = apply { this.proxy = proxy }

fun baseUrl(baseUrl: String) = apply { clientOptions.baseUrl(baseUrl) }
/** Alias for calling [Builder.proxy] with `proxy.orElse(null)`. */
fun proxy(proxy: Optional<Proxy>) = proxy(proxy.getOrNull())

/**
* The socket factory used to secure HTTPS connections.
*
* If this is set, then [trustManager] must also be set.
*
* If unset, then the system default is used. Most applications should not call this method,
* and instead use the system default. The default include special optimizations that can be
* lost if the implementation is modified.
*/
fun sslSocketFactory(sslSocketFactory: SSLSocketFactory?) = apply {
this.sslSocketFactory = sslSocketFactory
}

/** Alias for calling [Builder.sslSocketFactory] with `sslSocketFactory.orElse(null)`. */
fun sslSocketFactory(sslSocketFactory: Optional<SSLSocketFactory>) =
sslSocketFactory(sslSocketFactory.getOrNull())

/**
* The trust manager used to secure HTTPS connections.
*
* If this is set, then [sslSocketFactory] must also be set.
*
* If unset, then the system default is used. Most applications should not call this method,
* and instead use the system default. The default include special optimizations that can be
* lost if the implementation is modified.
*/
fun trustManager(trustManager: X509TrustManager?) = apply {
this.trustManager = trustManager
}

/** Alias for calling [Builder.trustManager] with `trustManager.orElse(null)`. */
fun trustManager(trustManager: Optional<X509TrustManager>) =
trustManager(trustManager.getOrNull())

/**
* The verifier used to confirm that response certificates apply to requested hostnames for
* HTTPS connections.
*
* If unset, then a default hostname verifier is used.
*/
fun hostnameVerifier(hostnameVerifier: HostnameVerifier?) = apply {
this.hostnameVerifier = hostnameVerifier
}

/** Alias for calling [Builder.hostnameVerifier] with `hostnameVerifier.orElse(null)`. */
fun hostnameVerifier(hostnameVerifier: Optional<HostnameVerifier>) =
hostnameVerifier(hostnameVerifier.getOrNull())

/**
* Whether to throw an exception if any of the Jackson versions detected at runtime are
Expand All @@ -56,6 +111,40 @@ class LithicOkHttpClient private constructor() {

fun clock(clock: Clock) = apply { clientOptions.clock(clock) }

fun baseUrl(baseUrl: String?) = apply { clientOptions.baseUrl(baseUrl) }

/** Alias for calling [Builder.baseUrl] with `baseUrl.orElse(null)`. */
fun baseUrl(baseUrl: Optional<String>) = baseUrl(baseUrl.getOrNull())

fun sandbox() = apply { clientOptions.sandbox() }

fun responseValidation(responseValidation: Boolean) = apply {
clientOptions.responseValidation(responseValidation)
}

fun timeout(timeout: Timeout) = apply { clientOptions.timeout(timeout) }

/**
* Sets the maximum time allowed for a complete HTTP call, not including retries.
*
* See [Timeout.request] for more details.
*
* For fine-grained control, pass a [Timeout] object.
*/
fun timeout(timeout: Duration) = apply { clientOptions.timeout(timeout) }

fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }

fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) }

fun webhookSecret(webhookSecret: String?) = apply {
clientOptions.webhookSecret(webhookSecret)
}

/** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */
fun webhookSecret(webhookSecret: Optional<String>) =
webhookSecret(webhookSecret.getOrNull())

fun headers(headers: Headers) = apply { clientOptions.headers(headers) }

fun headers(headers: Map<String, Iterable<String>>) = apply {
Expand Down Expand Up @@ -136,38 +225,6 @@ class LithicOkHttpClient private constructor() {
clientOptions.removeAllQueryParams(keys)
}

fun timeout(timeout: Timeout) = apply {
clientOptions.timeout(timeout)
this.timeout = timeout
}

/**
* Sets the maximum time allowed for a complete HTTP call, not including retries.
*
* See [Timeout.request] for more details.
*
* For fine-grained control, pass a [Timeout] object.
*/
fun timeout(timeout: Duration) = timeout(Timeout.builder().request(timeout).build())

fun maxRetries(maxRetries: Int) = apply { clientOptions.maxRetries(maxRetries) }

fun proxy(proxy: Proxy) = apply { this.proxy = proxy }

fun responseValidation(responseValidation: Boolean) = apply {
clientOptions.responseValidation(responseValidation)
}

fun apiKey(apiKey: String) = apply { clientOptions.apiKey(apiKey) }

fun webhookSecret(webhookSecret: String?) = apply {
clientOptions.webhookSecret(webhookSecret)
}

/** Alias for calling [Builder.webhookSecret] with `webhookSecret.orElse(null)`. */
fun webhookSecret(webhookSecret: Optional<String>) =
webhookSecret(webhookSecret.getOrNull())

fun fromEnv() = apply { clientOptions.fromEnv() }

/**
Expand All @@ -178,7 +235,15 @@ class LithicOkHttpClient private constructor() {
fun build(): LithicClient =
LithicClientImpl(
clientOptions
.httpClient(OkHttpClient.builder().timeout(timeout).proxy(proxy).build())
.httpClient(
OkHttpClient.builder()
.timeout(clientOptions.timeout())
.proxy(proxy)
.sslSocketFactory(sslSocketFactory)
.trustManager(trustManager)
.hostnameVerifier(hostnameVerifier)
.build()
)
.build()
)
}
Expand Down
Loading