Skip to content

Commit 7b190ef

Browse files
feat: add network tokens and 3ds co-badged cards props
Co-authored-by: fern-api <115122769+fern-api[bot]@users.noreply.github.com>
1 parent c161fb7 commit 7b190ef

8 files changed

Lines changed: 392 additions & 0 deletions

File tree

src/main/java/com/basistheory/resources/networktokens/AsyncNetworkTokensClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.basistheory.core.ClientOptions;
77
import com.basistheory.core.RequestOptions;
8+
import com.basistheory.types.NetworkTokenCryptogram;
89
import java.util.concurrent.CompletableFuture;
910

1011
public class AsyncNetworkTokensClient {
@@ -31,4 +32,12 @@ public CompletableFuture<Void> create() {
3132
public CompletableFuture<Void> create(RequestOptions requestOptions) {
3233
return this.rawClient.create(requestOptions).thenApply(response -> response.body());
3334
}
35+
36+
public CompletableFuture<NetworkTokenCryptogram> cryptogram(String id) {
37+
return this.rawClient.cryptogram(id).thenApply(response -> response.body());
38+
}
39+
40+
public CompletableFuture<NetworkTokenCryptogram> cryptogram(String id, RequestOptions requestOptions) {
41+
return this.rawClient.cryptogram(id, requestOptions).thenApply(response -> response.body());
42+
}
3443
}

src/main/java/com/basistheory/resources/networktokens/AsyncRawNetworkTokensClient.java

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
import com.basistheory.core.ClientOptions;
1010
import com.basistheory.core.ObjectMappers;
1111
import com.basistheory.core.RequestOptions;
12+
import com.basistheory.errors.BadRequestError;
13+
import com.basistheory.errors.ForbiddenError;
14+
import com.basistheory.errors.InternalServerError;
15+
import com.basistheory.errors.NotFoundError;
16+
import com.basistheory.errors.UnauthorizedError;
17+
import com.basistheory.types.NetworkTokenCryptogram;
18+
import com.basistheory.types.ProblemDetails;
19+
import com.basistheory.types.ValidationProblemDetails;
20+
import com.fasterxml.jackson.core.JsonProcessingException;
1221
import java.io.IOException;
1322
import java.util.concurrent.CompletableFuture;
1423
import okhttp3.Call;
@@ -75,4 +84,91 @@ public void onFailure(@NotNull Call call, @NotNull IOException e) {
7584
});
7685
return future;
7786
}
87+
88+
public CompletableFuture<BasisTheoryApiHttpResponse<NetworkTokenCryptogram>> cryptogram(String id) {
89+
return cryptogram(id, null);
90+
}
91+
92+
public CompletableFuture<BasisTheoryApiHttpResponse<NetworkTokenCryptogram>> cryptogram(
93+
String id, RequestOptions requestOptions) {
94+
HttpUrl httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
95+
.newBuilder()
96+
.addPathSegments("network-tokens")
97+
.addPathSegment(id)
98+
.addPathSegments("cryptogram")
99+
.build();
100+
Request okhttpRequest = new Request.Builder()
101+
.url(httpUrl)
102+
.method("POST", RequestBody.create("", null))
103+
.headers(Headers.of(clientOptions.headers(requestOptions)))
104+
.addHeader("Content-Type", "application/json")
105+
.addHeader("Accept", "application/json")
106+
.build();
107+
OkHttpClient client = clientOptions.httpClient();
108+
if (requestOptions != null && requestOptions.getTimeout().isPresent()) {
109+
client = clientOptions.httpClientWithTimeout(requestOptions);
110+
}
111+
CompletableFuture<BasisTheoryApiHttpResponse<NetworkTokenCryptogram>> future = new CompletableFuture<>();
112+
client.newCall(okhttpRequest).enqueue(new Callback() {
113+
@Override
114+
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
115+
try (ResponseBody responseBody = response.body()) {
116+
if (response.isSuccessful()) {
117+
future.complete(new BasisTheoryApiHttpResponse<>(
118+
ObjectMappers.JSON_MAPPER.readValue(
119+
responseBody.string(), NetworkTokenCryptogram.class),
120+
response));
121+
return;
122+
}
123+
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
124+
try {
125+
switch (response.code()) {
126+
case 400:
127+
future.completeExceptionally(new BadRequestError(
128+
ObjectMappers.JSON_MAPPER.readValue(
129+
responseBodyString, ValidationProblemDetails.class),
130+
response));
131+
return;
132+
case 401:
133+
future.completeExceptionally(new UnauthorizedError(
134+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ProblemDetails.class),
135+
response));
136+
return;
137+
case 403:
138+
future.completeExceptionally(new ForbiddenError(
139+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ProblemDetails.class),
140+
response));
141+
return;
142+
case 404:
143+
future.completeExceptionally(new NotFoundError(
144+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
145+
response));
146+
return;
147+
case 500:
148+
future.completeExceptionally(new InternalServerError(
149+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ProblemDetails.class),
150+
response));
151+
return;
152+
}
153+
} catch (JsonProcessingException ignored) {
154+
// unable to map error response, throwing generic error
155+
}
156+
future.completeExceptionally(new BasisTheoryApiApiException(
157+
"Error with status code " + response.code(),
158+
response.code(),
159+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
160+
response));
161+
return;
162+
} catch (IOException e) {
163+
future.completeExceptionally(new BasisTheoryException("Network error executing HTTP request", e));
164+
}
165+
}
166+
167+
@Override
168+
public void onFailure(@NotNull Call call, @NotNull IOException e) {
169+
future.completeExceptionally(new BasisTheoryException("Network error executing HTTP request", e));
170+
}
171+
});
172+
return future;
173+
}
78174
}

