即使使用实时 api 凭据,Paypal Express 结帐错误
Posted
技术标签:
【中文标题】即使使用实时 api 凭据,Paypal Express 结帐错误【英文标题】:Paypal Express Checkout Error even with live api credentials 【发布时间】:2015-03-07 07:48:03 【问题描述】:当我想在实时应用程序上执行 Express Checkout 方法时,我收到“错误:安全标头无效”。我已经使用有效的实时 API 凭据设置了 API 凭据,这是我从企业/商家帐户获得的。Api 端点也处于正确状态:https://api-3t.paypal.com/nvp。
我已经在沙盒上使用沙盒 API 凭据和 API 端点 (https://api-3t.sandbox.paypal.com/nvp) 对其进行了测试,它可以正常工作。
我真的不知道怎么了。
我是否需要创建 Paypal 应用程序来进行实时 API 调用?
下面是我使用 php curl 调用 API 的代码。
class CakePalComponent extends Component
/*
* Create your onetime paypal api config,
*/
/*
*set your paypal api mode sandbox/live
*/
private $PayPalMode = 'live';
/*
*set your paypal api username
*/
private $PayPalApiUsername = 'intllabresearchXXX@XXX.com';
/*
*set your paypal api password
*/
private $PayPalApiPassword = 'XXXXLIVEAPIPASSWORD';
/*
*set your paypal api signature
*/
private $PayPalApiSignature = 'XXXXLIVEAPISIGNATURE';
/*
*set your paypal currency code
*/
private $PayPalCurrencyCode = 'USD';
/*
*set your paypal return URL
*/
private $PayPalReturnURL = 'http://intllab.com/apps/posts/ppReturn/';
/*
*set your paypal cancel URL
*/
private $PayPalCancelURL = 'http://intllab.com/apps/posts/ppCancel/';
public function beforeFilter()
//$this->Auth->allow('setExpressCheckout');
public function setExpressCheckout($ppdata)
$paypalmode = ($this->PayPalMode == 'sandbox')?'.sandbox':'';
if (is_array($ppdata))
CakeSession::delete('SessionData');
foreach ($ppdata['items'] as $n => $item)
//remove any array comes with
unset($ppdata['x']);
unset($ppdata['y']);
foreach ($item as $items)
#if tax enable
if (isset($ppdata['tax']))
$tax = $ppdata['tax'];
else
$tax = null;
#if shipping enable
if (isset($ppdata['shipcost']))
$shipcost = $ppdata['shipcost'];
else
$shipcost = null;
#if ship discount enable
if (isset($ppdata['shipdiscount']))
$shipdiscount = $ppdata['shipdiscount'];
else
$shipdiscount = null;
#if handling cost enable
if (isset($ppdata['handlingcost']))
$handlingcost = $ppdata['handlingcost'];
else
$handlingcost = null;
#if insurance cost enable
if (isset($ppdata['insurancecost']))
$insurancecost = $ppdata['insurancecost'];
else
$insurancecost = null;
$tier = 'Tier'.' '.$items['tierid'].':-'.$items['tierdesc'];
#if items quantity is more than 1
$totalprice = $items['price']*$items['quantity'];
$grandtotal = $items['price']+$tax+$shipcost+$shipdiscount+$handlingcost+$insurancecost;
$ppdata = "&METHOD=SetExpressCheckout".
"&RETURNURL=".urlencode($this->PayPalReturnURL).
"&CANCELURL=".urlencode($this->PayPalCancelURL).
"&PAYMENTREQUEST_0_PAYMENTACTION=".urlencode("SALE").
"&L_PAYMENTREQUEST_0_NAME0=".urlencode($items['name']).
"&L_PAYMENTREQUEST_0_NUMBER0=".urlencode($items['id']).
"&L_PAYMENTREQUEST_0_DESC0=".urlencode($tier).
"&L_PAYMENTREQUEST_0_AMT0=".urlencode($items['price']).
"&L_PAYMENTREQUEST_0_QTY0=".urlencode($items['quantity']).
"&NOSHIPPING=0".
"&PAYMENTREQUEST_0_ITEMAMT=".urlencode($totalprice).
"&PAYMENTREQUEST_0_TAXAMT=".urlencode($tax).
"&PAYMENTREQUEST_0_SHIPPINGAMT=".urlencode($shipcost).
"&PAYMENTREQUEST_0_SHIPDISCAMT=".urlencode($shipdiscount).
"&PAYMENTREQUEST_0_HANDLINGAMT=".urlencode($handlingcost).
"&PAYMENTREQUEST_0_INSURANCEAMT=".urlencode($insurancecost).
"&PAYMENTREQUEST_0_AMT=".urlencode($grandtotal).
"&PAYMENTREQUEST_0_CURRENCYCODE=".urlencode($this->PayPalCurrencyCode).
"&PAYMENTREQUEST_0_PAYMENTREQUESTID=".urlencode($items['tier_id']).
"&LOCALECODE=GB".
"&LOGOIMG=http://intllab.com/apps/theme/V6/img/images/logov2longB.png".
#site logo
"&CARTBORDERCOLOR=FFFFFF".
#border color of cart
"&ALLOWNOTE=1";
#write session
CakeSession::write('SessionData', array(
'tier_id' => $items['tier_id'],
'item_name' => $items['name'],
'item_number' => $items['id'],
'item_description' => $tier,
'item_price' => $items['price'],
'item_quantity' => $items['quantity'],
'totalprice' => $totalprice,
'tax' => $tax,
'shipcost' => $shipcost,
'shipdiscount' => $shipdiscount,
'handlingcost' => $handlingcost,
'insurancecost' => $insurancecost,
'grandtotal' => $grandtotal,
));
#begin api contact,execute setExpressCheckout
$httpParsedResponseAr = $this->httpPost('SetExpressCheckout', $ppdata, $this->PayPalApiUsername, $this->PayPalApiPassword, $this->PayPalApiSignature, $this->PayPalMode);
if ("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
$paypalurl = 'https://www'.$paypalmode.'.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].'';
header('Location:'.$paypalurl);
exit;
else
echo 'From CakePal: Error! '.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';
else
return false;
public function doExpressCheckoutPayment($token, $payerID)
$sessionData = CakeSession::read('SessionData');
$ppdata = '&TOKEN='.urlencode($token).
'&PAYERID='.urlencode($payerID).
'&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("SALE").
'&L_PAYMENTREQUEST_0_NAME0='.urlencode($sessionData['item_name']).
'&L_PAYMENTREQUEST_0_NUMBER0='.urlencode($sessionData['item_number']).
'&L_PAYMENTREQUEST_0_DESC0='.urlencode($sessionData['item_description']).
'&L_PAYMENTREQUEST_0_AMT0='.urlencode($sessionData['item_price']).
'&L_PAYMENTREQUEST_0_QTY0='.urlencode($sessionData['item_quantity']).
'&PAYMENTREQUEST_0_ITEMAMT='.urlencode($sessionData['totalprice']).
'&PAYMENTREQUEST_0_TAXAMT='.urlencode($sessionData['tax']).
'&PAYMENTREQUEST_0_SHIPPINGAMT='.urlencode($sessionData['shipcost']).
'&PAYMENTREQUEST_0_HANDLINGAMT='.urlencode($sessionData['handlingcost']).
'&PAYMENTREQUEST_0_SHIPDISCAMT='.urlencode($sessionData['shipdiscount']).
'&PAYMENTREQUEST_0_INSURANCEAMT='.urlencode($sessionData['insurancecost']).
'&PAYMENTREQUEST_0_PAYMENTREQUESTID='.urlencode($sessionData['tier_id']).
'&PAYMENTREQUEST_0_AMT='.urlencode($sessionData['grandtotal']).
'&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode($this->PayPalCurrencyCode);
#begin api contact,execute doExpressCheckoutPayment
$httpParsedResponseAr = $this->httpPost('DoExpressCheckoutPayment', $ppdata, $this->PayPalApiUsername, $this->PayPalApiPassword, $this->PayPalApiSignature, $this->PayPalMode);
if ("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]))
return true;
else
return $httpParsedResponseAr["L_LONGMESSAGE0"];
public function getExpressCheckoutDetails($token, $payerID)
$ppdata = '&TOKEN='.urlencode($token);
#begin api contact,execute setExpressCheckoutDetails
$httpParsedResponseAr = $this->httpPost('GetExpressCheckoutDetails', $ppdata, $this->PayPalApiUsername, $this->PayPalApiPassword, $this->PayPalApiSignature, $this->PayPalMode);
if (strtoupper($httpParsedResponseAr["ACK"]) == "SUCCESS" || strtoupper($httpParsedResponseAr["ACK"]) == "SUCCESSWITHWARNING")
return $httpParsedResponseAr;
else
return false;
CakeSession::destroy('SessionData');
function httpPost($methodName_, $nvpStr_, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode)
$API_UserName = urlencode($this->PayPalApiUsername);
$API_Password = urlencode($this->PayPalApiPassword);
$API_Signature = urlencode($this->PayPalApiSignature);
$paypalmode = ($this->PayPalMode == 'sandbox')?'.sandbox':'';
$API_Endpoint = "https://api-3t".$paypalmode.".paypal.com/nvp";
$version = urlencode('119');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
$httpResponse = curl_exec($ch);
if (!$httpResponse)
exit("$methodName_ failed: " .curl_error($ch).'('.curl_errno($ch).')');
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value)
$tmpAr = explode("=", $value);
if (sizeof($tmpAr) > 1)
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
if ((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr))
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
return $httpParsedResponseAr;
非常感谢您的宝贵时间。
【问题讨论】:
检查您的 Paypal API 用户名 - 您上面的内容看起来像是一个电子邮件地址,但它不应该是(当然,我只是根据您上面的内容)。 嗨@EdSF。我从我的企业帐户上的 API 签名生成器获取用户名凭据。它给了我这种用户名“intllabresearch_myapi1.gmail.com”,我该怎么办? 这实际上看起来是正确的(如果那是您的实际 api 用户名,请从这个 public 论坛中删除它)。 不,这不是实际的 api 用户名。我只是举个例子。 我不是 PHP 开发人员,所以..检查您传递给httpPost
的字符串 $ppdata
- 它可能只是格式错误。我认为您在setExpressCheckout
中发送了两次METHOD
(除非我的眼睛欺骗了我)。嗯……
【参考方案1】:
此错误表示您未使用正确的 API 凭据。
如果凭据正确,请查看您的端点。
沙盒凭据在生产环境中无效,实时凭据将在沙盒中产生此错误
【讨论】:
您好,我已经说过我没有在生产环境中使用沙箱凭据。您可以阅读我的声明。 错误码是10002。长消息是“Security header is not valid”。 抱歉坚持,请您逐字核对您的凭据。如您所见,这是唯一的可能性。 developer.paypal.com/docs/classic/api/errorcodes 注意:您的凭证上是否有 + 号,有人对此有疑问。 zen-cart.com/… 感谢您的关注@lea。我已经检查了两次和三次,我可以验证凭据没有“+”号。 不客气,很抱歉我能帮到你。 :(以上是关于即使使用实时 api 凭据,Paypal Express 结帐错误的主要内容,如果未能解决你的问题,请参考以下文章
PayPal - 使用 REST API 从沙盒切换到真实账户