Você está na página 1de 6

Paypal and NuSOAP

This is a quick guide to building webservice clients for Paypal SOAP webservices.

If you would like an overview of Paypal integration services, the secured payment gateways or API services it provides, read here.

First things:
If you are trying to build a quick but reliable client code to do a transaction through Paypal SOAP API's, if you are using PHP, then
don't even bother-to, or, worry-about the Paypal SDK or samples that you can download at the Paypal integration center. Trust me,
those samples only make it look like its so complex.

And further, if you had a look at the paypal developer community forums, some posts might make it look like if you are trying things
with NuSOAP or any SOAP SDK other than what PayPal provides, then you are reinventing the wheel.

Things are not as difficult.. and scanning quick through Paypal's SDK and samples for PHP, I had a feeling the whole thing is way too
much for simple requirements like for example 'Sending money to one or more Paypal users through API'.

Samples

What better than understanding things with an easy sample. All samples below are tested with PHP5.x and NuSOAP 0.7.2 (NuSOAP
avaliable here)

For all samples you will need:


1. You should have / will need a Paypal Business account (not the free account or even the premier account), to query Paypal
webservices.. all Paypal integration services are only provided for business accounts.

You can though, test with sandbox/test accounts.. with dummy money, dummy transactions and all. The sandbox user's guide will
help you create such accounts.

2. You will need either,


- a combination of API Username, Password and signature, or,
- an API Certificate (if you can install the certificate on your server).

These things are provided at no extra cost for Business accounts. Again, you can get them with a sandbox test account also.

More details on API signature/certificates here.

To create a sandbox test account, use this Sandbox user's guide.

3. Paypal SOAP API referrence: Just have this pdf document with you while you are developing.. don't worry about going through it
entirely. In below samples, I will give you the only pages you might need to refer to for specific details.. and later as you develop for
more requirements you will refer this document more.

I will make two samples here..


1. A 'get transaction details' sample
2. A 'send money / mass payment' sample

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 the3t 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 partxsi: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"

A 'send money / mass payment' sample:

The most common paypal integration that everybody does is for accepting payments, or 'receiving money' as per paypal terms.On the
paypal website, you can send money to somebody too.. to do this with code or with integration services, there is only one way... make
a 'MassPay' request with Paypal API services.

MassPay, as it says, is for sending money to multiple people at once, up to 250 recipients, and nothing stops you from sending money
to just one person which is as good as the 'send money' thing on the website. But yes, when you do this, it is shown as a 'Mass
Payment' transaction with a separate details link on the website, rather than like a 'send money' transcation.Everything about the
previous sample(in the previous page) and this sample, is same, except the method name and the SOAP request body. We will study
these portions alone.

The MassPay request body:

$bodyReq2 = "
<MassPayReq xmlns="urn:ebay:api:PayPalAPI">
<MassPayRequest>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">$s_Ver</Version>
<EmailSubject xsi:type="xsd:string">my email subj</EmailSubject>

<ReceiverType xmlns="urn:ebay:apis:eBLReceiverInfo">EmailAddress</ReceiverType>

<MassPayItem xmlns="urn.ebay:apis:eBLMassPayItemType">
<ReceiverEmail xmlns="urn.ebay:apis:eBLEmailAddressType">somebody@pookmail.com</ReceiverEmail>
<ReceiverID xsi:type="xsd:string"></ReceiverID>
<Amount xmlns="urn.ebay:apis:eBLBasicAmountType" currencyID="USD">1.50</Amount>
<UniqueId xsi:type="xsd:string">Invoice_134213</UniqueId>
<Note xsi:type="xsd:string">payment body message</Note>
</MassPayItem>
</MassPayRequest>
</MassPayReq>
";

Just like in previous example, the structure of the request is 'MassPay' appended to a 'Req', and then a child element with 'MassPay'
appended to a 'Request'.. and then goes the mandatory version element, and then the inputs for the call.

MassPay requests need to have three items.

1. Email subject - subject of the mail that paypal sends to the receipients saying they have received money from you. If you have
more recipients, this is the same message subject sent to everyone, so don't put usernames or user related information in the subject.

2. ReceiverType - There are two types in which you can mention receipients for the payment, either by their email IDs of their paypal
account, or their paypal id. Using email is preferred more though since you can ask that information from your users easily.

The ReceiverType is a setting for the rest of the inputs. If you say EmailAddress, paypal service will read all your recipient
information as emails. You cannot use emails for some recipients and IDs for some.

3. MassPayItem - This is one block of information saying who is the recipient, and what is the amount of money to send.. apart from
other information like currency, unique reference number, etc.,

For sending money to more than one recipient, just add more MassPayItem elements one after the other in the request.

A MassPayItem shall have the following:

Both 'ReceiverEmail' and 'ReceiverID' elements:


If the ReceiverType = "EmailAddress", then we fill 'ReceiverEmail' element with the recipient's paypal email... else, you fill the
'ReceiverID' element with the person's paypal ID (not email ID).

'Amount' element:
This element's value says the amount that shoudl be sent to the recipient. Having this inside the MassPayItem element allows us to
specify different amounts for each recipient.

You might think, you can send one SOAP request for each user rather than put them all together. But, you will save a lot of money
doing it this way, and that is what MassPayment is all about. Refer to the fee section to verify this, you only spend a maximum of
2USD, how much ever money you send with a Mass Payment request. And though you can have upto 250 recipients, its all together
considered as one request by Paypal services doing this way.

Notice the 'currencyID' attribute in the element. This is a mandatory attribute, and the allowed values are given in Page 21 of the API
ref document.

'UniqueId' element:
This element is only for you... meaning Paypal does nothing with it but just record it as an identifier string with your transaction. The
maximum number of characters this element's value can have is given in the API ref document. If the document says this is an
optional element, you can leave this element if you don't want it.

I use this element for putting an invoice or payment ref id that I have in my application's database.. which provides for a way to later
link each database transaction in my application to a paypal transaction.

'Note' element:
This is just the same note you would type in a texbox on paypal website, when you are sending money manually to somebody. The
message in this element goes with the body of the email paypal sends to the recipient.

Again, if the document says this is an optional element, you can leave this.

Você também pode gostar