PPExt - PayPal extension




	$buttonManager = Yii::app()->getModule('payPal')->buttonManager; 

	$nvp = array(

		'BUTTONTYPE'=>'BUYNOW',

	); 

	$buttonManager->createButton("Test Button", $nvp);



I tried to run this code, but it encountered a problem and couldn’t create the button. And it logged this:


Failed create button

Request: BUTTONTYPE=BUYNOW&METHOD=BMCreateButton

in

C:\xampp\htdocs\dtweb\protected\modules\payPal\components\PPButtonManager.php

(241)

in

C:\xampp\htdocs\dtweb\protected\modules\payPal\components\PPButtonManager.php

(60)

in C:\xampp\htdocs\dtweb\themes\shadow_dancer\views\site\index.php (21)

After some debugging and google search, I realized that the problem is in the cURL. The PayPal url header is HTTPS and my CURL’s HTTPS certificate was outdated. Thus, I downloaded this file:

http:// curl . haxx . se / ca / cacert.pem (remove the spaces, the forum does not let me add links in my posts since it is one of my first posts)

and saved it under the protected/modules/paypal/components. Then I modified the httpGet function in PPUtils.php like this:




	public static function httpGet($url, $getVars ="", $parsed=true) {

		// Send request

		$ch = curl_init();

		curl_setopt($ch, CURLOPT_URL, "$url?$getVars");

		curl_setopt($ch, CURLOPT_VERBOSE, true);

		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

		curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__)."\cacert.pem"); // added this line

		$httpResponse = curl_exec($ch);

		$result = null;


		// Return error if the request failed

		if(!$httpResponse) {

			$result = array("status" => false, "error_msg" => curl_error($ch), "error_no" => curl_errno($ch));

		}

		...



Then it worked.

Edit:

(Another method)

You can also add these two lines to PPUtils.php instead of doing everything I wrote above:




curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);



Dear All,

this is my first post, but I have well read all that I found.

I really appreciate this module. I have integrated it successfully in my current (and first with yii) project.

I use ‘class’=>‘payPal.components.PPDbButtonManager’, so my buttons are also stored locally in my db.

Buttons are created successfully and a basic transition with paypal sandbox is successfully completed, with PDT and IPN…

But I don’t understand some things.

My situation is that I will create (or retrieve) the button at the checkout step, so always I have "1 button for 1 sessionID".

If the web user don’t proceed with the payment and he modify the cart, at the next checkout, the button (previously created) must be updated for the price.

[Step1]: the user proceed with the checkout for a cart amount of 200.25, so the button is created and stored in my db

[Step2]: the user go back and add some items in the cart, changing the total amount to 400.50

[Step3]: the user newly proceed with the checkout. At this point the button must be updated in the price.

My log is ok, no error message, but the price is always the old one, as the updateButton have failed.

Are my logic and code wrong?

Any help is welcome! Thanks in advance.


  

        $paypalButtonName = CHtml::encode('Cart' . $mySessionID);

        $buttonManager = Yii::app()->getModule('payPal')->buttonManager;

        $myPaypalButton = $buttonManager->getButton($paypalButtonName);

        if(!$myPaypalButton)

        {     

            $nvp = array(

                'BUTTONTYPE'=>'BUYNOW',

                'L_BUTTONVAR0'=>'currency_code=EUR',

                'L_BUTTONVAR1'=>'item_name=' . CHtml::encode('Cart' . $mySessionID),

                'L_BUTTONVAR2'=>'amount='.(string)(number_format(Yii::app()->shoppingCart->getCost(),2))  

            );

            $myPaypalButton = $buttonManager->createButton($paypalButtonName, $nvp);

        } else {                    

            $myPaypalButton = $buttonManager->updateButton($paypalButtonName, array('L_BUTTONVAR0'=>'amount='.(string)(number_format(Yii::app()->shoppingCart->getCost(),2))));            

        }  

I think that the problem can be in updateButton, where the new price is in

L_BUTTONVAR0 but in the same array the old price is in L_BUTTONVAR5. I suppose that paypal founding both prices, update the button with the second.

[font="Courier New"]

[color="#2E8B57"][Step1] 2012/08/30 09:09:32 [info] [payPal.components.PPButtonManager] Successfully created button[/color]

Request: BUTTONTYPE=BUYNOW&L_BUTTONVAR0=currency_code=EUR&L_BUTTONVAR1=item_name=Cartrb7lpfglf79qd9pe3j5t2rlbc4&L_BUTTONVAR2=amount=200.25&METHOD=BMCreateButton

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (240)

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (72)

in /web/htdocs/www.mydev/home/myproject/protected/controllers/CartController.php (47)

[b][color="#2E8B57"]

[Step3] 2012/08/30 09:10:51 [info] [payPal.components.PPButtonManager] Successfully fetched button details[/color][/b]

