Skip to content
Closed
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
3 changes: 2 additions & 1 deletion src/main/java/com/stripe/model/v2/core/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.stripe.model.HasId;
import com.stripe.model.StripeObject;
import com.stripe.v2.Amount;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -5345,7 +5346,7 @@ public static class Relationship extends StripeObject {

/** The percentage of the Account's identity that the individual owns. */
@SerializedName("percent_ownership")
String percentOwnership;
BigDecimal percentOwnership;

/**
* Whether the individual is authorized as the primary representative of the Account. This
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/stripe/model/v2/core/AccountPerson.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.annotations.SerializedName;
import com.stripe.model.HasId;
import com.stripe.model.StripeObject;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -584,7 +585,7 @@ public static class Relationship extends StripeObject {

/** The percentage of the Account's identity that the individual owns. */
@SerializedName("percent_ownership")
String percentOwnership;
BigDecimal percentOwnership;

/**
* Whether the individual is authorized as the primary representative of the Account. This is
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/stripe/net/JsonEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,42 @@
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

final class JsonEncoder {
/**
* Serializes BigDecimal as a JSON string (e.g., "25.5") rather than a JSON number (25.5). All
* BigDecimal fields in the Stripe API use format: decimal, and the V2 API expects them as strings
* on the wire.
*/
private static final TypeAdapter<BigDecimal> BIG_DECIMAL_STRING_ADAPTER =
new TypeAdapter<BigDecimal>() {
@Override
public void write(JsonWriter out, BigDecimal value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(value.toPlainString());
}
}

@Override
public BigDecimal read(JsonReader in) throws IOException {

@vibeops-ai vibeops-ai Bot Jun 11, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛑 Blocker · Bug · The read method calls in.nextString() unconditionally, but Gson's JsonReader.nextString() only works when the current token is a JSON string. If the Stripe API returns percent_ownership as a JSON number (e.g., 25.5) instead of a string (e.g., "25.5"), this will throw IllegalStateException because the current token is NUMBER, not STRING. The adapter assumes all BigDecimal values come as strings, but APIs can return them as either strings or numbers.

🔗 Backed by: agent reasoning

Suggested change
public BigDecimal read(JsonReader in) throws IOException {
Check token type first:
```java
`Override`
public BigDecimal read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.STRING) {
return new BigDecimal(in.nextString());
} else {
return BigDecimal.valueOf(in.nextDouble());
}
}


*Was this helpful? React with :+1: or :-1: to help VibeOps learn.*

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question — In JsonEncoder.java: The read method of BIG_DECIMAL_STRING_ADAPTER calls in.nextString() unconditionally. Could you clarify the intent here?

If this was intentional, I'll note it and won't flag it as a bug. If not, I can flag the related usages as blockers.

Reply here and I'll learn from your answer.

return new BigDecimal(in.nextString());
}
};

private static final Gson BODY_GSON =
new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.serializeNulls()
.registerTypeAdapter(BigDecimal.class, BIG_DECIMAL_STRING_ADAPTER)
.create();

public static HttpContent createHttpContent(Map<String, Object> params) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.annotations.SerializedName;
import com.stripe.net.ApiRequestParams;
import com.stripe.v2.Amount;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -15655,7 +15656,7 @@ public static class Relationship {

/** The percent owned by the person of the account's legal entity. */
@SerializedName("percent_ownership")
String percentOwnership;
BigDecimal percentOwnership;

/** The person's title (e.g., CEO, Support Engineer). */
@SerializedName("title")
Expand All @@ -15666,7 +15667,7 @@ private Relationship(
Boolean executive,
Map<String, Object> extraParams,
Boolean owner,
String percentOwnership,
BigDecimal percentOwnership,
String title) {
this.director = director;
this.executive = executive;
Expand All @@ -15689,7 +15690,7 @@ public static class Builder {

private Boolean owner;

private String percentOwnership;
private BigDecimal percentOwnership;

private String title;

Expand Down Expand Up @@ -15758,7 +15759,7 @@ public Builder setOwner(Boolean owner) {
}

/** The percent owned by the person of the account's legal entity. */
public Builder setPercentOwnership(String percentOwnership) {
public Builder setPercentOwnership(BigDecimal percentOwnership) {
this.percentOwnership = percentOwnership;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.stripe.net.ApiRequestParams;
import com.stripe.param.common.EmptyParam;
import com.stripe.v2.Amount;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -7123,7 +7124,7 @@ public static class Relationship {

/** The percent owned by the person of the account's legal entity. */
@SerializedName("percent_ownership")
String percentOwnership;
BigDecimal percentOwnership;

/** The person's title (e.g., CEO, Support Engineer). */
@SerializedName("title")
Expand All @@ -7134,7 +7135,7 @@ private Relationship(
Boolean executive,
Map<String, Object> extraParams,
Boolean owner,
String percentOwnership,
BigDecimal percentOwnership,
String title) {
this.director = director;
this.executive = executive;
Expand All @@ -7157,7 +7158,7 @@ public static class Builder {

private Boolean owner;

private String percentOwnership;
private BigDecimal percentOwnership;

private String title;

Expand Down Expand Up @@ -7226,7 +7227,7 @@ public Builder setOwner(Boolean owner) {
}

/** The percent owned by the person of the account's legal entity. */
public Builder setPercentOwnership(String percentOwnership) {
public Builder setPercentOwnership(BigDecimal percentOwnership) {
this.percentOwnership = percentOwnership;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.stripe.net.ApiRequestParams;
import com.stripe.param.common.EmptyParam;
import com.stripe.v2.Amount;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -17078,7 +17079,7 @@ public Builder setOwner(Boolean owner) {
}

/** The percent owned by the person of the account's legal entity. */
public Builder setPercentOwnership(String percentOwnership) {
public Builder setPercentOwnership(BigDecimal percentOwnership) {
this.percentOwnership = percentOwnership;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import com.google.gson.annotations.SerializedName;
import com.stripe.net.ApiRequestParams;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -2575,7 +2576,7 @@ public static class Relationship {

/** The percentage of ownership the person has in the associated legal entity. */
@SerializedName("percent_ownership")
String percentOwnership;
BigDecimal percentOwnership;

/** Indicates whether the person is a representative of the associated legal entity. */
@SerializedName("representative")
Expand All @@ -2592,7 +2593,7 @@ private Relationship(
Map<String, Object> extraParams,
Boolean legalGuardian,
Boolean owner,
String percentOwnership,
BigDecimal percentOwnership,
Boolean representative,
String title) {
this.authorizer = authorizer;
Expand Down Expand Up @@ -2623,7 +2624,7 @@ public static class Builder {

private Boolean owner;

private String percentOwnership;
private BigDecimal percentOwnership;

private Boolean representative;

Expand Down Expand Up @@ -2700,7 +2701,7 @@ public Builder setOwner(Boolean owner) {
}

/** The percentage of ownership the person has in the associated legal entity. */
public Builder setPercentOwnership(String percentOwnership) {
public Builder setPercentOwnership(BigDecimal percentOwnership) {
this.percentOwnership = percentOwnership;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.annotations.SerializedName;
import com.stripe.net.ApiRequestParams;
import com.stripe.param.common.EmptyParam;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -2545,7 +2546,7 @@ public static class Relationship {

/** The percentage of ownership the person has in the associated legal entity. */
@SerializedName("percent_ownership")
String percentOwnership;
BigDecimal percentOwnership;

/** Indicates whether the person is a representative of the associated legal entity. */
@SerializedName("representative")
Expand All @@ -2562,7 +2563,7 @@ private Relationship(
Map<String, Object> extraParams,
Boolean legalGuardian,
Boolean owner,
String percentOwnership,
BigDecimal percentOwnership,
Boolean representative,
String title) {
this.authorizer = authorizer;
Expand Down Expand Up @@ -2593,7 +2594,7 @@ public static class Builder {

private Boolean owner;

private String percentOwnership;
private BigDecimal percentOwnership;

private Boolean representative;

Expand Down Expand Up @@ -2670,7 +2671,7 @@ public Builder setOwner(Boolean owner) {
}

/** The percentage of ownership the person has in the associated legal entity. */
public Builder setPercentOwnership(String percentOwnership) {
public Builder setPercentOwnership(BigDecimal percentOwnership) {
this.percentOwnership = percentOwnership;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.annotations.SerializedName;
import com.stripe.net.ApiRequestParams;
import com.stripe.param.common.EmptyParam;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -2918,7 +2919,7 @@ public Builder setOwner(Boolean owner) {
}

/** The percentage of ownership the person has in the associated legal entity. */
public Builder setPercentOwnership(String percentOwnership) {
public Builder setPercentOwnership(BigDecimal percentOwnership) {
this.percentOwnership = percentOwnership;
return this;
}
Expand Down