Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Stripe-java v27.0.0 to beta branch #1888

Merged
merged 8 commits into from
Oct 3, 2024
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
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@
},
"java.configuration.updateBuildConfiguration": "automatic",
// LSP was ooming and it recommended this change
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable"
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable",
"java.test.config": {
"vmargs": [ "-Dstripe.disallowGlobalResponseGetterFallback=true"]
prathmesh-stripe marked this conversation as resolved.
Show resolved Hide resolved

}
}
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
# Changelog

## 27.0.0 - 2024-10-01
* [#1880](https://github.com/stripe/stripe-java/pull/1880) Support for APIs in the new API version 2024-09-30.acacia

This release changes the pinned API version to `2024-09-30.acacia`. Please read the [API Upgrade Guide](https://stripe.com/docs/upgrades#2024-09-30.acacia) and carefully review the API changes before upgrading.

### ⚠️ Breaking changes due to changes in the API

* Rename `usage_threshold_config` to `usage_threshold` on `Billing.Alert` and `billing.AlertCreateParams`
* Remove support for `filter` on `Billing.Alert` and `billing.AlertCreateParams`. Use the filters on the `usage_threshold` instead
* Remove support for `customer_consent_collected` on `terminal.ReaderProcessSetupIntentParams`

### ⚠️ Other Breaking changes in the SDK

* Adjusted default values for HTTP requests. You can use the old defaults by setting them explicitly. New values are:
- max retries: `0` -> `2`
* Add method `parseThinEvent()` on the `StripeClient` class to parse [thin events](https://docs.corp.stripe.com/event-destinations#events-overview). Rename `constructEvent()` method on the same class to `parseSnapshotEvent()` to clearly distinguish between the two kinds of events.
* Breaking changes to public classes that are meant for internal use only and should not affect you
* Renamed `setStripeResponseGetter` on `ApiResource` to `setGlobalResponseGetter
* Added another parameter to FormEncoder.flattenParams()
* Removed the deprecated constructor overload on `APIRequest`
* Removed `GlobalStripeResponseGetterOptions.getAPiKey` & `StripeResponseGetterOptions.getApiKey`. We now use a higher abstraction called `Authenticator` instead of passing around api keys
* Changed return type of `RequestOptions.RequestOptionsBuilder.getConnectTimeout` from int to java.lang.Integer.
* Removed the public constructor on `StripeRequest` in favor of a static `StripeRequest.create()`
* The unused field `partnerId` on class `Stripe` is removed

### Additions

* Add support for `usage_threshold` on `Billing.Alert` and `billing.AlertCreateParams`
* Add support for `custom_unit_amount` on `ProductCreateParams.default_price_data`
* Add support for `allow_redisplay` on `terminal.ReaderProcessPaymentIntentParams.process_config` and `terminal.ReaderProcessSetupIntentParams`
* Add support for new value `2024-09-30.acacia` on enum `WebhookEndpointCreateParams.api_version`
* Add support for new Usage Billing APIs `Billing.MeterEvent`, `Billing.MeterEventAdjustments`, `Billing.MeterEventSession`, `Billing.MeterEventStream` and the new Events API `Core.Events` under the [v2 namespace ](https://docs.corp.stripe.com/api-v2-overview)
* Add methods [rawRequest()](https://github.com/stripe/stripe-java/tree/master?tab=readme-ov-file#custom-requests) on the `StripeClient` class that takes a HTTP method type, url and relevant parameters to make requests to the Stripe API that are not yet supported in the SDK.

### Changes
* Change `billingportal.ConfigurationCreateParams.features.subscription_update.default_allowed_updates` and `billingportal.ConfigurationCreateParams.features.subscription_update.products` to be optional

## 26.13.0-beta.1 - 2024-09-18
* [#1870](https://github.com/stripe/stripe-java/pull/1870) Update generated code for beta
* Remove support for resource `QuotePhase`
Expand Down
2 changes: 1 addition & 1 deletion OPENAPI_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1267
v1268
3 changes: 1 addition & 2 deletions src/main/java/com/stripe/ApiVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
package com.stripe;

final class ApiVersion {
public static final String CURRENT = "2024-06-20";
public static final String PREVIEW_CURRENT = "cs_ubb_launch";
public static final String CURRENT = "2024-09-30.acacia";
}
20 changes: 16 additions & 4 deletions src/main/java/com/stripe/Stripe.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ public abstract class Stripe {
public static final int DEFAULT_READ_TIMEOUT = 80 * 1000;

public static final String API_VERSION = ApiVersion.CURRENT;
public static final String PREVIEW_API_VERSION = ApiVersion.PREVIEW_CURRENT;
public static final String CONNECT_API_BASE = "https://connect.stripe.com";
public static final String LIVE_API_BASE = "https://api.stripe.com";
public static final String UPLOAD_API_BASE = "https://files.stripe.com";
public static final String METER_EVENTS_API_BASE = "https://meter-events.stripe.com";
public static final String VERSION = "26.13.0-beta.1";

public static volatile String apiKey;
public static volatile String clientId;
public static volatile boolean enableTelemetry = true;
public static volatile String partnerId;

/**
* Stripe API version which is sent by default on requests. This can be updated to include beta
Expand Down Expand Up @@ -48,14 +47,14 @@ public static void addBetaVersion(String betaName, String betaVersion) {
private static volatile int connectTimeout = -1;
private static volatile int readTimeout = -1;

private static volatile int maxNetworkRetries = 0;
private static volatile int maxNetworkRetries = 2;

private static volatile String apiBase = LIVE_API_BASE;
private static volatile String connectBase = CONNECT_API_BASE;
private static volatile String uploadBase = UPLOAD_API_BASE;
private static volatile String meterEventsBase = METER_EVENTS_API_BASE;
private static volatile Proxy connectionProxy = null;
private static volatile PasswordAuthentication proxyCredential = null;

private static volatile Map<String, String> appInfo = null;

/**
Expand Down Expand Up @@ -94,6 +93,18 @@ public static String getUploadBase() {
return uploadBase;
}

/**
* (FOR TESTING ONLY) If you'd like your events requests to hit your own (mocked) server, you can
* set this up here by overriding the base api URL.
*/
public static void overrideMeterEventsBase(final String overriddenMeterEventsBase) {
meterEventsBase = overriddenMeterEventsBase;
}

public static String getMeterEventsBase() {
return meterEventsBase;
}

/**
* Set proxy to tunnel all Stripe connections.
*
Expand All @@ -116,6 +127,7 @@ public static int getConnectTimeout() {
if (connectTimeout == -1) {
return DEFAULT_CONNECT_TIMEOUT;
}

return connectTimeout;
}

Expand Down
127 changes: 103 additions & 24 deletions src/main/java/com/stripe/StripeClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

import com.stripe.exception.SignatureVerificationException;
import com.stripe.exception.StripeException;
import com.stripe.model.Event;
import com.stripe.model.StripeObject;
import com.stripe.model.ThinEvent;
import com.stripe.net.*;
import com.stripe.net.Webhook.Signature;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import lombok.Getter;
Expand Down Expand Up @@ -40,6 +41,24 @@ protected StripeResponseGetter getResponseGetter() {
return responseGetter;
}

/**
* Returns an StripeEvent instance using the provided JSON payload. Throws a JsonSyntaxException
* if the payload is not valid JSON, and a SignatureVerificationException if the signature
* verification fails for any reason.
*
* @param payload the payload sent by Stripe.
* @param sigHeader the contents of the signature header sent by Stripe.
* @param secret secret used to generate the signature.
* @return the StripeEvent instance
* @throws SignatureVerificationException if the verification fails.
*/
public ThinEvent parseThinEvent(String payload, String sigHeader, String secret)
throws SignatureVerificationException {
Signature.verifyHeader(payload, sigHeader, secret, Webhook.DEFAULT_TOLERANCE);

return ApiResource.GSON.fromJson(payload, ThinEvent.class);
}

/**
* Returns an Event instance using the provided JSON payload. Throws a JsonSyntaxException if the
* payload is not valid JSON, and a SignatureVerificationException if the signature verification
Expand All @@ -51,9 +70,9 @@ protected StripeResponseGetter getResponseGetter() {
* @return the Event instance
* @throws SignatureVerificationException if the verification fails.
*/
public Event constructEvent(String payload, String sigHeader, String secret)
public com.stripe.model.Event constructEvent(String payload, String sigHeader, String secret)
throws SignatureVerificationException {
Event event = Webhook.constructEvent(payload, sigHeader, secret);
com.stripe.model.Event event = Webhook.constructEvent(payload, sigHeader, secret);
event.setResponseGetter(this.getResponseGetter());
return event;
}
Expand All @@ -71,9 +90,10 @@ public Event constructEvent(String payload, String sigHeader, String secret)
* @return the Event instance
* @throws SignatureVerificationException if the verification fails.
*/
public Event constructEvent(String payload, String sigHeader, String secret, long tolerance)
public com.stripe.model.Event constructEvent(
String payload, String sigHeader, String secret, long tolerance)
throws SignatureVerificationException {
Event event = Webhook.constructEvent(payload, sigHeader, secret, tolerance);
com.stripe.model.Event event = Webhook.constructEvent(payload, sigHeader, secret, tolerance);
event.setResponseGetter(this.getResponseGetter());
return event;
}
Expand Down Expand Up @@ -367,6 +387,10 @@ public com.stripe.service.TreasuryService treasury() {
return new com.stripe.service.TreasuryService(this.getResponseGetter());
}

public com.stripe.service.V2Services v2() {
return new com.stripe.service.V2Services(this.getResponseGetter());
}

public com.stripe.service.WebhookEndpointService webhookEndpoints() {
return new com.stripe.service.WebhookEndpointService(this.getResponseGetter());
}
Expand All @@ -376,7 +400,7 @@ static class ClientStripeResponseGetterOptions extends StripeResponseGetterOptio
// When adding setting here keep them in sync with settings in RequestOptions and
// in the RequestOptions.merge method
@Getter(onMethod_ = {@Override})
private final String apiKey;
private final Authenticator authenticator;

@Getter(onMethod_ = {@Override})
private final String clientId;
Expand Down Expand Up @@ -405,8 +429,14 @@ static class ClientStripeResponseGetterOptions extends StripeResponseGetterOptio
@Getter(onMethod_ = {@Override})
private final String connectBase;

@Getter(onMethod_ = {@Override})
private final String meterEventsBase;

@Getter(onMethod_ = {@Override})
private final String stripeContext;

ClientStripeResponseGetterOptions(
String apiKey,
Authenticator authenticator,
String clientId,
int connectTimeout,
int readTimeout,
Expand All @@ -415,8 +445,10 @@ static class ClientStripeResponseGetterOptions extends StripeResponseGetterOptio
PasswordAuthentication proxyCredential,
String apiBase,
String filesBase,
String connectBase) {
this.apiKey = apiKey;
String connectBase,
String meterEventsBase,
String stripeContext) {
this.authenticator = authenticator;
this.clientId = clientId;
this.connectTimeout = connectTimeout;
this.readTimeout = readTimeout;
Expand All @@ -426,6 +458,8 @@ static class ClientStripeResponseGetterOptions extends StripeResponseGetterOptio
this.apiBase = apiBase;
this.filesBase = filesBase;
this.connectBase = connectBase;
this.meterEventsBase = meterEventsBase;
this.stripeContext = stripeContext;
}
}

Expand All @@ -438,7 +472,7 @@ public static StripeClientBuilder builder() {
}

public static final class StripeClientBuilder {
private String apiKey;
private Authenticator authenticator;
private String clientId;
private int connectTimeout = Stripe.DEFAULT_CONNECT_TIMEOUT;
private int readTimeout = Stripe.DEFAULT_READ_TIMEOUT;
Expand All @@ -448,24 +482,43 @@ public static final class StripeClientBuilder {
private String apiBase = Stripe.LIVE_API_BASE;
private String filesBase = Stripe.UPLOAD_API_BASE;
private String connectBase = Stripe.CONNECT_API_BASE;
private String meterEventsBase = Stripe.METER_EVENTS_API_BASE;
private String stripeContext;

/**
* Constructs a request options builder with the global parameters (API key and client ID) as
* default values.
*/
public StripeClientBuilder() {}

public Authenticator getAuthenticator() {
return this.authenticator;
}

public StripeClientBuilder setAuthenticator(Authenticator authenticator) {
this.authenticator = authenticator;
return this;
}

public String getApiKey() {
return this.apiKey;
if (authenticator instanceof BearerTokenAuthenticator) {
return ((BearerTokenAuthenticator) authenticator).getApiKey();
}

return null;
}

/**
* Set API key to use for authenticating requests.
*
* @param apiKey API key
*/
public StripeClientBuilder setApiKey(String apiKey) {
this.apiKey = apiKey;
if (apiKey == null) {
this.authenticator = null;
} else {
this.authenticator = new BearerTokenAuthenticator(apiKey);
}
return this;
}

public StripeClientBuilder clearApiKey() {
this.authenticator = null;
return this;
}

Expand Down Expand Up @@ -601,18 +654,42 @@ public String getConnectBase() {
return this.connectBase;
}

/** Constructs a {@link StripeClient} with the specified configuration. */
/**
* Set the base URL for the Stripe Meter Events API. By default this is
* "https://events.stripe.com".
*
* <p>This only affects requests made with a {@link com.stripe.net.BaseAddress} of EVENTMES.
*/
public StripeClientBuilder setMeterEventsBase(String address) {
this.meterEventsBase = address;
return this;
}

public String getMeterEventsBase() {
return this.meterEventsBase;
}

public StripeClientBuilder setStripeContext(String context) {
this.stripeContext = context;
return this;
}

public String getStripeContext() {
return this.stripeContext;
}

/** Constructs a {@link StripeResponseGetterOptions} with the specified values. */
public StripeClient build() {
return new StripeClient(new LiveStripeResponseGetter(buildOptions(), null));
}

StripeResponseGetterOptions buildOptions() {
if (this.apiKey == null) {
if (this.authenticator == null) {
throw new IllegalArgumentException(
"No API key provided. Use setApiKey to set the Stripe API key");
"No authentication settings provided. Use setApiKey to set the Stripe API key");
}
return new ClientStripeResponseGetterOptions(
this.apiKey,
this.authenticator,
this.clientId,
connectTimeout,
readTimeout,
Expand All @@ -621,7 +698,9 @@ StripeResponseGetterOptions buildOptions() {
proxyCredential,
apiBase,
filesBase,
connectBase);
connectBase,
meterEventsBase,
this.stripeContext);
}
}

Expand Down Expand Up @@ -672,7 +751,7 @@ public StripeResponse rawRequest(
}

/** Deserializes StripeResponse returned by rawRequest into a similar class. */
public StripeObject deserialize(String rawJson) throws StripeException {
return StripeObject.deserializeStripeObject(rawJson, this.getResponseGetter());
public StripeObject deserialize(String rawJson, ApiMode apiMode) throws StripeException {
return StripeObject.deserializeStripeObject(rawJson, this.getResponseGetter(), apiMode);
}
}
Loading
Loading