Request: METHOD=BMGetButtonDetails&HOSTEDBUTTONID=BHZA4CZMPVGAY

Response: WEBSITECODE=<form action="…webscr" method="post">

<input type="hidden" name="cmd" value="_s-xclick">

<input type="hidden" name="hosted_button_id" value="BHZA4CZMPVGAY">

<input type="image" src="…" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">

<img alt="" border="0" src="…" width="1" height="1">

</form>

&EMAILLINK=…webscr?cmd=_s-xclick&hosted_button_id=BHZA4CZMPVGAY&HOSTEDBUTTONID=BHZA4CZMPVGAY&BUTTONCODE=HOSTED&BUTTONTYPE=BUYNOW&BUTTONSUBTYPE=PRODUCTS&L_BUTTONVAR0="bn=65SCB4HF3URR2:PP-BuyNowBF_P"&L_BUTTONVAR1="no_note=0"&L_BUTTONVAR2="business=65SCB4HF3URR2"&L_BUTTONVAR3="currency_code=EUR"&L_BUTTONVAR4="item_name=Cartrb7lpfglf79qd9pe3j5t2rlbc4"&L_BUTTONVAR5="amount=200.25"&BUTTONIMAGE=REG&BUYNOWTEXT=BUYNOW&BUTTONCOUNTRY=IT&BUTTONLANGUAGE=en&TIMESTAMP=2012-08-30T07:10:51Z&CORRELATIONID=8acf8b24a1036&ACK=Success&VERSION=63.0&BUILD=3587318

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (240)

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (153)

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (88)

[color="#008000"]2012/08/30 09:10:52 [info] [payPal.components.PPButtonManager] Successfully updated button[/color]

Request: WEBSITECODE=<form action="…webscr" method="post">

<input type="hidden" name="cmd" value="_s-xclick">

<input type="hidden" name="hosted_button_id" value="BHZA4CZMPVGAY">

<input type="image" src="…" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">

<img alt="" border="0" src="…" width="1" height="1">

</form>

&EMAILLINK=…webscr?cmd=_s-xclick&hosted_button_id=BHZA4CZMPVGAY&HOSTEDBUTTONID=BHZA4CZMPVGAY&BUTTONCODE=HOSTED&BUTTONTYPE=BUYNOW&BUTTONSUBTYPE=PRODUCTS&[color="#0000FF"]L_BUTTONVAR0=amount=400.50[/color]&L_BUTTONVAR1="no_note=0"&L_BUTTONVAR2="business=65SCB4HF3URR2"&L_BUTTONVAR3="currency_code=EUR"&L_BUTTONVAR4="item_name=Cartrb7lpfglf79qd9pe3j5t2rlbc4"&[color="#FF0000"]L_BUTTONVAR5="amount=200.25"[/color]&BUTTONIMAGE=REG&BUYNOWTEXT=BUYNOW&BUTTONCOUNTRY=IT&BUTTONLANGUAGE=en&TIMESTAMP=2012-08-30T07:10:51Z&CORRELATIONID=8acf8b24a1036&ACK=Success&VERSION=63.0&BUILD=3587318&METHOD=BMUpdateButton

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (240)

in /web/htdocs/www.mydev/home/myproject/protected/modules/payPal/components/PPButtonManager.php (104)

in /web/htdocs/www.mydev/home/myproject/protected/controllers/CartController.php (53)[/font]

Hello Yii people,

I found this extension and I must say in beginning it was tough to grasp what’s this all about (talk about paypal documentation)

but I managed to do a test payment in just a few hours.

In my project, I want successful processed payments notified by IPN to be recorded into site database. So should I use the IPN listener onSuccess event?

$ipn->onSuccess = function($event) {

};

also I want paypal to pass trough userId, itemId, itemName from my products database, so will this work?




$ipn->onSuccess = function($event) {

$userid = $event->details["custom"];

$itemid = $event->details["item_number"];

$projectname = $event->details["item_name"];


$newDBdata = new ProjectData();

$newDBdata->userid = $userid;

$newDBdata->itemid = $itemid;

$newDBdata->projectname = $projectname;


if($newDBdata->validate())

   $newDBdata->save();

};



is it good practice to modify it in this way?

(note: i’m writing code from top of my head so it may have mistakes)

also, how should I use:




