PPExt - PayPal extension I'm developing a PayPal extension
#61
Posted 18 August 2011 - 04:14 PM
Trying to get property of non-object (/home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php:103)
I'm using the example controller.
#62
Posted 18 August 2011 - 05:08 PM
tuschkan, on 18 August 2011 - 10:10 AM, said:
Do I need this?
'env'=>'sandbox',
I set all settings like for sandbox but with real account data, env is commented out. But it won't work.
PPExt is in the sandbox by default, to go live replace
'env' => 'sandbox'
with
'env' => ''
tuschkan, on 18 August 2011 - 04:14 PM, said:
Trying to get property of non-object (/home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php:103)
I'm using the example controller.
I need more information to give you a good answer on this. Have you modified PPPhpTransaction.php? Could you post the track stace (from the application log)?
#63
Posted 18 August 2011 - 05:10 PM
2011/08/07 14:49:12 [info] [payPal.controllers.ipn.PPIpnAction] Successfull IPN request Request: cmd=_notify-validate&mc_gross=39.91&protection_eligibility=Eligible&address_status=confirmed&payer_id=T4YK2TRA2MAXY&tax=0.00&address_street=1+Main+St&payment_date=04%3A48%3A29+Aug+07%2C+2011+PDT&payment_status=Completed&charset=windows-1252&address_zip=95131&first_name=Test&mc_fee=1.46&address_country_code=US&address_name=Test+User¬ify_version=3.2&custom=872&payer_status=verified&business=o.test_1312236115_biz%40gmail.com&address_country=United+States&address_city=San+Jose&quantity=1&verify_sign=AfZa-X9xQQDI-EDvbMaXq9gs045VASgw5o3D.KNIoPoLauJRvn.mzNfp&payer_email=o.tura_1312717469_per%40gmail.com&txn_id=9GU259941J0014206&payment_type=instant&btn_id=1829010&last_name=User&address_state=CA&receiver_email=o.test_1312236115_biz%40gmail.com&payment_fee=1.46&shipping_discount=0.00&insurance_amount=0.00&receiver_id=X2AFDH9NN7H6Y&txn_type=web_accept&item_name=My+button&discount=0.00&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&shipping_method=Default&handling_amount=0.00&transaction_subject=872&payment_gross=39.91&shipping=0.00&ipn_track_id=C3zzS7evgtWpzw-zCNLpVA Response: VERIFIED in /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/controllers/ipn/PPIpnAction.php (128) in /home/amirades/amiradesign.com.ua/test/protected/controllers/PayController.php (93) in /home/amirades/amiradesign.com.ua/test/index.php (15) 2011/08/07 14:49:12 [error] [php] Trying to get property of non-object (/home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php:103) Stack trace: #0 /home/amirades/amiradesign.com.ua/test/yii/framework/base/CModel.php(152): CInlineValidator->validate() #1 /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php(129): PPPhpTransaction->validate() #2 /home/amirades/amiradesign.com.ua/test/protected/controllers/PayController.php(129): PPPhpTransaction->save() #3 /home/amirades/amiradesign.com.ua/test/yii/framework/base/CComponent.php(568): PayController->ipnRequest() #4 /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/controllers/ipn/PPIpnAction.php(61): PPIpnAction->raiseEvent() #5 /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/controllers/ipn/PPIpnAction.php(129): PPIpnAction->onRequest() #6 /home/amirades/amiradesign.com.ua/test/protected/controllers/PayController.php(93): PPIpnAction->run() #7 /home/amirades/amiradesign.com.ua/test/yii/framework/web/actions/CInlineAction.php(50): PayController->actionIpn() #8 /home/amirades/amiradesign.com.ua/test/yii/framework/web/CController.php(300): CInlineAction->runWithParams() #9 /home/amirades/amiradesign.com.ua/test/yii/framework/web/CController.php(278): PayController->runAction() #10 /home/amirades/amiradesign.com.ua/test/yii/framework/web/CController.php(257): PayController->runActionWithFilters() #11 /home/amirades/amiradesign.com.ua/test/yii/framework/web/CWebApplication.php(328): PayController->run() #12 /home/amirades/amiradesign.com.ua/test/yii/framework/web/CWebApplication.php(121): CWebApplication->runController() #13 /home/amirades/amiradesign.com.ua/test/yii/framework/base/CApplication.php(155): CWebApplication->processRequest() #14 /home/amirades/amiradesign.com.ua/test/index.php(15): CWebApplication->run() REQUEST_URI=/pay/ipn in /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php (103) in /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php (129) in /home/amirades/amiradesign.com.ua/test/protected/controllers/PayController.php (129) 2011/08/07 14:49:12 [trace] [system.CModule] Loading "errorHandler" application component in /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php (103) in /home/amirades/amiradesign.com.ua/test/protected/modules/payPal/models/PPPhpTransaction.php (129) in /home/amirades/amiradesign.com.ua/test/protected/controllers/PayController.php (129)
#64
Posted 18 August 2011 - 05:47 PM
public function save() {
Yii::log("Transaction saved: {$this->txnId}", 'info');
return true;
}
If you get "Transaction saved: ..." in your log you are one step further, you are able
to get the data from IPN request. The next step is to create a new model (preferably,
one that you store in a database) with your custom validation rules.
#65
Posted 04 September 2011 - 12:15 PM
Here it is..
<?php
//include payPal libraries
Yii::import('payPal.models.*');
Yii::import('payPal.controllers.ipn.*');
Yii::import('payPal.components.*');
class ApiController extends Controller {
public function actionIpn() {
Yii::log('API:IPN:PAYPALREQUEST','info','application.controllers.api');
$ipn = new PPIpnAction($this,"ipn");
$ipn->onRequest = array($this, "ipnRequest");
$ipn->onFailure = array($this, "ipnFailure");
$ipn->onSuccess = array($this, "ipnSuccess");
$ipn->run();
}
public function ipnRequest($event) {
Yii::log("API:IPN:READY_TO_PROCESS","info","application.controllers.api");
//Check transaction ID
if (!isset($event->details["txn_id"])) {
$event->msg = "API:IPN:HAS_NO_TX";
Yii::log($event->msg,"warning","application.controllers.api");
$event->sender->onFailure($event);
return;
} else {
$event->msg = "API:IPN:CONFIRMED_TXN_ID";
Yii::log($event->msg,"info","application.controllers.api");
}
//Check currency
if ('USD' != $event->details['mc_currency']) {
$event->msg = "API:IPN:WRONG_CURRENCY";
Yii::log($event->msg,"warning","application.controllers.api");
$event->sender->onFailure($event);
return;
} else {
$event->msg = "API:IPN:CONFIRMED_CURRENCY ";
Yii::log($event->msg,"info","application.controllers.api");
}
//Check status
if ($event->details['payment_status'] != 'Completed') {
$event->msg = "API:IPN:NOT COMPLETE";
Yii::log($event->msg,"warning","application.controllers.api");
$event->sender->onFailure($event);
return;
} else {
$event->msg = "API:IPN:CONFIRMED_STATUS";
Yii::log($event->msg,"info","application.controllers.api");
}
//Add transaction to transaction logging table
$trans = new Transaction;
$trans->txnId = $event->details['txn_id'];
$trans->paymentStatus = $event->details['payment_status'];
$trans->quantity = $event->details['quantity'];
$trans->mcCurrency = $event->details['mc_currency'];
$trans->mcGross = $event->details['mc_gross'];
$trans->receiverEmail = $event->details['receiver_email'];
$trans->teetime_id = $event->details['custom'];
//Set pending status to confirmed status in tee time record
$teetime = Teetime::model()->findbyPk($event->details['custom']);
$teetime->status = "confirmed";
$teetime->update();
if($trans->save()) {
$event->msg = "API:IPN:TNX_SAVED";
Yii::log($event->msg,'info','application.controllers.api');
$event->sender->onSuccess($event,$trans,$teetime);
} else {
$event->msg = "API:IPN:TNX_NOT_SAVED";
Yii::log($event->msg,'info','application.controllers.api');
$event->sender->onFailure($event);
}
//passes all tests and successful transaction load
$event->msg = "API:IPN:CONFIRMED_AND_SAVED";
Yii::log($event->msg,'info','application.controllers.api');
$event->sender->onSuccess($event);
}
public function ipnSuccess($event,$trans,$teetime) {
Yii::log('API:IPN:SUCCESS_HANDLER_STARTS','info','application.controllers.api');
//get the player record
$player=Player::model()->findByPk($teetime->player_id);
// Set up parameters for admin email
$to = "email here";
$subject = "Reservation Confirmed";
$message = "<p>Blah Blah</p>
<p>Blah Blah:</p>
<p>Player: $player->name</p>
<p>Phone: $player->phone</p>
<p>Email: $player->email</p>
<p>Day: $teetime->date</p>
<p>Time: $teetime->time</p>
";
$from = "email here";
$headers = "MIME-Version: 1.0" . "\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\n";
$headers .= "From: $from" . "\n";
// Send email
if(mail($to,$subject,$message,$headers)) {
Yii::log('API:IPN:ADMIN EMAIL SENT','info','application.controllers.api');
} else {
Yii::log('API:IPN:ADMIN EMAIL FAILED','info','application.controllers.api');
};
// Set up parameters for player email
$to = "$player->email";
$subject = "Your Reservation";
$message = "<p>Hello $player->name,</p>
<p>Blah Blah</p>
<p>Blah Blah</p>
<p>Day: $teetime->date at $teetime->time</p>
<p>Our Address:</p>
<p><a href='http://maps.google.com/mapsBlah Blah</a></p>
<p>Questions? Check out our <a href='http://Blah Blah'>contact information.</a></p>
";
$from = "email here";
$headers = "MIME-Version: 1.0" . "\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\n";
$headers .= "From: $from" . "\n";
// Send email
if(mail($to,$subject,$message,$headers)) {
Yii::log('API:IPN:USER EMAIL SENT','info','application.controllers.api');
} else {
Yii::log('API:IPN:USER EMAIL FAILED','info','application.controllers.api');
};
}
public function ipnFailure($event) {
Yii::log('API:IPN:FAILURE_HANDLER_STARTS','info','application.controllers.api');
//Failure handlng, emails, etc. here.
}
}
#66
Posted 06 September 2011 - 01:58 PM
#67
Posted 27 September 2011 - 01:41 PM
I am trying to integrate PayPal payments on my site and this looks like a great extension, but I am having a bit of trouble understanding how this works and what the best approach for my site would be. Here's what I'm trying to do:
- My site has a basic cart for virtual products.
- After a user is done adding stuff to their cart, I just want to be able to let them pay for the cart total via PayPal.
- How do I initiate the transaction to PayPal? Where do I supply the transaction amount, etc.?
- I DO have a model and db table created to store the transactions, but am really having a problem understanding how the transaction flow works. Any help would be appreciated. I just want to do this:
Say order total is $5.00:
Initiate transaction to PayPal for $5.000->user sends payment via PayPal->process IPN payment via listener->log transaction
Also, where does the payment receipt confirmation page fit into this (the page that the user is returned to from PayPal)?
Thanks!
UPDATE
======
OK, I did some further in-depth reading on IPN and PDT and it looks like PDT might be the best option for me, but I would really appreciate your guys' input. My cart consists of virtual items (classified listings) and they are stored in the session. I want to have a button to pay with PayPal (I understand the button initiates the payment process) and have the user returned to a URL which will handle the PDT transaction and display a confirmation page to the user. I was considering using IPN in conjunction with PDT, but since I only store the cart items in a session, it would be rather difficult to do this via IPN since I don't have a transaction in the db that refers to the cart items being processed. However, if I use PDT, I can confirm receipt of payment and then create the actual order in the db from the session and clear the session afterwards.
My question is - is PDT pretty reliable? I suppose there can still be cases where the transaction might get interrupted somehow while getting back to my site and I might wind up with a payment that didn't get processed on my site. Any suggestions on how to handle this better? Thanks!
#68
Posted 29 September 2011 - 01:58 AM
trenchard, on 06 September 2011 - 01:58 PM, said:
To stop PayPal from sending the same IPN request, all you need to do is to send the same message back for verification. This is done by the PPExt's IPN functionality. If you get VERIFIED the loop should be closed (it's 100% sure that PayPal received the request back in the correct format). See "IPN Protocol and Architecture for details.
TwinMoons, on 27 September 2011 - 01:41 PM, said:
The easiest way (as you stated in your EDIT) is to create a button. This can be done dynamically with
the button manager. But, as you are using a shopping cart you should also consider PayPals built-in cart
functionality, see BMCreateButton (PayPal) for details about creating buttons.
TwinMoons, on 27 September 2011 - 01:41 PM, said:
Say order total is $5.00:
Initiate transaction to PayPal for $5.000->user sends payment via PayPal->process IPN payment via listener->log transaction
Also, where does the payment receipt confirmation page fit into this (the page that the user is returned to from PayPal)?
1. System creates BuyNow button for purchase (amount = $5.00) and add it to page
2. User clicks BuyNow button and enters his / her payment info.
3. PayPal sends IPN request to IPN handler (your site) with payment details
4. System verifies IPN request from PayPal and stores transaction (incl. payment processing)
5. User is returned to your site (could use PDT here, but only to show payment details, not for payment processing)
System refers to your site.
TwinMoons, on 27 September 2011 - 01:41 PM, said:
PayPal will create the transaction and return a transaction id to your site, IPN shouldn't be a problem. To identify the user / purchase you can send an id via the BuyNow button (see earlier posts in this thread).
TwinMoons, on 27 September 2011 - 01:41 PM, said:
You should never rely on PDT for payment processing. PDT depends on the user, all payment information is sent via the users browser in a redirect. If the user clicks stop, their browser crashes, they lose their connection, etc. the payment will go unnoticed. IPN is communication directly between you and PayPal, it's the only option.
#69
Posted 29 September 2011 - 11:44 AM
#70
Posted 29 September 2011 - 01:00 PM
TwinMoons, on 29 September 2011 - 11:44 AM, said:
Thank you for the positive feedback!
TwinMoons, on 29 September 2011 - 11:44 AM, said:
The API reference states that you can use L_BUTTONVARn for HTML standard button variables, these can be found at HTML Variables for websites payments standard, there you'll see the documentation of image_url, it's not a button image. You can use your own custom image by modifying
the HTML code returned from PayPal, similar to how you send an item id (referring to earlier posts in this thread), but I think it's best to use PayPal's standard buttons (then the customers know what they're getting into).
TwinMoons, on 29 September 2011 - 11:44 AM, said:
The API reference states that you can use BUTTONTYPE=PAYMENT since version 65.2 in the page I linked in the previous post. Currently PPExt specifies version 63.0, to make it work as 65.2 you can edit PayPalModule.php and replace VERSION = "63.0" with VERSION = "65.2".
#71
Posted 09 October 2011 - 09:59 AM
Quote
Request: BUTTONTYPE=BUYNOW&L_BUTTONVAR0=currency_code=USD&L_BUTTONVAR1=item_name=My button&L_BUTTONVAR2=amount=200.00&METHOD=BMCreateButton
This is my main.php
'modules'=>array( 'payPal'=>array( 'env'=>'sandbox', 'account'=>array( 'username'=>'bin123_1318166859_biz_api1.gmail.com', 'password'=>'1318166884', 'signature'=>'AZKdSX2UnD6t8-u4FaIYQkAFkDEoAAPuJ0U5b2ufylTICbsNAu8ulRsc', 'email'=>'bin123_1318166859_biz@gmail.com', 'identityToken'=>'PE6NERXVSGGCU', ), 'components'=>array( 'buttonManager'=>array( //'class'=>'payPal.components.PPDbButtonManager' 'class'=>'payPal.components.PPPhpButtonManager', ), ), ),
And I use code example above
$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);- curl on
Please tell me any wrong
#72
Posted 09 October 2011 - 10:37 AM
nib.111, on 09 October 2011 - 09:59 AM, said:
2011/10/09 16:42:40 [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
Please tell me any wrong
I can't see anything wrong with your code, but from the error message, it seems like you got a HTTP error, i.e. you did not get a connection to PayPal. Unless you got more error messages, the request failed in PPUtil.php, line 212:
// Return false on HTTP error if ($response['status'] === false) return false;
Could you try to make a HTTP request using CURL to another site to make sure it's working (you can do this using PPUtils::httpGet(), or directly with curl-commands).
#73
Posted 09 October 2011 - 12:20 PM
I make a request to google by using PPUtils::httpGet() which use curl and it give me a reponse html since I think it work. but still fail created
I also request to api sandbox create button manually and this work.
So, what happend ? :-s
Quote
Request: BUTTONTYPE=BUYNOW&L_BUTTONVAR0=currency_code=USD&L_BUTTONVAR1=item_name=My product&L_BUTTONVAR2=amount=200.00&METHOD=BMCreateButton
in E:\xampp\htdocs\easy\protected\modules\payPal\components\PPButtonManager.php (240)
in E:\xampp\htdocs\easy\protected\modules\payPal\components\PPButtonManager.php (60)
in E:\xampp\htdocs\easy\protected\modules\ESoftware\controllers\PaypalController.php (20)
PaypalController is my test.
And if I could create a button without hosted on PP but use IPN ?
----------
Well, there are a problem connect https
Quote
error_msg = SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
error_no = 60
How solve ?
#74
Posted 09 October 2011 - 01:52 PM
nib.111, on 09 October 2011 - 12:20 PM, said:
Quote
error_msg = SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
error_no = 60
There was a similar issue with IPN, see
post #25
You can probably fix the problem by adding
// Quick fix for missing SSL certs curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
to PPUtils::httpGet(..), after curl_init. But keep in mind that this is a quick fix, the root cause is a missing cert. See how to properly secure remote calls from php for details on how to fix this (and about security issues with the quick fix).
nib.111, on 09 October 2011 - 12:20 PM, said:
Yes you can, IPN is completely separate from the button manager. But using hosted buttons is the most secure alternative.
#75
Posted 10 October 2011 - 02:05 AM
I just a question. How I know exactly order id what customer paid :|. As customer buynow, a order be generated with its id. When IPN notify, I dont know order id for update status of order. Can you help me ?
I think a field in button with orderId when create it, but too much button will be created. maybe wrong
#76
Posted 10 October 2011 - 02:26 AM
nib.111, on 10 October 2011 - 02:05 AM, said:
I think a field in button with orderId when create it, but too much button will be created. maybe wrong
You can add a hidden field named "custom" to the button form, this will be returned to you in the IPN requests, see post #19 for an example.
#78
Posted 18 October 2011 - 06:09 AM
Wanted, on 30 May 2011 - 07:36 AM, said:
CException
Property "PayPalModule.buttonManager" is not defined.
/usr/local/apache2/htdocs/framework/base/CModule.php(88)
076 /**
077 * Getter magic method.
078 * This method is overridden to support accessing application components
079 * like reading module properties.
080 * @param string $name application component or property name
081 * @return mixed the named property value
082 */
083 public function __get($name)
084 {
085 if($this->hasComponent($name))
086 return $this->getComponent($name);
087 else
088 return parent::__get($name);
089 }
090
091 /**
092 * Checks if a property value is null.
093 * This method overrides the parent implementation by checking
094 * if the named application component is loaded.
095 * @param string $name the property name or the event name
096 * @return boolean whether the property value is null
097 */
098 public function __isset($name)
099 {
100 if($this->hasComponent($name))Hi,
I am getting the same error, does anyone knows how to solve it?
Thanks,

Help















