Paypal API issues, using PHP5 and nusoap

Posted 1 year, 6 months ago on August 27, 2006 by dave #

Back in Aug 2005, I found something wrong with the http://www.paypal.com/wsdl/PayPalSvc.wsdl file, it’s still a problem!

I have a really interesting situation trying to retrieve order information from Paypal. I compiled PHP 5.0.4 –with-soap thinking that I would just use the built in Soap implemention that comes with PHP5. So, I start with PayPal’s GetTransactionDetails API call. It didn’t work because the service address location defined in the production WSDL has the sandbox URL in it. I complained about this to Paypal, they ignored it, and even released another, version 2.0, of their WSDL with the same mistake in it. I don’t know what they’re doing over there… I can hardly believe that they are allowing this mistake to continue to live in production for weeks (now becoming months).

My workaround to this initial problem was to download the WSDL onto my own website, make the corrections myself, and point my service to my version of the PayPal WSDL. You can see it at http://www.modphp.org/PayPalSvc.wsdl (compared to Paypal’s version at http://www.paypal.com/wsdl/PayPalSvc.wsdl

(I just looked again, Aug 2006, and there is a lot that has changed, so the main point of this is mererly:

1841c798
<                       <wsdlsoap:address location=”https://api.sandbox.paypal.com/2.0/”/>

>                       <wsdlsoap:address location=”https://api.paypal.com/2.0/”/>
1844c801
<                       <wsdlsoap:address location=”https://api-aa.sandbox.paypal.com/2.0/”/>

>                       <wsdlsoap:address location=”https://api-aa.paypal.com/2.0/”/>

)

Now I can GetTransactionDetails, yeah!

Next problem: the other API call I want to make is TransactionSearch API. I found that whenever I make this call using PHP’s Soap and only one match is found, it works fine. But, when the result is multiple results, PHP Seg faults. I’ve tried for hours to fix this, recompiled PHP several times. I finally moved to nusoap… but when I include nusoap, I cannot create a new soapclient object, because the name soapclient is reserved by PHP – I cannot redeclare it in nusoap. The solution to this is to rename all occurances of soapclient in the nusoap.php file with nusoapclient.

Yeah, problem was resolved, until Aug 18, when PayPal published their new version of their WSDL and service. My function (above in my last post) stopped working. I had to find a new way to make the call. Here is the result:

define( ‘PAYPAL_WSDL’, ‘http://www.modphp.org/PayPalSvc.wsdl’);
define( ‘PAYPAL_USERNAME’, ‘xxxxxxxxxxxxxxxxxxxxx’);
define( ‘PAYPAL_PASSWORD’, ‘xxxxxxxxxxxxx’);
define( ‘PAYPAL_CERT_PATH’, ‘/path/to/cert.pem’ );

 function getTransaction( $id )
 {
   $soap = new SoapClient(PAYPAL_WSDL, array( ‘trace’ => true, ‘soap_version’ => SOAP_1_1, ‘local_cert’ => PAYPAL_CERT_PATH ));
   $soapHeader = new SoapHeader(“urn:ebay:api:PayPalAPI”, “RequesterCredentials”, array(
                                                                               “Credentials” => new SoapVar(array(
                                                                               “Username” => PAYPAL_USERNAME,
                                                                               “Password” => PAYPAL_PASSWORD,
                             “Subject”   => null), SOAP_ENC_OBJECT, NULL, NULL, NULL, “urn:ebay:apis:eBLBaseComponents”)
                                                                               ), 1);
   $params = array(‘GetTransactionDetailsRequest’=>array(‘Version’ => ‘1.0’, ‘TransactionID’ => $id));
   try{
     $result = $soap->__soapCall(“GetTransactionDetails”, array($params), NULL, $soapHeader);
   }
   catch (Exception $e)
   {
     echo “Caught exception: “. $e->getMessage() . “n”;
     _dPrint($result);
     if (is_soap_fault($result)) {
      trigger_error(“SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})”, E_ERROR);
     }
     return array();
   }

#print_r($soap->__getLastRequest());

   return $result;
 }

 function getTransactions( $startdate=false, $enddate=false )
 {
   require_once(“nusoap.php”);
   $startdate = $startdate ? strtotime($startdate) : time()-86400;
   $startdate = date(“Y-m-dTH:i:s-0700″, $startdate);
   $enddate = $enddate ? strtotime($enddate) : time();
   $enddate = date(“Y-m-dTH:i:s-0700″, $enddate);
   $result = array();

       $client = new nusoapclient(“https://api.paypal.com/2.0/”);
       $client->authtype = “certificate”;
       $client->certRequest = array ( ‘sslcertfile’ => PAYPAL_CERT_PATH );

       $msg = ‘<?xml version=”1.0″ encoding=”UTF-8″?>
       <SOAP-ENV:Envelope xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:ns1=”urn:ebay:apis:eBLBaseComponents” xmlns:ns2=”urn:ebay:api:PayPalAPI”><SOAP-ENV:Header><ns2:RequesterCredentials SOAP-ENV:mustUnderstand=”1″><ns1:Credentials>
           <Username>’.PAYPAL_USERNAME.'</Username>
           <Password>’.PAYPAL_PASSWORD.'</Password>
           <Subject/>
           </ns1:Credentials></ns2:RequesterCredentials></SOAP-ENV:Header><SOAP-ENV:Body>
           <ns2:TransactionSearchReq>
           <ns2:TransactionSearchRequest>
             <ns1:Version>1.0</ns1:Version>
             <ns2:StartDate>’.$startdate.'</ns2:StartDate>
             <ns2:EndDate>’.$enddate.'</ns2:EndDate>
           </ns2:TransactionSearchRequest>
           </ns2:TransactionSearchReq></SOAP-ENV:Body></SOAP-ENV:Envelope>';
       $result = $client->send($msg);

       // Check for a fault
       if ($client->fault) {
               echo ‘<h2>Fault</h2><pre>';
               print_r($result);
               echo ‘</pre>';
               return array();
       } else {
               // Check for errors
               $err = $client->getError();
               if ($err) {
                       // Display the error
                       echo ‘<h2>Error</h2><pre>’ . $err . ‘</pre>';
                       return array();
               }
       }
   return $result[‘PaymentTransactions’];
 }

Dave.

34 thoughts on “Paypal API issues, using PHP5 and nusoap

  1. Just wanted to say thanks for posting this.

    I knew there must be some way to send pre-written XML to the service, I was using
    $client->call()
    which obviously wasn’t going to work.

    PS. I like your authentication system – another use of webservices?

Comments are closed.