即使使用实时 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 从沙盒切换到真实账户

贝宝休息api

沙盒的 PayPal API 凭据

Paypal:从沙盒上线

带有 paypal ios sdk 的应用程序。沙盒和实时凭据?

API 凭据与 paypal_permissions gem 不正确