PayPal Direct Payment API Component

4 : The Paypal Component

By Mariano Iglesias (mariano)
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)

The Paypal Component


Component Class:

<?php 
/**
 * Paypal Direct Payment API Component class file.
 *
 * @filesource
 * @copyright        Mariano Iglesias - mariano@cricava.com
 * @link            http://www.marianoiglesias.com.ar Mariano Iglesias
 * @package            cake
 * @subpackage        cake.controllers.components
 */

require_once('PayPal.php');
require_once(
'PayPal/Profile/API.php');
require_once(
'PayPal/Profile/Handler.php');
require_once(
'PayPal/Profile/Handler/Array.php');
require_once(
'PayPal/Type/AbstractResponseType.php');
require_once(
'PayPal/Type/AddressType.php');
require_once(
'PayPal/Type/BasicAmountType.php');
require_once(
'PayPal/Type/CreditCardDetailsType.php');
require_once(
'PayPal/Type/DoCaptureResponseDetailsType.php');
require_once(
'PayPal/Type/DoCaptureResponseType.php');
require_once(
'PayPal/Type/DoDirectPaymentRequestType.php');
require_once(
'PayPal/Type/DoDirectPaymentRequestDetailsType.php');
require_once(
'PayPal/Type/DoDirectPaymentResponseType.php');
require_once(
'PayPal/Type/DoExpressCheckoutPaymentRequestType.php');
require_once(
'PayPal/Type/DoExpressCheckoutPaymentRequestDetailsType.php');
require_once(
'PayPal/Type/DoExpressCheckoutPaymentResponseType.php');
require_once(
'PayPal/Type/DoVoidResponseType.php');
require_once(
'PayPal/Type/ErrorType.php');
require_once(
'PayPal/Type/GetExpressCheckoutDetailsRequestType.php');
require_once(
'PayPal/Type/GetExpressCheckoutDetailsResponseDetailsType.php');
require_once(
'PayPal/Type/GetExpressCheckoutDetailsResponseType.php');
require_once(
'PayPal/Type/GetTransactionDetailsResponseType.php');
require_once(
'PayPal/Type/PayerInfoType.php');
require_once(
'PayPal/Type/PaymentDetailsType.php');
require_once(
'PayPal/Type/PersonNameType.php');
require_once(
'PayPal/Type/RefundTransactionResponseType.php');
require_once(
'PayPal/Type/SetExpressCheckoutRequestType.php');
require_once(
'PayPal/Type/SetExpressCheckoutRequestDetailsType.php');
require_once(
'PayPal/Type/SetExpressCheckoutResponseType.php');
require_once(
'PayPal/Type/TransactionSearchResponseType.php');

define ('CAKE_COMPONENT_PAYPAL_ENVIRONMENT_LIVE''live');
define ('CAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOX''sandbox');
define ('CAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOX_BETA''beta-sandbox');
define ('CAKE_COMPONENT_PAYPAL_ORDER_TYPE_SALE''Sale');
define ('CAKE_COMPONENT_PAYPAL_CURRENCY''USD');
define ('CAKE_COMPONENT_PAYPAL_CHARSET_DEFAULT''iso-8859-1');
define ('CAKE_COMPONENT_PAYPAL_ACK_SUCCESS''Success');
define ('CAKE_COMPONENT_PAYPAL_ACK_SUCCESS_WITH_WARNING''SuccessWithWarning');
define ('CAKE_COMPONENT_PAYPAL_SESSION_SAVE_PATH'ROOT DS APP_DIR DS 'tmp' DS 'sessions'); // No trailing slash!
define ('CAKE_COMPONENT_PAYPAL_EXPRESS_CHECKOUT_URL''https://www.{$environment}.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token={$token}');

define ('CAKE_COMPONENT_PAYPAL_ERROR_CANT_CREATE_CALLER'1);
define ('CAKE_COMPONENT_PAYPAL_ERROR_INVALID_ORDER'2);
define ('CAKE_COMPONENT_PAYPAL_ERROR_INVALID_BUYER'3);
define ('CAKE_COMPONENT_PAYPAL_ERROR_CANT_GET_AMOUNT_TYPE'4);
define ('CAKE_COMPONENT_PAYPAL_ERROR_INVALID_CREDIT_CARD_EXPIRATION_DATE'5);
define ('CAKE_COMPONENT_PAYPAL_ERROR_CREDIT_CARD_NOT_SET'6);
define ('CAKE_COMPONENT_PAYPAL_ERROR_INVALID_REQUEST'7);
define ('CAKE_COMPONENT_PAYPAL_ERROR_INVALID_CVV2'10504);
define ('CAKE_COMPONENT_PAYPAL_ERROR_INVALID_CREDIT_CARD'10527);

/**
 * Provides a wrapper for Paypal Direct Payment API.
 * 
 * @author        Mariano Iglesias - mariano@cricava.com
 * @package        cake
 * @subpackage    cake.controllers.components
 */
class PaypalComponent extends Object
{
    
/**#@+
     * @access protected
     */
    /**
     * Name of this component.
     *
     * @since 1.0
     * @var string
     */
    
var $name 'Paypal';
    
/**
     * Components that will be used.
     * 
     * @since 1.0
     * @var array
     */
    
var $components = array('Session');
    
/**#@-*/
    /**#@+
     * @access private
     */
    /**
     * Settings.
     *
     * @since 1.0
     * @var array
     */
    
var $settings = array(
        
'api.environment' => CAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOX,
        
'api.username' => null,
        
'api.password' => null,
        
'api.certificate' => null,
        
'api.signature' => null,
        
'api.charset' => CAKE_COMPONENT_PAYPAL_CHARSET_DEFAULT
    
);
    
/**
     * Paypal API caller.
     *
     * @since 1.0
     * @var CallerServices
     */
    
var $caller;
    
/**
     * Last Paypal error code.
     *
     * @since 1.0
     * @var int
     */
    
var $errorCode;
    
/**
     * Last Paypal error.
     *
     * @since 1.0
     * @var string
     */
    
var $error;
    
/**#@-*/
    