src/main/java/com/basistheory/resources/networktokens/NetworkTokensClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import com.basistheory.core.ClientOptions;
77
import com.basistheory.core.RequestOptions;
8+
import com.basistheory.types.NetworkTokenCryptogram;
89

910
public class NetworkTokensClient {
1011
protected final ClientOptions clientOptions;
@@ -30,4 +31,12 @@ public void create() {
3031
public void create(RequestOptions requestOptions) {
3132
this.rawClient.create(requestOptions).body();
3233
}
34+
35+
public NetworkTokenCryptogram cryptogram(String id) {
36+
return this.rawClient.cryptogram(id).body();
37+
}
38+
39+
public NetworkTokenCryptogram cryptogram(String id, RequestOptions requestOptions) {
40+
return this.rawClient.cryptogram(id, requestOptions).body();
41+
}
3342
}

src/main/java/com/basistheory/resources/networktokens/RawNetworkTokensClient.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
import com.basistheory.core.ClientOptions;
1010
import com.basistheory.core.ObjectMappers;
1111
import com.basistheory.core.RequestOptions;
12+
import com.basistheory.errors.BadRequestError;
13+
import com.basistheory.errors.ForbiddenError;
14+
import com.basistheory.errors.InternalServerError;
15+
import com.basistheory.errors.NotFoundError;
16+
import com.basistheory.errors.UnauthorizedError;
17+
import com.basistheory.types.NetworkTokenCryptogram;
18+
import com.basistheory.types.ProblemDetails;
19+
import com.basistheory.types.ValidationProblemDetails;
20+
import com.fasterxml.jackson.core.JsonProcessingException;
1221
import java.io.IOException;
1322
import okhttp3.Headers;
1423
import okhttp3.HttpUrl;
@@ -58,4 +67,69 @@ public BasisTheoryApiHttpResponse<Void> create(RequestOptions requestOptions) {
5867
throw new BasisTheoryException("Network error executing HTTP request", e);
5968
}
6069
}
70+
71+
public BasisTheoryApiHttpResponse<NetworkTokenCryptogram> cryptogram(String id) {
72+
return cryptogram(id, null);
73+
}
74+
75+
public BasisTheoryApiHttpResponse<NetworkTokenCryptogram> cryptogram(String id, RequestOptions requestOptions) {
76+
HttpUrl httpUrl = HttpUrl.parse(this.clientOptions.environment().getUrl())
77+
.newBuilder()
78+
.addPathSegments("network-tokens")
79+
.addPathSegment(id)
80+
.addPathSegments("cryptogram")
81+
.build();
82+
Request okhttpRequest = new Request.Builder()
83+
.url(httpUrl)
84+
.method("POST", RequestBody.create("", null))
85+
.headers(Headers.of(clientOptions.headers(requestOptions)))
86+
.addHeader("Content-Type", "application/json")
87+
.addHeader("Accept", "application/json")
88+
.build();
89+
OkHttpClient client = clientOptions.httpClient();
90+
if (requestOptions != null && requestOptions.getTimeout().isPresent()) {
91+
client = clientOptions.httpClientWithTimeout(requestOptions);
92+
}
93+
try (Response response = client.newCall(okhttpRequest).execute()) {
94+
ResponseBody responseBody = response.body();
95+
if (response.isSuccessful()) {
96+
return new BasisTheoryApiHttpResponse<>(
97+
ObjectMappers.JSON_MAPPER.readValue(responseBody.string(), NetworkTokenCryptogram.class),
98+
response);
99+
}
100+
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
101+
try {
102+
switch (response.code()) {
103+
case 400:
104+
throw new BadRequestError(
105+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ValidationProblemDetails.class),
106+
response);
107+
case 401:
108+
throw new UnauthorizedError(
109+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ProblemDetails.class),
110+
response);
111+
case 403:
112+
throw new ForbiddenError(
113+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ProblemDetails.class),
114+
response);
115+
case 404:
116+
throw new NotFoundError(
117+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response);
118+
case 500:
119+
throw new InternalServerError(
120+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ProblemDetails.class),
121+
response);
122+
}
123+
} catch (JsonProcessingException ignored) {
124+
// unable to map error response, throwing generic error
125+
}
126+
throw new BasisTheoryApiApiException(
127+
"Error with status code " + response.code(),
128+
response.code(),
129+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
130+
response);
131+
} catch (IOException e) {
132+
throw new BasisTheoryException("Network error executing HTTP request", e);
133+
}
134+
}
61135
}

