505 lines
19 KiB
Text
505 lines
19 KiB
Text
NAME
|
|
Business::PayPal::API - PayPal SOAP API client with sandbox support
|
|
|
|
VERSION
|
|
version 0.71
|
|
|
|
SYNOPSIS
|
|
use Business::PayPal::API qw( ExpressCheckout GetTransactionDetails );
|
|
|
|
## certificate authentication
|
|
my $pp = new Business::PayPal::API
|
|
( Username => 'my_api1.domain.tld',
|
|
Password => 'this_is_my_password',
|
|
PKCS12File => '/path/to/cert.pkcs12',
|
|
PKCS12Password => '(pkcs12 password)',
|
|
sandbox => 1 );
|
|
|
|
## PEM cert authentication
|
|
my $pp = new Business::PayPal::API
|
|
( Username => 'my_api1.domain.tld',
|
|
Password => 'this_is_my_password',
|
|
CertFile => '/path/to/cert.pem',
|
|
KeyFile => '/path/to/cert.pem',
|
|
sandbox => 1 );
|
|
|
|
## 3-token (Signature) authentication
|
|
my $pp = new Business::PayPal::API
|
|
( Username => 'my_api1.domain.tld',
|
|
Password => 'Xdkis9k3jDFk39fj29sD9', ## supplied by PayPal
|
|
Signature => 'f7d03YCpEjIF3s9Dk23F2V1C1vbYYR3ALqc7jm0UrCcYm-3ksdiDwjfSeii', ## ditto
|
|
sandbox => 1 );
|
|
|
|
my %response = $pp->SetExpressCheckout( ... );
|
|
|
|
DESCRIPTION
|
|
Business::PayPal::API supports both certificate authentication and the
|
|
new 3-token "Signature" authentication.
|
|
|
|
It also support PayPal's development *sandbox* for testing. See the
|
|
sandbox parameter to new() below for details.
|
|
|
|
Business::PayPal::API can import other API derived classes:
|
|
|
|
use Business::PayPal::API qw( RefundTransaction );
|
|
|
|
This allows for much more concise and intuitive usage. For example,
|
|
these two statements are equivalent:
|
|
|
|
use Business::PayPal::API::RefundTransaction;
|
|
my $pp = new Business::PayPal::API::RefundTransaction( ... );
|
|
$pp->RefundTransaction( ... );
|
|
|
|
and more concisely:
|
|
|
|
use Business::PayPal::API qw( RefundTransaction );
|
|
my $pp = new Business::PayPal::API( ... );
|
|
$pp->RefundTransaction( ... );
|
|
|
|
The advantage of this becomes clear when you need to use multiple API
|
|
calls in your program; this allows you to use the same object to invoke
|
|
the various methods, instead of creating a new object for each subclass.
|
|
Here is an example of a API object used to invoke various PayPal APIs
|
|
with the same object:
|
|
|
|
use Business::PayPal::API qw( GetTransactionDetails
|
|
TransactionSearch
|
|
RefundTransaction );
|
|
my $pp = new Business::PayPal::API( ... );
|
|
my $records = $pp->TransactionSearch( ... );
|
|
|
|
my %details = $pp->GetTransactionDetails( ... );
|
|
|
|
my %resp = $pp->RefundTransaction( ... );
|
|
|
|
However, you may certainly use just the subclass if that's all you need.
|
|
Every subclass should work as its own self-contained API.
|
|
|
|
For details on Business::PayPal::API::* subclasses, see each subclass's
|
|
individual documentation.
|
|
|
|
new
|
|
Creates a new Business::PayPal::API object.
|
|
|
|
A note about certificate authentication: PayPal (and this module)
|
|
support either PKCS#12 certificate authentication or PEM certificate
|
|
authentication. See options below.
|
|
|
|
Username
|
|
Required. This is the PayPal API username, usually in the form of
|
|
'my_api1.mydomain.tld'. You can find or create your API credentials
|
|
by logging into PayPal (if you want to do testing, as you should,
|
|
you should also create a developer sandbox account) and going to:
|
|
|
|
My Account -> Profile -> API Access -> Request API Credentials
|
|
|
|
Please see the *PayPal API Reference* and *PayPal Sandbox User
|
|
Guide* for details on creating a PayPal business account and sandbox
|
|
account for testing.
|
|
|
|
Password
|
|
Required. If you use certificate authentication, this is the PayPal
|
|
API password created when you setup your certificate. If you use
|
|
3-token (Signature) authentication, this is the password PayPal
|
|
assigned you, along with the "API User Name" and "Signature Hash".
|
|
|
|
Subject
|
|
Optional. This is used by PayPal to authenticate 3rd party billers
|
|
using your account. See the documents in "SEE ALSO".
|
|
|
|
Signature
|
|
Required for 3-token (Signature) authentication. This is the
|
|
"Signature Hash" you received when you did "Request API Credentials"
|
|
in your PayPal Business Account.
|
|
|
|
PKCS12File
|
|
Required for PKCS#12 certificate authentication, unless the
|
|
HTTPS_PKCS12_FILE environment variable is already set.
|
|
|
|
This contains the path to your private key for PayPal
|
|
authentication. It is used to set the HTTPS_PKCS12_FILE environment
|
|
variable. You may set this environment variable yourself and leave
|
|
this field blank.
|
|
|
|
PKCS12Password
|
|
Required for PKCS#12 certificate authentication, unless the
|
|
HTTPS_PKCS12_PASSWORD environment variable is already set.
|
|
|
|
This contains the PKCS#12 password for the key specified in
|
|
PKCS12File. It is used to set the HTTPS_PKCS12_PASSWORD environment
|
|
variable. You may set this environment variable yourself and leave
|
|
this field blank.
|
|
|
|
CertFile
|
|
Required for PEM certificate authentication, unless the
|
|
HTTPS_CERT_FILE environment variable is already set.
|
|
|
|
This contains the path to your PEM format certificate given to you
|
|
from PayPal (and accessible in the same location that your Username
|
|
and Password and/or Signature Hash are found) and is used to set the
|
|
HTTPS_CERT_FILE environment variable. You may set this environment
|
|
variable yourself and leave this field blank.
|
|
|
|
You may combine both certificate and private key into one file and
|
|
set CertFile and KeyFile to the same path.
|
|
|
|
KeyFile
|
|
Required for PEM certificate authentication, unless the
|
|
HTTPS_KEY_FILE environment variable is already set.
|
|
|
|
This contains the path to your PEM format private key given to you
|
|
from PayPal (and accessible in the same location that your Username
|
|
and Password and/or Signature Hash are found) and is used to set the
|
|
HTTPS_KEY_FILE environment variable. You may set this environment
|
|
variable yourself and leave this field blank.
|
|
|
|
You may combine both certificate and private key into one file and
|
|
set CertFile and KeyFile to the same path.
|
|
|
|
sandbox
|
|
Required. If set to true (default), Business::PayPal::API will
|
|
connect to PayPal's development sandbox, instead of PayPal's live
|
|
site. *You must explicitly set this to false (0) to access PayPal's
|
|
live site*.
|
|
|
|
If you use PayPal's development sandbox for testing, you must have
|
|
already signed up as a PayPal developer and created a Business
|
|
sandbox account and a Buyer sandbox account (and make sure both of
|
|
them have Verified status in the sandbox).
|
|
|
|
When testing with the sandbox, you will use different usernames,
|
|
passwords, and certificates (if using certificate authentication)
|
|
than you will when accessing PayPal's live site. Please see the
|
|
PayPal documentation for details. See "SEE ALSO" for references.
|
|
|
|
PayPal's sandbox reference:
|
|
|
|
<https://www.paypal.com/IntegrationCenter/ic_sandbox.html>
|
|
|
|
NAME
|
|
Business::PayPal::API - PayPal API
|
|
|
|
ERROR HANDLING
|
|
Every API call should return an Ack response, whether *Success*,
|
|
*Failure*, or otherwise (depending on the API call). If it returns any
|
|
non-success value, you can find an *Errors* entry in your return hash,
|
|
whose value is a listref of hashrefs:
|
|
|
|
[ { ErrorCode => 10002,
|
|
LongMessage => "Invalid security header" },
|
|
|
|
{ ErrorCode => 10030,
|
|
LongMessage => "Some other error" }, ]
|
|
|
|
You can retrieve these errors like this:
|
|
|
|
%response = $pp->doSomeAPICall();
|
|
if( $response{Ack} ne 'Success' ) {
|
|
for my $err ( @{$response{Errors}} ) {
|
|
warn "Error: " . $err->{LongMessage} . "\n";
|
|
}
|
|
}
|
|
|
|
TESTING
|
|
Testing the Business::PayPal::API::* modules requires that you create a
|
|
file containing your PayPal Developer Sandbox authentication credentials
|
|
(e.g., API certificate authentication or 3-Token authentication
|
|
signature, etc.) and setting the WPP_TEST environment variable to point
|
|
to this file.
|
|
|
|
The format for this file is as follows:
|
|
|
|
Username = your_api.username.com
|
|
Password = your_api_password
|
|
|
|
and then ONE of the following options:
|
|
|
|
a) supply 3-token authentication signature
|
|
|
|
Signature = xxxxxxxxxxxxxxxxxxxxxxxx
|
|
|
|
b) supply PEM certificate credentials
|
|
|
|
CertFile = /path/to/cert_key_pem.txt
|
|
KeyFile = /path/to/cert_key_pem.txt
|
|
|
|
c) supply PKCS#12 certificate credentials
|
|
|
|
PKCS12File = /path/to/cert.p12
|
|
PKCS12Password = pkcs12_password
|
|
|
|
You may also set the appropriate HTTPS_* environment variables for b)
|
|
and c) above (e.g., HTTPS_CERT_FILE, HTTPS_KEY_FILE, HTTPS_PKCS12_File,
|
|
HTTPS_PKCS12_PASSWORD) in lieu of putting this information in a file.
|
|
|
|
Then use "WPP_TEST=my_auth.txt make test" (for Bourne shell derivates)
|
|
or "setenv WPP_TEST my_auth.txt && make test" (for C-shell derivates).
|
|
|
|
See 'auth.sample.*' files in this package for an example of the file
|
|
format. Variables are case-*sensitive*.
|
|
|
|
Any of the following variables are recognized:
|
|
|
|
Username Password Signature Subject
|
|
CertFile KeyFile PKCS12File PKCS12Password
|
|
BuyerEmail
|
|
|
|
Note: PayPal authentication may *fail* if you set the certificate
|
|
environment variables and attempt to connect using 3-token
|
|
authentication (i.e., PayPal will use the first authentication
|
|
credentials presented to it, and if they fail, the connection is
|
|
aborted).
|
|
|
|
TROUBLESHOOTING
|
|
PayPal Authentication Errors
|
|
If you are experiencing PayPal authentication errors (e.g., "Security
|
|
header is not valid", "SSL negotiation failed", etc.), you should make
|
|
sure:
|
|
|
|
* your username and password match those found in your PayPal
|
|
Business account sandbox (this is not the same as your regular
|
|
account.
|
|
|
|
* you're not trying to use your live username and password for
|
|
sandbox testing and vice versa.
|
|
|
|
* if the sandbox works but "live" does not, make sure you've turned
|
|
off the 'sandbox' parameter correctly. Otherwise you'll be
|
|
passing your PayPal sandbox credentials to PayPal's live site
|
|
(which won't work).
|
|
|
|
* if you use certificate authentication, your certificate must be
|
|
the correct one (live or sandbox) depending on what you're doing.
|
|
|
|
* if you use 3-Token authentication (i.e., Signature), you don't
|
|
have any B<PKCS12*> parameters or B<CertFile> or B<KeyFile>
|
|
parameters in your constructor AND that none of the corresponding
|
|
B<HTTPS_*> environment variables are set. PayPal prefers
|
|
certificate authentication since it occurs at connection time; if
|
|
it fails, it will not try Signature authentication.
|
|
|
|
Try clearing your environment:
|
|
|
|
## delete all HTTPS, SSL env
|
|
delete $ENV{$_} for grep { /^(HTTPS|SSL)/ } keys %ENV;
|
|
|
|
## now put our own HTTPS env back in
|
|
$ENV{HTTPS_CERT_FILE} = '/var/path/to/cert.pem';
|
|
|
|
## create our paypal object
|
|
my $pp = new Business::PayPal::API...
|
|
|
|
* if you have already loaded Net::SSLeay (or IO::Socket::SSL), then
|
|
Net::HTTPS will prefer to use IO::Socket::SSL. I don't know how
|
|
to get SOAP::Lite to work with IO::Socket::SSL (e.g.,
|
|
Crypt::SSLeay uses HTTPS_* environment variables), so until then,
|
|
you can use this hack:
|
|
|
|
local $IO::Socket::SSL::VERSION = undef;
|
|
|
|
$pp->DoExpressCheckoutPayment(...);
|
|
|
|
This will tell Net::HTTPS to ignore the fact that IO::Socket::SSL
|
|
is already loaded for this scope and import Net::SSL (part of the
|
|
Crypt::SSLeay package) for its 'configure()' method.
|
|
|
|
* if you receive a message like "500 Can't connect to
|
|
api.sandbox.paypal.com:443 (Illegal seek)", you'll need to make
|
|
sure you have Crypt::SSLeay installed. It seems that other crypto
|
|
modules don't do the certificate authentication quite as well,
|
|
and LWP needs this to negotiate the SSL connection with PayPal.
|
|
|
|
See the DEBUGGING section below for further hints.
|
|
|
|
PayPal Munging URLs
|
|
PayPal seems to be munging my URLs when it returns.
|
|
|
|
SOAP::Lite follows the XML specification carefully, and encodes '&' and
|
|
'<' characters before applying them to the SOAP document. PayPal does
|
|
not properly URL-decode HTML entities '&' and '<' on the way
|
|
back, so if you have an ampersand in your ReturnURL (for example), your
|
|
customers will be redirected here:
|
|
|
|
http://domain.tld/prog?arg1=foo&arg2=bar
|
|
|
|
instead of here:
|
|
|
|
http://domain.tld/prog?arg1=foo&arg2=bar
|
|
|
|
Solution:
|
|
|
|
Use CDATA tags to wrap your request:
|
|
|
|
ReturnURL => '<![CDATA[http://domain.tld/prog?arg1=foo&arg2=bar]]>'
|
|
|
|
You may also use semicolons instead of ampersands to separate your URL
|
|
arguments:
|
|
|
|
ReturnURL => 'http://domain.tld/prog?arg1=foo;arg2=bar'
|
|
|
|
(thanks to Ollie Ready)
|
|
|
|
DEBUGGING
|
|
You can see the raw SOAP XML sent and received by Business::PayPal::API
|
|
by setting it's $Debug variable:
|
|
|
|
$Business::PayPal::API::Debug = 1;
|
|
$pp->SetExpressCheckout( %args );
|
|
|
|
this will print the XML being sent, and dump a Perl data structure of
|
|
the SOM received on STDERR (so check your error_log if running inside a
|
|
web server).
|
|
|
|
If anyone knows how to turn a SOAP::SOM object into XML without setting
|
|
outputxml(), let me know.
|
|
|
|
DEVELOPMENT
|
|
If you are a developer wanting to extend Business::PayPal::API for other
|
|
PayPal API calls, you can review any of the included modules (e.g.,
|
|
RefundTransaction.pm or ExpressCheckout.pm) for examples on how to do
|
|
this until I have more time to write a more complete document.
|
|
|
|
But in a nutshell:
|
|
|
|
package Business::PayPal::API::SomeAPI;
|
|
|
|
use 5.008001;
|
|
use strict;
|
|
use warnings;
|
|
|
|
use SOAP::Lite 0.67;
|
|
use Business::PayPal::API ();
|
|
|
|
our @ISA = qw(Business::PayPal::API);
|
|
our @EXPORT_OK = qw( SomeAPIMethod );
|
|
|
|
sub SomeAPIMethod {
|
|
...
|
|
}
|
|
|
|
Notice the @EXPORT_OK variable. This is *not* used by Exporter (we don't
|
|
load Exporter at all): it is a special variable used by
|
|
Business::PayPal::API to know which methods to import when
|
|
Business::PayPal::API is run like this:
|
|
|
|
use Business::PayPal::API qw( SomeAPI );
|
|
|
|
That is, Business::PayPal::API will import any subroutine into its own
|
|
namespace from the @EXPORT_OK array. Now it can be used like this:
|
|
|
|
use Business::PayPal::API qw( SomeAPI );
|
|
my $pp = new Business::PayPal::API( ... );
|
|
$pp->SomeAPIMethod( ... );
|
|
|
|
Of course, we also do a 'use Business::PayPal::API' in the module so
|
|
that it can be used as a standalone module, if necessary:
|
|
|
|
use Business::PayPal::API::SomeAPI;
|
|
my $pp = new Business::PayPal::API::SomeAPI( ... ); ## same args as superclass
|
|
$pp->SomeAPIMethod( ... );
|
|
|
|
Adding the @EXPORT_OK array in your module allows your module to be used
|
|
in the most convenient way for the given circumstances.
|
|
|
|
EXAMPLES
|
|
Andy Spiegl <paypalcheckout.Spiegl@kascada.com> has kindly donated some
|
|
example code (in German) for the ExpressCheckout API which may be found
|
|
in the eg directory of this archive. Additional code examples for other
|
|
APIs may be found in the t test directory.
|
|
|
|
EXPORT
|
|
None by default.
|
|
|
|
CAVEATS
|
|
Because I haven't figured out how to make SOAP::Lite read the WSDL
|
|
definitions directly and simply implement those (help, anyone?), I have
|
|
essentially recreated all of those WSDL structures internally in this
|
|
module.
|
|
|
|
(Note - 6 Oct 2006: SOAP::Lite's WSDL support is moving ahead, but
|
|
slowly. The methods used by this API are considered "best practice" and
|
|
are safe to use).
|
|
|
|
As with all web services, if PayPal stop supporting their API endpoint,
|
|
this module *may stop working*. You can help me keep this module
|
|
up-to-date if you notice such an event occurring.
|
|
|
|
Also, I didn't implement a big fat class hierarchy to make this module
|
|
"academically" correct. You'll notice that I fudged colliding parameter
|
|
names in DoExpressCheckoutPayment and similar fudging may be found in
|
|
GetTransactionDetails. The good news is that this was written quickly,
|
|
works, and is dead-simple to use. The bad news is that this sort of
|
|
collision might occur again as more and more data is sent in the API
|
|
(call it 'eBay API bloat'). I'm willing to take the risk this will be
|
|
rare (PayPal--please make it rare!).
|
|
|
|
ACKNOWLEDGEMENTS
|
|
Wherein I acknowledge all the good folks who have contributed to this
|
|
module in some way:
|
|
|
|
* Daniel P. Hembree
|
|
|
|
for authoring the AuthorizationRequest, CaptureRequest,
|
|
DirectPayments, ReauthorizationRequest, and VoidRequest extensions.
|
|
|
|
Danny's contact information may be found in the AUTHOR section of
|
|
the above modules.
|
|
|
|
* <jshiles at base16consulting daught com>
|
|
|
|
for finding some API typos in the ExpressCheckout API
|
|
|
|
* Andy Spiegl <paypalcheckout.Spiegl@kascada.com>
|
|
|
|
for giving me the heads-up on PayPal's new 3-token auth URI and for
|
|
a sample command-line program (found in the 'eg' directory)
|
|
demonstrating the ExpressCheckout API.
|
|
|
|
* Ollie Ready <oready at drjays daught com>
|
|
|
|
for the heads-up on the newest 3-token auth URI as well as a pile of
|
|
documentation inconsistencies.
|
|
|
|
* Michael Hendricks <michael at ndrix daught org>
|
|
|
|
for a patch that adds ShippingTotal to the DirectPayments module.
|
|
|
|
* Erik Aronesty, Drew Simpson via rt.cpan.org (#28596)
|
|
|
|
for a patch to fix getFields() when multiple items are returned
|
|
|
|
* Sebastian Böhm via email, SDC via rt.cpan.org (#38915)
|
|
|
|
for a heads-up that the PayPal documentation for MassPay API was
|
|
wrong regarding the *UniqueId* parameter.
|
|
|
|
* Jonathon Wright via email
|
|
|
|
for patches for ExpressCheckout and RecurringPayments that implement
|
|
*BillingAgreement* and *DoReferenceTransaction* API calls.
|
|
|
|
SEE ALSO
|
|
SOAP::Lite, <https://www.paypal.com/IntegrationCenter/ic_pro_home.html>,
|
|
<https://www.paypal.com/IntegrationCenter/ic_expresscheckout.html>,
|
|
<https://www.sandbox.paypal.com/en_US/pdf/PP_Sandbox_UserGuide.pdf>,
|
|
<https://developer.paypal.com/en_US/pdf/PP_APIReference.pdf>
|
|
|
|
AUTHOR
|
|
Scott Wiersdorf, <scott@perlcode.org>
|
|
|
|
COPYRIGHT AND LICENSE
|
|
Copyright (C) 2006, 2007 by Scott Wiersdorf
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the same terms as Perl itself, either Perl version 5.8.6 or, at
|
|
your option, any later version of Perl 5 you may have available.
|
|
|
|
AUTHOR
|
|
Scott Wiersdorf <scott@perlcode.org>
|
|
|
|
COPYRIGHT AND LICENSE
|
|
This software is copyright (c) 2013 by Scott Wiersdorf.
|
|
|
|
This is free software; you can redistribute it and/or modify it under
|
|
the same terms as the Perl 5 programming language system itself.
|
|
|