    /**
     * Startup the component.
     *
     * @param AppController $controller    The controller using the component
     * 
     * @access public
     * @since 1.0
     */
    
function startup(&$controller)
    {
    }
    
    
/**
     * Stores the current session to a temporary file for later retrieval.
     * 
     * @return bool    true if stored, false otherwise
     * 
     * @access public
     * @since 1.0
     */
    
function storeSession()
    {
        
$sessionFileHandle fopen(CAKE_COMPONENT_PAYPAL_SESSION_SAVE_PATH DS session_id() . '.ser.tmp''w');
                        
        if (
$sessionFileHandle !== false)
        {
            
fwrite($sessionFileHandleserialize($_SESSION));
            
fclose($sessionFileHandle);
            
            return 
true;
        }
        
        return 
false;
    }
    
    
/**
     * Restores the specified session.
     * 
     * @param string    Session ID
     * 
     * @return bool    true if able to restore, false otherwise
     * 
     * @access public
     * @since 1.0
     */
    
function restoreSession($session_id)
    {
        if (
preg_match('/^[A-Za-z0-9]*$/'$session_id))
        {
            
$sessionFile CAKE_COMPONENT_PAYPAL_SESSION_SAVE_PATH DS $session_id '.ser.tmp';
            
            if (@
file_exists($sessionFile) && @is_file($sessionFile) && @is_readable($sessionFile) && @filesize($sessionFile) > 0)
            {
                
$contents file_get_contents($sessionFile);
                
$oldSession = @unserialize($contents);
                
                if (
is_array($oldSession) && count($oldSession) > 0)
                {
                    foreach(
$oldSession as $id => $value)
                    {
                        
$this->Session->write($id$value);
                    }
                }
                
                @
unlink($sessionFile);
                
                return 
true;
            }
        }
        
        return 
false;
    }
    
    
/**
     * Sets the API environment.
     * 
     * @param string $environment    API environment.
     * 
     * @access public
     * @since 1.0
     */
    
function setEnvironment($environment)
    {
        if (
in_array($environment, array(CAKE_COMPONENT_PAYPAL_ENVIRONMENT_LIVECAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOXCAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOX_BETA)))
        {
            
$this->settings['api.environment'] = $environment;
        }
    }
    
    
/**
     * Sets the full path to the certificate file.
     * 
     * @param string $certificate    Path to Certificate file.
     * 
     * @access public
     * @since 1.0
     */
    
function setCertificate($certificate)
    {
        
$this->settings['api.certificate'] = $certificate;
    }
    
    
/**
     * Sets the API signature.
     * 
     * @param string $signature    API signature.
     * 
     * @access public
     * @since 1.0
     */
    
function setSignature($signature)
    {
        
$this->settings['api.signature'] = $signature;
    }
    
    
/**
     * Sets the API user.
     * 
     * @param string $user    API user.
     * 
     * @access public
     * @since 1.0
     */
    
function setUser($user)
    {
        
$this->settings['api.username'] = $user;
    }
    
    
/**
     * Sets the API password.
     * 
     * @param string $password    API password.
     * 
     * @access public
     * @since 1.0
     */
    
function setPassword($password)
    {
        
$this->settings['api.password'] = $password;
    }
    
    
/**
     * Sets the default charset.
     * 
     * @param string $charset    charset (example: iso-8859-1)
     * 
     * @access public
     * @since 1.0
     */
    
function setCharset($charset)
    {
        
$this->settings['api.charset'] = $charset;
    }
    
    
/**
     * Sets the URL to which PayPal Express Checkout will redirect when setting the token.
     * 
     * @param string $uri    The URI (for example, $this->here from a controller)
     * 
     * @access public
     * @since 1.0
     */
    
function setTokenUrl($uri)
    {
        
$this->settings['express.token_uri'] = $uri;
    }
    
    
/**
     * Sets the URL to which PayPal Express Checkout will redirect when order cancelled.
     * 
     * @param string $uri    The URI (for example, $this->here from a controller)
     * 
     * @access public
     * @since 1.0
     */
    
function setCancelUrl($uri)
    {
        
$this->settings['express.cancel_uri'] = $uri;
    }
    
    
/**
     * Sets the order to be processed. The order is an indexed array.
     * Example:
     * 
     * Array
     * (
     *     [action] => Sale
     *     [description] => ORDER_DESCRIPTION
     *     [id] => INVOICE_ID
     *     [total] => 200
     *     [buyer] => Array
     *         (
     *             [first] => FIRST_NAME
     *             [last] => LAST_NAME
     *             [address1] => ADDRESS_1
     *             [address2] => ADDRESS_2
     *             [city] => CITY
     *             [state] => STATE (two letter for US)
     *             [zip] => ZIP
     *             [country] => us
     *         )
     *     [cc] => Array
     *         (
     *             [type] => Visa/MasterCard/Discovery/Amex
     *             [number] => CC_NUMBER
     *             [expiration] => 1/2010
     *             [cvv2] => 123
     *             [owner] => Array
     *                 (
     *                     [first] => HOLDER_FIRST_NAME
     *                     [last] => HOLDER_LAST_NAME
     *                 )
     *         )
     * )
     * 
     * @param array $order    Order to be processed.
     * 
     * @access public
     * @since 1.0
     */
    
function setOrder($order)
    {
        
$this->settings['order'] = $order;
    }
    
    
/**
     * Gets the latest error message. If more than one error message was
     * reported by PayPal, each message is separated by a new line.
     * 
     * @return string    Latest error message (null if none).
     * 
     * @access public
     * @since 1.0
     */
    
function getError()
    {
        return 
$this->error;
    }
    
    
/**
     * Gets the latest error code.
     * 
     * @return int    latest error code (0 if no error).
     * 
     * @access public
     * @since 1.0
     */
    
function getErrorCode()
    {
        return 
$this->errorCode;
    }
    
    
/**
     * Performs a direct payment with the specified order. If order was processed,
     * returns an indexed array with:
     * 
     * - transaction: Paypal Transaction id
     * - ack: success code
     * - avs: AVS response code for US credit cards (see https://www.paypal.com/IntegrationCenter/ic_direct-payment.html)
     * - cvv2: CVV response code for US credit cards (see - avs: AVS response code for US credit cards (see https://www.paypal.com/IntegrationCenter/ic_direct-payment.html)
     * - amount: processed amount
     * 
     * In case of error it returns false and sets error code and error message.
     * 
     * @return mixed    array if success, false otherwise.
     * 
     * @since 1.0
     * @access public
     */
    
function directPayment()
    {
        
$this->_initialize();
        
        if (!isset(
$this->caller))
        {
            return 
false;
        }
        
        if (!isset(
$this->settings['order']) || !isset($this->settings['order']['total']) || !isset($this->settings['order']['action']))
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_ORDER;
            
$this->error 'Order was not set up properly';
            return 
false;
        }
        
        
$this->errorCode 0;
        
$this->error null;
        
        
// Set up buyer's information
        
        
$shipTo =& PayPal::getType('AddressType');
        
