php将自定义值发送到Paypal Express结帐并再次捕获值

时间:2017-01-07 04:21:21

标签: php paypal paypal-sandbox

我已经设置了快速结账。它做得很好。但我想发送一些自定义值,并再次想要抓住它们。基本上我的index.php就像这样

<form method="post" action="process.php?paypal=checkout">
    <input type="hidden" name="itemname" value="Canon EOS Rebel XS" /> 
    <input type="hidden" name="itemnumber" value="10000" /> 
    <input type="hidden" name="itemdesc" value="Capture all your special moments with the Canon EOS Rebel XS/1000D DSLR camera and cherish the memories over and over again." /> 
    <input type="hidden" name="itemprice" value="225.00" />
    <input type='hidden' name='user_id' value='2'>
    Quantity : <select name="itemQty"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select> 
    <input class="dw_button" type="submit" name="submitbutt" value="Buy (225.00 <?php echo PPL_CURRENCY_CODE; ?>)" />
</form>

然后process.php文件就像这样

<?php
include_once("config.php");
include_once("functions.php");
include_once("paypal.class.php");

    $paypal= new MyPayPal();

    //Post Data received from product list page.
    if(_GET('paypal')=='checkout'){     
        $products = [];
        $products[0]['ItemName'] = _POST('itemname'); //Item Name
        $products[0]['ItemPrice'] = _POST('itemprice'); //Item Price
        $products[0]['ItemNumber'] = _POST('itemnumber'); //Item Number
        $products[0]['ItemDesc'] = _POST('itemdesc'); //Item Number
        $products[0]['ItemQty'] = _POST('itemQty'); // Item Quantity
        $charges = [];

        //Other important variables like tax, shipping cost
        $charges['TotalTaxAmount'] = 0;  //Sum of tax for all items in this order. 
        $charges['HandalingCost'] = 0;  //Handling cost for this order.
        $charges['InsuranceCost'] = 0;  //shipping insurance cost for this order.
        $charges['ShippinDiscount'] = 0; //Shipping discount for this order. Specify this as negative number.
        $charges['ShippinCost'] = 0; //Although you may change the value later, try to pass in a shipping amount that is reasonably accurate.
        $paypal->SetExpressCheckOut($products, $charges);       
    }
    elseif(_GET('token')!=''&&_GET('PayerID')!=''){

        print_r($paypal->DoExpressCheckoutPayment());
        echo $_GET['OrderID'];
    }
    else{


    }

config.php is like this
<?php

  //start session in all pages
  if (session_status() == PHP_SESSION_NONE) { session_start(); } //PHP >= 5.4.0
  //if(session_id() == '') { session_start(); } //uncomment this line if PHP < 5.4.0 and comment out line above

    // sandbox or live
    define('PPL_MODE', 'sandbox');

    if(PPL_MODE=='sandbox'){

        define('PPL_API_USER', 'XXXXX');
        define('PPL_API_PASSWORD', 'XXXXX');
        define('PPL_API_SIGNATURE', 
            'XXXXXXXXXX');
    }
    else{

        define('PPL_API_USER', 'XXXXX');
        define('PPL_API_PASSWORD', 'XXXXX');
        define('PPL_API_SIGNATURE', 'XXXXXXXXXX');
    }

    define('PPL_LANG', 'EN');

    define('PPL_LOGO_IMG', 'http://localhost/paypal/img/logo.png');

    define('PPL_RETURN_URL', 'http://localhost/paypal/process.php');
    define('PPL_CANCEL_URL', 'http://localhost/paypal/cancel_url.php');

    define('PPL_CURRENCY_CODE', 'EUR');

functions.php是这样的

function _GET($label='',$default='',$set_default=false){

    $value=$default;

    if(isset($_GET[$label])&&!empty($_GET[$label])){

        $value=$_GET[$label];
    }

    if($set_default===true&&(!isset($_GET[$label])||$_GET[$label]=='')){

        $_GET[$label]=$default;
    }

    return $value;      
}

function _POST($label='',$default='',$set_default=false){

    $value=$default;

    if(isset($_POST[$label])&&!empty($_POST[$label])){

        $value=$_POST[$label];
    }

    if($set_default===true&&(!isset($_POST[$label])||$_POST[$label]=='')){

        $_POST[$label]=$default;
    }       

    return $value;      
}   

function _SESSION($label='',$default='',$set_default=false){

    $value=$default;

    if(isset($_SESSION[$label])&&!empty($_SESSION[$label])){

        $value=$_SESSION[$label];
    }

    if($set_default===true&&(!isset($_SESSION[$label])||$_SESSION[$label]=='')){

        $_SESSION[$label]=$default;
    }   

    return $value;      
}   

