taxjar / taxjar-java Goto Github PK
View Code? Open in Web Editor NEWSales Tax API Client for Java
Home Page: https://developers.taxjar.com/api/reference/?java
License: MIT License
Sales Tax API Client for Java
Home Page: https://developers.taxjar.com/api/reference/?java
License: MIT License
Hello,
We're seeing some very bad issues with the SDK, namely that orders from one merchant are ending up in another merchant's account. Suddenly I'm wondering if this SDK is multi-threaded?
I have concerns. When I delve down into the source code, I see that the api token is stored as a static member of the TaxJar client class. Why is this?? I'm very worried that such design is leading to one token overwriting another token.
Regards,
Perry Tew
What is the plan for another release that upgrades the OkHttp library to at least the 4.9.3 to address CVE-2021-0341?
We've increased the timeout up to 5 minutes, but the server is still timing out after only 30 seconds.
11:47:13.768 [] [main] INFO listOrders()
11:47:43.168 [] [main] INFO failed: com.taxjar.exception.TaxjarException: Service Unavailable - Request Timed Out
at com.taxjar.Taxjar.listOrders()
This happens almost 100% of the time on our linux production environment. Happens much less on our dev environments. Not really sure why that would be the case.
We've had to set the program to run hourly until it works each day. Which is obviously not optimal. Occasionally it takes over 24hrs to get a success. But it always takes at least 5-10 tries before the sever responds correctly. Normally if we run it immediately after an error it works.
Thoughts?
Hey TaxJar,
I discovered an issue with the sdk when trying to do an update to a refund. It was blowing up with an unparsable exception (trace below). I was using a transaction id of our order id concatenated with the characters " [REFUND]" (notice the leading space). This worked for the create refund since that was a POST and the transaction id was part of the json payload. But for the subsequent PUT call made by the api.updateRefund, it blew up because the transaction id was a path parameter.
When I changed my scheme to order id + "-REFUND" (no spaces or brackets), it worked without issue.
I'm proceeding without issue, so this isn't a showstopper for me. But you may wish to url encode all path parameters to avoid any future issues.
Finally, it would be most helpful if you trapped the following exception:
java.lang.NullPointerException at com.taxjar.exception.TaxjarException.parseMessage(TaxjarException.java:28) at com.taxjar.exception.TaxjarException.<init>(TaxjarException.java:15) at com.taxjar.exception.TaxjarException.<init>(TaxjarException.java:11) at com.taxjar.net.ApiRequest.execute(ApiRequest.java:23) at com.taxjar.Taxjar.updateRefund(Taxjar.java:296)
This was happening when the sdk attempted to parse the response coming back from the server. Since my request was blowing up, I'm assuming your server was sending back a 404 or a 500 error. If the parseMessage fails, it would be super helpful if you trapped that failure and threw an exception with the http status code and response body.
If the sdk had done such a thing, my troubleshooting would have accelerated. As soon as I saw a 404 or 500 with a message of "no such endpoint", etc, I would have immediately started looking at the request construction.
Just some thoughts. Great API. We've enjoyed using it. Thanks again for providing it.
Cheers,
Perry Tew
Hey. This is a follow up to issue #14.
We just had two more transactions from one merchant go into another merchant's TaxJar account.
I've reviewed the code and found another area of concern.
Within com.taxjar.TaxJar.java, the variable apiService is static. That variable is configured via a retrofit object that uses client credentials.
I've removed the static modifier for this variable and recompiled without issue. If there's no compelling reason to have that variable static, would you please consider removing the static modifier to eliminate another source of cross threading contamination?
Regards,
Perry Tew
Hi,
I get the following exception after I have submitted about 100 or so transactions taxjar transactions (I submit them in bulk, one day at a time). Once the error starts most of the subsequent get the same error. When I resubmit the missed transactions after a minute or so, they all go through. Any help will be appreciated.
Thanks.
com.google.gson.JsonSyntaxException: Expected a com.google.gson.JsonObject but was com.google.gson.JsonPrimitive
at com.google.gson.internal.bind.TypeAdapters$35$1.read(TypeAdapters.java:913)
at com.google.gson.Gson.fromJson(Gson.java:887)
at com.google.gson.Gson.fromJson(Gson.java:852)
at com.google.gson.Gson.fromJson(Gson.java:801)
at com.google.gson.Gson.fromJson(Gson.java:773)
at com.taxjar.exception.TaxjarException.(TaxjarException.java:12)
at com.taxjar.Taxjar.createOrder(Taxjar.java:410)
On "2021-12-07T23:15:20.485Z" UTC, during TaxJar outage due to AWS downtime, some our calls to Tax Calculations API return nullPointer error (see logs below). It appears that the TaxJarClient Java class TaxjarException does not handle properly null errorMessage
.
We are using taxjar-java:5.0.1
We noticed that your Exception tests covers empty json
but it does not test for null json
.
Could you please improve the class TaxjarException to handle null ErrorMessage?
testEmptyJson:
public void testEmptyJson() { String json = "{}"; TaxjarException e = new TaxjarException(json); assertTrue(e instanceof TaxjarException); assertEquals(json, e.getMessage()); assertEquals((Integer) 0, e.getStatusCode()); }
LOGS:
error.stack_trace: "java.lang.NullPointerException: null
at com.taxjar.exception.TaxjarException.parseMessage(TaxjarException.java:29)
at com.taxjar.exception.TaxjarException.<init>(TaxjarException.java:16)
at com.taxjar.exception.TaxjarException.<init>(TaxjarException.java:12)
at com.taxjar.net.ApiRequest.execute(ApiRequest.java:23)
at com.taxjar.Taxjar.taxForOrder(Taxjar.java:170)
at ***.**.**.***.api.tax.taxjar.TaxJarClient.calculateTax(TaxJarClient.java:49)
There is a mismatch between the JSON response to a "Tax for Order" request and the corresponding java classes in the 1.3.0 release of the client.
From Breakdown.java:
@SerializedName("special_district_tax_rate")
Float specialDistrictTaxRate;
The JSON response contains:
"special_tax_rate": 0,
From BreakdownLineItem,
@SerializedName("state_tax_rate")
Float stateTaxRate;
And the corresponding field in the JSON response:
"state_sales_tax_rate": 0.06,
Hello,
Received this via email:
What you need to do: Your account has been identified as one with potential discrepancies that would immediately benefit from this update. To implement this change, please have your technical team complete the following:
Add the below code to the header of code for your TaxJar API integration calls. This code will enable your site to use the latest version of the TaxJar API.
“x-api-version”: “2020-08-07”
Once added, test your current requests against the new version. This version should return an error message with the type of incorrect data sent to TaxJar, so you can fix any errors.
Once you are able to successfully test your data on the new API version, you should be good to go.
Thank you,
Perry Tew
Why use Float instead of BigDecimal in your Tax object?
We have a lot of transactions and every other day we end up with a socket timeout. Is there any way currently to increase the timeout for Taxjar without modifying source?
I believe the default is only 10 seconds for OkHttp3 as of 2.5.0.
client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
So maybe:
Taxjar.java:
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@OverRide
public okhttp3.Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + apiToken)
.addHeader("User-Agent", "TaxJarJava/" + VERSION)
.build();
return chain.proceed(newRequest);
}
})
// TIMEOUT
.connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(120, TimeUnit.SECONDS)
// OUTEMIT
.build();
java.net.SocketTimeoutException: timeout
at okio.Okio$4.newTimeoutException(Okio.java:232)
at okio.AsyncTimeout.exit(AsyncTimeout.java:285)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:241)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:355)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:227)
at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215)
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.taxjar.Taxjar$1.intercept(Taxjar.java:74)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall.execute(RealCall.java:77)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
at com.taxjar.Taxjar.listOrders(Taxjar.java:297)
...
Caused by: java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:190)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:891)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at okio.Okio$2.read(Okio.java:140)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237)
... 28 more
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.