        if (isset(
$this->settings['order']['buyer']))
        {
            
$this->settings['order']['buyer']['country'] = strtoupper($this->settings['order']['buyer']['country']);
            
            if (
$this->settings['order']['buyer']['country'] == 'US')
            {
                
$this->settings['order']['buyer']['state'] = strtoupper($this->settings['order']['buyer']['state']);
            }
            
            
$shipTo->setName($this->settings['order']['buyer']['first'] . ' ' $this->settings['order']['buyer']['last']);
            
$shipTo->setStreet1($this->settings['order']['buyer']['address1']);
            
            if (isset(
$this->settings['order']['buyer']['address2']))
            {
                
$shipTo->setStreet2($this->settings['order']['buyer']['address2']);
            }
            
            
$shipTo->setCityName($this->settings['order']['buyer']['city']);
            
$shipTo->setStateOrProvince($this->settings['order']['buyer']['state']);
            
$shipTo->setPostalCode($this->settings['order']['buyer']['zip']);
            
$shipTo->setCountry($this->settings['order']['buyer']['country']);
        }
        else
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_BUYER;
            
$this->error 'Buyer was not set in order';
            return 
false;
        }
        
        
// Set up total $ for order
        
        
$orderTotal =& PayPal::getType('BasicAmountType');
        
        if (
PayPal::isError($orderTotal)) 
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_CANT_GET_AMOUNT_TYPE;
            
$this->error $orderTotal->getMessage();
            return 
false;
        }
        
        
$orderTotal->setattr('currencyID'CAKE_COMPONENT_PAYPAL_CURRENCY);
        
$orderTotal->setval($this->settings['order']['total'], $this->settings['api.charset']);
        
        
// Set up payment details
        
        
$paymentDetails =& PayPal::getType('PaymentDetailsType');
        
        
$paymentDetails->setOrderTotal($orderTotal);
        
$paymentDetails->setShipToAddress($shipTo);
        
        if (isset(
$this->settings['order']['description']))
        {
            
$paymentDetails->setOrderDescription($this->settings['order']['description'], $this->settings['api.charset']);
        }
        
        if (isset(
$this->settings['order']['id']))
        {
            
$paymentDetails->setInvoiceId($this->settings['order']['id'], $this->settings['api.charset']);
        }
        
        
// Set up credit card information
        
        
$cardDetails =& PayPal::getType('CreditCardDetailsType');
        
        if (isset(
$this->settings['order']['cc']))
        {
            
$personDetails =& PayPal::getType('PersonNameType');
            
            if (isset(
$this->settings['order']['cc']['owner']))
            {
                
$personDetails->setFirstName($this->settings['order']['cc']['owner']['first']);
                
$personDetails->setLastName($this->settings['order']['cc']['owner']['last']);
            }
            else
            {
                
$personDetails->setFirstName($this->settings['order']['buyer']['first']);
                
$personDetails->setLastName($this->settings['order']['buyer']['last']);
            }
            
            
$payerDetails =& PayPal::getType('PayerInfoType');
            
            
$payerDetails->setPayerName($personDetails);
            
$payerDetails->setPayerCountry($this->settings['order']['buyer']['country']);
            
$payerDetails->setAddress($shipTo);
            
            
$cardDetailsExpiration explode('/'$this->settings['order']['cc']['expiration']);
            
            if (
count($cardDetailsExpiration) != || $cardDetailsExpiration[0] < || $cardDetailsExpiration[0] > 12 || $cardDetailsExpiration[1] < date('Y'))
            {
                
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_CREDIT_CARD_EXPIRATION_DATE;
                
$this->error 'Credit Card Expiration date seems to be wrong (format: month/year)';
                return 
false;
            }
            
            
$cardDetailsExpiration[0] = str_pad($cardDetailsExpiration[0], 2'0'STR_PAD_LEFT);
            
            
$cardDetails->setCreditCardType($this->settings['order']['cc']['type']);
            
$cardDetails->setCreditCardNumber($this->settings['order']['cc']['number']);
            
$cardDetails->setCVV2($this->settings['order']['cc']['cvv2']);
            
$cardDetails->setExpMonth($cardDetailsExpiration[0]);
            
$cardDetails->setExpYear($cardDetailsExpiration[1]);
            
$cardDetails->setCardOwner($payerDetails);
        }
        else
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_CREDIT_CARD_NOT_SET;
            
$this->error 'Credit Card was not set in order';
            return 
false;
        }
        
        
// Set up request details
        
        
$requestDetails =& PayPal::getType('DoDirectPaymentRequestDetailsType');
        
        
$requestDetails->setPaymentDetails($paymentDetails);
        
$requestDetails->setCreditCard($cardDetails);
        
$requestDetails->setPaymentAction($this->settings['order']['action']);
        
