【问题标题】:Paypal Express Checkout Error even with live api credentials即使使用实时 api 凭据,Paypal Express 结帐错误
【发布时间】: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(除非我的眼睛欺骗了我)。嗯……

标签: php api curl paypal


【解决方案1】:

此错误表示您未使用正确的 API 凭据。

如果凭据正确,请查看您的端点。

沙盒凭据在生产环境中无效,实时凭据将在沙盒中产生此错误

【讨论】:

  • 您好,我已经说过我没有在生产环境中使用沙箱凭据。您可以阅读我的声明。
  • 错误码是10002。长消息是“Security header is not valid”。
  • 抱歉坚持,请您逐字核对您的凭据。如您所见,这是唯一的可能性。 developer.paypal.com/docs/classic/api/errorcodes 注意:您的凭证上是否有 + 号,有人对此有疑问。 zen-cart.com/…
  • 感谢您的关注@lea。我已经检查了两次和三次,我可以验证凭据没有“+”号。
  • 不客气,很抱歉我能帮到你。 :(
猜你喜欢
  • 1970-01-01
  • 2017-03-21
  • 2016-11-13
  • 1970-01-01
  • 2012-06-30
  • 2016-11-29
  • 2017-03-25
  • 2017-11-01
  • 2020-10-06
相关资源
最近更新 更多