src/main/java/com/basistheory/resources/threeds/sessions/requests/AuthenticateThreeDsSessionRequest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public final class AuthenticateThreeDsSessionRequest {
3131

3232
private final String authenticationType;
3333

34+
private final Optional<String> cardBrand;
35+
3436
private final Optional<String> challengePreference;
3537

3638
private final Optional<Boolean> requestDecoupledChallenge;
@@ -54,6 +56,7 @@ public final class AuthenticateThreeDsSessionRequest {
5456
private AuthenticateThreeDsSessionRequest(
5557
String authenticationCategory,
5658
String authenticationType,
59+
Optional<String> cardBrand,
5760
Optional<String> challengePreference,
5861
Optional<Boolean> requestDecoupledChallenge,
5962
Optional<Integer> decoupledChallengeMaxTime,
@@ -66,6 +69,7 @@ private AuthenticateThreeDsSessionRequest(
6669
Map<String, Object> additionalProperties) {
6770
this.authenticationCategory = authenticationCategory;
6871
this.authenticationType = authenticationType;
72+
this.cardBrand = cardBrand;
6973
this.challengePreference = challengePreference;
7074
this.requestDecoupledChallenge = requestDecoupledChallenge;
7175
this.decoupledChallengeMaxTime = decoupledChallengeMaxTime;
@@ -88,6 +92,11 @@ public String getAuthenticationType() {
8892
return authenticationType;
8993
}
9094

95+
@JsonProperty("card_brand")
96+
public Optional<String> getCardBrand() {
97+
return cardBrand;
98+
}
99+
91100
@JsonProperty("challenge_preference")
92101
public Optional<String> getChallengePreference() {
93102
return challengePreference;
@@ -147,6 +156,7 @@ public Map<String, Object> getAdditionalProperties() {
147156
private boolean equalTo(AuthenticateThreeDsSessionRequest other) {
148157
return authenticationCategory.equals(other.authenticationCategory)
149158
&& authenticationType.equals(other.authenticationType)
159+
&& cardBrand.equals(other.cardBrand)
150160
&& challengePreference.equals(other.challengePreference)
151161
&& requestDecoupledChallenge.equals(other.requestDecoupledChallenge)
152162
&& decoupledChallengeMaxTime.equals(other.decoupledChallengeMaxTime)
@@ -163,6 +173,7 @@ public int hashCode() {
163173
return Objects.hash(
164174
this.authenticationCategory,
165175
this.authenticationType,
176+
this.cardBrand,
166177
this.challengePreference,
167178
this.requestDecoupledChallenge,
168179
this.decoupledChallengeMaxTime,
@@ -196,6 +207,10 @@ public interface AuthenticationTypeStage {
196207
public interface _FinalStage {
197208
AuthenticateThreeDsSessionRequest build();
198209

210+
_FinalStage cardBrand(Optional<String> cardBrand);
211+
212+
_FinalStage cardBrand(String cardBrand);
213+
199214
_FinalStage challengePreference(Optional<String> challengePreference);
200215

201216
_FinalStage challengePreference(String challengePreference);
@@ -257,6 +272,8 @@ public static final class Builder implements AuthenticationCategoryStage, Authen
257272

258273
private Optional<String> challengePreference = Optional.empty();
259274

275+
private Optional<String> cardBrand = Optional.empty();
276+
260277
@JsonAnySetter
261278
private Map<String, Object> additionalProperties = new HashMap<>();
262279

@@ -266,6 +283,7 @@ private Builder() {}
266283
public Builder from(AuthenticateThreeDsSessionRequest other) {
267284
authenticationCategory(other.getAuthenticationCategory());
268285
authenticationType(other.getAuthenticationType());
286+
cardBrand(other.getCardBrand());
269287
challengePreference(other.getChallengePreference());
270288
requestDecoupledChallenge(other.getRequestDecoupledChallenge());
271289
decoupledChallengeMaxTime(other.getDecoupledChallengeMaxTime());
@@ -410,11 +428,25 @@ public _FinalStage challengePreference(Optional<String> challengePreference) {
410428
return this;
411429
}
412430

431+
@java.lang.Override
432+
public _FinalStage cardBrand(String cardBrand) {
433+
this.cardBrand = Optional.ofNullable(cardBrand);
434+
return this;
435+
}
436+
437+
@java.lang.Override
438+
@JsonSetter(value = "card_brand", nulls = Nulls.SKIP)
439+
public _FinalStage cardBrand(Optional<String> cardBrand) {
440+
this.cardBrand = cardBrand;
441+
return this;
442+
}
443+
413444
@java.lang.Override
414445
public AuthenticateThreeDsSessionRequest build() {
415446
return new AuthenticateThreeDsSessionRequest(
416447
authenticationCategory,
417448
authenticationType,
449+
cardBrand,
418450
challengePreference,
419451
requestDecoupledChallenge,
420452
decoupledChallengeMaxTime,

0 commit comments

Comments
 (0)