$requestDetails->setIPAddress($_SERVER['SERVER_ADDR']);
        
        
// Set up request
        
        
$request =& PayPal::getType('DoDirectPaymentRequestType');
        
        
$request->setDoDirectPaymentRequestDetails($requestDetails);
        
        
// Execute request
        
        
$response $this->caller->DoDirectPayment($request);
        
        if (
PayPal::isError($response))
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_REQUEST;
            
$this->error $response->getMessage();
            
            return 
false;
        }
        
        
$response_ack $response->getAck();
        
        if (
$response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS || $response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS_WITH_WARNING)
        {
            
$response_amount $response->getAmount();
            
            
$result = array (
                
'transaction' => $response->getTransactionID(),
                
'ack' => $response_ack,
                
'avs' => $response->getAVSCode(),
                
'cvv2' => $response->getCVV2Code(),
                
'amount' => $response_amount->_value
            
);
            
            return 
$result;
        }
        else
        {
            
$errorList $response->getErrors();
            
            if(!
is_array($errorList))
            {
                
$this->errorCode $errorList->getErrorCode();
                
$this->error '#' $errorList->getErrorCode() . ': ' $errorList->getShortMessage() . ' [' $errorList->getLongMessage() . ']';
            }
            else
            {
                
$this->error '';
                
                foreach(
$errorList as $error)
                {
                    if (!empty(
$this->error))
                    {
                        
$this->error .= "\n";
                    }
                    
                    
$this->errorCode $error->getErrorCode();
                    
$this->error .= '#' $error->getErrorCode() . ': ' $error->getShortMessage() . ' [' $error->getLongMessage() . ']';
                }
            }
        }
        
        return 
false;
    }
    
    
/**
     * Performs an express checkout payment with the specified order. If order was processed,
     * returns an indexed array with:
     * 
     * - transaction: Paypal Transaction id
     * - ack: success code
     * - amount: processed amount
     * 
     * In case of error it returns false and sets error code and error message.
     * 
     * Please note that this function should be called TWICE to make an actual payment. First call
     * sets environment and paypal token up and tells paypal to redirect back to the URL specified
     * by the function setTokenUrl(). Once this URL is reached (meaning paypal has sent us the
     * generated token) then this function should be called again to perform the actual payment.
     * 
     * @return mixed    array if success, false otherwise.
     * 
     * @since 1.0
     * @access public
     */
    
function expressCheckout()
    {
        
$this->_initialize();
        
        if (!isset(
$this->caller))
        {
            return 
false;
        }
        
        if (!isset(
$this->settings['order']) || !isset($this->settings['order']['total']) || !isset($this->settings['order']['action']))
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_ORDER;
            
$this->error 'Order was not set up properly';
            return 
false;
        }
        
        
$this->errorCode 0;
        