public function getButtonForm($id,$userId) {

    if ( ($button = $this->buttonManager->getButton($id)) !== false)

        return self::addHiddenField('custom',$userId,$button->webSiteCode);

    else return false;



to pass more than one parameter? like this…




public function getButtonForm($id,$userId,$itemname,$itemid) {

...

}



Also, how should I render created button in view page?

can I call something like this?




echo $buttonManager->getButton('name')->webSiteCode;



i have button in database.

when I do this, i get an error that PPDbButtonManager is not defined

Hi,

Anyway to achieve this (https://www.paypal.com/cgi-bin/webscr?cmd=_pdn_howto_checkout_outside#methodtwo) with your extension? I’m managing my own cart and would like to send a group of items at once.

Cheers,

Matt

Have you solved this problem?

I don like using of form to


    <div>

    <form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">

        <input type="hidden" name="cmd" value="_cart">

        <input type="hidden" name="upload" value="1">

        <input type="hidden" name="business" value="my@email.com">

        <input type="hidden" name="custom" value="asgasgasgagahsdgsdghsgag">

        <input type="hidden" name="currency_code" value="EUR">

        <input type="hidden" name="return" value="http://return.link">

        <input type="hidden" name="cancel_return" value="http://cancel.link">

        <ul>

            <li>

                <input name="quantity_1" value="1">

                <input type="hidden" name="item_name_1" value="Product 1">

                <input type="hidden" name="amount_1" value="25.01">

                <input type="hidden" name="discount_amount_1" value="5.00">

            </li>

            <li>

                <input name="quantity_2" value="1">

                <input type="hidden" name="item_name_2" value="Product 2">

                <input type="hidden" name="amount_2" value="12.71">

                <input type="hidden" name="discount_amount_2" value="5.00">

            </li>

        </ul>

        <input type="submit" value="Checkout">

    </form>

</div>

Cause data like account email, custom variable, prices and discounts are note safe

Is it possible to send cart data to paypal via api, not using form with hidden fields?

Hi.

I ran into the same problem, and managed to find a workaround.

The problem is that paypal rearranges the configuration parameters of the button, when you do the update.

In your case, I guess, you pass the new price something like:

L_BUTTONVARx="amount=99.00"

where x is the same x you used at creation time.

But it is likely that Paypal will have changed the value of x, so your new value will be taken as a distinct parameter, which will override or will be overriden depending on the order of the parameters of the same type.

To make an example, I used to set

L_BUTTONVAR5="amount=99.00"

but the button had another parameter like this:

L_BUTTONVAR10="amount=59.00"

so that the old value (with x=10) was used, and the new one ignored.

I solved the problem by just inserting the following piece of code in the updateButton of the Button manager:


  

   public function updateButton($name, $nvp = array()) {

      if (empty($name) || !$this->getButton($name))

         return false;

      $btNvp = $this->getButtonDetails($name);

      $btNvp['METHOD'] = 'BMUpdateButton';


      /* Added code - start */

      foreach ($btNvp as $k => $v) {

         if(substr($k, 0, 11) == 'L_BUTTONVAR') {

            unset($btNvp[$k]);

         }

      } 

      /* Added code - end */

.....



What it does is it unsets all the variables of type L_BUTTONVARx and resets them all, avoiding the problem.

Be sure not to forget to pass all of them to the updateButton function.

Hi Stainlik,

I have a problem, I wish it’s not too late to ask. I followed the instruction and used your example file to create product with session. But from the very beginning I cannot create a button in actionAdmin. I check the log file I’m getting the following error.




2013/01/22 13:32:42 [error] [payPal.components.PPButtonManager] Failed create button

Request: BUTTONTYPE=BUYNOW&L_BUTTONVAR0=currency_code=USD&L_BUTTONVAR1=item_name=Product name&L_BUTTONVAR2=amount=20.00&METHOD=BMCreateButton

in C:\wamp\www\kaghazkahi\protected\modules\payPal\components\PPButtonManager.php (240)

in C:\wamp\www\kaghazkahi\protected\modules\payPal\components\PPButtonManager.php (60)

in C:\wamp\www\kaghazkahi\protected\controllers\StoreController.php (108)



line 60 is where it calls phputils. I’m running wamp on Windows and php version is 5.4. Thank you.

Hello guys,

I am creating PayPal pays for first time.

Right now I want to do it according this article PayPal Integration And IPN (Instant Payment Notification) (I cant add link so I must change in whole post - you will see :) )

What I want?

I am offering 3 types of Premium package on my site. User can choose one and pay it through PayPal. When it is payed I will change some informations in specific user.

So I need PayPal where custom field will be Order ID (from Order I know which User did the Order). After click on "Pay by PayPal" it will be redirected to PayPal page where will be price… After that I need to receive information if Order was payed or not - so I need IPN.

My questions to that article.


// Define LIVE constant as true if 'localhost' is not present in the host name. Configure the detecting of environment as necessary of course.

defined('LIVE') || define('LIVE', strpos($_SERVER['HTTP_HOST'],'localhost')===false ? true : false);

if (LIVE) {

  define('PAYPAL_SANDBOX',false);

  define('PAYPAL_HOST', '//link');

  define('PAYPAL_URL', '//link webscr');

  define('PAYPAL_EMAIL',''); // live email of merchant

}else{

  define('PAYPAL_HOST', '//sandbox link');

  define('PAYPAL_URL', '//sanbox link webscr');

  define('PAYPAL_EMAIL', ''); // dev email of merchant

  define('PAYPAL_SANDBOX',true);

}

my config/main.php


return array {

//here is all settings

}

so that code should be out of array or where? How it should look?

And second question to this block is: dev email of merchant is my email which I used to register on PayPal or email of Test Acount?

From view file I confused with this block




$.post(Yii::app()->getRequest()->getBaseUrl().'order/create'; ?>',$('#orderForm').serializeArray(),function(orderResp) {

            if(orderResp.error === undefined){

                var action;

                $('#paypalOrderId').val(orderResp.id);

                $('#orderForm').attr({action:'<?php echo PAYPAL_URL?>',onsubmit:true}).submit();

            }else{

                alert(orderResp.error);

            }

        },'json');



why is there ?>? Where it started? And how should looks Create action in OrderController? I have never created new record like this.

So the result of my post is that I need step by step what I should do when I want to create PayPal pays. Maybe after I will do it I can make article step by step with all steps (also configuration in PayPal)

Is there possibility to create this with PPExt? Or PPExt is just for Buttons?

Thank you for all answers

i include following code but button not appear

&lt;?php

$buttonManager = Yii::app()->getModule(‘payPal’)->buttonManager;

$nvp = array(

'BUTTONTYPE' =&gt; 'BUYNOW',


'L_BUTTONVAR0' =&gt; 'currency_code=USD',


'L_BUTTONVAR1' =&gt; 'item_name=My button',


'L_BUTTONVAR2' =&gt; 'amount=200.00',);

$buttonManager->createButton(‘My button’, $nvp);

?>

Hi, Thanks for this great extension, I’m using it on my second project!

I’ve come accross a bug when using the listner to receive an “Adaptive Payment PAY” IPN notification. Now maybe it’s not strictly within scope of this project as the the listener wasn’t designed to accept these kinds of notifications, but this fix allowed me to use the IPN Listener for PayPal Adaptive Payments too.

The problem is that when the extension validates the IPN request with PayPal by sending back a copy of the post, it rebuilds the $_POST array into a query string, but the method used breaks if the IPN request has an array in it (as is the case with an Adaptive Payment).

Here is the change I made to controllers/ipn/PPIpnAction.php starting line 95

Before




		/** Send IPN Request (HTTP POST) to PayPal **/

		// 2010-10-28: TESTED OK

		$event->requestAr = array_merge(array("cmd"=>"_notify-validate"), $_POST);

		$postVars = PPUtils::implode('&',PPUtils::urlencode($event->requestAr));

		$response = PPUtils::httpPost(PPUtils::getUrl(PPUtils::IPN), $postVars, false);



After




		/** Send IPN Request (HTTP POST) to PayPal **/

		// 2010-10-28: TESTED OK

		$event->requestAr = array_merge(array("cmd"=>"_notify-validate"), $_POST);

		$postVars = file_get_contents('php://input');

		$postVars = "cmd=_notify-validate&".$postVars;

		$response = PPUtils::httpPost(PPUtils::getUrl(PPUtils::IPN), $postVars, false);



Hello wonderful yii community, I’m trying to get the button to show but its not.

here is my main.php under config


'payPal'=>array(

				'env'=>'sandbox',

				'account'=>array(

						'username'=>'mainakelvin43_api1.gmail.com',

						'password'=>'DUAMUSPMSR5YG65Y',

						'signature'=>'ADc7.nBEFERB6ovgp64HlCZbUfw4AZ0ywbxCR9F4ulrLU4jFkQeqG.Cc',

						'email'=>'kelvinmaina43@gmail.com',

						'identityToken'=>'5ZA7AU93JW2DG',

				),

				'components'=>array(

						'buttonManager'=>array(

								//'class'=>'payPal.components.PPDbButtonManager'

								'class'=>'payPal.components.PPPhpButtonManager',

						),

				),

		),

the view.php where i need it to show and its not


<?php

/* @var $this OrdersController */

/* @var $model Orders */


$this->breadcrumbs=array(

	'Orders'=>array('index'),

	'Create',

);


$this->menu=array(

	array('label'=>'List Orders', 'url'=>array('index')),

	array('label'=>'Manage Orders', 'url'=>array('admin')),

);




echo Yii::getPathOfAlias('webroot'). "/uploads/orders/";

?>


<h1>Create An Order</h1>


<?php $this->renderPartial('_form', array('model'=>$model)); 




$buttonManager = Yii::app()->getModule('payPal')->buttonManager;

$buttonManager->createButton("My button", array('BUTTONTYPE'=>'BUYNOW'));


    //echo($buttonManager->webSiteCode);


?>

any help is appreciated.

thanks