6

我有一个网站可以引导我的客户使用贝宝快速结账。我想为客人提供付款选项,而无需创建贝宝帐户。我有 2 个变量可用于 paypal SetExpressCheckout API 调用,但无法确定将其放置在我的代码中的哪个位置。有人可以帮我弄这个吗?

变量和值:

SOLUTIONTYPE = 唯一的 LANDINGPAGE = 计费

编码:

<?php

/**
 * PayPal class
 */
class PayPal
{
    var $version = "64";

    /**
     * Wether or not use Sandbox mode
     */
    var $sandbox = false;

    /**
     * The API credentials
     */
    var $api_username;
    var $api_password;
    var $api_signature;

    /**
     * The API endpoint and the URL for non-sandbox integration
     */
    var $api_endpoint = 'https://api-3t.paypal.com/nvp';
    var $paypal_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=';

    /**
     * Proxy settings
     */
    var $use_proxy = false;
    var $proxy_host = '127.0.0.1';
    var $proxy_port = 808;

    /**
     * BN Code is only applicable for partners
     */
    var $bncode = "PP-ECWizard";

    /**
     * Some private keys
     */
    private $_token;
    private $_payerId;
    private $_currency = 'EUR';
    private $_paymentType = 'Sale';
    private $_resArray = array();

    /**
     * Constructor
     * @param string $api_username
     * @param string $api_password
     * @param string $api_signature
     */
    public function __construct($api_username, $api_password, $api_signature) {

        $this->api_username = $api_username;
        $this->api_password = $api_password;
        $this->api_signature = $api_signature;
    }

    /**
     * Set Sandbox status
     */
    public function useSandbox() {

        $this->sandbox = true;
        $this->api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
        $this->paypal_url = 'https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=';
    }

    /**
     * When using a proxy server, set the host and port
     * @param string $host
     * @param integer $port
     */
    public function useProxy($host, $port=808) {

        if(!empty($host) && !empty($port) && is_numeric($port)) {

            $this->use_proxy = true;
            $this->proxy_host = $host;
            $this->proxy_port = (integer) $port;
        }
    }

    /**
     * Sets a new BN ocde
     */
    public function setBNcode($bncode=null) {

        $this->bncode = $bncode;
    }

    /**
     * Sets the currency used for the order
     */
    public function setCurrency($currency='EUR') {

        $this->_currency = $currency;
    }

    /**
     * The type of payment is done here
     */
    public function setPaymentType($type='Sale') {

        $this->_paymentType = $type;
    }

    /**
     * An express checkout transaction starts with a token, that
     * identifies to PayPal your transaction
     * In this example, when the script sees a token, the script
     * knows that the buyer has already authorized payment through
     * paypal. If no token was found, the action is to send the buyer
     * to PayPal to first authorize payment
     * 
     * Prepares the parameters for the SetExpressCheckout API Call.
     * 
     * @param string $paymentAmount:        Total value of the shopping cart
     * @param string $returnURL:            the page where buyers return to after they are done with the payment review on PayPal
     * @param string $cancelURL:            the page where buyers return to when they cancel the payment review on PayPal
    */
    function shortcutExpressCheckout($paymentAmount, $returnURL, $cancelURL) 
    {
        // Construct the parameter string that describes the SetExpressCheckout API call in the shortcut implementation
        $nvpstr = '&PAYMENTREQUEST_0_AMT='. $paymentAmount;
        $nvpstr .= '&PAYMENTREQUEST_0_PAYMENTACTION='.$this->_paymentType;
        $nvpstr .= '&RETURNURL='.$returnURL;
        $nvpstr .= '&CANCELURL='.$cancelURL;
        $nvpstr .= '&PAYMENTREQUEST_0_CURRENCYCODE='.$this->_currency;

        // Make the API call to PayPal
        // If the API call succeded, then redirect the buyer to PayPal to begin to authorize payment.
        // If an error occured, show the resulting errors
        $resArray = $this->_hashCall('SetExpressCheckout', $nvpstr);
        $ack = strtoupper($resArray["ACK"]);

        if($ack == 'SUCCESS' || $ack == 'SUCCESSWITHWARNING') {
            $this->_token = urldecode($resArray["TOKEN"]);
        }
        else {
            throw new PayPal_Exception($resArray['L_ERRORCODE0'].': '.$resArray['L_SHORTMESSAGE0'].', '.$resArray['L_LONGMESSAGE0']);
        }

        // save result
        $this->_resArray = $resArray;
    }

    /**
     * Sets a token for confirm purposes
     * @param string $token
     */
    public function setToken($token) {

        if(!empty($token)) {

            $this->_token = $token;
        }
    }

    /**
     * Returns the token set for the current payment
     * @return string
     */
    public function getToken() {

        return $this->_token;
    }

    /**
     * Sets the payer id for confirm purposes
     * @param string $payerid
     */
    public function setPayer($payerid) {

        if(!empty($payerid)) {

            $this->_payerId = $payerid;
        }
    }

    /**
     * Returns the result array set for the current payment
     * @return array
     */
    public function getResult() {

        return $this->_resArray;
    }

