Categories
PHP
Javascript
MySQL
C#
VB
VB.NET
ASP.NET
Regex
Packaging & compression
General Web Tech
Tech Speak


Google


This website looks best on firefox.
 
Resource Center : Tech Speak : <Paypal and NuSOAP>

Paypal and NuSOAP

Posted by: Floresense Team
Pages: 1  2  3  

A 'get transaction details' sample:

This sample will query Paypal webservices regarding a transaction on your paypal account with the transaction ID, and get details of the transaction as a response.

All things you need:
1. A TransactionID from your account.

Login to your paypal account and get one from your transaction history.
If you are using a sandbox test account, add some dummy funds through the sandbox paypal login, send money to somebody creating a transaction and note down its transaction ID... if you need help on how to do all this with the test accounts, is explained in the sandbox user's guide.

The basic blocks:

First, include the nusoap library in your code... from whatever path you want to apply. I generally put my NuSOAP libraries inside a folder structure like php/nusoap/ and hence the below path.

include_once("php/nusoap/nusoap.php");

Then, set the constants

$wsdl_URL = "https://api.sandbox.paypal.com/wsdl/PayPalSvc.wsdl";
$s_URL = "https://api-3t.sandbox.paypal.com/2.0/";

The above are the wsdl and SOAP endpoint URLs we will use. Note that we are using the sandbox URLs here assuming we are going to read details of a transaction from a Paypal test user/sandbox user account.

A note about the above URLs:
The wsdl and end-point URLs for a production service or live (non-test) service is different from the above.
Also, the above end-point URL is for testing with API username-pass-signature security, and hence the 3t in the end-point url. For testing with API certificate, the end-point URL is different.

All URLs are clearly tabulated in the API referrence docs's Pages 12 and 15. Use the apporpriate URLs.

Get version information:

$s_Ver = "3.2";

The above is the version number of the wsdl found in the given URL. This version number has to be passed in the SOAP request we create, otherwise the server just rejects the request with 'Incompatible version' errors.

You can code to extract the version number from the wsdl xml itself.. but I just made it easy for myself by hard-coding it. 

Set HEADER constants for SOAP request

$header = "".
"<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType">".
 "<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType">".
  "<Username>@api_username@</Username>".
  "<Password>@api_password@</Password>".
  "<Signature>@api_signature@</Signature>".
 "</Credentials>".
"</RequesterCredentials>";
  $api_username = "your api username here";
  $api_password = "your api password";
  $api_signature= "your long api signature";

The above constants are for allowing us create a Header element for our SOAP Envelope.

You should be wondering why I am creating the xml manually without doing it through NuSOAP. Paypal webservices have a strange request structure out of what is done in normal webservices... and even a slight variation in the structure of the request is rejected outright with fault codes.

After much trial-n-error, the best way I learnt is to create the requests manually as strings, and just send them to the server using NuSOAP.

Yes, this way we are not using NuSOAP much. But NuSOAP still helps in all other parts, where if we didn't use NuSOAP we would be having the overhead of coding directly with sockets, parsing responses ourselves, and all.

Instantiate soapclient class.

$s = new nu_soapclient($wsdl_URL, true);

Open a new soapclient object.. notice that I call it nu_soapclient. Actually in nusoap library, the classname is only soapclient. But since I use PHP5, and since PHP5 has a built-in soapclient class, they both clash. I had to do a find-replace in all nusoap files for changing soapclient to nu_soapclient. This is a problem with many people's webservices when they migrate from PHP4 to PHP5 and their services or clients stop working.

Handling instantiating errors

 $err = $s->getError();
 if ($err)
  die("Soap client constructor err.. check wsdl url");

Verify that the soapclient instance is successfully created. It can fail if your wsdl url is not available. and you should fail trying the rest of the code.

Set the end point URL.

//set end point
 $s->setEndpoint($s_URL);

Once successfully read the wsdl, all we have to do is set the end-point url and send the soap request. The above code sets the end point URL.

Note:
Notice that we use two URLs here.. one wsdl and one endpoint url. If you have used NuSOAP before, you might have just used one URL.. which serves as both the endpoint and the wsdl url.

Here since our wsdl and endpoint URLs we use are different, we first create the soapclient object with the wsdl URL and notice that we mention a second parameter 'true' during object creation. The true is for saying that the URL is a wsdl URL. By default it is false, and the url is assumed as the end-point URL.

You can't send SOAP requests to the wsdl URL we have, only the end-point knows how to process the requests...and hence we set the end-point URL.

Make and set the HEADER for the SOAP request

//add header
 $tmp_header = $header;
 
 $tmp_header = str_replace("@api_username@", $api_username, $tmp_header);
 $tmp_header = str_replace("@api_password@", $api_password, $tmp_header);
 $tmp_header = str_replace("@api_signature@", $api_signature, $tmp_header);
 $s->setHeaders($tmp_header);

 With above code, we prepare the header and set it to the SOAP request. NuSOAP will take care of creating the template of the request.. we only push the header and the body parts manually.

Prepare the body of the request

