Paypal Datasource

This article is also available in the following languages:
By toste
Simple datasource to communicate with the Paypal NVP api.
Simple datasource to communicate with the Paypal NVP api.

Install instructions :

- Place the newest version of paypal_source.php in your app/models/datasources folder
- Add the credidentials to database.php :

         var $paypal = array(
            'datasource' => 'paypal',
            'environment' => 'sandbox', // 'sandbox' or 'live'
             'currency' => 'CAD',
            'username' => '...',
            'password' => '...',
            'signature' => '...'
        );
 
- Call it from anywhere :

        $paypal = ConnectionManager::getDataSource('paypal');    
        $response = $paypal->directPayment($billing, $payment);    
 



<?php
/**
 * Paypal Datasource 1.0
 * 
 * Paypal datasource to communicate with the Paypal NVP api.
 * 
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * Install instructions :
 * 
 *  - Place the newest version of paypal_source.php in your app/models/datasources folder
 *  - Add the credidentials to database.php :
 *         var $paypal = array(
 *            'datasource' => 'paypal',
 *            'environment' => 'sandbox', // 'sandbox' or 'live'
 *             'currency' => 'CAD',
 *            'username' => '...',
 *            'password' => '...',
 *            'signature' => '...'
 *        );
 *  - Call it from anywhere :
 *             $paypal = ConnectionManager::getDataSource('paypal');    
 *            $response = $paypal->directPayment($billing, $payment);    
 * 
 * 
 * @author Sébastien Testeau <seb@binaryninja.com>
 * @copyright Copyright 2008, Sébastien Testeau, Ltd.
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
 * @created December 23, 2008
 * @version 1.0
 * 
 */ 

App::import('Core', array('Xml''HttpSocket'));

class 
PaypalSource extends DataSource 
{      
      var 
$description "Paypal direct payment API";
    var 
$environment '';        
    var 
$currency '';
    
    
// Set up your API credentials, PayPal end point, and API version.
    
var    $userName "";
    var    
$password "";
    var    
$signature "";
    var 
$Http null;
    
    
//class var
    
var $nvpStr null;
      var 
$nvpreq null;

    function 
__construct($config) {
        
parent::__construct($config);        
        
$this->Http =& new HttpSocket();
        
        
$this->userName $this->config['username'];
        
$this->password $this->config['password'];
        
$this->signature $this->config['signature'];
        
$this->environment $this->config['environment'];
        
$this->currency $this->config['currency'];
    }
    
    
/**
     * Returns information about this payment processor.
     * This is meant to be shown to the user on the payment screen, so that they can select this payment method.
     *
     */
     
function info() {
         return 
$this->description;
     }
     
    
/**
     * Called by the checkout routine for payment processing to initialize payment data
     *
     * @param unknown_type $billing
     * @param unknown_type $shipping
     * @param unknown_type $payment
     * @return mixed    array if success, false otherwise.
     */
    
function doDirectPayment($billing$payment) {
        
// Set request-specific fields.
        
$paymentType urlencode('Sale');                // Authorization or 'Sale'
        
$firstName urlencode($billing['firstname']);
        
$lastName urlencode($billing['lastname']);
        
$creditCardType urlencode($payment['cc_type']);
        
$creditCardNumber urlencode($payment['cc']);
        
$expDateMonth $payment['expiration']['month'];
        
// Month must be padded with leading zero
        
$padDateMonth urlencode(str_pad($expDateMonth2'0'STR_PAD_LEFT));
        
        
$expDateYear urlencode($payment['expiration']['year']);
        
$cvv2Number urlencode($payment['security_code']);
        
$address1 urlencode($billing['address']);
        
$address2 "";
        
$city urlencode($billing['city']);
        
$state urlencode($billing['state']);
        
$zip urlencode($billing['postcode']);
        
$country urlencode($billing['country']);                // US or other valid country code
        
$amount urlencode($payment['amount']);
        
$currencyID urlencode('CAD');                            // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
        
        // Add request-specific fields to the request string.
        
$this->nvpStr =    "&PAYMENTACTION=$paymentType&AMT=$amount&CREDITCARDTYPE=$creditCardType&ACCT=$creditCardNumber".
                    
"&EXPDATE=$padDateMonth$expDateYear&CVV2=$cvv2Number&FIRSTNAME=$firstName&LASTNAME=$lastName".
                    
"&STREET=$address1&CITY=$city&STATE=$state&ZIP=$zip&COUNTRYCODE=$country&CURRENCYCODE=$currencyID";
        
        return 
$this->query("doDirectPayment");
    }
    
    
    function 
getBalance() {        
        
// Add request-specific fields to the request string.
        
$this->nvpStr =    "";        
        return 
$this->query("GetBalance");
    }
    
    
/**
     * Refund the transaction 
     * 
     * @param $transaction_id
     * @param String $refund_type
     * @param float $amount
     * @param String $memo
     * @return mixed    array if success, false otherwise.
     */
    
function refundTransaction($transaction_id$refund_type 'Full'$amount null$memo null) {        
        
// Set request-specific fields.
        
$transactionID urlencode($transaction_id);
        
$refundType urlencode($refund_type);                    // or 'Partial'
        
$currencyID urlencode($this->currency);                
        
        if(isset(
$amount) && isset($memo) && $refund_type === 'Partial') {
            
$this->nvpStr "&TRANSACTIONID=$transactionID&REFUNDTYPE=$refundType&CURRENCYCODE=$currencyID&AMOUNT=$amount&MEMO=$memo";
        } else {
            
$this->nvpStr "&TRANSACTIONID=$transactionID&REFUNDTYPE=$refundType&CURRENCYCODE=$currencyID";
        }        
            
        return 
$this->query("RefundTransaction");
    }
    
    
/**
     * Get the details of a transaction
     *
     * @param  $transaction_id
     * @return mixed    array if success, false otherwise.
     */
    
function getTransactionDetails($transaction_id) {        
        
// Set request-specific fields.
        
$transactionID urlencode($transaction_id);
        
$this->nvpStr "&TRANSACTIONID=$transactionID";    
            
        return 
$this->query("RefundTransaction");
    }
    
    
/**
     * Search for a transaction during the specified time frame.
     *
     * @param $transaction_id
     * @param $startDateStr
     * @param $endDateStr
     * @return mixed    array if success, false otherwise.
     */
    
function search($transaction_id$startDateStr null$endDateStr null) {
        
// Set request-specific fields.
        
$transactionID urlencode($transaction_id);
        
        
// Add request-specific fields to the request string.
        
$this->nvpStr "&TRANSACTIONID=$transactionID";
        
        
// Set additional request-specific fields and add them to the request string.
        
if(isset($startDateStr)) {
           
$start_time strtotime($startDateStr);
           
$iso_start date('Y-m-d\T00:00:00\Z',  $start_time);
           
$this->nvpStr .= "&STARTDATE=$iso_start";
          }
        
        if(isset(
$endDateStr)&&$endDateStr!='') {
           
$end_time strtotime($endDateStr);
           
$iso_end date('Y-m-d\T24:00:00\Z'$end_time);
           
$this->nvpStr .= "&ENDDATE=$iso_end";
        }
        return 
$this->query("TransactionSearch");
    }
    
    
/**
     * Performs the communication with the paypal api
     * 
     * In case of error it returns false 
     * @return mixed array if success, false otherwise.
     * 
     */
    
function query($methodName) {
        
// Set up your API credentials, PayPal end point, and API version.
        
$API_UserName urlencode($this->userName);
        
$API_Password urlencode($this->password);
        
$API_Signature urlencode($this->signature);
                
        
$API_Endpoint "https://api-3t.paypal.com/nvp";        
        if(
"sandbox" === $this->environment || "beta-sandbox" === $this->environment) {
            
$API_Endpoint "https://api-3t.$this->environment.paypal.com/nvp";
        }
        
$version urlencode('51.0');
    
        
// Set the API operation, version, and API signature in the request.
        
$this->nvpreq "METHOD=$methodName&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$this->nvpStr";
        
        
//call the web service
        
$response $this->Http->post($API_Endpoint$this->nvpreq);
            
        if(!
$response) {
            return 
false;
        }
    
        
// Extract the response details.
        
$httpResponseAr explode("&"$response);
    
        
$httpParsedResponseAr = array();
        foreach (
$httpResponseAr as $i => $value) {
            
$tmpAr explode("="$value);
            if(
sizeof($tmpAr) > 1) {
                
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
            }
        }
    
        if((
== sizeof($httpParsedResponseAr)) || !array_key_exists('ACK'$httpParsedResponseAr)) {
            return 
false;
        }
        return 
$httpParsedResponseAr;        
    }
    
    
}
?> 

