Skip to content

Commit 45b7658

Browse files
authored
Release java SDK v3.35.0 (#49)
* Release version 3.35.0 * Updating the central repo
1 parent af796d7 commit 45b7658

31 files changed

Lines changed: 373 additions & 85 deletions

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
### v3.35.0 (2025-07-18)
2+
* * *
3+
4+
### New Resources:
5+
* BillingConfiguration has been added.
6+
* Brand has been added.
7+
8+
### New Attributes:
9+
* has_children has been added to Hierarchy
10+
* coupon_applicability_mappings has been added to QuotedRamp.
11+
12+
### New Endpoint:
13+
* listHierarchyDetail has been added to Customer.
14+
15+
### New Input parameters:
16+
* change_reason children has been added to Entitlement#CreateRequest.
17+
* entitlements[apply_grandfathering] has been added to Entitlement#CreateRequest.
18+
* replace_primary_payment_source has been added to Purchase#CreateRequest.
19+
* omnichannel_subscription has been added to RecordedPurchase#CreateRequest.
20+
* contract_term has been added to Subscription#RemoveScheduledCancellationRequest.
21+
* contract_term_billing_cycle_on_renewal has been added to Subscription#RemoveScheduledCancellationRequest.
22+
23+
### New Enums:
24+
* payconiq_by_bancontact has been added to PaymentMethodType.
25+
* solidgate has been added to Gateway.
26+
* solidgate has been added to PaymentMethod.
27+
128
### v3.34.0 (2025-06-23)
229
* * *
330

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,64 @@ public class Sample {
154154
```
155155
`isIdempotencyReplayed()` method can be accessed to differentiate between original and replayed requests.
156156

157+
158+
### Retry HandlingAdd commentMore actions
159+
160+
Chargebee's SDK includes built-in retry logic to handle temporary network issues and server-side errors. This feature is **disabled by default** but can be **enabled when needed**.
161+
162+
#### Key features include:
163+
164+
- **Automatic retries for specific HTTP status codes**: Retries are automatically triggered for status codes `500`, `502`, `503`, and `504`.
165+
- **Exponential backoff**: Retry delays increase exponentially to prevent overwhelming the server.
166+
- **Rate limit management**: If a `429 Too Many Requests` response is received with a `Retry-After` header, the SDK waits for the specified duration before retrying.
167+
> *Note: Exponential backoff and max retries do not apply in this case.*
168+
- **Customizable retry behavior**: Retry logic can be configured using the `retryConfig` parameter in the environment configuration.
169+
170+
#### Example: Customizing Retry Logic
171+
172+
You can enable and configure the retry logic by passing a `retryConfig` object when initializing the Chargebee environment:
173+
174+
```java
175+
import com.chargebee.Environment;
176+
public class Sample {
177+
public static void main(String[] args) throws Exception {
178+
Environment.configure("{site}", "{site_api_key}");
179+
Environment.defaultConfig().updateRetryConfig(
180+
new com.chargebee.internal.RetryConfig(
181+
true,
182+
3,
183+
500,
184+
new java.util.HashSet<>(java.util.Arrays.asList(500))
185+
)
186+
);
187+
// ... your Chargebee API operations ...
188+
}
189+
}
190+
191+
```
192+
193+
#### Example: Rate Limit retry logic
194+
195+
You can enable and configure the retry logic for rate-limit by passing a `retryConfig` object when initializing the Chargebee environment:
196+
197+
```java
198+
import com.chargebee.Environment;
199+
public class Sample {
200+
public static void main(String[] args) throws Exception {
201+
Environment.configure("{site}", "{site_api_key}");
202+
Environment.defaultConfig().updateRetryConfig(
203+
new com.chargebee.internal.RetryConfig(
204+
true,
205+
3,
206+
500,
207+
new java.util.HashSet<>(java.util.Arrays.asList(429))
208+
)
209+
);
210+
// ... your Chargebee API operations ...
211+
}
212+
}
213+
```
214+
157215
## Contribution
158216
***
159217
You may contribute patches to any of the **Active** versions of this library. To do so, raise a PR against the [respective branch](#library-versions).

pom.xml

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.chargebee</groupId>
66
<artifactId>chargebee-java</artifactId>
7-
<version>3.34.1-SNAPSHOT</version>
7+
<version>3.35.0</version>
88

99

1010
<packaging>jar</packaging>
@@ -14,6 +14,14 @@
1414

1515
<url>https://github.com/chargebee/chargebee-java</url>
1616

17+
<licenses>
18+
<license>
19+
<name>MIT License</name>
20+
<url>https://opensource.org/licenses/MIT</url>
21+
<distribution>repo</distribution>
22+
</license>
23+
</licenses>
24+
1725
<organization>
1826
<name>ChargeBee</name>
1927
<url>http://www.chargebee.com</url>
@@ -80,12 +88,6 @@
8088
</dependency>
8189
</dependencies>
8290

83-
<parent>
84-
<groupId>org.sonatype.oss</groupId>
85-
<artifactId>oss-parent</artifactId>
86-
<version>9</version>
87-
</parent>
88-
8991
<build>
9092
<resources>
9193
<resource>
@@ -96,6 +98,16 @@
9698
</resource>
9799
</resources>
98100
<plugins>
101+
<plugin>
102+
<groupId>org.sonatype.central</groupId>
103+
<artifactId>central-publishing-maven-plugin</artifactId>
104+
<version>0.8.0</version>
105+
<extensions>true</extensions>
106+
<configuration>
107+
<publishingServerId>central</publishingServerId>
108+
<autoPublish>false</autoPublish>
109+
</configuration>
110+
</plugin>
99111
<plugin>
100112
<groupId>org.apache.maven.plugins</groupId>
101113
<artifactId>maven-gpg-plugin</artifactId>

src/main/java/com/chargebee/Environment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class Environment {
3838

3939
public static final String API_VERSION = "v2";
4040

41-
public static final String LIBRARY_VERSION = "3.34.0";
41+
public static final String LIBRARY_VERSION = "3.35.0";
4242

4343
private final String apiBaseUrl;
4444

src/main/java/com/chargebee/internal/HttpUtil.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static Result get(String url, Params params, Map<String,String> headers,
4545
url = url + '?' + toQueryStr(params); // fixme: what about url size restrictions ??
4646
}
4747
HttpURLConnection conn = createConnection(url, Method.GET, headers, env);
48-
Resp resp = sendRequestWithRetry(conn, env);
48+
Resp resp = sendRequestWithRetry(conn, env, false);
4949
return resp.toResult();
5050
}
5151

@@ -54,16 +54,22 @@ public static ListResult getList(String url, Params params, Map<String,String> h
5454
url = url + '?' + toQueryStr(params, true); // fixme: what about url size restrictions ??
5555
}
5656
HttpURLConnection conn = createConnection(url, Method.GET, headers, env);
57-
Resp resp = sendRequestWithRetry(conn, env);
57+
Resp resp = sendRequestWithRetry(conn, env, false);
5858
return resp.toListResult();
5959
}
60+
public static Result post(String url, Params params, Map<String,String> headers, Environment env, boolean isIdempotent) throws IOException {
61+
return doFormSubmit(url, Method.POST, toQueryStr(params), headers, env, isIdempotent);
62+
}
6063

6164
public static Result post(String url, Params params, Map<String,String> headers, Environment env) throws IOException {
62-
return doFormSubmit(url, Method.POST, toQueryStr(params), headers, env);
65+
return doFormSubmit(url, Method.POST, toQueryStr(params), headers, env, false);
6366
}
64-
6567
public static Result post(String url, String content, Map<String,String> headers, Environment env) throws IOException {
66-
return doFormSubmit(url, Method.POST, content, headers, env);
68+
return doFormSubmit(url, Method.POST, content, headers, env, false);
69+
}
70+
71+
public static Result post(String url, String content, Map<String,String> headers, Environment env, boolean isIdempotent) throws IOException {
72+
return doFormSubmit(url, Method.POST, content, headers, env, isIdempotent);
6773
}
6874

6975

@@ -100,10 +106,10 @@ private static String enc(String val) {
100106
}
101107
}
102108

103-
private static Result doFormSubmit(String url, Method m, String queryStr, Map<String,String> headers, Environment env) throws IOException {
109+
private static Result doFormSubmit(String url, Method m, String queryStr, Map<String,String> headers, Environment env, boolean isIdempotent) throws IOException {
104110
HttpURLConnection conn = createConnection(url, m, headers, env);
105111
writeContent(conn, queryStr);
106-
Resp resp = sendRequestWithRetry(conn, env);
112+
Resp resp = sendRequestWithRetry(conn, env,isIdempotent);
107113
return resp.toResult();
108114
}
109115

@@ -129,11 +135,17 @@ static HttpURLConnection createConnection(String url, Method m, Map<String, Stri
129135
return conn;
130136
}
131137

132-
private static Resp sendRequestWithRetry(HttpURLConnection conn, Environment env) throws IOException {
138+
private static Resp sendRequestWithRetry(HttpURLConnection conn, Environment env, boolean isIdempotent) throws IOException {
133139
int attempt = 0;
134140
int lastRetryAfterDelay = 0;
135141
while (true) {
136142
try {
143+
if (attempt > 0) {
144+
conn.setRequestProperty("X-CB-Retry-Attempt", String.valueOf(attempt));
145+
if (isIdempotent && conn.getRequestProperty("X-CB-Idempotency-Key") == null) {
146+
conn.setRequestProperty("X-CB-Idempotency-Key", UUID.randomUUID().toString());
147+
}
148+
}
137149
return sendRequest(conn);
138150
} catch (Exception e) {
139151
int statusCode = extractStatusCode(e);

src/main/java/com/chargebee/internal/Request.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public Request(Method httpMethod, String uri, String pathParam, String subDomain
3434
this.isJsonRequest = isContentTypeJson;
3535
}
3636

37+
public U setIdempotency(boolean isIdempotent) {
38+
this.isIdempotent = isIdempotent;
39+
return (U) this;
40+
}
41+
3742
public U param(String paramName, Object value){
3843
params.add(paramName, value);
3944
return (U)this;
@@ -43,6 +48,7 @@ public Result request() throws Exception {
4348
return request(Environment.defaultConfig());
4449
}
4550

51+
4652
public Result request(Environment env) throws Exception {
4753
RequestWrap c = new RequestWrap<Request>(env, this) {
4854

@@ -70,12 +76,12 @@ private static Result _request(Environment env, Request<?> req) throws IOExcepti
7076
return HttpUtil.get(url, req.params(), req.headers, env);
7177
case POST:
7278
if(req instanceof BatchRequest) {
73-
return HttpUtil.post(url, ((BatchRequest<?>) req).buildRequest(), req.headers, env);
79+
return HttpUtil.post(url, ((BatchRequest<?>) req).buildRequest(), req.headers, env, req.isIdempotent);
7480
} else if(req.isJsonRequest){
7581
req.headers.put(HttpUtil.CONTENT_TYPE_HEADER_NAME, "application/json;charset=" + Environment.CHARSET);
76-
return HttpUtil.post(url, req.params.toString(), req.headers, env);
82+
return HttpUtil.post(url, req.params.toString(), req.headers, env, req.isIdempotent);
7783
}else {
78-
return HttpUtil.post(url, req.params(), req.headers, env);
84+
return HttpUtil.post(url, req.params(), req.headers, env, req.isIdempotent);
7985
}
8086
default:
8187
throw new RuntimeException("Not handled type [" + req.httpMeth + "]");

src/main/java/com/chargebee/internal/RequestBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class RequestBase<U extends RequestBase> {
1818
protected Map<String,String> headers = new HashMap();
1919
protected String subDomain;
2020
protected boolean isJsonRequest;
21+
protected boolean isIdempotent;
2122

2223
public U setIdempotencyKey(String idempotencyKey){
2324
headers.put(IDEMPOTENCY_HEADER, idempotencyKey);

src/main/java/com/chargebee/internal/ResultBase.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ public QuotedRamp quotedRamp() {
132132
return (QuotedRamp)get("quoted_ramp");
133133
}
134134

135+
public BillingConfiguration billingConfiguration() {
136+
return (BillingConfiguration)get("billing_configuration");
137+
}
138+
135139
public QuoteLineGroup quoteLineGroup() {
136140
return (QuoteLineGroup)get("quote_line_group");
137141
}
@@ -340,6 +344,10 @@ public UsageFile usageFile() {
340344
return (UsageFile)get("usage_file");
341345
}
342346

347+
public Brand brand() {
348+
return (Brand)get("brand");
349+
}
350+
343351
public List<AdvanceInvoiceSchedule> advanceInvoiceSchedules() {
344352
return (List<AdvanceInvoiceSchedule>) getList("advance_invoice_schedules", "advance_invoice_schedule");
345353
}
@@ -376,10 +384,6 @@ public List<InAppSubscription> inAppSubscriptions() {
376384
return (List<InAppSubscription>) getList("in_app_subscriptions", "in_app_subscription");
377385
}
378386

379-
public List<DifferentialPrice> differentialPrices() {
380-
return (List<DifferentialPrice>) getList("differential_prices", "differential_price");
381-
}
382-
383387

384388
private List<? extends Resource> getList(String pluralName, String singularName) {
385389
JSONArray listModels = jsonObj.optJSONArray(pluralName);

src/main/java/com/chargebee/internal/RetryConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ public boolean shouldRetry(int statusCode, int retryCount) {
2525
}
2626

2727
public static RetryConfig defaultConfig() {
28-
return new RetryConfig(false, 3, 500, new HashSet<>(Arrays.asList(500)));
28+
return new RetryConfig(false, 3, 500, new HashSet<>(Arrays.asList(500, 502, 503, 504)));
2929
}
3030
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.chargebee.models;
2+
3+
import com.chargebee.*;
4+
import com.chargebee.internal.*;
5+
import com.chargebee.filters.*;
6+
import com.chargebee.filters.enums.SortOrder;
7+
import com.chargebee.internal.HttpUtil.Method;
8+
import com.chargebee.models.enums.*;
9+
import org.json.*;
10+
import java.io.*;
11+
import java.sql.Timestamp;
12+
import java.util.*;
13+
14+
public class BillingConfiguration extends Resource<BillingConfiguration> {
15+
16+
public static class BillingDate extends Resource<BillingDate> {
17+
public BillingDate(JSONObject jsonObj) {
18+
super(jsonObj);
19+
}
20+
21+
public Timestamp startDate() {
22+
return optTimestamp("start_date");
23+
}
24+
25+
public Timestamp endDate() {
26+
return optTimestamp("end_date");
27+
}
28+
29+
}
30+
31+
//Constructors
32+
//============
33+
34+
public BillingConfiguration(String jsonStr) {
35+
super(jsonStr);
36+
}
37+
38+
public BillingConfiguration(JSONObject jsonObj) {
39+
super(jsonObj);
40+
}
41+
42+
// Fields
43+
//=======
44+
45+
public Boolean isCalendarBillingEnabled() {
46+
return reqBoolean("is_calendar_billing_enabled");
47+
}
48+
49+
public List<BillingConfiguration.BillingDate> billingDates() {
50+
return optList("billing_dates", BillingConfiguration.BillingDate.class);
51+
}
52+
53+
// Operations
54+
//===========
55+
56+
57+
}

0 commit comments

Comments
 (0)