Yii Framework Forum: PPExt - PayPal extension - Yii Framework Forum

Jump to content

  • (6 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

PPExt - PayPal extension I'm developing a PayPal extension Rate Topic: ****- 1 Votes

#1 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 26 October 2010 - 05:29 PM

Hello

Latest version can be downloaded from:
http://www.yiiframew...xtension/ppext/

EDIT: The first version (ppext.tar.gz / ppext.zip in this post) has faulty IPN-code,
please download from the url above.

I am developing an event based PayPal extension for Yii, and would like to know it there is any interest in this? Feedback and feature requests are very welcome.

Features so far:
- Button manager (you specify settings using an array of NVP-values)
- PDT handler
- IPN handler
- Logging via Yii::log()

EXAMPLE USAGE

PDT- and IPN listeners (see src-code for a better example, including some payment processing)
class MinimalController extends Controller
{
	public function actionPdt() {
		$pdt = new PPPdtAction($this, "pdt");

                // Process payment
		$pdt->onRequest = function($event) {
			$this->onSuccess($event);
		};

                // Notify user on success
		$pdt->onSuccess = function($event) {
			$event->sender->controller->renderText("Success");
		};

                // Notify user on failure
		$pdt->onFailure = function($event) {
			$event->sender->controller->renderText("Failure");
		};

		$pdt->run();
	}

	public function actionIpn() {
		$ipn = new PPIpnAction($this,"ipn");

                // Process payment
		$ipn->onRequest = function($event) {
			$event->setMsg("Received payment.");
			$ipn->onSuccess($event);
		};

                // Log success
		$ipn->onSuccess = function($event) {
			Yii::log($event->msg, "info", "payPal.controllers.DefaultController");
		};

                // Log failure
		$ipn->onFailure = function($event) {
			Yii::log($event->msg, "error", "payPal.controller.DefaultController");
		};

		$ipn->run();
	}
}


Button Manager - Creating a buy now button
$this->bm = Yii::app()->getModule('payPal')->buttonManager;
$this->bm->createButton($name, array('BUTTONTYPE'=>'BUYNOW'));


Installation instructions:

1. Extract the file into WebRoot/modules/payPal
2. Open WebRoot/modules/payPal/PayPalModule.php for further instructions

Attached File(s)


1

#2 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 26 October 2010 - 08:48 PM

Discovered a bug in the previous attachment, this should work better.

Attached File(s)


0

#3 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 27 October 2010 - 08:35 PM

I have done some refactoring and cleaned up the IPN and PDT functionality.
- All IPN and PDT events are logged (success and failure)
- Moved ipnRequest and pdtRequest from PPUtils into IPN- and PDT actions
- Details about events (payments usually) is now stored in PPEvent::details

The new event class:
class PPEvent extends CEvent {
	public $responseAr = array();	// HTTP Response from PayPal
	public $requestAr = array();	// HTTP Request sent to PayPal
	public $details = array();	// Verified payment details (assoc array)
	public $msg = "";		// Description of event
}


Version 0.2 will be uploaded as soon as I have finished a couple of additional improvements, and testing.
0

#4 User is offline   spamec 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 19-February 09

Posted 28 October 2010 - 05:42 AM

This looks really neat... thanks for sharing and inspiring piece of code :)
0

#5 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 28 October 2010 - 04:02 PM

Thanks for the positive reply :)

Version 0.2 is ready:
- PPIpnAction and PPPdtAction cleaned up and tested
- DefaultController (IPN and PDT example) cleaned up and tested
- Updated documentation

Todo:
- PPDbButtonManager - Database implementation of the button manager
- Helper methods for common buttons
- Standard payment processing methods (validating payment status, saving transactions in DB, ..)?

Attached File(s)


0

#6 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,450
  • Joined: 04-October 10

Posted 28 October 2010 - 04:35 PM

Thank you very much for sharing. I keep my self 'connected' to this post to see how it evolves.
¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#7 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 28 October 2010 - 05:00 PM

Uploaded module into:
http://www.yiiframew...xtension/ppext/
0

#8 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,450
  • Joined: 04-October 10

Posted 29 October 2010 - 02:27 AM

Thank you stianlik
¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
0

#9 User is offline   jamesmoey 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 26
  • Joined: 17-July 09

Posted 01 November 2010 - 07:12 PM

Bug in components/PPUtils.php

Index: application/modules/payPal/components/PPUtils.php
===================================================================
--- application/modules/payPal/components/PPUtils.php	(revision )
+++ application/modules/payPal/components/PPUtils.php	(revision )
@@ -205,7 +205,7 @@
 
 		// Sent HTTP GET request
 		$getStr = self::urlencode($getVars);
