In this section, we’ll learn how to implement an abstract
DoDirectPayment
API request and validate it by using
curl
before transitioning into a GAE implementation. In the
next section, we’ll integrate DoDirectPayment
into Tweet
Relevance.
To implement a Direct Payment transaction, you need to invoke
the DoDirectPayment
API and provide
information to identify the buyer’s credit or debit card and the
amount of the payment. Setting up a minimal transaction is
accomplished through the following steps in which you construct a URL
request to the PayPal API endpoint for
DoDirectPayment
:
Specify the amount of the transaction, including the currency if it is not in US dollars. You should specify the total amount of the transaction if it is known; otherwise, specify the subtotal:
AMT=
amount
CURRENCYCODE=
currencyID
Specify the payment action. It is best practice to
explicitly specify the payment action as one
of the following values, even though the default value is Sale
:
PAYMENTACTION=Sale
PAYMENTACTION=Authorization
Specify the IP address of the buyer’s computer:
IPADDRESS=
xxx.xxx.xxx.xxx
Specify information about the card being used. You must specify the type of card as well as the account number:
CREDITCARDTYPE=Visa
ACCT=
1234567891011123
The type of credit/debit card being used, the card issuer, and the Payment Receiving Preferences setting on your PayPal Profile might require that you set the following fields as well:
EXPDATE=
012013
CVV2=
123
Specify information about the card holder. You must provide the first and last name of the card holder, as well as the billing address associated with the card:
FIRSTNAME=
John
LASTNAME=
Doe
STREET=
1313
Mockingbird Lane
CITY=
Franklin
STATE=
TN
ZIP=
37064
COUNTRYCODE=
US
A minimal Python implementation of a
DoDirectPayment
transaction using GAE is coming up
shortly. First, however, it may be helpful to execute a transaction
using a shell script using curl
to ensure that your buyer
and seller configuration is setup correctly. In order to use
DoDirectPayment
as part of Website Payments Pro, you may
need to create a business account in the developer sandbox environment
and explicitly indicate that the account is a merchant account for
Website Payments Pro, as shown in Figure 5-2. The 3-Token credentials associated
with this account should allow you to process
DoDirectPayment
transactions, whereas credentials
associated with a Seller account should not.
Chances are pretty good that you already have one or more
personal accounts configured in the developer sandbox that you’ve
already been using as a buyer or receiver of a payment. Ensure that
you are using the credit card information associated with one of these
accounts, because the DoDirectPayment
API will validate
the DoDirectPayment
transaction using this faux credit
card number and expiration date. [A live DoDirectPayment
transaction may validate all other fields and provide back any of many
possible error
codes for other validation issues that you should be prepared
to handle.] An example shell script that demonstrates the
DoDirectPayment
using the guidance provided in this
section is shown in Example 5-1. If you
are comfortable working with shell scripts in a Linux environment or
are able to reconfigure the script to execute on Windows, it is highly
recommended that you replace the variables at the top of the script
with your own merchant account 3-Token credentials and buyer account
credit card information and receive a successful response before
proceeding. If you are unable to run the script, don’t worry—a Python
example with GAE is coming up shortly. The point of including a shell
script here is to show that the actual execution of a
DoDirectPayment
is truly just a single HTTP
request.
Example 5-1. DoDirectPayment.sh—a minimal Bash script illustrating the use of the DoDirectPayment API
#!/bin/bash # Ensure that the 3-Token credentials are with a business account that has explicitly # been configured for Website Payments Pro at http://developer.paypal.com USER="XXX" PWD="XXX" SIGNATURE="XXX" # Ensure that the credit card used is a real credit card number from an account # that has been configured at http://developer.paypal.com # The sandbox environment does require that the credit card number and expiry # be valid ACCT="XXX" EXPDATE="XXX" RESULT=$(curl -s \ https://api-3t.sandbox.paypal.com/nvp -d "VERSION=82.0\ &USER=$USER\ &PWD=$PWD\ &SIGNATURE=$SIGNATURE\ &METHOD=DoDirectPayment\ &PAYMENTACTION=Sale\ &IPADDRESS=192.168.0.1\ &AMT=8.88\ &CREDITCARDTYPE=Visa\ &ACCT=$ACCT\ &EXPDATE=$EXPDATE\ &CVV2=123\ &FIRSTNAME=John\ &LASTNAME=Smith\ &STREET=1000 Elm St.\ &CITY=Franklin\ &STATE=TN\ &ZIP=37064\ &COUNTRYCODE=US"\ ;) echo $RESULT;
A successful response from the script should look something like the following:
TIMESTAMP=2012%2d01%2d22T02%3a14%3a59Z &CORRELATIONID=46d8df6362e04 &ACK=Success &VERSION=82%2e0 &BUILD=2278658 &AMT=8%2e88 &CURRENCYCODE=USD &AVSCODE=X &CVV2MATCH=M &TRANSACTIONID=0BD118857L408034Y
Your business logic should be prepared to fully parse the
results and be prepared to take all necessary actions for contingent
situations such as aberrations with AVSCODE
or
CVV2MATCH
, even if the ACK
field is
Success
. For example, you should be prepared to handle
the case when AVSCODE
isn’t X
, which
indicates an “exact match” according to the AVS
and CVV2 Response Codes documentation. The official
documentation on DoDirectPayment
also contains
information on how to use PayPal’s fraud management filters to help
you identify potentially fraudulent transactions—another important
consideration you should be prepared to tackle with a
DoDirectPayment
implementation.
Even though the PayPal Sandbox environment doesn’t appear to
validate fields pertaining to AVSCODE
and
CVV2MATCH
, such as street address, zip code, or the
three-digit code on the backs of credit cards, it’s critical that
you think through and simulate testing scenarios before moving into
production with DoDirectPayment
.
Like all other transactions in the Sandbox environment, you are able to log into the merchant account and view the details of the transaction in the account history. Figure 5-3 shows what the merchant account history might look like after a successful transaction.
Unlike the other PayPal products that have been demonstrated
thus far, DoDirectPayment
requires only a single request
and response. In terms of the buyer’s user experience, PayPal isn’t
playing an intermediary role and you are handling the account
information yourself, so there’s no need for a more roundabout
approval process involving redirects. Thus, the implementation details
for completing a DoDirectPayment
transaction are
considerably simpler, as shown in Example 5-2.
Example 5-2. main.py—a minimal DoDirectPayment example using GAE
""" A minimal GAE application that makes an API request to PayPal and parses the result. Fill in your own 3 Token Credentials from your sandbox account """ from google.appengine.ext import webapp from google.appengine.ext.webapp import util from google.appengine.api import urlfetch import urllib import cgi # Replace these values with your own 3-Token credentials from a sandbox # merchant account that was configured for Website Payments Pro and a faux # credit card number and expiry from a "personal" buyer account user_id = "XXX" password = "XXX" signature = "XXX" credit_card_number = "XXX" credit_card_expiry ="XXX" 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 'USER' : user_id, 'PWD' : password, 'SIGNATURE' : signature, # API Version and Operation 'METHOD' : 'DoDirectPayment', 'VERSION' : '82.0', # API specifics for DoDirectPayment 'PAYMENTACTION' : 'Sale', 'IPADDRESS' : '192.168.0.1', 'AMT' : '8.88', 'CREDITCARDTYPE' : 'Visa', 'ACCT' : credit_card_number, 'EXPDATE' : credit_card_expiry, 'CVV2' : '123', 'FIRSTNAME' : 'Billy', 'LASTNAME' : 'Jenkins', 'STREET' : '1000 Elm St.', 'CITY' : 'Franklin', 'STATE' : 'TN', 'ZIP' : '37064', 'COUNTRYCODE' : 'US' } # 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, deadline=10, # seconds 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()
There should be little explanation that’s required for
understanding this example if you’ve read previous chapters. A single
API request is passed in with all of the appropriate parameters, and a
response is returned with the standard fields from Table 5-2, indicating
success or failure along with a few other pertinent details. If you
haven’t already, take the time to run the example to ensure that you
have successfully configured your sandbox merchant account to be
enabled for Website Payments Pro and are using valid credit card
information from a sandbox personal account. The next section
integrates DoDirectPayment
into Tweet Relevance.