Although PayPal offers a number of SDKs for a number of common programming languages including Java, ASP.NET, Ruby, PHP, and Cold Fusion, the applications in this book use the NVP APIs directly. Visit the SDKs and Downloads section of PayPal’s Integration Center for more details about the various SDKs that are available.
In order to make PayPal API requests, you’ll first need to register a merchant account and obtain API credentials. Since it wouldn’t be a very good idea to implement a commerce application in a live production environment that involves real accounts and real money, PayPal offers a wonderful sandbox environment to use while developing your application. Using the sandbox environment, you can set up faux buyer and seller accounts to fully test the payment flows and track the flow of funds before flipping the switch on your application code and going live. The faux buyer account acts like someone buying a product from a marketplace, and the faux seller account acts like the marketplace that’s selling the products. For the most part, switching between the two is as simple as changing the target server URL and the API credentials from sandbox values to production values. The rest of your application will remain unchanged, so it’s a fairly painless experience to go live. The remainder of this chapter steps through the process of obtaining API credentials for the sandbox environment, and shows you how to use them to make a PayPal API request.
Developing your application only requires access to the PayPal API sandbox. You can sign up for access to the sandbox environment at https://developer.paypal.com. Once your account is established, you can create test accounts for buyers and sellers as well as obtain API credentials. Sandbox accounts and live accounts require different processes to obtain credentials.
This book doesn’t cover some of the nuances of transitioning to a live environment, but you’ll essentially just sign up for a merchant account, substitute the production API credentials that come with your merchant account into your web application, and update the API endpoints that your web application uses for making requests. There’s also a handy Go Live Checklist that’s maintained in PayPal’s official documentation that summarizes the key steps.
Use the following steps for a sandbox account:
Go to https://developer.paypal.com and click Sign Up Now.
Enter the requested information and click Agree and Submit.
PayPal will send you an email to complete the signup process.
After confirming your email address, you can create test accounts and access API credentials by logging into https://developer.paypal.com/ with the email/password combination you provided during the signup process.
Click the Test Accounts link.
Click the Create Test Account link.
Choose Seller for the account type and select the other appropriate options. Going with the defaults is highly recommended and results in API credentials being created automatically.
Click the API credentials link to access your API credentials.
Click the Enter Sandbox Test Site button to log in to faux buyer and seller accounts. Note that after the initial login to https://developer.paypal.com/, you can log in to individual sandbox accounts by accessing https://www.sandbox.paypal.com directly.
You cannot use the same email/password combination to log in to your sandbox account at https://developer.paypal.com/ that you use to log in to your ordinary PayPal account (unless, of course, you intentionally used the very same email/password combination for both accounts, which is not recommended).
If this is your first encounter with the PayPal Sandbox Test Environment, these steps can seem slightly confusing at first since you end up with so many accounts. The key takeaways are that you can create a developer account and log in to the sandbox environment. From within the sandbox environment, you can create faux buyer and seller accounts, and the creation of a faux seller account provides you with API credentials for the faux merchant account. Note, however, that in order to log in to these faux accounts, you’ll need to establish a session by first logging in through https://www.sandbox.paypal.com and using the faux account credentials for each individual account; you cannot log in to http://paypal.com with the faux credentials. Figures 1-3 through 1-7 show the overall login flow.
Figure 1-4. Once logged into the sandbox environment, you can create and manage test accounts from the Test Accounts menu item.
Figure 1-6. Select an account and click Enter Sandbox Test Site to launch a login. (Notice the message in the upper-right corner of the screen that alerts you that you have already established a developer session.)
Figure 1-7. Use the faux account credentials to log in to the account—it provides the same view as if it were a real merchant account!
Once you’ve successfully worked your way through the developer sandbox fundamentals, you’re ready to use your faux merchant account’s API credentials to programatically make a request.
PayPal offers two methods for authenticating requests: certificates and “3-token credentials,” which are comprised of a username, password, and signature. You are already familiar with the concept of securing an account by using a username and a password, but perhaps you’re not familiar with the additional signature. Essentially, the signature is an additional password that is intrinsically virtually impossible to guess or crack, and the addition of it to the authentication process results in a scheme known as multi-factor authentication since the signature is an additional factor that is used in addition to the password. By default, faux accounts are set up with 3-token credentials, and we’ll use the API Signature method of specifying credentials throughout this book. Figure 1-8 illustrates the 3-token credentials in a developer sandbox account.
The remainder of this section works through a few implementation
details and culminates with the equivalent of a working “Hello,
world!” example to illustrate how to make a PayPal API request and
parse the response. Specifically, we’ll call the
SetExpressCheckout
API, which is the first step involved
in using the Express Checkout product. Express Checkout is featured in
depth in the next chapter, so for now, don’t worry about the details
of what it does. At this point, just think of it as an opaque API
operation, and focus on the details of making the request and parsing
the response. The key steps your application must accomplish to post
to the NVP API include URL encoding, constructing the request in a
format the NVP API can interpret, and posting the request via HTTPS to
the server. The remainder of this section works through these
details.
Both the request to the PayPal server and the response from the server are URL encoded. This method ensures that you can transmit special characters, characters not typically allowed in a URL, and characters that have reserved meanings in a URL. For example:
NAME=John Doe&COMPANY=Acme Goods & Services
is URL encoded as follows:
NAME=John+Doe&Company=Acme+Goods+%26+Services
Each application language typically has a specific built-in URL encode method. Refer to the list in Table 1-1 for some specific functions in common programming languages.
Table 1-1. URL encoding and decoding methods for common programming languages
Application language | Encoding Function Name | Decoding Function Name |
---|---|---|
ASP.NET | System.Web.HttpUtility.UrlEncode | System.Web.HttpUtility.UrlDecode |
Classic ASP | Server.URLEncode | No built-in function |
Java | java.net.URLEncoder.encode | java.net.URLEncoder.decode |
PHP | urlencode | urldecode |
ColdFusion | URLEncode | URLDecode |
Python | urllib.urlencode | urlparse.parse_qs |
Since Python is used as the primary programming language in
this book, Example 1-4 illustrates a Python
interpreter session showing you how to decode and encode URL query
string parameters. The very same logic holds for your GAE app,
except that the parse_qs
function may need be imported
from the cgi
module instead of the
urlparse
module because of changes to Python packages
between versions 2.6 and 2.7.
At the time of this writing, Python 2.5 was still the
default version to run on GAE, but Python 2.7 seemed imminently
releasable and was in an experimental state. Note that as of
Python 2.6, parse_qs
was moved into the
urlparse
module, so attempting to import it from
cgi
will fail if and when GAE defaults to Python
version 2.7.
Example 1-4. Encoding and decoding a URL with Python version 2.7
>>> import urllib >>> encoded_qs = urllib.urlencode({'NAME' : 'John Doe', 'COMPANY' : 'Acme Goods & Services'}) >>> print encoded_qs 'COMPANY=Acme+Goods+%26+Services&NAME=John+Doe' >>> import urlparse >>> decoded_qs = urlparse.parse_qs(encoded_qs) # use cgi.parse_qs for Python 2.5 and older >>> print decoded_qs {'COMPANY': ['Acme Goods & Services'], 'NAME': ['John Doe']}
One very minor nuance to observe is that parse_qs
returns lists of values for each field in the dictionary result. The
reason is that it is legal for URL query string items to be keyed by
duplicate field names. For example, foo=1&foo=2&foo=3
is a valid query
string, so parse_qs
needs to be able to return all of
these values back to you uniformly.
Each NVP API request is composed of required and optional
parameters and their corresponding values. Parameters are not
case-sensitive, but certain values such as the API Password,
(PWD
), are case-sensitive. The
required parameters for all NVP API transactions are USER
, PWD
, METHOD
, and VERSION
. The METHOD
, or type of transaction you are
calling the NVP API to process, has an associated VERSION
. Together the METHOD
and VERSION
define the exact behavior of the
API operation you want performed. This will be followed by the
information posted from your application, including things such as
Item, Quantity, and Cost.
API operations can change between versions, so when you change a version number, be sure to test your application code again before going live.
Each NVP API response is composed of an acknowledgment (or ACK), a timestamp, a CorrelationID unique to the transaction, and a build number stating the API version used to process the transaction. This basic response is then followed by a series of name/value pairs holding the transaction data, which you can parse and handle accordingly in your application. The acknowledgment will be one of the responses outlined in Table 1-2.
PayPal maintains a fairly detailed list of error codes that is very handy to bookmark and consult during debugging situations.
Now that we have established some of the fundamentals, let’s make a PayPal API request using GAE. Example 1-5 ties together the common concepts from this chapter and shows you how do it.
Example 1-5. An updated main.py that illustrates how to make a PayPal API request and parse the response
from google.appengine.ext import webapp from google.appengine.ext.webapp import util from google.appengine.api import urlfetch import urllib import cgi class MainHandler(webapp.RequestHandler): def get(self): # Sandbox NVP API endpoint sandbox_api_url = 'https://api-3t.sandbox.paypal.com/nvp' nvp_params = { # 3 Token Credentials - Replace XXX with your own values 'USER' : 'XXX', 'PWD' : 'XXX', 'SIGNATURE' : 'XXX', # API Version and Operation 'METHOD' : 'SetExpressCheckout', 'VERSION' : '82.0', # API specifics for SetExpressCheckout 'PAYMENTREQUEST_0_AMT' : '1.00', 'RETURNURL' : 'http://ppapis2e.appspot.com/xxx_returnurl_xxx', 'CANCELURL' : 'http://ppapis2e.appspot.com/xxx_cancelurl_xxx' } # Make a secure request and pass in nvp_params as a POST payload result = urlfetch.fetch( sandbox_api_url, payload = urllib.urlencode(nvp_params), method=urlfetch.POST, validate_certificate=True ) if result.status_code == 200: # OK decoded_url = cgi.parse_qs(result.content) for (k,v) in decoded_url.items(): self.response.out.write('<pre>%s=%s</pre>' % (k,v[0],)) else: self.response.out.write('Could note fetch %s (%i)' % (url, result.status_code,)) def main(): application = webapp.WSGIApplication([('/', MainHandler)], debug=True) util.run_wsgi_app(application) if __name__ == '__main__': main()
Hopefully, the code is pretty self-explanatory. GAE’s
urlfetch.fetch
function is used to make a secure
request to the sandbox
API endpoint, which includes the standard USER
,
PWD
, and SIGNATURE
parameters from under
the “API Credentials” tab of the sandbox environment, along with an
API operation and version as
defined by METHOD
and VERSION
,
respectively. The SetExpressCheckout
API requires a minimum of a request amount and redirect
URL.
Keeping up with updates to PayPal’s API isn’t quite as simple as one would imagine. The simplest way to keep up with developments is to consult About Previous Versions of the API.
The important thing to take away from this particular example is just that you can substitute in your own 3-token credentials and successfully execute the code. It should run on your local development machine, but also take the opportunity to deploy it as a live application and see it run out on the Web as well.
Example 1-6. Sample results from executing Example 1-5, which calls SetExpressCheckout and displays the results
ACK=Success TIMESTAMP=2011-11-16T15:38:28Z TOKEN=EC-7JK870639U925801V VERSION=82.0 BUILD=2256005 CORRELATIONID=f7f4dbb891723
Once you’ve successfully run the code and get back a sample response as shown in Example 1-6, you should be ready to move on to the next chapter, where we’ll explore the Express Checkout product in more detail and build a (hopefully) fun and realistic sample app that incorporates it to implement the payment flow. However, before turning to the next chapter, you should definitely check out, review, and run the sample code for Tweet Relevance, the foundational sample project that’s used throughout this book and introduced in Appendix A.