$this->error null;
        
        if (!isset(
$_REQUEST['token']))
        {
            if (isset(
$this->settings['express.token_uri']))
            {
                
$tokenUrl $this->settings['express.token_uri'];
            }
            else
            {
                
$serverName $_SERVER['SERVER_NAME'];
                
$serverPort $_SERVER['SERVER_PORT'];
                
                
$pathParts pathinfo($_SERVER['SCRIPT_NAME']);
                
$pathInfo $pathParts['dirname'];
            
                
$tokenUrl 'http://';
               
                if (isset(
$_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') == 0)
                {
                    
$tokenUrl 'https://';
                }
               
                
$tokenUrl .= $serverName . ($serverPort != 80 ':' $serverPort '');
                
$tokenUrl .= $pathInfo;
                
$tokenUrl .= '/' $_SERVER['SCRIPT_NAME'];
                
                if (!empty(
$_SERVER['QUERY_STRING']))
                {
                    
$tokenUrl .= '?' $_SERVER['QUERY_STRING'];
                }
            }
            
            if (isset(
$this->settings['express.cancel_uri']))
            {
                
$cancelUrl $this->settings['express.cancel_uri'];
            }
            
            
// Set up total $ for order
            
            
$orderTotal =& PayPal::getType('BasicAmountType');
            
            if (
PayPal::isError($orderTotal)) 
            {
                
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_CANT_GET_AMOUNT_TYPE;
                
$this->error $orderTotal->getMessage();
                return 
false;
            }
            
            
$orderTotal->setattr('currencyID'CAKE_COMPONENT_PAYPAL_CURRENCY);
            
$orderTotal->setval($this->settings['order']['total'], $this->settings['api.charset']);
            
            
// Set up request details
            
            
$requestDetails =& PayPal::getType('SetExpressCheckoutRequestDetailsType');
            
            
$requestDetails->setReturnURL($tokenUrl);
            
$requestDetails->setCancelURL($cancelUrl);
            
$requestDetails->setPaymentAction($this->settings['order']['action']);
            
$requestDetails->setOrderTotal($orderTotal);
            
            
// Set up request
            
            
$request =& PayPal::getType('SetExpressCheckoutRequestType');
            
            
$request->setSetExpressCheckoutRequestDetails($requestDetails);
            
            
// Execute request
            
            
$response $this->caller->SetExpressCheckout($request);
            
            if (
PayPal::isError($response))
            {
                
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_REQUEST;
                
$this->error $response->getMessage();
                
                return 
false;
            }
            
            
$response_ack $response->getAck();
        
            if (
$response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS || $response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS_WITH_WARNING)
            {
                
$token $response->getToken();
                      
                
$payPalUrl CAKE_COMPONENT_PAYPAL_EXPRESS_CHECKOUT_URL;
                      
                
$payPalUrl str_replace('{$environment}'$this->settings['api.environment'], $payPalUrl);
                
$payPalUrl str_replace('{$token}'$token$payPalUrl);
                
                
header('Location: ' $payPalUrl);
                exit;
            }
            else
            {
                
$errorList $response->getErrors();
                
                if(!
is_array($errorList))
                {
                    
$this->errorCode $errorList->getErrorCode();
                    
$this->error '#' $errorList->getErrorCode() . ': ' $errorList->getShortMessage() . ' [' $errorList->getLongMessage() . ']';
                }
                else
                {
                    
$this->error '';
                    
                    foreach(
$errorList as $error)
                    {
                        if (!empty(
$this->error))
                        {
                            
$this->error .= "\n";
                        }
                        
                        
$this->errorCode $error->getErrorCode();
                        
$this->error .= '#' $error->getErrorCode() . ': ' $error->getShortMessage() . ' [' $error->getLongMessage() . ']';
                    }
                    
                    return 
false;
                }
            }
        }
        else
        {
            
// Set up request
            
            
$request =& PayPal::getType('GetExpressCheckoutDetailsRequestType');
            
            
$request->setToken($_REQUEST['token']);
            
            
// Execute request
            
            
$response $this->caller->GetExpressCheckoutDetails($request);
            
            if (
PayPal::isError($response))
            {
                
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_REQUEST;
                
$this->error $response->getMessage();
                
                return 
false;
            }
            
            
$response_ack $response->getAck();
        
            if (
$response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS || $response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS_WITH_WARNING)
            {
                
$responseDetails $response->getGetExpressCheckoutDetailsResponseDetails();
                
                
$payerInfo $responseDetails->getPayerInfo();
                
$payerId $payerInfo->getPayerID();
            }
            else
            {
                
$errorList $response->getErrors();
                
                if(!
is_array($errorList))
                {
                    
$this->errorCode $errorList->getErrorCode();
                    
$this->error '#' $errorList->getErrorCode() . ': ' $errorList->getShortMessage() . ' [' $errorList->getLongMessage() . ']';
                }
                else
                {
                    
$this->error '';
                    
                    foreach(
$errorList as $error)
                    {
                        if (!empty(
$this->error))
                        {
                            
$this->error .= "\n";
                        }
                        
                        
$this->errorCode $error->getErrorCode();
                        
$this->error .= '#' $error->getErrorCode() . ': ' $error->getShortMessage() . ' [' $error->getLongMessage() . ']';
                    }
                }
                
                return 
false;
            }
            
            
// Set up total $ for order
            
            
$orderTotal =& PayPal::getType('BasicAmountType');
            
            if (
PayPal::isError($orderTotal)) 
            {
                
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_CANT_GET_AMOUNT_TYPE;
                
$this->error $orderTotal->getMessage();
                
                return 
false;
            }
            
            
$orderTotal->setattr('currencyID'CAKE_COMPONENT_PAYPAL_CURRENCY);
            
$orderTotal->setval($this->settings['order']['total'], $this->settings['api.charset']);
            
            
// Set up payment details
        
            
$paymentDetails =& PayPal::getType('PaymentDetailsType');
            
            
$paymentDetails->setOrderTotal($orderTotal);
            
            if (isset(
$this->settings['order']['description']))
            {
                
$paymentDetails->setOrderDescription($this->settings['order']['description'], $this->settings['api.charset']);
            }
            
            if (isset(
$this->settings['order']['id']))
            {
                
$paymentDetails->setInvoiceId($this->settings['order']['id'], $this->settings['api.charset']);
            }
            
            
// Set up request details
            
            
$requestDetails =& PayPal::getType('DoExpressCheckoutPaymentRequestDetailsType');
            
            
$requestDetails->setToken($_REQUEST['token']);
            
$requestDetails->setPayerID($payerId);
            
$requestDetails->setPaymentAction($this->settings['order']['action']);
            
$requestDetails->setPaymentDetails($paymentDetails);
            
            
// Set up request
            
            
$request =& PayPal::getType('DoExpressCheckoutPaymentRequestType');
            
            
$request->setDoExpressCheckoutPaymentRequestDetails($requestDetails);
            
            
// Execute request
            
            
$response $this->caller->DoExpressCheckoutPayment($request);
            
            if (
PayPal::isError($response))
            {
                
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_INVALID_REQUEST;
                
$this->error $response->getMessage();
                
                return 
false;
            }
            
            
$response_ack $response->getAck();
            
            if (
$response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS || $response_ack == CAKE_COMPONENT_PAYPAL_ACK_SUCCESS_WITH_WARNING)
            {
                
$responseDetails $response->getDoExpressCheckoutPaymentResponseDetails();
                
$responsePaymentInfo $responseDetails->getPaymentInfo();
                
                
$response_amount $responsePaymentInfo->getGrossAmount();
                
                
$result = array (
                    
'transaction' => $responsePaymentInfo->getTransactionID(),
                    
'ack' => $response_ack,
                    
'amount' => $response_amount->_value
                
);
                
                return 
$result;
            }
            else
            {
                
$errorList $response->getErrors();
                
                if(!
is_array($errorList))
                {
                    
$this->errorCode $errorList->getErrorCode();
                    
$this->error '#' $errorList->getErrorCode() . ': ' $errorList->getShortMessage() . ' [' $errorList->getLongMessage() . ']';
                }
                else
                {
                    
$this->error '';
                    
                    foreach(
$errorList as $error)
                    {
                        if (!empty(
$this->error))
                        {
                            
$this->error .= "\n";
                        }
                        
                        
$this->errorCode $error->getErrorCode();
                        
$this->error .= '#' $error->getErrorCode() . ': ' $error->getShortMessage() . ' [' $error->getLongMessage() . ']';
                    }
                }
                
                return 
false;
            }
        }
        
        return 
false;
    }
    
    
/**
     * Initializes the PayPal API caller handler.
     * 
     * @return bool    true on success, false otherwise.
     * 
     * @access private
     * @since 1.0
     */
    
function _initialize()
    {
        
$this->errorCode 0;
        
$this->error null;
        
        
$handler =& ProfileHandler_Array::getInstance(array(
            
'username' => $this->settings['api.username'],
            
'certificateFile' => null,
            
'subject' => null,
            
'environment' => $this->settings['api.environment'] ));
                 
        
$pid ProfileHandler::generateID();
        
        
$profile =& new APIProfile($pid$handler);
        
        
$profile->setAPIUsername($this->settings['api.username']);
        
$profile->setAPIPassword($this->settings['api.password']); 
        
        if(isset(
$this->settings['api.certificate']))
        {
            
$profile->setCertificateFile($this->settings['api.certificate']); 
        }
        
        
$profile->setSignature($this->settings['api.signature']);
        
$profile->setEnvironment($this->settings['api.environment']);
        
        
$this->caller =& PayPal::getCallerServices($profile);
        
        if (
PayPal::isError($this->caller))
        {
            
$this->errorCode CAKE_COMPONENT_PAYPAL_ERROR_CANT_CREATE_CALLER;
            
$this->error $this->caller->getMessage();
            
            unset(
$this->caller);
            
            return 
false;
        }
        
        return 
true;
    }
}
?>

