PayPal Direct Payment API Component
Useful component that provides a wrapper for PayPal's Direct Payment API, allowing any cake based application to accept payments via Direct Payment (processing credit cards and payments without leaving your website) and Express Checkout (allowing users to use their PayPal account to pay)
Index
Introduction
While building a large CakePHP based application I found myself needing to integrate PayPal Direct Payment API with CakePHP. For those of you who don't know this API here's a short statement from PayPal's website describing its main objective:
Direct Payment API offers you direct credit card payment processing capability through PayPal. For credit card transactions, customers stay on your website as PayPal processes the payment in the background.
Now, I have built PayPal Direct Payment API applications in the past, but I wanted to bake paypal the proper cakish way. Furthermore, as PayPal's TOS states, PayPal's business rules require that sites that offer Direct Payment API (credit card processing without leaving your website) also must offer Express Checkout Payment (where buyer gets transferred to PayPal's website to confirm the order and then taken back to your website.) It is a bummer, but it is mandatory.
It is also important to know that only people with bank accounts in the US can apply for Website Payments Pro (the PayPal service that allows you to use Direct Payment API.) While this may discourage some bakers from even trying the API, you should now that PayPal offers a Sandbox environment to allow you to test every aspect of the integration.
For that purpose I've created a CakePHP component that provides a wrapper for PayPal's Direct Payment API. I have tested it with CakePHP 1.1.10.3825 running on:
- Apache 2, Windows XP, PHP 4.4.4
- Apache 2, Debian Linux, PHP 5.2.0
Pre-requisites
PEAR and PayPal Direct Payment API
You'll obviously need PayPal's Direct Payment API for PHP. You can get it at:https://www.paypal.com/IntegrationCenter/ic_sdk-resource.html
It is a PEAR based package so needless to say PEAR's core must be included on the vendors path. It is up to you how you install the API on your cake environment. This is what I've done:
- Downloaded PEAR base from http://pear.php.net/package/PEAR
- Unzipped PEAR based to {CAKE}/app/vendors/PEAR
- Downloaded PayPal Direct Payment SDK from https://www.paypal.com/IntegrationCenter/ic_sdk-resource.html
- Unzipped directory php-sdk/lib in SDK's zip to {CAKE}/app/vendors/PEAR
- Created a pear.inc.php file on {CAKE}/app/vendors with following content: Download code
// Set path to PEAR filesܡםX]yZ0x%w ((kjaܡםDownload code
define('PEAR_PATH', dirname(__FILE__) . DS . 'PEAR');
// Add PEAR path to library path
set_include_path(PEAR_PATH . PATH_SEPARATOR . get_include_path());vendor('pear.inc');
Set up a PayPal Sandbox account
Can't really go through the whole explanation, but follow instructions on https://www.paypal.com/IntegrationCenter/ic_sandbox.htmlImportant Notes
There are two ways to make a payment: through Direct Payment API and via Express Checkout.
The Direct Payment API takes mandatory information such as order amount, credit card info, and shipping addresses to process the order by contacting PayPal's server via SOAP messages. When it is done, you either get a succesfull code (meaning that the sale was made) or an error. Therefore, it is a one-time call to the component. You set up the component's required variables, call directPayment(), and you get the appropiate result.
Unlike the simplicity of Direct Payment API, Express Checkout requires the user to be redirected to PayPal's website to confirm the payment, and then sends a callback to your site sending a Token ID. This callback is a way for PayPal to give us this ID that we will need when we want it to process the order. This means that you will need to call expressCheckout() function inside the component twice: when you initiate the payment (at which point the user is redirected to paypal) and when you get back the token and want to perform the actual transaction. There's no need to tell the component which token you've got, it will figure out what it's supposed to do when you call expressCheckout().
One very important issue regarding Express Checkout: I have my PayPal payment behind an authenticated action. When testing online I discovered that after paypal's callback to my website Cake's session got lost. Since you can tell the component which will be the URL that will be called when PayPal gives the callback, I added Cake's session ID to the URL. Before the first call to expressCheckout(), the call that makes the redirect to paypal, I store the session information using the component's function:
Download code
$this->Paypal->storeSession();
Then, when I get the callback (which I can check because I specify which URL gets called) I restore the session:
Download code
if (isset($_REQUEST['csid']))
{
// Restore session
if (!$this->Paypal->restoreSession($_REQUEST['csid']))
{
$this->redirect('/');
exit;
}
}
Comments
Comment
1 PayPal Direct Payment API Version
Is the API used the US version for paypal pro?
I am wondering as paypal pro api is now avaliable in the uk but doesn't use the same sdk as the US version.
Would it be easy to have an all-in-one component that handled all version as this could be updated centrally instead of the uk users having to write there own?
Penfold
Comment
2 PayPal Direct Payment API Version
Penfold: Well I'm using the API they give you when you look for DirectPayment's SDK. I find it hard to believe they would change the API for another country. Can you provide a link (to my email) with the information you have that tells you their SDKs are different for US and UK?
Comment
3 Thanks
Question
4 UK version
Comment
5 Thank You
I'll be trying it out today. It will most definitely save me many, many hours.
Question
6 API Question
Controller Class:
<?php$this->Paypal->setEnvironment(CAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOX);
$this->Paypal->setUser('ApiUser');
$this->Paypal->setPassword('ApiPassword');
$this->Paypal->setCertificate('sandbox.paypal.com.pem');
$this->Paypal->setOrder($order);
?>
Hi, where should i put the pem file? technically it is located under {cake}/app/vendors/PEAR/PayPal/cert but the code errors up the says sandbox.paypal.com.pem cannot be located.
Please, badly need help to implement your API.
Comment
7 API Question
Comment
8 important
- Remove setCertificate and replace it with
$this->Paypal->setSignature('signature provided by paypal');.
and people it worked!!
Question
9 Cake 1.2 integration for the Paypal component
Comment
10 Cake 1.2 integration for the Paypal component
Comment
11 Fatal Error
Warning (2): require_once(PayPal.php) [function.require-once]: failed to open stream: No such file or directory [APP/controllers/components/paypal.php, line 12]Comment
12 Complicated Solutions
I try to implement the whole tutorials but it seems...it's quit difficult for me to understand with specially it doesn't give any instruction where to go. Where to put the a certain code. Specially the form and it's components.
Can u or anyone could help me how to make a step by step work in cooking paypal payment methods? Sorry but i'm just a newbie,...could anyone help me???
thnks