How do i integrate PayPal IPN in my Joomla Custom Component?
I am not sure the title of this question covers what I mean. In this Joomla component I am writing I have built in the ability for customers to buy via PayPal. At first I wrote a seperate view for the IPN, but even though the script worked without a flaw, it kept sending a 503 back to IPN (probably because the ipn-url was something like www.example.com/index.php?option=com_component&view=paypal) so i rewro开发者_开发百科te part of the script and now the IPN-url is www.example.com/paypal.php. Since this is an actual page it now correctly sends a 200 instead of a 503 back to PayPal. But...now I don't know how to call the rest of my script which handles all the emailing and database storing of a payment. Since this paypal.php is called directly (and not via index.php) it works completely seperate from Joomla so I cannot call in a Model (or at least I don't know how to do that).
This is my paypal.php file:
<?php
$header = "";
$req = 'cmd=_notify-validate';
$get_magic_quotes_exists = false;
if (function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($_POST as $key => $value) {
if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
}
else {
$value = urlencode($value);
$req .= "&$key=$value";
}
}
// Post back to PayPal to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if ($fp) {
fputs($fp, $header . $req);
while (!feof($fp)) {
$res = fgets($fp, 1024);
if (strcmp($res, "VERIFIED") == 0) {
// Here I must process the payment (emails, database, etc.)
}
else {
// Error
}
}
}
fclose($fp);
Now at the place where it says 'Here I must process payment' I must be able to get data from the database and store data into the database. So how do I make it so this file acts as part of my component so I can call methods from my Model(s)? Or is there some other way I can integrate IPN into my model while ensuring a 200 instead of a 503.
UPDATE: Someone mentioned using curl so i tried that. The handler now looks like this:
<?php
$header = "";
$req = 'cmd=_notify-validate';
$postData = 'option=com_component&view=buy&layout=paypal';
$get_magic_quotes_exists = false;
if (function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($_POST as $key => $value) {
if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
$value = urlencode(stripslashes($value));
}
else {
$value = urlencode($value);
$req .= "&$key=$value";
$postData .= "&$key=$value";
}
}
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
if ($fp) {
fputs($fp, $header . $req);
while (!feof($fp)) {
$res = fgets($fp, 1024);
if (strcmp($res, "VERIFIED") == 0) {
$ch = curl_init("http://www.example.com/index.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$output = curl_exec($ch);
if ($output == FALSE) {
// Error
}
curl_close($ch);
}
else {
// Error
}
}
}
fclose($fp);
The IPN still works fine, but the component is not 'executed'. I never used curl before so maybe it is a fault in the script?
Got it myself finally; so somewhere I found out that to be able to access most of the basic functionality of Joomla from any file you simply need to include 2 files:
/includes/defines.php
/includes/framework.php
Then you simply initialise the framework like so:
$framework = & JFactory::getApplication('site');
$framework->initialise();
And then I import the model which contains all the database/email functionality:
JLoader::import('joomla.application.component.model');
JLoader::import('modelname', 'path_to_my/models');
$model= JModel::getInstance('ModelName', 'ComponentnameModel');
And now I can access the methods from that model (and thus the database) from my IPN-handler.
I just had a similar issue with a paypal component on my website and figured out where the 503 notification originated from.
This issue could have to do with the online/offline status of your website. If your website is offline (meaning you have to log in as admin to have a look at your website) and you're not logged in (PayPal isn't logged in as well) Joomla is generating a standard message displaying a message like"
This site is down for maintenance. Please check back again soon.
This message is send with a 503 notification.
Depending on how your component is developed, the ipn message from PayPal can be processed by your website, while still sending a 503 error to PayPal.
Hope this helps you out.
For a component com_mycomponent, your mycomponent.php should look like
// Require the com_content helper library
require_once (JPATH_COMPONENT.DS.'controller.php');
// Create the controller
$controller = new MyComponentController();
// Perform the Request task
$controller->execute(JRequest::geCmd('task'));
// Redirect if set by the controller
$controller->redirect();
In controller.php, then use
class MyComponentCOntroller extends JController{
function processPaypalPayment(){
//paste your code here
}
}
In Paypal set your IPN to:
http://mysite.com/?option=com_mycomponent&task=processPaypalPayment
精彩评论