Comments 168

CakePHP Team Comments Author Comments
 

Comment

1 PayPal Direct Payment API Version

Hi,

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
Posted Nov 28, 2006 by Penfold
 

Comment

2 PayPal Direct Payment API Version

Is the API used the US version for paypal pro?
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?
Posted Nov 28, 2006 by Mariano Iglesias
 

Comment

3 Thanks

You have simplified it a lot :)
Posted Dec 31, 1969 by Abhimanyu Grover
 

Question

4 UK version

So... does anyone know if this will now work for the UK also?
Posted Dec 31, 1969 by Dallas Ms
 

Comment

5 Thank You

Thank you very much for providing this.
I'll be trying it out today. It will most definitely save me many, many hours.
Posted Jul 13, 2007 by Antonie Potgieter
 

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.
Posted Aug 4, 2007 by john diegor
 

Comment

7 API Question

I am still testing but when I put 'sandbox.paypal.com.pem' in {cake}/app/webroot/ I stopped getting that error. Hope this helps!
Posted Aug 5, 2007 by Landon
 

Comment

8 important

this is the way to solve the certificate problem :

- Remove setCertificate and replace it with
$this->Paypal->setSignature('signature provided by paypal');.
and people it worked!!
Posted Oct 27, 2007 by joren
 

Question

9 Cake 1.2 integration for the Paypal component

Has someone created a similar component to work with Paypal API on Cake 1.2? I tried this component on 1.2 but it doesn't seem to work right. Errors here and there.
Posted Oct 28, 2007 by Tengku Zahasman
 

Comment

10 Cake 1.2 integration for the Paypal component

@Tengku: what errors are you seeing? "Erros here and there" is by no means a help for me to fix them, is it? BTW I'm using it on a 1.2 application and have not seen anything bad happening, so PLEASE report the errors you are getting.
Posted Oct 28, 2007 by Mariano Iglesias
 

Comment

11 Fatal Error

I am trying to use the component but I am getting the following example when trying to run the example.
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]
Posted Mar 27, 2008 by Donald Walters
 

Comment

12 Complicated Solutions

Hi!
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
Posted May 8, 2008 by geri
 

Comment

13 hi i have same problem... can you help me with it

hi i have same problem... can you help me with it...

i am able to copy PEAR and paypal component ...every thing is working fine (it is able to include Pear , recognize paypal component).. but i am unable to figure out hoe to implement it in my project.

please guide me to solve this issue..

i will be greatfull to you if you can send some example application if you can...


Thanks in advance

M A Rasheed



Hi!
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
Posted Sep 29, 2008 by rasheed M A
 

Question

14 Reset Endpoints?

First off, I would really like to thank you for writing this package. It's been fantastic so far. So, Thanks!

So, here is my situation. I seem to have everything working fine on cake1.2 on my local box (os x leopard). However, when I deploy the same code to the pre-production box (Aplus.net shared hosting), I am getting a curl permission denied issue. Typically this can be due to proxy issues, and I think its only related to hitting the sandbox site.

Apparently, this can be fixed by resetting the endpoint URL to api-aa.sandbox.paypal.com/2.0/.

However, I can not for the life of me find the section in the code that is physically setting the URL request in the DirectPayment method. I see how its setting the environment to the constant declared above (i.e. CAKE_COMPONENT_PAYPAL_ENVIRONMENT_SANDBOX)-- and I can see in the Express Checkout where its replacing the string based off of that value. But, I can not find how the request is being built for the directPayment method to change the value to api-aa.sandbox.paypal.com/2.0/.

Please let me know if anyone has any ideas.

Thanks!

Chris
Posted Oct 27, 2008 by Christopher Geheran
 

Question

15 I want guideline to integrate Paypal in any Cake Project

Hi All,

I am not able to understand the given code. Some part of code is not explained where to place it
Posted Nov 4, 2008 by ramanpreet
 

Comment

16 I am getting same error on live server

I am trying to use the component but I am getting the following example when trying to run the example.
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]



Hi it is working fine on local system (localhost)but it is not working on live server.... any solution?


please help me!!

Thanks in advance

M A Rasheed
Posted Nov 6, 2008 by rasheed M A
 

Comment

17 Instructions for use

This component is absolutely fantastic and greatly simplifies the use of PayPal's API when doing a checkout. Well done to the Author.

To use this component, the following steps need to be taken:

1) The complete code for the component (located on page 4) needs to be saved as app/controller/components/paypal.php
2) In the controller you wish to use the component for, add: var $uses = array('Paypal');
3) In your controller, add the example express() method (provided on page 2).

This presumes that you have the PayPal API set up. The PayPal API is completely separate to this component. To install the PayPal API:

1) Download the PayPal API from the PayPal SDK website
2) Copy the file PayPal.php and the folder PayPal into your existing PEAR installation.

This again assume that you have a working PEAR installation, and that your include_path correctly includes your PEAR library.
Posted Nov 20, 2008 by Aidan Lister
 

Question

18 Accessing the SetExpressCheckoutRequestDetails object

For a customised experience, access to the SetExpressCheckoutRequestDetails object is required. For example, setOrderDescription, and setNoShipping ...

At the moment, the way the component is written, it's not possible to access this object. Can the author think of a way to allow customisation without hardcoding it in the component?
Posted Nov 20, 2008 by Aidan Lister
 