$bodyReq = "
<GetTransactionDetailsReq xmlns="urn:ebay:api:PayPalAPI">
<GetTransactionDetailsRequest>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">$s_Ver</Version>
<TransactionID xsi:type="xsd:string">0BX72473A6277713F</TransactionID>
</GetTransactionDetailsRequest>
</GetTransactionDetailsReq>
";

The above is the xml request structure for the Paypal API method GetTransactionDetails. We will shortly study the structure of this xml using our API ref document.

Notice the input we send 'TransactionID' plugged into the request's body.

Also, notice that we plug the Version information into the request's body. The version element is mandatory in every SOAP request sent to Paypal.

And now, send the request:

$result = $s->call("GetTransactionDetails", $bodyReq);

The above code makes the SOAP request to the endpoint URL. It mentions the method we are trying to access GetTransactionDetails. The second parameter is the request's body.

NuSOAP plugs the body into the request it has generated for us with the header also in place, and then sends the request to the server.

The full code:

 
include_once("php/nusoap/nusoap.php");
 
$wsdl_URL = "https://api.sandbox.paypal.com/wsdl/PayPalSvc.wsdl";
$s_URL = "https://api-3t.sandbox.paypal.com/2.0/";
$s_Ver = "3.2";
 
$header = "".
"<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xsi:type="ebl:CustomSecurityHeaderType">".
 "<Credentials xmlns="urn:ebay:apis:eBLBaseComponents" xsi:type="ebl:UserIdPasswordType">".
  "<Username>@api_username@</Username>".
  "<Password>@api_password@</Password>".
  "<Signature>@api_signature@</Signature>".
 "</Credentials>".
"</RequesterCredentials>";
 
 $api_username = "your api username here";
  $api_password = "your api password";
  $api_signature= "your long api signature";
 
 
 
 $s = new nu_soapclient($wsdl_URL, true);
 
$err = $s->getError();
 if ($err)
  die("Soap client constructor err.. check wsdl url");
 
 //set end point
 $s->setEndpoint($s_URL);
 
 
//add header
 $tmp_header = $header;
 
 $tmp_header = str_replace("@api_username@", $api_username, $tmp_header);
 $tmp_header = str_replace("@api_password@", $api_password, $tmp_header);
 $tmp_header = str_replace("@api_signature@", $api_signature, $tmp_header);
 
 $s->setHeaders($tmp_header);
 
$bodyReq = "
<GetTransactionDetailsReq xmlns="urn:ebay:api:PayPalAPI">
<GetTransactionDetailsRequest>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">$s_Ver</Version>
<TransactionID xsi:type="xsd:string">0BX72473A6277713F</TransactionID>
</GetTransactionDetailsRequest>
</GetTransactionDetailsReq>
";
 
$result = $s->call("GetTransactionDetails", $bodyReq);
 
//check whether response has Faultcodes.
if (!$err = $s->getError())
 echo "Result: $result";
else
 echo "Error: $err";
 
// For debugging the request xml    
echo "<xmp>".$s->request."</xmp>";
 
// For viewing response xml
echo "<xmp>".$s->response."</xmp>";
 

The last few lines process the xml response received from the server. NuSOAP's getError() method helps us extract fault messages if any embedded in the response.

The later lines that print the request and the response xml help in debugging.

Especially, if you have errors or fault codes from the server, you have to study the xml request that NuSOAP generated and sent to the server. Comparing the request structure to the request template explained in page 16 of the API ref document. Also, you can compare the structure to the wsdl definitions in the wsdl URL, and if needed appropriately modify the body string that you add to the request.

Building the request xml:

$bodyReq = "
<GetTransactionDetailsReq xmlns="urn:ebay:api:PayPalAPI">
<GetTransactionDetailsRequest>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">$s_Ver</Version>
<TransactionID xsi:type="xsd:string">0BX72473A6277713F</TransactionID>
</GetTransactionDetailsRequest>
</GetTransactionDetailsReq>
";

Unfortunately, Paypal website or documents, or the developer community don't seem to have a one-stop place where all sample request templates for all methods are put up. We need this, because Paypal has this strange thing of having the actual method name appended with a 'Req' and then mandatorily have a child element with the method name and a 'Request'.. and so on. And this is actually why we can't use NuSOAP or any library to generate the request.

But, if you create your requests based on the wsdl definition then you don't need any other referrences. Paypal documents will only confuse you by having the method name different from the actual method name you should call and all that.

But the basics are like this:

To query the method 'GetTransactionDetails'

1. Create the element GetTransactionDetailsReq with the namespace "urn:ebay:api:PayPalAPI"

2. Create a child element GetTransactionDetailsRequest

3. Put the inputs for the method inside this child. Make sure your inputs have the proper types or namespaces set.

For ex, if you refere the wsdl you will see that TransactionID is of type string. Just copy this part xsi:type="xsd:string" from the wsdl and add it.
Also, for the mandatory Version information, you have to apply the namespace "urn:ebay:apis:eBLBaseComponents"

Sample 2 - A send money /MassPay request sample.. in next page

Pages: 1  2  3  

Advertisement

2005 - 2008 © Floresense.com