-		$getStr = self::implode("&",$getStr);
+		$getStr .= self::implode("&",$getStr);
 		$response = PPUtils::httpGet(self::getUrl(self::NVP), $getStr, true);
 
 		// Return false on HTTP error

0

#10 User is offline   jamesmoey 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 26
  • Joined: 17-July 09

Posted 01 November 2010 - 07:16 PM

Please ignore my last post. My mistake.
0

#11 User is offline   jamesmoey 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 26
  • Joined: 17-July 09

Posted 02 November 2010 - 01:49 AM

The run method in PPIpnAction class check that txn_id exist otherwise it is consider the notification as failure without even doing the validation with Paypal.

  • I think it should validation the notification with Paypal no matter what. And log any invalidate notification as hack attempt.
  • Also there are notification that does not contain txn_id. For example subscr_cancel or the subscription update. Maybe we should check both subscr_id and txn_id before marking the notification as failure.

0

#12 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 02 November 2010 - 03:35 AM

View Postjamesmoey, on 02 November 2010 - 01:49 AM, said:

  • I think it should validation the notification with Paypal no matter what. And log any invalidate notification as hack attempt.
  • Also there are notification that does not contain txn_id. For example subscr_cancel or the subscription update. Maybe we should check both subscr_id and txn_id before marking the notification as failure.



I think it's sensible to remove the txn_id check. Then all requests will be validated (failures are also logged) and txn_id / subscr_id can be checked by a simple isset() in onRequest.

EDIT: I have made the changes, check out version 0.4.
0

#13 User is offline   jamesmoey 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 26
  • Joined: 17-July 09

Posted 02 November 2010 - 05:52 PM

Excellent work by the way. A big time saver for me.

Consider putting this on github?
0

#14 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 03 November 2010 - 04:01 AM