Comment

19 Paypal

Paypal has been a great help for those subscribers to easily pay their bills. But here comes the new Revolution Money. It is not an IPO on funding popular uprising against government. Revolution Money is a new method of credit card style transactions. Think of Revolution Money as a credit card with a PIN number. You can use it for store purchases, payday loans, whatever you wish. It's being bankrolled right now by major corporations, as it will eliminate merchant fees on credit purchases. It is also being hailed as the biggest, and amongst the first, competitors with PayPal. The Revolution Card will be available soon, and it is expected to make an immediate impact. It could be worth looking into payday loans to get in on Revolution Money.
Posted Apr 14, 2009 by ArthurD
 

Question

20 How to solve Cannot modify header information Error ?

Cannot modify header information - headers already sent by (output started at D:\xampp\htdocs\web\gemshub\app\controllers\home_controller.php:100) [APP\controllers\components\paypal.php, line 731]

it will occur when on line number 731 in paypal.php

header('Location: ' . $payPalUrl);
Posted Apr 22, 2009 by Harsh Gupta
 

Question

21 Requires more Detailed Installation

Hello,

Thanks for this tutorial. I have tried to follow it through along with help from existing comments but there seem to be header modify error that is very annoying.

This is what I have done.

I have saved the PaypalComponent php script as paypal.php in components/.
I have created a folder inside vendor called "PEAR", inside I have extracted the base lib folder from pear base package as well as the Paypal SDK.
I have also created a Pear.inc.php file inside vendor that Includes the PEAR directory.
In my payment controller, I have added App::import('Vendor', 'PearVendor', array('file' => 'pear.inc.php')); on the top.
And var $components = array('othAuth', 'Paypal');

Now, when I try to access any actions inside this controller, it gives me the following error:

Warning (2): Cannot modify header information - headers already sent by (output started at F:\production\Workspace\paymenttest\dev\app\controllers\components\paypal.php:984) [CORE\cake\libs\controller\controller.php, line 640]
Code | Context

$status = "Location: http://localhost/users/login?from=users/express"

header - [internal], line ??
Controller::header() - CORE\cake\libs\controller\controller.php, line 640
Controller::redirect() - CORE\cake\libs\controller\controller.php, line 621
othAuthComponent::redirect() - APP\controllers\components\oth_auth.php, line 818
othAuthComponent::check() - APP\controllers\components\oth_auth.php, line 936
AppController::beforeFilter() - APP\app_controller.php, line 26
Dispatcher::_invoke() - CORE\cake\dispatcher.php, line 209
Dispatcher::dispatch() - CORE\cake\dispatcher.php, line 194
[main] - APP\webroot\index.php, line 88

---------

Any help is appreciated.
Posted May 29, 2009 by FANDI
 

Comment

22 Paypal outdated endpoints

I have successfully tested my app in the sandbox environment.
When moved to LIVE, I was getting success response messages with the transaction IDs. However, no money being charged to the CC and no money going to the Paypal's account.

After spending about an hour with the Paypal technician on the phone, we learned that the endpoint URLs are incorrect in the PEAR package !.

To correct that, you need to update these files :
(suppose you installed the PEAT into vendors (not in the app dir, but in the root of your cake installation)

vendors/PEAR/Paypal/lib/Paypal/wsdl/paypal-endpoints.php
vendors/PEAR/Paypal/lib/Paypal/wsdl/paypal-endpoints.xml

Note ; I do not know which file is used , so I update both of them

This is the new values for the LIVE environment :
'PayPalAPI' => 'https://api-3t.paypal.com',
'PayPalAPIAA' => 'https://api-3t.paypal.com',
'PayPalAPI-threetoken' => 'https://api-3t.paypal.com',
'PayPalAPIAA-threetoken' => 'https://api-3t.paypal.com',


Change the URL in the XML file to https://api-3t.paypal.com as well.

Everything should be fine and you should get the money into your account.

Note : these files also hold min and max values for the price you charge via Paypal.

Note 2 : I have created complete a complete payments controller with four (4) steps :
1) enter personal info
2) enter billing info
3) review order (with the options to edit)
4) process payment

The payments controller also have admin functionality.

Let me know if anyone were interested in this as a packge.

Good Luck

Martin
Posted Jun 11, 2009 by Martin Halla
 

Comment

23 PayPal Direct Payment API Component for 1.2

After a whole day of searching for an answer and struggling with
trying to make the component work, I finally got it working in Cake
1.2. I'm relatively new to Cake, but have been working with PHP for
over 5 year, so there are a few things that I'm not sure if I used the
best way to do it.

So this are the confusions I got:
1. The PEAR directory I comes like PEAR-1.8.1/PEAR. I wasn't sure of
which of the two directories I should uncompress and where. Also I had
confusions with what directories should be uncompressed from the
PayPal SDK.
For the PEAR directory, you should uncompress the files so you get the
file PEAR.php in vendors/PEAR/ (vendors/PEAR/PEAR.php).
For the SDK, you should uncompress the php-sdk/lib directory at
vendors/PEAR/.
The final directory structure should look like the following: (only
showing the main files, not all of them)
->{CAKE}/app/vendors
->./PEAR
->./HTTP
->./Log
->./Net
->./PayPal
->./PEAR
->PayPal.php
->Multi.php
->Log.php
->PEAR.php
->Multi.php

2. The second confusion I had was how to replace the vendors call to
App::import() for Cake 1.2... Unfortunately this wasn't working for me
at all. So I (and this is the part that I think is not how it's
supposed to be done, but I worked for me) went to the bootstrap file
({cake}/app/config/bootstrap.php) and added the following code to the
bottom of the file:
set_include_path(dirname
(__FILE__).DS.'..'.DS.'vendors'.DS.'PEAR'.PATH_SEPARATOR.get_include_path
());
This sets the PEAR directory in the vendors file as part of the
include path, so all the require calls from {cake}/app/controllers/
components/paypal.php work fine.

