From 83ba5fe602853ce2a49eb0bd831c8b30a1e2ee05 Mon Sep 17 00:00:00 2001 From: David Brownman Date: Wed, 4 Mar 2026 16:06:25 -0800 Subject: [PATCH 1/6] add "prepare" to justfile --- justfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/justfile b/justfile index d48f299877e..072f3a4600f 100644 --- a/justfile +++ b/justfile @@ -5,6 +5,10 @@ import? '../sdk-codegen/utils.just' _default: just --list --unsorted +# ⭐ run format and tests to prepare for CI +[no-exit-message] +prepare: format test + # ⭐ run the whole test suite [no-exit-message] test *args: From 778371b0eb12fd7d487ea382f3e8054efe111949 Mon Sep 17 00:00:00 2001 From: David Brownman Date: Wed, 4 Mar 2026 16:06:26 -0800 Subject: [PATCH 2/6] add Stripe-Request-Trigger header --- .../java/com/stripe/model/v2/core/Event.java | 7 ++++-- .../model/v2/core/EventNotification.java | 10 ++++---- .../com/stripe/net/RawRequestOptions.java | 9 ++++++++ .../java/com/stripe/net/RequestOptions.java | 23 ++++++++++++++++++- .../java/com/stripe/net/StripeRequest.java | 5 ++++ .../java/com/stripe/model/v2/EventTests.java | 23 ++++++++++++++----- 6 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/stripe/model/v2/core/Event.java b/src/main/java/com/stripe/model/v2/core/Event.java index 1c9b0fed797..c446579e402 100644 --- a/src/main/java/com/stripe/model/v2/core/Event.java +++ b/src/main/java/com/stripe/model/v2/core/Event.java @@ -98,12 +98,15 @@ protected StripeObject fetchRelatedObject(RelatedObject relatedObject) throws St objectClass = StripeRawJsonObject.class; } - RequestOptions opts = null; + RequestOptions.RequestOptionsBuilder optsBuilder = + new RequestOptions.RequestOptionsBuilder().setStripeRequestTrigger("event=" + id); if (context != null) { - opts = new RequestOptions.RequestOptionsBuilder().setStripeAccount(context).build(); + optsBuilder.setStripeAccount(context); } + RequestOptions opts = optsBuilder.build(); + return this.responseGetter.request( new ApiRequest( BaseAddress.API, ApiResource.RequestMethod.GET, relatedObject.getUrl(), null, opts), diff --git a/src/main/java/com/stripe/model/v2/core/EventNotification.java b/src/main/java/com/stripe/model/v2/core/EventNotification.java index 99c99b13fb7..c5d8a483e40 100644 --- a/src/main/java/com/stripe/model/v2/core/EventNotification.java +++ b/src/main/java/com/stripe/model/v2/core/EventNotification.java @@ -106,12 +106,12 @@ public static EventNotification fromJson(String payload, StripeClient client) { } private RawRequestOptions getRequestOptions() { - if (context == null) { - return null; + RawRequestOptions.RawRequestOptionsBuilder builder = + new RawRequestOptions.RawRequestOptionsBuilder().setStripeRequestTrigger("event=" + id); + if (context != null) { + builder.setStripeContext(context.toString()); } - return new RawRequestOptions.RawRequestOptionsBuilder() - .setStripeContext(context.toString()) - .build(); + return builder.build(); } /* retrieves the full payload for an event. Protected because individual push classes use it, but type it correctly */ diff --git a/src/main/java/com/stripe/net/RawRequestOptions.java b/src/main/java/com/stripe/net/RawRequestOptions.java index ba0384c338e..71764416105 100644 --- a/src/main/java/com/stripe/net/RawRequestOptions.java +++ b/src/main/java/com/stripe/net/RawRequestOptions.java @@ -13,6 +13,7 @@ public RawRequestOptions( String clientId, String idempotencyKey, String stripeContext, + String stripeRequestTrigger, String stripeAccount, String stripeVersionOverride, String baseUrl, @@ -27,6 +28,7 @@ public RawRequestOptions( clientId, idempotencyKey, stripeContext, + stripeRequestTrigger, stripeAccount, stripeVersionOverride, baseUrl, @@ -88,6 +90,12 @@ public RawRequestOptionsBuilder setStripeContext(StripeContext stripeContext) { return this; } + @Override + public RawRequestOptionsBuilder setStripeRequestTrigger(String stripeRequestTrigger) { + super.setStripeRequestTrigger(stripeRequestTrigger); + return this; + } + @Override public RawRequestOptionsBuilder setStripeAccount(String stripeAccount) { super.setStripeAccount(stripeAccount); @@ -137,6 +145,7 @@ public RawRequestOptions build() { normalizeClientId(this.clientId), normalizeIdempotencyKey(this.idempotencyKey), normalizeStripeContext(this.stripeContext), + stripeRequestTrigger, normalizeStripeAccount(this.stripeAccount), normalizeStripeVersion(this.stripeVersionOverride), normalizeBaseUrl(this.baseUrl), diff --git a/src/main/java/com/stripe/net/RequestOptions.java b/src/main/java/com/stripe/net/RequestOptions.java index 42c910777a2..af3b9120500 100644 --- a/src/main/java/com/stripe/net/RequestOptions.java +++ b/src/main/java/com/stripe/net/RequestOptions.java @@ -13,6 +13,7 @@ public class RequestOptions { private final Authenticator authenticator; private final String clientId; private final String stripeContext; + private final String stripeRequestTrigger; private final String idempotencyKey; private final String stripeAccount; private final String baseUrl; @@ -32,7 +33,7 @@ public class RequestOptions { public static RequestOptions getDefault() { return new RequestOptions( - null, null, null, null, null, null, null, null, null, null, null, null); + null, null, null, null, null, null, null, null, null, null, null, null, null); } protected RequestOptions( @@ -40,6 +41,7 @@ protected RequestOptions( String clientId, String idempotencyKey, String stripeContext, + String stripeRequestTrigger, String stripeAccount, String stripeVersionOverride, String baseUrl, @@ -52,6 +54,7 @@ protected RequestOptions( this.clientId = clientId; this.idempotencyKey = idempotencyKey; this.stripeContext = stripeContext; + this.stripeRequestTrigger = stripeRequestTrigger; this.stripeAccount = stripeAccount; this.stripeVersionOverride = stripeVersionOverride; this.baseUrl = baseUrl; @@ -82,6 +85,10 @@ public String getStripeContext() { return stripeContext; } + public String getStripeRequestTrigger() { + return stripeRequestTrigger; + } + public String getIdempotencyKey() { return idempotencyKey; } @@ -153,6 +160,7 @@ public RequestOptionsBuilder toBuilderFullCopy() { .setClientId(this.clientId) .setIdempotencyKey(this.idempotencyKey) .setStripeAccount(this.stripeAccount) + .setStripeRequestTrigger(this.stripeRequestTrigger) .setConnectTimeout(this.connectTimeout) .setReadTimeout(this.readTimeout) .setMaxNetworkRetries(this.maxNetworkRetries) @@ -166,6 +174,7 @@ public static class RequestOptionsBuilder { protected String clientId; protected String idempotencyKey; protected String stripeContext; + protected String stripeRequestTrigger; protected String stripeAccount; protected String stripeVersionOverride; protected Integer connectTimeout; @@ -251,6 +260,15 @@ public RequestOptionsBuilder clearStripeContext() { return this; } + public String getStripeRequestTrigger() { + return stripeRequestTrigger; + } + + public RequestOptionsBuilder setStripeRequestTrigger(String stripeRequestTrigger) { + this.stripeRequestTrigger = stripeRequestTrigger; + return this; + } + public RequestOptionsBuilder setIdempotencyKey(String idempotencyKey) { this.idempotencyKey = idempotencyKey; return this; @@ -371,6 +389,7 @@ public RequestOptions build() { normalizeClientId(this.clientId), normalizeIdempotencyKey(this.idempotencyKey), stripeContext, + stripeRequestTrigger, normalizeStripeAccount(this.stripeAccount), normalizeStripeVersion(this.stripeVersionOverride), normalizeBaseUrl(this.baseUrl), @@ -473,6 +492,7 @@ static RequestOptions merge(StripeResponseGetterOptions clientOptions, RequestOp clientOptions.getClientId(), // clientId null, // idempotencyKey clientOptions.getStripeContext(), // stripeContext + null, // stripeRequestTrigger clientOptions.getStripeAccount(), // stripeAccount null, // stripeVersionOverride null, // baseUrl @@ -505,6 +525,7 @@ static RequestOptions merge(StripeResponseGetterOptions clientOptions, RequestOp options.getClientId() != null ? options.getClientId() : clientOptions.getClientId(), options.getIdempotencyKey(), stripeContext, + options.getStripeRequestTrigger(), options.getStripeAccount() != null ? options.getStripeAccount() : clientOptions.getStripeAccount(), diff --git a/src/main/java/com/stripe/net/StripeRequest.java b/src/main/java/com/stripe/net/StripeRequest.java index 89433bfde9f..63dde82a3f6 100644 --- a/src/main/java/com/stripe/net/StripeRequest.java +++ b/src/main/java/com/stripe/net/StripeRequest.java @@ -321,6 +321,11 @@ private static HttpHeaders buildHeaders( headerMap.put("Stripe-Context", Arrays.asList(options.getStripeContext())); } + // Stripe-Request-Trigger + if (options.getStripeRequestTrigger() != null) { + headerMap.put("Stripe-Request-Trigger", Arrays.asList(options.getStripeRequestTrigger())); + } + // Stripe-Account if (options.getStripeAccount() != null) { headerMap.put("Stripe-Account", Arrays.asList(options.getStripeAccount())); diff --git a/src/test/java/com/stripe/model/v2/EventTests.java b/src/test/java/com/stripe/model/v2/EventTests.java index dabebb682b8..62517ce4f57 100644 --- a/src/test/java/com/stripe/model/v2/EventTests.java +++ b/src/test/java/com/stripe/model/v2/EventTests.java @@ -8,10 +8,15 @@ import com.stripe.model.billing.Meter; import com.stripe.model.v2.core.Event; import com.stripe.net.ApiResource; +import com.stripe.net.HttpHeaders; +import com.stripe.net.StripeResponse; import java.io.IOException; import java.time.Instant; +import java.util.Collections; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; public class EventTests extends BaseStripeTest { public static String v2PayloadNoData = null; @@ -115,12 +120,13 @@ public void retrieveObjectFetchesAndDeserializesObject() throws StripeException, V1BillingMeterErrorReportTriggeredEvent event = (V1BillingMeterErrorReportTriggeredEvent) Event.parse(v2PayloadNoData); event.setResponseGetter(networkSpy); - stubRequest( - ApiResource.RequestMethod.GET, - "/v1/billing/meters/meter_123", - null, - Meter.class, - getResourceAsString("/api_fixtures/billing_meter.json")); + String fixtureJson = getResourceAsString("/api_fixtures/billing_meter.json"); + Mockito.doAnswer( + (Answer) + invocation -> + new StripeResponse(200, HttpHeaders.of(Collections.emptyMap()), fixtureJson)) + .when(httpClientSpy) + .request(Mockito.any()); assertEquals("/v1/billing/meters/meter_123", event.getRelatedObject().getUrl()); assertEquals("meter_123", event.getRelatedObject().getId()); @@ -141,6 +147,11 @@ public void retrieveObjectFetchesAndDeserializesObject() throws StripeException, assertEquals("active", meter.getStatus()); assertNull(meter.getStatusTransitions().getDeactivatedAt()); assertEquals(1727303036, meter.getUpdated()); + + verifyStripeRequest( + req -> + assertEquals( + "event=evt_234", req.headers().firstValue("Stripe-Request-Trigger").orElse(null))); } // FIXME (jar) this should no longer be possible; confirm this and remove before merge From 9f95a2c22af239dfcf5fd0672d7a588e8a3740e5 Mon Sep 17 00:00:00 2001 From: David Brownman Date: Thu, 5 Mar 2026 11:54:51 -0800 Subject: [PATCH 3/6] Simplify builders --- .../java/com/stripe/model/v2/core/Event.java | 4 +-- .../com/stripe/net/RawRequestOptions.java | 2 +- .../java/com/stripe/net/RequestOptions.java | 29 ++++++++----------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/stripe/model/v2/core/Event.java b/src/main/java/com/stripe/model/v2/core/Event.java index c446579e402..7c378b4d7cc 100644 --- a/src/main/java/com/stripe/model/v2/core/Event.java +++ b/src/main/java/com/stripe/model/v2/core/Event.java @@ -98,8 +98,8 @@ protected StripeObject fetchRelatedObject(RelatedObject relatedObject) throws St objectClass = StripeRawJsonObject.class; } - RequestOptions.RequestOptionsBuilder optsBuilder = - new RequestOptions.RequestOptionsBuilder().setStripeRequestTrigger("event=" + id); + RequestOptions.RequestOptionsBuilder optsBuilder = new RequestOptions.RequestOptionsBuilder(); + optsBuilder.setStripeRequestTrigger("event=" + id); if (context != null) { optsBuilder.setStripeAccount(context); diff --git a/src/main/java/com/stripe/net/RawRequestOptions.java b/src/main/java/com/stripe/net/RawRequestOptions.java index 71764416105..a46dec01e1c 100644 --- a/src/main/java/com/stripe/net/RawRequestOptions.java +++ b/src/main/java/com/stripe/net/RawRequestOptions.java @@ -8,7 +8,7 @@ public class RawRequestOptions extends RequestOptions { private Map additionalHeaders; - public RawRequestOptions( + private RawRequestOptions( Authenticator authenticator, String clientId, String idempotencyKey, diff --git a/src/main/java/com/stripe/net/RequestOptions.java b/src/main/java/com/stripe/net/RequestOptions.java index af3b9120500..39a0c97a48f 100644 --- a/src/main/java/com/stripe/net/RequestOptions.java +++ b/src/main/java/com/stripe/net/RequestOptions.java @@ -32,8 +32,7 @@ public class RequestOptions { private final PasswordAuthentication proxyCredential; public static RequestOptions getDefault() { - return new RequestOptions( - null, null, null, null, null, null, null, null, null, null, null, null, null); + return new RequestOptionsBuilder().build(); } protected RequestOptions( @@ -487,21 +486,17 @@ protected static String normalizeStripeAccount(String stripeAccount) { static RequestOptions merge(StripeResponseGetterOptions clientOptions, RequestOptions options) { if (options == null) { - return new RequestOptions( - clientOptions.getAuthenticator(), // authenticator - clientOptions.getClientId(), // clientId - null, // idempotencyKey - clientOptions.getStripeContext(), // stripeContext - null, // stripeRequestTrigger - clientOptions.getStripeAccount(), // stripeAccount - null, // stripeVersionOverride - null, // baseUrl - clientOptions.getConnectTimeout(), // connectTimeout - clientOptions.getReadTimeout(), // readTimeout - clientOptions.getMaxNetworkRetries(), // maxNetworkRetries - clientOptions.getConnectionProxy(), // connectionProxy - clientOptions.getProxyCredential() // proxyCredential - ); + return new RequestOptionsBuilder() + .setAuthenticator(clientOptions.getAuthenticator()) + .setClientId(clientOptions.getClientId()) + .setStripeContext(clientOptions.getStripeContext()) + .setStripeAccount(clientOptions.getStripeAccount()) + .setConnectTimeout(clientOptions.getConnectTimeout()) + .setReadTimeout(clientOptions.getReadTimeout()) + .setMaxNetworkRetries(clientOptions.getMaxNetworkRetries()) + .setConnectionProxy(clientOptions.getConnectionProxy()) + .setProxyCredential(clientOptions.getProxyCredential()) + .build(); } // callers need to be able to explicitly unset context per-request From 21e24071865a1d80250a7142c817263ccc6a74ea Mon Sep 17 00:00:00 2001 From: David Brownman Date: Thu, 5 Mar 2026 12:10:41 -0800 Subject: [PATCH 4/6] Use additionalHeaders directly in RawRequestOptions --- .../stripe/model/v2/core/EventNotification.java | 6 +++++- .../java/com/stripe/net/RawRequestOptions.java | 14 ++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/stripe/model/v2/core/EventNotification.java b/src/main/java/com/stripe/model/v2/core/EventNotification.java index c5d8a483e40..1ed573bc2af 100644 --- a/src/main/java/com/stripe/model/v2/core/EventNotification.java +++ b/src/main/java/com/stripe/model/v2/core/EventNotification.java @@ -15,6 +15,8 @@ import com.stripe.net.RawRequestOptions; import com.stripe.net.StripeResponse; import java.time.Instant; +import java.util.Collections; +import java.util.Map; import lombok.AccessLevel; import lombok.Getter; @@ -107,7 +109,9 @@ public static EventNotification fromJson(String payload, StripeClient client) { private RawRequestOptions getRequestOptions() { RawRequestOptions.RawRequestOptionsBuilder builder = - new RawRequestOptions.RawRequestOptionsBuilder().setStripeRequestTrigger("event=" + id); + new RawRequestOptions.RawRequestOptionsBuilder() + .setAdditionalHeaders( + Collections.singletonMap("Stripe-Request-Trigger", "event=" + id)); if (context != null) { builder.setStripeContext(context.toString()); } diff --git a/src/main/java/com/stripe/net/RawRequestOptions.java b/src/main/java/com/stripe/net/RawRequestOptions.java index a46dec01e1c..4d91dc9847a 100644 --- a/src/main/java/com/stripe/net/RawRequestOptions.java +++ b/src/main/java/com/stripe/net/RawRequestOptions.java @@ -8,12 +8,13 @@ public class RawRequestOptions extends RequestOptions { private Map additionalHeaders; - private RawRequestOptions( + // TODO: make this private + // see: https://go/j/DEVSDK-3018 + public RawRequestOptions( Authenticator authenticator, String clientId, String idempotencyKey, String stripeContext, - String stripeRequestTrigger, String stripeAccount, String stripeVersionOverride, String baseUrl, @@ -28,7 +29,7 @@ private RawRequestOptions( clientId, idempotencyKey, stripeContext, - stripeRequestTrigger, + null, stripeAccount, stripeVersionOverride, baseUrl, @@ -90,12 +91,6 @@ public RawRequestOptionsBuilder setStripeContext(StripeContext stripeContext) { return this; } - @Override - public RawRequestOptionsBuilder setStripeRequestTrigger(String stripeRequestTrigger) { - super.setStripeRequestTrigger(stripeRequestTrigger); - return this; - } - @Override public RawRequestOptionsBuilder setStripeAccount(String stripeAccount) { super.setStripeAccount(stripeAccount); @@ -145,7 +140,6 @@ public RawRequestOptions build() { normalizeClientId(this.clientId), normalizeIdempotencyKey(this.idempotencyKey), normalizeStripeContext(this.stripeContext), - stripeRequestTrigger, normalizeStripeAccount(this.stripeAccount), normalizeStripeVersion(this.stripeVersionOverride), normalizeBaseUrl(this.baseUrl), From eabec1df50e108b047929233046c2aae95a67607 Mon Sep 17 00:00:00 2001 From: David Brownman Date: Thu, 5 Mar 2026 13:22:56 -0800 Subject: [PATCH 5/6] regenerate --- src/main/java/com/stripe/model/v2/core/EventNotification.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/stripe/model/v2/core/EventNotification.java b/src/main/java/com/stripe/model/v2/core/EventNotification.java index 1ed573bc2af..2f77dd9d6b4 100644 --- a/src/main/java/com/stripe/model/v2/core/EventNotification.java +++ b/src/main/java/com/stripe/model/v2/core/EventNotification.java @@ -16,7 +16,6 @@ import com.stripe.net.StripeResponse; import java.time.Instant; import java.util.Collections; -import java.util.Map; import lombok.AccessLevel; import lombok.Getter; From 4b075e2c2b6322b9fb5a2b4290a45266352c042e Mon Sep 17 00:00:00 2001 From: David Brownman Date: Thu, 5 Mar 2026 13:34:11 -0800 Subject: [PATCH 6/6] add comment about broken test --- src/main/java/com/stripe/model/v2/core/Event.java | 2 +- src/test/java/com/stripe/model/v2/EventTests.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/stripe/model/v2/core/Event.java b/src/main/java/com/stripe/model/v2/core/Event.java index 7c378b4d7cc..17d4f3dfd5a 100644 --- a/src/main/java/com/stripe/model/v2/core/Event.java +++ b/src/main/java/com/stripe/model/v2/core/Event.java @@ -99,7 +99,7 @@ protected StripeObject fetchRelatedObject(RelatedObject relatedObject) throws St } RequestOptions.RequestOptionsBuilder optsBuilder = new RequestOptions.RequestOptionsBuilder(); - optsBuilder.setStripeRequestTrigger("event=" + id); + // optsBuilder.setStripeRequestTrigger("event=" + id); // TODO https://go/j/DEVSDK-3018 if (context != null) { optsBuilder.setStripeAccount(context); diff --git a/src/test/java/com/stripe/model/v2/EventTests.java b/src/test/java/com/stripe/model/v2/EventTests.java index 62517ce4f57..46ee05be680 100644 --- a/src/test/java/com/stripe/model/v2/EventTests.java +++ b/src/test/java/com/stripe/model/v2/EventTests.java @@ -115,6 +115,7 @@ public void parsesV2EventAndDeserializesEventData() throws StripeException { assertEquals("foo", data.getDeveloperMessageSummary()); } + // currently intentionally broken while we wait for the major & https://go/j/DEVSDK-3018 @Test public void retrieveObjectFetchesAndDeserializesObject() throws StripeException, IOException { V1BillingMeterErrorReportTriggeredEvent event =