和paypal.class.php文件就像这样

    function GetProductsTotalAmount($products){
        $ProductsTotalAmount=0;
        foreach($products as $p => $item){
            $ProductsTotalAmount = $ProductsTotalAmount + $this -> GetItemTotalPrice($item);    
        }

        return $ProductsTotalAmount;
    }

    function GetGrandTotal($products, $charges){
        $GrandTotal = $this -> GetProductsTotalAmount($products);

        foreach($charges as $charge){
            $GrandTotal = $GrandTotal + $charge;
        }

        return $GrandTotal;
    }

    function SetExpressCheckout($products, $charges, $noshipping='1'){
        $padata  =  '&METHOD=SetExpressCheckout';           
        $padata .=  '&RETURNURL='.urlencode(PPL_RETURN_URL);
        $padata .=  '&CANCELURL='.urlencode(PPL_CANCEL_URL);
        $padata .=  '&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("SALE");

        foreach($products as $p => $item){

            $padata .=  '&L_PAYMENTREQUEST_0_NAME'.$p.'='.urlencode($item['ItemName']);
            $padata .=  '&L_PAYMENTREQUEST_0_NUMBER'.$p.'='.urlencode($item['ItemNumber']);
            $padata .=  '&L_PAYMENTREQUEST_0_DESC'.$p.'='.urlencode($item['ItemDesc']);
            $padata .=  '&L_PAYMENTREQUEST_0_AMT'.$p.'='.urlencode($item['ItemPrice']);
            $padata .=  '&L_PAYMENTREQUEST_0_QTY'.$p.'='. urlencode($item['ItemQty']);
        }       

        $padata .=  '&NOSHIPPING='.$noshipping; 

        $padata .=  '&PAYMENTREQUEST_0_ITEMAMT='.urlencode($this -> GetProductsTotalAmount($products));

        $padata .=  '&PAYMENTREQUEST_0_TAXAMT='.urlencode($charges['TotalTaxAmount']);
        $padata .=  '&PAYMENTREQUEST_0_SHIPPINGAMT='.urlencode($charges['ShippinCost']);
        $padata .=  '&PAYMENTREQUEST_0_HANDLINGAMT='.urlencode($charges['HandalingCost']);
        $padata .=  '&PAYMENTREQUEST_0_SHIPDISCAMT='.urlencode($charges['ShippinDiscount']);
        $padata .=  '&PAYMENTREQUEST_0_INSURANCEAMT='.urlencode($charges['InsuranceCost']);
        $padata .=  '&PAYMENTREQUEST_0_AMT='.urlencode($this->GetGrandTotal($products, $charges));
        $padata .=  '&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode(PPL_CURRENCY_CODE);


        $padata .=  '&LOCALECODE='.PPL_LANG; //PayPal pages to match the language on your website;
        $padata .=  '&LOGOIMG='.PPL_LOGO_IMG; //site logo
        $padata .=  '&CARTBORDERCOLOR=FFFFFF'; //border color of cart
        $padata .=  '&ALLOWNOTE=1';


        $_SESSION['ppl_products'] =  $products;
        $_SESSION['ppl_charges']    =  $charges;

        $httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $padata);

        //Respond according to message we receive from Paypal
        if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){

            $paypalmode = (PPL_MODE=='sandbox') ? '.sandbox' : '';

            $paypalurl ='https://www'.$paypalmode.'.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].'';

            header('Location: '.$paypalurl);
        }
        else{

            echo '<div style="color:red"><b>Error : </b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';

            echo '<pre>';

                print_r($httpParsedResponseAr);

            echo '</pre>';
        }   
    }       


    function DoExpressCheckoutPayment(){

        if(!empty(_SESSION('ppl_products'))&&!empty(_SESSION('ppl_charges'))){

            $products=_SESSION('ppl_products');

            $charges=_SESSION('ppl_charges');

            $padata  =  '&TOKEN='.urlencode(_GET('token'));
            $padata .=  '&PAYERID='.urlencode(_GET('PayerID'));
            $padata .=  '&PAYMENTREQUEST_0_PAYMENTACTION='.urlencode("SALE");

            //set item info here, otherwise we won't see product details later  

            foreach($products as $p => $item){

                $padata .=  '&L_PAYMENTREQUEST_0_NAME'.$p.'='.urlencode($item['ItemName']);
                $padata .=  '&L_PAYMENTREQUEST_0_NUMBER'.$p.'='.urlencode($item['ItemNumber']);
                $padata .=  '&L_PAYMENTREQUEST_0_DESC'.$p.'='.urlencode($item['ItemDesc']);
                $padata .=  '&L_PAYMENTREQUEST_0_AMT'.$p.'='.urlencode($item['ItemPrice']);
                $padata .=  '&L_PAYMENTREQUEST_0_QTY'.$p.'='. urlencode($item['ItemQty']);
            }

            $padata .=  '&PAYMENTREQUEST_0_ITEMAMT='.urlencode($this -> GetProductsTotalAmount($products));
            $padata .=  '&PAYMENTREQUEST_0_TAXAMT='.urlencode($charges['TotalTaxAmount']);
            $padata .=  '&PAYMENTREQUEST_0_SHIPPINGAMT='.urlencode($charges['ShippinCost']);
            $padata .=  '&PAYMENTREQUEST_0_HANDLINGAMT='.urlencode($charges['HandalingCost']);
            $padata .=  '&PAYMENTREQUEST_0_SHIPDISCAMT='.urlencode($charges['ShippinDiscount']);
            $padata .=  '&PAYMENTREQUEST_0_INSURANCEAMT='.urlencode($charges['InsuranceCost']);
            $padata .=  '&PAYMENTREQUEST_0_AMT='.urlencode($this->GetGrandTotal($products, $charges));
            $padata .=  '&PAYMENTREQUEST_0_CURRENCYCODE='.urlencode(PPL_CURRENCY_CODE);

            //We need to execute the "DoExpressCheckoutPayment" at this point to Receive payment from user.

            $httpParsedResponseAr = $this->PPHttpPost('DoExpressCheckoutPayment', $padata);

            //vdump($httpParsedResponseAr);

            //Check if everything went ok..
            if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){

                echo '<h2>Success</h2>';
                echo 'Your Transaction ID : '.urldecode($httpParsedResponseAr["PAYMENTINFO_0_TRANSACTIONID"]);

                /*
                //Sometimes Payment are kept pending even when transaction is complete. 
                //hence we need to notify user about it and ask him manually approve the transiction
                */

                if('Completed' == $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]){

                    echo '<div style="color:green">Payment Received! Your product will be sent to you very soon!</div>';
                }
                elseif('Pending' == $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]){

                    echo '<div style="color:red">Transaction Complete, but payment may still be pending! '.
                    'If that\'s the case, You can manually authorize this payment in your <a target="_new" href="http://www.paypal.com">Paypal Account</a></div>';
                }

                $this->GetTransactionDetails();
            }
            else{

                echo '<div style="color:red"><b>Error : </b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';

                echo '<pre>';

                    print_r($httpParsedResponseAr);

                echo '</pre>';
            }
        }
        else{

            // Request Transaction Details

            $this->GetTransactionDetails();
        }
    }

    function GetTransactionDetails(){

        // we can retrive transection details using either GetTransactionDetails or GetExpressCheckoutDetails
        // GetTransactionDetails requires a Transaction ID, and GetExpressCheckoutDetails requires Token returned by SetExpressCheckOut

        $padata =   '&TOKEN='.urlencode(_GET('token'));

        $httpParsedResponseAr = $this->PPHttpPost('GetExpressCheckoutDetails', $padata, PPL_API_USER, PPL_API_PASSWORD, PPL_API_SIGNATURE, PPL_MODE);

        if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){

            echo '<br /><b>Stuff to store in database :</b><br /><pre>';

            echo '<pre>';

                print_r($httpParsedResponseAr);

            echo '</pre>';
        } 
        else  {

            echo '<div style="color:red"><b>GetTransactionDetails failed:</b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';

            echo '<pre>';

                print_r($httpParsedResponseAr);

            echo '</pre>';

        }
    }

    function PPHttpPost($methodName_, $nvpStr_) {

            // Set up your API credentials, PayPal end point, and API version.
            $API_UserName = urlencode(PPL_API_USER);
            $API_Password = urlencode(PPL_API_PASSWORD);
            $API_Signature = urlencode(PPL_API_SIGNATURE);

            $paypalmode = (PPL_MODE=='sandbox') ? '.sandbox' : '';

            $API_Endpoint = "https://api-3t".$paypalmode.".paypal.com/nvp";
            $version = urlencode('109.0');

            // Set the curl parameters.
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
            curl_setopt($ch, CURLOPT_VERBOSE, 1);
            //curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');

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

            // Set the API operation, version, and API signature in the request.
            $nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";

            // Set the request as a POST FIELD for curl.
            curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

            // Get response from the server.
            $httpResponse = curl_exec($ch);

            if(!$httpResponse) {
                exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
            }

            // Extract the response details.
            $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;
    }
}

所以有人可以告诉我如何将user_id的值发送到paypal并再次从paypal获取值。

1 个答案:

答案 0 :(得分:0)

简短而甜蜜的方式是使用PAYMENTREQUEST_0_CUSTOM参数传递DoExpressCheckoutPayment请求中的user_id值。此参数可用于存储最多256个字符的数据。

如果您正在使用IPN,您将获得$ _POST ['custom']并且它将具有您传入的相同值。如果您使用GetTransactionDetails来提取有关交易的详细信息,它也将可用。

另一种选择是使用PAYMENTREQUEST_0_INVNUM将发票ID传递给PayPal。这将假设您有某种与您的用户记录相关的订单/发票记录。

这样,PayPal详细信息将包含您的实际订单ID,并将在IPN,GetTransactionDetails等中返回。使用该ID,您可以随时撤回相关的用户数据。