无法通过cURL连接到PayPal API
我试图通过“Classic”NVP API设置PayPal Express Payment。无法通过cURL连接到PayPal API
尝试使用cURL从我的服务器连接到PayPal-Sandbox,连接停止并在大约2分钟后超时。
我使用的是example call从文档:
curl -v --insecure https://api-3t.sandbox.paypal.com/nvp -d "USER=platfo_1255077030_biz_api1.gmail.com&PWD=1255077037&SIGNATURE=Abg0gYcQyxQvnf2HDJkKtA-p6pqhA1k-KTYE0Gcy1diujFio4io5Vqjf&METHOD=SetExpressCheckout&VERSION=78&PAYMENTREQUEST_0_PAYMENTACTION=SALE&PAYMENTREQUEST_0_AMT=19&PAYMENTREQUEST_0_CURRENCYCODE=USD&cancelUrl=http://www.yourdomain.com/cancel.html&returnUrl=http://www.yourdomain.com/success.html"
壳牌输出为:
* About to connect() to api-3t.sandbox.paypal.com port 443 (#0)
* Trying 173.0.82.83... Connection timed out
* couldn't connect to host
* Closing connection #0
curl: (7) couldn't connect to host
当我试图通过PHP curl
做到这一点,我没有得到任何错误并只是一个空的资源句柄。
我可以轻松地从我的本地机器和其他服务器上访问我可以访问的请求(并获取正确的数据),所以我猜这是一些服务器端配置错误。不是服务员的人我有点无知。
卷曲启用并记录在phpinfo
如下:
libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
OpenSSL是使能的。另外,我在尝试连接到API的实时版本时遇到同样的问题。
A)先试着wget https://api-3t.sandbox.paypal.com/nvp
,看看您是否可以得到“错误的请求”回答一个简单的连接,如果不是你已经被封锁了PayPal服务器或防火墙阻止你在端口443来访问贝宝
B)尝试添加自定义标题:-H "Host: api-3t.sandbox.paypal.com"
curl -v --insecure https://api-3t.sandbox.paypal.com/nvp -d "USER=platfo_1255077030_biz_api1.gmail.com&PWD=1255077037&SIGNATURE=Abg0gYcQyxQvnf2HDJkKtA-p6pqhA1k-KTYE0Gcy1diujFio4io5Vqjf&METHOD=SetExpressCheckout&VERSION=78&PAYMENTREQUEST_0_PAYMENTACTION=SALE&PAYMENTREQUEST_0_AMT=19&PAYMENTREQUEST_0_CURRENCYCODE=USD&cancelUrl=http://www.yourdomain.com/cancel.html&returnUrl=http://www.yourdomain.com/success.html" -H "Host: api-3t.sandbox.paypal.com"
C)你使用的是什么卷曲的版本和在什么平台上?我有:
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2
尝试
$ch = curl_init();
# Merchant Account Credentials
$ppUserID = "User Id Email"; //Take it from sandbox dashboard for test mode or take it from paypal.com account in production mode, help: https://developer.paypal.com/docs/classic/api/apiCredentials/
$ppPass = "User Pass"; //Take it from sandbox dashboard for test mode or take it from paypal.com account in production mode, help: https://developer.paypal.com/docs/classic/api/apiCredentials/
$ppSign = "Paypal Sign"; //Take it from sandbox dashboard for test mode or take it from paypal.com account in production mode, help: https://developer.paypal.com/docs/classic/api/apiCredentials/
$ppAppID = "APP-80W284485P519543T"; //if it is sandbox then app id is always: APP-80W284485P519543T
$paypal_header_options = array();
$paypal_header_options[] = "X-PAYPAL-SECURITY-USERID: $ppUserID";
$paypal_header_options[] = "X-PAYPAL-SECURITY-PASSWORD: $ppPass";
$paypal_header_options[] = "X-PAYPAL-SECURITY-SIGNATURE: $ppSign";
$paypal_header_options[] = "X-PAYPAL-REQUEST-DATA-FORMAT: NV";
$paypal_header_options[] = "X-PAYPAL-RESPONSE-DATA-FORMAT: NV";
$paypal_header_options[] = "X-PAYPAL-APPLICATION-ID: $ppAppID";
$URL = 'https://api-3t.sandbox.paypal.com/nvp'
.'?USER='.$ppUserID
.'&PWD='.$ppPass
.'&SIGNATURE='.$ppSign
.'&METHOD=SetExpressCheckout'
.'&VERSION=93'
.'&RETURNURL=https://localhost/express-checkout-single-product/success.php?success=true'
.'&CANCELURL=https://localhost/express-checkout-single-product/index.php'
.'&PAYMENTREQUEST_0_CURRENCYCODE=USD'
.'&PAYMENTREQUEST_0_AMT=250.00' #The payment amount for the first receiver # Merchant(Primary AC) Account Amount
.'&PAYMENTREQUEST_0_ITEMAMT=225.00' # Merchant(Primary AC) Account Email
.'&PAYMENTREQUEST_0_TAXAMT=25.00' #Receiver designation (there can be only 1 primary receiver)
.'&PAYMENTREQUEST_0_PAYMENTACTION=Order'
.'&PAYMENTREQUEST_0_SELLERPAYPALACCOUNTID=email'
.'&PAYMENTREQUEST_0_PAYMENTREQUESTID=CART110-PAYMENT0' #The payment amount for the second receiver # Seller(Secondry AC) Account Amount
.'&PAYMENTREQUEST_1_CURRENCYCODE=USD'
.'&PAYMENTREQUEST_1_AMT=75.00' #The payment amount for the first receiver # Merchant(Primary AC) Account Amount
.'&PAYMENTREQUEST_1_ITEMAMT=65.00' # Merchant(Primary AC) Account Email
.'&PAYMENTREQUEST_1_TAXAMT=10.00' #Receiver designation (there can be only 1 primary receiver)
.'&PAYMENTREQUEST_1_PAYMENTACTION=Order'
.'&PAYMENTREQUEST_1_SELLERPAYPALACCOUNTID=email'
.'&PAYMENTREQUEST_1_PAYMENTREQUESTID=CART110-PAYMENT1'
.'&L_PAYMENTREQUEST_0_NAME0=Departs2'
.'&L_PAYMENTREQUEST_0_NAME0=Sunset'
.'&L_PAYMENTREQUEST_0_QTY0=1'
.'&L_PAYMENTREQUEST_0_AMT0=125'
.'&L_PAYMENTREQUEST_0_TAXAMT0=15'
.'&L_PAYMENTREQUEST_0_NAME1=Departs'
.'&L_PAYMENTREQUEST_0_QTY1=1'
.'&L_PAYMENTREQUEST_0_AMT1=100.00'
.'&L_PAYMENTREQUEST_0_TAXAMT1=10.00';
curl_setopt($ch, CURLOPT_URL, $URL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($ch, CURLOPT_HTTPHEADER, $paypal_header_options);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$paypal_response = curl_exec($ch);
$responseAr = explode('&', $paypal_response);
$parsedResponseAr = array();
foreach($responseAr as $i => $value) {
$tmpAr = explode('=', $value);
if(!empty($tmpAr))
$parsedResponseAr[strtoupper($tmpAr[0])] = urldecode($tmpAr[1]);
}
print_r(json_encode($parsedResponseAr));
curl_close($ch);
最有可能的PayPal快速支付服务停止/切断,因为错误的身份验证或没有有效的SSL证书颁发的的连接。在这种情况下,请尝试向服务提供商咨询此问题。
希望能解决您的问题。
您的错误是由于您的服务器版本的nss包和api-3t.sandbox.paypal.com使用SNI证书。您可以通过在bash中执行
openssl s_client -servername api-3t.sandbox.paypal.com -tlsextdebug -connect api-3t.sandbox.paypal.com:443 2>/dev/null | grep "server name"
验证。输出是TLS server extension "server name" (id=0), len=0
,表示该服务器具有SNI证书。
解决方案其实很简单。
红帽变种:
sudo yum -y update nss*
对于Debian变种:
sudo apt-get update nss*
你并不真的需要改变你的代码(用于连接明智的问题)
也许您的服务器上有一些阻止这些请求的防火墙规则,您是否可以使用curl访问其他网站从这台服务器?其他HTTPS网站呢? – talkol 2013-03-11 17:28:23
谢谢,奇怪的是我可以很容易地将curl用于其他域,包括'https'连接。 – m90 2013-03-11 17:30:36
看看这里的意见http://stackoverflow.com/questions/12936733/timeout-on-connecting-to-https他们都是有关的出站防火墙限制..有人甚至提到贝宝:) – talkol 2013-03-11 17:37:25