PayPal沙盒已更新为使用 TLS 1.2 (https://devblog.paypal.com/upcoming-security-changes-notice/#tls)。我最后没有任何变化,我看到了"handshake_failure"错误。
我已经按照 https://github.com/paypal/TLS-update#paypal-java-sdk-support 中的建议更新了我们使用的 JAVA 库。我使用旧版 1.x 版本。
但是,PayPal抛出PayPalException。
[com.paypal.sdk.exceptions.TransactionException] (http-localhost/127.0.0.1:8082-7) (400)Bad Request:
除了更新PayPal_base.jar(肥皂)之外,我还使用VM选项"-Dhttps.protocols=TLSv1.1,TLSv1.2",但它没有任何区别。
我正在使用的PayPal端点是
https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=
我尝试使用 https://developer.paypal.com/docs/classic/api/endpoints/中提供的端点API签名-> SOAP ->沙盒,但没有成功。
关于还需要做什么的任何建议?
更新
我运行了他们提供的测试应用程序(TlsCheck.java/jar),下面是结果
java "-Dhttps.protocols=TLSv1.1,TLSv1.2" -jar TlsCheck.jar
this client supports TLS 1.2
Failed to connect to TLS 1.2 endpoint
在浏览器中访问端点 tlstest.paypal.com 会返回"400 错误请求"。将端点更改为 https://tlstest.paypal.com 将按预期返回"PayPal_连接_OK"。
我还制作了 TlsCheck.java的副本(使用其默认端点 tlstest.paypal.com)并通过我的 IDE 运行它,该 IDE 返回以下内容(尽管它最初无法连接)
this client supports TLS 1.2
Successfully connected to TLS 1.2 endpoint
尝试使用其他端点(如"api-3t.sandbox.paypal.com/2.0/")进行相同的操作,但无法连接到它,指出
Failed to connect to TLS 1.2 endpoint
更新
事实证明,我使用 TslCheck 的测试失败了.jar因为 JAR 中使用的端点是"tlscheck.chargify.com"(无效??),但源代码(来自同一位置 https://github.com/paypal/TLS-update/tree/master/java)使用了不同的端点"tlstest.paypal.com"(有效)。
更新
尽管更新了 PayPal_base.jar但我目前看到"没有名为 PayPalAPIAA 的服务可用",最终导致 404 错误请求。还确认我在轴库中使用 HTTP/1.0 作为 HTTPSender,我们使用默认值为 HTTP/1.1。我还没有找到合适的方法来绕过它。我尝试按照 https://www-10.lotus.com/ldd/pfwiki.nsf/dx/10022008035400PMWEBRCB.htm 切换到HTTP/1.1。这在我的情况下不起作用!!!
适用于PayPal TLS 1.2 新 SHA 256 证书。
*)从PayPal沙盒帐户(>商家销售工具)下载 PayPal_cert.pem> apiaccess。*) 运行 openssl pkcs12 -export -in cert_key_pem.txt -inkey cert_key_pem.txt -out PayPal_cert.p12
public HashMap httpcall( String methodName, String nvpRequestStr) {
String version = "2.3";
String agent = "Mozilla/4.0";
String respText = "";
HashMap nvp = null;
String encodedData = "METHOD=" + methodName + "&VERSION=" + gv_Version + "&PWD=" + gv_APIPassword + "&USER=" + gv_APIUserName + nvpRequestStr;
try
{
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream keyInput = new FileInputStream("/Users/Downloads/paypal_cert.p12");
keyStore.load(keyInput, "changeit".toCharArray());
keyInput.close();
keyManagerFactory.init(keyStore, "changeit".toCharArray());
SSLContext context = SSLContext.getInstance("TLSV1.2");
context.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
URL url = new URL(gv_APIEndpoint);
HttpsURLConnection conn=(HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(context.getSocketFactory());
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty( "Content-Length", String.valueOf( encodedData.length()) );
conn.setRequestMethod("POST");
DataOutputStream output = new DataOutputStream( conn.getOutputStream());
output.writeBytes( encodedData );
output.flush();
output.close ();
// Read input from the input stream.
DataInputStream in = new DataInputStream (conn.getInputStream());
int rc = conn.getResponseCode();
if ( rc != -1)
{
BufferedReader is = new BufferedReader(new InputStreamReader( conn.getInputStream()));
String _line = null;
while(((_line = is.readLine()) !=null))
{
respText = respText + _line;
}
nvp = deformatNVP( respText );
}
return nvp;
} catch (NoSuchAlgorithmException e) {e.printStackTrace(); return null;
} catch (UnknownHostException e) {e.printStackTrace(); return null;
} catch (IOException e) {e.printStackTrace(); return null;
} catch (KeyManagementException e) {e.printStackTrace(); return null;
} catch (UnrecoverableKeyException e) {e.printStackTrace(); return null;
} catch (CertificateException e) {e.printStackTrace(); return null;
} catch (KeyStoreException e) {e.printStackTrace(); return null;}
}
public HashMap deformatNVP( String pPayload )
{
HashMap nvp = new HashMap();
StringTokenizer stTok = new StringTokenizer( pPayload, "&");
while (stTok.hasMoreTokens())
{
StringTokenizer stInternalTokenizer = new StringTokenizer( stTok.nextToken(), "=");
if (stInternalTokenizer.countTokens() == 2)
{
String key = URLDecoder.decode( stInternalTokenizer.nextToken());
String value = URLDecoder.decode( stInternalTokenizer.nextToken());
nvp.put( key.toUpperCase(), value );
}
}
return nvp;
}
我已经通过简单地更新库来解决这个问题,以使用merchantsdk-2.14.117.jar,PayPal-core-1.7.0.jar和permissionsskd-2.4.109.jar。我们使用的库很旧,API 调用必须使用新库进行更新,但尽管包名称发生了变化(com.PayPal.soap.api 到 urn.ebay.api),但这些变化还是相当明显的。由于HTTP调用是由库进行的,我们不再需要担心HTTP/1.1。
我能够针对PayPal的沙盒环境进行测试和验证。