Search code examples
phppaypalexpress-checkout

PayPal TransactionID missing from GetExpressCheckoutDetails response


I am using PayPal's GetExpressCheckoutDetails call with a valid token to try and pull the details of a submitted transaction. However, the returned values are a very small subset of what PayPal says should be returned according to their documentation listed at the URL below.

https://developer.paypal.com/docs/classic/api/merchant/GetExpressCheckoutDetails_API_Operation_NVP/

Does anybody know why PayPal isn't returning the complete set of data? I don't care so much about most of it in this case, but we need the transaction ID, listed in the documetation as PAYMENTREQUEST_n_TRANSACTIONID so that we can match transactions in our database up with PayPal's transaction history.

paypalfunctions.php (relevent functions)

function GetShippingDetails( $token ) {
    $nvpstr="&TOKEN=" . $token;
    $resArray=hash_call("GetExpressCheckoutDetails",$nvpstr);
    $ack = strtoupper($resArray["ACK"]);
    if($ack == "SUCCESS" || $ack=="SUCCESSWITHWARNING") {   
        $_SESSION['payer_id'] = $resArray['PAYERID'];
        } 
    return $resArray;
    }

function hash_call($methodName,$nvpStr) {
    global $API_Endpoint, $version, $API_UserName, $API_Password, $API_Signature;
    global $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
    global $gv_ApiErrorURL;
    global $sBNCode;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$API_Endpoint);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);

    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)
        curl_setopt ($ch, CURLOPT_PROXY, $PROXY_HOST. ":" . $PROXY_PORT); 

    $nvpreq="METHOD=" . urlencode($methodName) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . $nvpStr . "&BUTTONSOURCE=" . urlencode($sBNCode);

    curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);

    $response = curl_exec($ch);

    $nvpResArray=deformatNVP($response);
    $nvpReqArray=deformatNVP($nvpreq);
    $_SESSION['nvpReqArray']=$nvpReqArray;

    if (curl_errno($ch)) {
        $_SESSION['curl_error_no']=curl_errno($ch) ;
        $_SESSION['curl_error_msg']=curl_error($ch);
        } else {
        curl_close($ch);
        }

    return $nvpResArray;
    }

function deformatNVP($nvpstr) {
    $intial=0;
    $nvpArray = array();

    while(strlen($nvpstr)) {
        $keypos= strpos($nvpstr,'=');
        $valuepos = strpos($nvpstr,'&') ? strpos($nvpstr,'&'): strlen($nvpstr);

        $keyval=substr($nvpstr,$intial,$keypos);
        $valval=substr($nvpstr,$keypos+1,$valuepos-$keypos-1);
        $nvpArray[urldecode($keyval)] =urldecode( $valval);
        $nvpstr=substr($nvpstr,$valuepos+1,strlen($nvpstr));
        }
    return $nvpArray;
    }

ExpressCheckoutReceipt.php

session_start();
ini_set( "session.bug_compat_warn", "off" );
require_once("paypalfunctions.php");

if ( isset( $_GET['token'] ) ) {
    $token = $_GET['token'];
    }

if ( $token != "" ) {
    $resArray = GetShippingDetails( $token );
    echo "<pre>";
    var_dump( $resArray );
    echo "</pre>";
    } else {
    echo "Error: Transaction Incomplete";
    }

Returned Array (real info removed)

As you can see, this returned array does not contain a Transaction ID. In fact, all of the newer n type variables that PayPal claims will be returned are missing.

    array(21) {
["TOKEN"]=>
  string(20) "EC-XXXXXXXXXXXXXXXXX"
  ["TIMESTAMP"]=>
  string(20) "2014-12-04T22:10:46Z"
  ["CORRELATIONID"]=>
  string(13) "XXXXXXXXXXXXXXX"
  ["ACK"]=>
  string(7) "Success"
  ["VERSION"]=>
  string(3) "2.3"
  ["BUILD"]=>
  string(8) "14086142"
  ["EMAIL"]=>
  string(31) "[email protected]"
  ["PAYERID"]=>
  string(13) "XXXXXXXXXXXXX"
  ["PAYERSTATUS"]=>
  string(8) "verified"
  ["BUSINESS"]=>
  string(25) "TestCo"
  ["FIRSTNAME"]=>
  string(9) "Test"
  ["LASTNAME"]=>
  string(6) "Test"
  ["COUNTRYCODE"]=>
  string(2) "US"
  ["SHIPTONAME"]=>
  string(25) "Test Test"
  ["SHIPTOSTREET"]=>
  string(20) "123 Test St."
  ["SHIPTOCITY"]=>
  string(6) "Test City"
  ["SHIPTOSTATE"]=>
  string(2) "CA"
  ["SHIPTOZIP"]=>
  string(5) "33333"
  ["SHIPTOCOUNTRYCODE"]=>
  string(2) "US"
  ["SHIPTOCOUNTRYNAME"]=>
  string(13) "United States"
  ["ADDRESSSTATUS"]=>
  string(9) "Confirmed"
}

Thanks!


Solution

  • If you can read the comments in the function of getShippingDetails() it says the authorization is not a completed transaction at this state - the buyer still needs an additional step to finalize the transaction

            //'--------------------------------------------------------------
            //' At this point, the buyer has completed authorizing the payment
            //' at PayPal.  The function will call PayPal to obtain the details
            //' of the authorization, incuding any shipping information of the
            //' buyer.  Remember, the authorization is not a completed transaction
            //' at this state - the buyer still needs an additional step to finalize
            //' the transaction
            //'--------------------------------------------------------------
    

    So you also need to call ConfirmPayment() method after this which will call DoExpressCheckoutPayment in the function