Thank you. I will consider github (or probably launchpad since I'm using bzr at the moment) and post a link if I decide to upload.
0

#15 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 16 December 2010 - 10:09 PM

Moved from how to use ppext.

Quote

I have download ppext. But can't understand how to use this extension. Maybe there are any examples?


I'm working on a simple ecommerce example, it will be posted on the extension page after completion.

Quote

I read it but can't understand yet. How to use buttonManager for example?


I have attached an example to illustrate how you:
- Create buy now buttons
- Remove buttons
- Display buttons
Everything is included in a controller to make it simple.

Attached File  PPStoreExampleController.php (4.96K)
Number of downloads: 244

Example: Creating a buy now button using the button manager
    $buttonManager = Yii::app()->getModule('payPal')->buttonManager;
    $nvp = array(
        'BUTTONTYPE'=>'BUYNOW',
        'L_BUTTONVAR0'=>'currency_code=USD',
        'L_BUTTONVAR1'=>'item_name=My button',
        'L_BUTTONVAR2'=>'amount=200.00',
    );
    $buttonManager->createButton('My button', $nvp);


For payment processing, you should look at PPDefaultController and PPPhpTransaction.
0

#16 User is offline   Konstantin Molchanov 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 16
  • Joined: 04-December 09

Posted 18 December 2010 - 03:03 AM

My steps:
1. Move module to /protected/modules/payPal
2. Create account on paypal with e-mail kostya.molchanov@gmail.com
3. In sandbox create 2 test-accounts - seller_1292519600_biz@gmail.com and buyer_1292577660_per@gmail.com
4. In config.php
'modules'=>array(
		'user',
		'rights',
		'payPal'=>array(
			'env'=>'sandbox',
			'account'=>array(
					'username'=>'seller_1292519600_biz@gmail.com',
					'password'=>'sellerseller',
					'signature'=>'Your PayPal API signature',
					'email'=>'seller_1292519600_biz@gmail.com',
					'identityToken'=>'Your PayPal identity token',
				),
			'components'=>array(
				'buttonManager'=>array(
//					'class'=>'payPal.components.PPDbButtonManager',
					'class'=>'payPal.components.PPPhpButtonManager',
				),
			),
		),
	),

5. In view.php file
		<?php
			$buttonManager = Yii::app()->getModule('payPal')->buttonManager;
			$nvp = array(
				'BUTTONTYPE'=>'BUYNOW',
				'L_BUTTONVAR0'=>'currency_code=USD',
				'L_BUTTONVAR1'=>'item_name=My button',
				'L_BUTTONVAR2'=>'amount=200.00',
			);
			$buttonManager->createButton('My button', $nvp);
		?>

6. Log
2010/12/18 13:47:30 [error] [payPal.helpers.PPUtils] NVP request failed
Request:BUTTONTYPE=BUYNOW&L_BUTTONVAR0=currency_code%3DUSD&L_BUTTONVAR1=item_name%3DMy+button&L_BUTTONVAR2=amount%3D200.00&METHOD=BMCreateButton&VERSION=63.0&USER=seller_1292519600_biz%40gmail.com&PWD=sellerseller&SIGNATURE=Your+PayPal+API+signature
Response:TIMESTAMP=2010-12-18T07:47:30Z&CORRELATIONID=8059d1cb27f4a&ACK=Failure&VERSION=63.0&BUILD=1603674&L_ERRORCODE0=10002&L_SHORTMESSAGE0=Security error&L_LONGMESSAGE0=Security header is not valid&L_SEVERITYCODE0=Error
in /home/gluck/src/thesloganchefs/protected/modules/payPal/components/PPUtils.php (222)
in /home/gluck/src/thesloganchefs/protected/modules/payPal/components/PPButtonManager.php (59)
in /home/gluck/src/thesloganchefs/protected/views/projects/view.php (21)
2010/12/18 13:47:30 [error] [payPal.components.PPButtonManager] Failed create button
Request: BUTTONTYPE=BUYNOW&L_BUTTONVAR0=currency_code=USD&L_BUTTONVAR1=item_name=My button&L_BUTTONVAR2=amount=200.00&METHOD=BMCreateButton
in /home/gluck/src/thesloganchefs/protected/modules/payPal/components/PPButtonManager.php (240)
in /home/gluck/src/thesloganchefs/protected/modules/payPal/components/PPButtonManager.php (60)
in /home/gluck/src/thesloganchefs/protected/views/projects/view.php (21)


This is my first problem. And where paypal will send payment results?
0

#17 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 18 December 2010 - 04:28 PM

Quote

'signature'=>'Your PayPal API signature',
'identityToken'=>'Your PayPal identity token',

You have to provide those values.
1. Login to paypal using the seller account
2. Find your signature at "My account" > "Profile" > "API Acess" > "View API Signature" (or "Request API Access")
3. Find your identityToken at "My account" > "Profile" and look for "Secure Merchant Account ID"

Quote

And where paypal will send payment results?

You will be notified of payments by IPN (see PPDefaultController). Configure the IPN handler
in your PayPal account at "My account" > "Profile" > "Instant Payment Notification Preferences".

Before processing payments using IPN, you should read and understand this: Introducing IPN
0

#18 User is offline   Konstantin Molchanov 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 16
  • Joined: 04-December 09

Posted 20 December 2010 - 03:21 PM

Thank you very much. I copy PPDefaultLegacyController to protected/controllers/PayController.php Instant Payment Notification Preferences i set http://mydomain.com/pay/ipn/ and everything become good, my site receive payments results. but there is another question, how to send for example user_id to paypal and then receive this user_id to make some actions on my site. I read about "custom" but can't create button with "custom" parametr and don't know how to receive this parametr from paypal.
0

#19 User is offline   stianlik 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 42
  • Joined: 14-October 10
  • Location:Norway

Posted 20 December 2010 - 04:30 PM

Quote

how to send for example user_id to paypal and then receive this user_id to make some actions on my site. I read about "custom" but can't create button with "custom" parametr and don't know how to receive this parametr from paypal.

To create buttons with the "custom" parameter set to $userId, you can include the following code in your controller (use getButtonForm($id,$userId) instead of $buttonManager->getButton($id)->webSiteCode in your actions):

/**
 * Get button form (HTML code) for button $id including
 * custom field with $userId as value.
 * 
 * @param string $id Button id
 * @param string $userId User id
 * @return string HTML Form
 */
public function getButtonForm($id,$userId) {
    if ( ($button = $this->buttonManager->getButton($id)) !== false)
        return self::addHiddenField('custom',$userId,$button->webSiteCode);
    else return false;
}
	
/**
 * Add hidden field to form.
 *
 * @param string $name Field name (e.g. 'custom')
 * @param string $value Field value (e.g. 'My custom value')
 * @param string $form Form (e.g. $button->webSiteCode)
 * @return string Form with hidden an extra hidden field
 */
public static function addHiddenField($name,$value,$form) {
	return preg_replace(
		'/< *\/form *>/i',
		'<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n</form>\n",
		$form
	);
}

When you receive the IPN- and PDT notifications from PayPal, the user id can be found in $event->details['custom'].

I will include a better mechanism for this sort of thing in the next version.
0

#20 User is offline   Konstantin Molchanov 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 16
  • Joined: 04-December 09

Posted 22 December 2010 - 03:31 AM

Everything works perfect. Thanks a lot!
0

Share this topic:


  • (6 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users