Posts

Zend Framework Paypal Website Payments Standard Form

Website Payments Standard uses a HTML form to send a payment proposal to paypal. This tehnique is a reliable implementation of IPN, which notifies your web site when the payment has been processed. The class below requires Zend Framework and uses ZendForm to generate the form. If you' re using the debug sandbox mode,the form generates text fields, otherwise it generates hidden fields. More info about Paypal Website Payment Standard Form.

Usage

  • in your controller : create the paymentAction, and also paymentNotifyAction (for IPN notifications), and the payementReturn action (for return and confirmation on your website). The code below uses user object with email and id attributes
public function paypal()
 {
$paypal=new Wb_Paypal_Standard(true);
$paypal->setBusinessEmail("business@owner.com");
 $paypal->setPayer($user->email, $user->id);
 $paypal->setAmount("50");
$paypal->setControllerUrl("http://" . $this->getRequest()->getHttpHost() . $this->view->url()    );
return $paypal;
}
public function paymentAction()
  {
$this->view->paypalForm=  $this->paypal()->form();
  }
public function paymentnotifyAction()
{
      $this->_helper->viewRenderer->setNoRender(); 
    $this->_helper->layout->disableLayout();

    try{
    if ($this->paypal()->validateNotify($this->getRequest()->getPost()))
    {

          $dbUserPayment=new Model_DbTable_Users_Payments()   ;
        $dbUserPayment->insert( array("ifv_user_id"=>$arrPost["payer_id"],"txn_id"=>$arrPost["txn_id"], "credits"=>$arrPost["custom"]));
      }
    }
    catch (Exception $e){PoleOuest_Log::error($e->getMessage());}

}
public function paymentreturnAction()
{
}
  • views : payment.phtml
    <?= $this->paypalForm ?>

Class : Wb_Paypal_Standard.php

<?php
class WB_Paypal_Standard
{
{
var $paypalUrlLive="https://www.paypal.com/cgi-bin/webscr";
var $paypalUrlTest="https://www.sandbox.paypal.com/cgi-bin/webscr";
var $currencyCode="EUR";
var $cmd="_xclick";
var $sandbox=false;

var $paypalData=array();
public function __construct($sandbox=false)
{
 $this->sandbox=$sandbox;
 if ($this->sandbox)
 $this->paypalData['url']= $this->paypalUrlTest;
 else    $this->paypalData['url']= $this->paypalUrlLive;
 }

public function form()
{
 if (!isset($this->paypalData['businessEmail'])) throw new Exception('Please specify paypal business account email ');
 if (!isset($this->paypalData['notifyUrl'])) throw new Exception('Please specify return url for ipn ');  
 if (!isset( $this->paypalData['payer_email'])) throw new Exception('Please specify payer email ');       
 if (!isset($this->paypalData['amount'])) throw new Exception('Please specify amount ');   
 $this->frm=new Zend_Form();
 $this->frm->setAttrib("id","frmPaypal");
 $this->frm->setAction($this->paypalData['url']) ;

 $this->addFormField("cmd", $this->cmd);
 $this->addFormField("business", $this->paypalData['businessEmail']);
 $this->addFormField("receiver",  $this->paypalData['businessEmail']);
 $this->addFormField("charset", "utf-8")  ;
 $this->addFormField("notify_url", $this->paypalData['notifyUrl']);     
 $this->addFormField("return", $this->paypalData['returnUrl']);
 $this->addFormField("payer_email", $this->paypalData['payer_email']);
 $this->addFormField("payer_id",$this->paypalData['payer_id']);   
 $this->addFormField("amount", $this->paypalData['amount']);  
 $this->addFormField("custom",$this->paypalData['custom']);
 $this->addFormField("currency_code", $this->currencyCode);
 foreach($this->arrItem as $k=>$v)        
 {
 $i="_" .($k+1);
 if ($this->cmd=="_xclick") $i="";
 $this->addFormField("item_name" . $i, $v['item_name']);
 if ($i!==""){ $this->addFormField("item_amount" . $i, $v['amount']);
 $this->addFormField("quantity" . $i, $v['quantity']);         }
 }
 $elt = $this->frm->createElement('submit','submitButton');
 $elt->setLabel('PAY');      $this->frm->addElement($elt);     
 return $this->frm;
}
public function addItem($arrItem)
{
 $this->arrItem[]=$arrItem;
}
public function addFormField($name, $value="")
{
 if ($this->sandbox) $fieldType="text"; else $field_type="hidden";  
 $elt=$this->frm->createElement($fieldType,$name)->setValue($value);
 if ($this->sandbox) $elt->setLabel($elt->getName());
 $this->frm->addElement($elt);   
}
public function validateNotify($arrPost)
{
 $client = new Zend_Http_Client($this->paypalData['url']);
 $client->setMethod(Zend_Http_Client::POST);
 $client->setParameterPost(array_merge(array('cmd' => '_notify-validate'),$arrPost));
 $response = $client->request();

 if ($response->getBody() != 'VERIFIED') throw new Exception('Invalid IPN Transaction : ' . $response->getBody());   
 elseif($arrPost["mc_gross"]=="") throw new Exception('Invalid IPN mcgross :  not set');   
 elseif($arrPost["payment_status"]!="Completed") throw new Exception('Invalid IPN payment_status : ' .  $arrPost["payment_status"]);   
 elseif($arrPost["txn_id"]=="") throw new Exception('Invalid IPN txn_id : not set ');   
 else return true;
}
public function setBusinessEmail($businessEmail){     $this->paypalData['businessEmail']=$businessEmail;}
public function setAmount($amount){      $this->paypalData['amount']=$amount;}
public function setCustom($custom){      $this->paypalData['custom']=$custom;}
public function setControllerUrl($controllerUrl)
{      
 $this->paypalData["notifyUrl"]=$controllerUrl . "notify";
 $this->paypalData['returnUrl']=$controllerUrl . "return";
}
public function setPayer($payer_email, $payer_id)
{
 $this->paypalData["payer_email"]=$payer_email;  
 $this->paypalData["payer_id"]=$payer_id;
}
}?>
public function paymentnotifyAction()
{
$this->prepareAjaxResponse();

try{
if ($this->paypal()->validateNotify($this->getRequest()->getPost()))
{

$dbUserPayment=new Model_DbTable_Users_Payments()   ;
$dbUserPayment->insert( array("ifv_user_id"=>$arrPost["payer_id"],"txn_id"=>$arrPost["txn_id"], "credits"=>$arrPost["custom"]));
}
}
catch (Exception $e){PoleOuest_Log::error($e->getMessage());}

}