3. I'm a bit ashamed of this one, but I forgot for a moment that they
were talking about a component for I was a bit confused of were to put
the paypal component content. It was a stupid confusion, but if
anybody has a doubt, you have to put the component in {cake}/app/
controllers/components/paypal.php.

Those were the main confusions that were bugging me during the whole
day.

To make the component work, follow this steps:
1. Download PEAR and place it how it's explained in my confusions #1
(above)
2. Download the PayPal PHP SDK (https://cms.paypal.com/us/cgi-bin/? cmd=_render-content&content_ID=developer/library_download_sdks) and
uncompress it how I explained in my confusions #1 (above) -> 3. Create the file {cake}/app/controllers/components/paypal.php and
write the components content (http://bakery.cakephp.org/leafs/view/22)
in this file.
4. Don't forget to add 'Paypal' to your controller's components: var
$components = array('Paypal');
5. Change the credentials (username,password and signature/
certificate) to your paypal's account
Note: In the example code, a certificate is being used instead of a
signature. Paypal let you use one or the other, if you use signature,
change the method call from $this->Paypal->setCertificate() to $this-
>Paypal->setSignature().
6. You should be able to use now the example code at
http://bakery.cakephp.org/leafs/view/20
I hope this was helpful for somebody. If you have any questions you
can send me an email and I'll try to help you!
Posted Jun 20, 2009 by Jorge Pedret
 

Comment

24 problem with live server

hi all

i did the installation like posted by Jorge Pedret. it works fine on my local server (win xp, xampp). but i get an error on my live server:
Fatal error: require_once() [http://php.net/function.require]: Failed opening required 'PEAR.php'
does anybody have any idea why?
Posted Jul 4, 2009 by Aleksej Denisenko
 

Question

25 a bit cofused about the paypal component

Firstly thanks for the article and all the work that went into it..

I am confused about the php component, I have this example component called components/paypal.php with the class PaypalComponent extends Object, also it seems that the userful component for direct paypal payment an example given as....

Useful component that provides a wrapper for PayPal's Direct Payment API, ...
Doing a Direct Payment

$order = array(
'action' => CAKE_COMPONENT_PAYPAL_ORDER_TYPE_SALE,
'description' => 'CakePHP Component',
'total' => 100.00,
'buyer' => array (
'first' => 'Mariano',
'last' => 'Iglesias',....

My question is where does this code go???

$order = array(
'action' => CAKE_COMPONENT_PAYPAL_ORDER_TYPE_SALE,
'description' => 'CakePHP Component',
'total' => 100.00,
'buyer' => array (
'first' => 'Mariano',
'last' => 'Iglesias',....

In the component/paypal.php component?
Posted Sep 30, 2009 by gabriel Kolbe
 

Question

26 Live problems

Thanks for this component it has worked great!

I was wondering if anybody has ran into this problem when going from the sandbox with zero problems to live.

When I go to place the order i get this error message:

Safari can't find the server "www.live.paypal.com".

I've tried the endpoints that Martin posted earlier and still didn't work.

All I did was change setEnvironment to this from the sandbox:

$this->Paypal->setEnvironment(CAKE_COMPONENT_PAYPAL_ENVIRONMENT_LIVE);

Any help or suggestions would be greatly appreciated.
Posted Nov 6, 2009 by Matthew Dicembrino
 

Comment

27 www.live.paypal.com

You need to eliminate the "live." part from the URL. I did this in a hackish manner, but in components/paypal.php I added the following line:
$payPalUrl = str_replace('live.', '', $payPalUrl);

underneath the line:
$payPalUrl = str_replace('{$environment}', $this->settings['api.environment'], $payPalUrl);

Thanks for this component it has worked great!

I was wondering if anybody has ran into this problem when going from the sandbox with zero problems to live.

When I go to place the order i get this error message:

Safari can't find the server "www.live.paypal.com".

I've tried the endpoints that Martin posted earlier and still didn't work.

All I did was change setEnvironment to this from the sandbox:

$this->Paypal->setEnvironment(CAKE_COMPONENT_PAYPAL_ENVIRONMENT_LIVE);

Any help or suggestions would be greatly appreciated.
Posted Dec 28, 2009 by Munksey
 

Comment

28 Internet Explorer 8.0

I was able to correct my previous problem but now have found another bug. Everything works find with Firefox, Safari, and IE 7, but in IE 8 the session gets lost and doesn't restore. This makes it so the cart is completely lost and when they pay through paypal I have no idea what they bought.

Somebody please let me know if its just a bug in my code or if it is with the component.
Posted Jan 31, 2010 by Matthew Dicembrino
 

Question

29 error on Profile::Profile()

Hi all

I'm fairly new to PEAR, though, have some experience with Cake ...

I'm following all the steps and think i manage to get the whole setup up and running ... I used

set_include_path(dirname(__FILE__).DS.'..'.DS.'vendors'.DS.'PEAR'.PATH_SEPARATOR.get_include_path());

to add PEAR include PATH ...

I keep getting these error messages:

----------------------------------------------
Missing argument 2 for Profile::Profile(), called in E:\workspaces\cake_1.2.5\cake\libs\class_registry.php on line 140 and defined [APP\vendors\PEAR\PayPal\Profile.php, line 59]
Undefined property: Profile::$table [CORE\cake\libs\model\model.php, line 646]
Warning (2): Cannot modify header information - headers already sent by (output started at E:\workspaces\cake_1.2.5\app\controllers\components\paypal.php:976) [CORE\cake\libs\controller\controller.php, line 644] ----------------------------------------------

I thought at first it might have to do with the Profile model i'm using in my app users section, but that sounds unlikely ..

ANyone has a clue what i might be doing wrong .. ?

Thanks all ....


////////////////////////////////

An update on this, for who might be having the same problem: setting debug to Configure::write('debug',0); seems to have fixed it, though am not sure yet cuz i still have to test the whole thing ...

cheers

ps Thanks for this copmponent by the way :-) ...
Posted Feb 16, 2010 by daniele longo