Search code examples
paypalexpress-checkout

Paypal ExpressCheckout with java SDK fails after retries, however customer is charged


I am responsible for the Paypal payment integration in a marketplace business, and have a serious issue that I hope anybody has experience with.

We are using ExpressCheckout in Java with the merchantsdk version 2.15.122. I understand that this is not the latest way of integration, but should still work properly.

We are applying the standard way of first creating a payment token via PayPalAPIInterfaceServiceService.setExpressCheckout, then redirecting the customer to Paypal, and the actually performing the payment via PayPalAPIInterfaceServiceService.doExpressCheckoutPayment.

I'm not sure the implementation code will help here, as it has worked fine for months, however a few days ago some disturbing errors started to appear. We have multiple cases in which there seem to be some kind of connectivity or response time issues which lead to request retries. We see read timeouts when performing the final doExpressCheckoutPayment as follows in the logs:

Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:940)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
at com.paypal.core.HttpConnection.execute(HttpConnection.java:91)

...and the paypal sdk also logs "Retry No : 1..." and "Retry No : 2...", so it seems that it re-tries twice. In the end, the payment seems to fail with following error:

com.paypal.exception.HttpErrorException: retry fails..  check log for more information
at com.paypal.core.HttpConnection.execute(HttpConnection.java:144)
at com.paypal.core.APIService.makeRequestUsing(APIService.java:177)
at com.paypal.core.BaseService.call(BaseService.java:265)
at urn.ebay.api.PayPalAPI.PayPalAPIInterfaceServiceService.doExpressCheckoutPayment(PayPalAPIInterfaceServiceService.java:1513)
at urn.ebay.api.PayPalAPI.PayPalAPIInterfaceServiceService.doExpressCheckoutPayment(PayPalAPIInterfaceServiceService.java:1465)

Unfortunately, we have been contacted by a few angry customers who seem to actually get charged in these retries. Some customers were even charged twice, i.e. once per re-try.

Does anybody have experience with such errors, and could provide some insights how to deal with these properly?

Thanks in advance for help!

UPDATE As correctly stated in the answers, Paypal charges a single token only once, the double charges are occurring due to re-tries by the customer because they see a payment failure on our platform, and run into the same problem multiple times. So multi-charging is not an issue, but still I wonder how this should be handled properly or whether it actually happens for other Paypal users as well.


Solution

  • I am not sure of this sdk integration but PayPal only does one payment on one EC-token. Subsequent attempts to charge the same EC token will fail.

    Can you check if there are multiple EC tokens generated for the use case when customer complains about charged multiple times?

    Other way to know the status of EC-Token calling GetExpressCheckoutDetails call to know the status of the EC-token. Reference doc: https://developer.paypal.com/docs/classic/api/merchant/GetExpressCheckoutDetails_API_Operation_NVP/