    /**
     * Prepares the parameters for the GetExpressCheckoutDetails API Call.
     *
     * @param string $paymentAmount:    The total payment amount.
     * @return object The NVP Collection object of the GetExpressCheckoutDetails Call Response.
     */
    function confirm($paymentAmount)
    {
        // Format the other parameters that were stored in the session from the previous calls
        $serverName = urlencode($_SERVER['SERVER_NAME']);

        $nvpstr = '&TOKEN='.urlencode($this->_token);
        $nvpstr .= '&PAYERID='.urlencode($this->_payerId);
        $nvpstr .= '&PAYMENTREQUEST_0_PAYMENTACTION='.$this->_paymentType;
        $nvpstr .= '&PAYMENTREQUEST_0_AMT='.$paymentAmount;
        $nvpstr .= '&PAYMENTREQUEST_0_CURRENCYCODE='.$this->_currency;
        $nvpstr .= '&IPADDRESS='.$serverName; 

        // Make the call to PayPal to finalize payment
        // if an error occured, show the resulting errors
        $resArray = $this->_hashCall('DoExpressCheckoutPayment', $nvpstr);

        $this->_resArray = $resArray;
    }

    /**
     * Function to perform the API call to PayPal using API signature
     * @param string $methodName:   is name of API  method.
     * @param string $nvpStr:       is nvp string.
     * @return array containing the response from the server.
     */
    private function _hashCall($methodName, $nvpStr)
    {
        // setting the curl parameters.
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->api_endpoint);
        curl_setopt($ch, CURLOPT_VERBOSE, 1);

        // turning 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);

        // if use_proxy set to TRUE, then only proxy will be enabled. 
        if($this->use_proxy) {

            curl_setopt ($ch, CURLOPT_PROXY, $this->proxy_host.':'.$this->proxy_port); 
        }

        // NVPRequest for submitting to server
        $nvpreq = 'METHOD='.urlencode($methodName);
        $nvpreq .= '&VERSION='.urlencode($this->version);
        $nvpreq .= '&PWD='.urlencode($this->api_password);
        $nvpreq .= '&USER='.urlencode($this->api_username);
        $nvpreq .= '&SIGNATURE='.urlencode($this->api_signature);
        $nvpreq .= $nvpStr.'&BUTTONSOURCE='.urlencode($this->bncode);

        // setting the nvpreq as POST FIELD to curl
        curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

        // getting response from server
        $response = curl_exec($ch);

        // convrting NVPResponse to an Associative Array
        $nvpResArray = $this->_deformatNVP($response);
        $nvpReqArray = $this->_deformatNVP($nvpreq);

        // Execute the Error handling module to display errors.
        if(curl_errno($ch)) {

            $error = curl_error($ch);
            throw new PayPal_Exception($error);
        } 
        // closing the curl
        else {

            curl_close($ch);
        }

        return $nvpResArray;
    }

    /**
     * This function will take NVPString and convert it to an Associative Array and it will decode the response.
     * It is usefull to search for a particular key and displaying arrays.
     * @param string $nvpstr is NVPString.
     * @return array $nvpArray is Associative Array.
     **/
    private function _deformatNVP($nvpstr)
    {
        $intial = 0;
        $nvpArray = array();

        while(strlen($nvpstr)) {
            // postion of Key
            $keypos = strpos($nvpstr, '=');

            // position of value
            $valuepos = strpos($nvpstr,'&') ? strpos($nvpstr, '&') : strlen($nvpstr);

            // getting the Key and Value values and storing in a Associative Array
            $keyval = substr($nvpstr, $intial, $keypos);
            $valval = substr($nvpstr, $keypos+1, $valuepos-$keypos-1);

            // decoding the respose
            $nvpArray[urldecode($keyval)] = urldecode($valval);
            $nvpstr = substr($nvpstr, $valuepos+1, strlen($nvpstr));
        }

        return $nvpArray;
    }

    /**
     * Redirects to PayPal.com site.
     */
    public function redirect() {

        $url = $this->paypal_url.$this->_token;
        header("Location: ".$url);
        exit();
    }
}

class PayPal_Exception extends Exception
{
    // Redefine the exception so message isn't optional
    public function __construct($message, $code = 0) {

        // make sure everything is assigned properly
        parent::__construct($message, $code);
    }

    // custom string representation of object
    public function __toString() {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }
}

?>
4

1 回答 1

2

无论您使用的是什么类库,它对 Express Checkout 的作用似乎都非常有限。它基本上是使用最低限度的选项来使其工作。

shortcutExpressCheckout()只接受 3 个参数: $paymentAmount$returnURL$cancelURL. 还有更多内容可以涉及,包括您尝试传递的选项。

在该函数中,他们生成 NVP 字符串并将其分配给 $nvpstr 变量。这是您需要添加新参数以获得所需效果的地方。

尝试这个...

// Construct the parameter string that describes the SetExpressCheckout API call in the shortcut implementation
$nvpstr = '&PAYMENTREQUEST_0_AMT='. $paymentAmount;
$nvpstr .= '&PAYMENTREQUEST_0_PAYMENTACTION='.$this->_paymentType;
$nvpstr .= '&RETURNURL='.$returnURL;
$nvpstr .= '&CANCELURL='.$cancelURL;
$nvpstr .= '&PAYMENTREQUEST_0_CURRENCYCODE='.$this->_currency;
$nvpstr .= '&SOLUTIONTYPE=Sole&LANDINGPAGE=Billing';

那应该为你做......我所做的只是将最后一行添加到这段代码中。

为了将来参考,您可能有兴趣查看我的 PayPal PHP 类库。它比你正在使用的这个更完整,并且使用起来非常简单。

于 2012-12-09T06:21:59.013 回答