Comments

  • Posted 02/19/10 07:50:23 AM
    I'll get this code to the new site.
  • Posted 10/01/09 03:51:58 AM
    Hi, firstly thanks for all the hardwork!

    I am trying to integrate this script into cake site, part of my problem is that I an new to cake, although I have about 5 years experience in php. In the explanation it says that you can call the code from anywhere ( $paypal = ConnectionManager::getDataSource('paypal');
    $response = $paypal->doDirectPayment($billing, $payment); )
    Even in the view? ( I suspect it has to be doDirectPayment NOT DirectPayment ) Can anyone give me an example of how this works in the view / controller / model ?
    Thanks Gabriel
  • Posted 03/27/09 11:49:42 PM

    /**
         * Get the details of a transaction
         *
         * @param  $transaction_id
         * @return mixed    array if success, false otherwise.
         */
        function getTransactionDetails($transaction_id) {        
            // Set request-specific fields.
            $transactionID = urlencode($transaction_id);
            $this->nvpStr = "&TRANSACTIONID=$transactionID";    
                
            return $this->query("RefundTransaction");
        } 

    Should be:


    /**
         * Get the details of a transaction
         *
         * @param  $transaction_id
         * @return mixed    array if success, false otherwise.
         */
        function getTransactionDetails($transaction_id) {        
            // Set request-specific fields.
            $transactionID = urlencode($transaction_id);
            $this->nvpStr = "&TRANSACTIONID=$transactionID";    
                
            return $this->query("GetTransactionDetails");
        }

    Don't make the same mistake I did. I accidentally refunded a transaction when I just wanted to view it.
  • Posted 01/17/09 09:44:47 PM
    Missing Database Table

    Error: Database table paypals for model Paypal was not found
  • Posted 01/05/09 10:41:43 PM
    I like it. I'm sure over time it could use some upgrades, but the base concept is great.
  • Posted 01/05/09 03:33:36 PM
    Does this work for reoccurring payments?
  • Posted 01/02/09 12:35:55 PM
    toste,

    This worked flawlessly for me both in the sandbox and in for the production site (live). Only suggestion I might give is making the variables the same for the form as they are in the class just to make it a little easier to keep track of. Other than that this script worked flawlessly and took me 15 minutes to get it working.

    Thanks so much!

Comments are closed for articles over a year old