如何在我的Joomla自定义组件中集成PayPal IPN?

时间:2011-08-14 21:29:07

标签: php joomla paypal-ipn

我不确定这个问题的标题是否涵盖了我的意思。 在我写的这个Joomla组件中,我建立了客户通过PayPal购买的能力。起初我为IPN编写了一个单独的视图,但即使脚本没有任何缺陷,它也会继续向IPN发送503(可能是因为ipn-url类似于www.example.com/index.php?option = com_component& view = paypal)所以我重写了部分脚本,现在IPN-url是www.example.com/paypal.php。由于这是一个实际的页面,它现在正确地将200而不是503发送回PayPal。 但是......现在我不知道如何调用我的脚本的其余部分来处理付款的所有电子邮件和数据库存储。因为这个paypal.php是直接调用的(而不是通过index.php),所以它与Joomla完全分开,因此我无法调用模型(或者至少我不知道该怎么做)。

这是我的paypal.php文件:

<?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);

现在,在“我必须处理付款”的地方,我必须能够从数据库中获取数据并将数据存储到数据库中。 那么我如何制作它以便这个文件作为我的组件的一部分,所以我可以调用我的模型中的方法?或者是否有其他方法可以将IPN集成到我的模型中,同时确保200而不是503。

更新: 有人提到使用curl,所以我尝试了。处理程序现在看起来像这样:

  <?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);

IPN仍然正常,但该组件未被“执行”。我之前从未使用过卷曲,所以也许这是剧本中的一个错误?

3 个答案:

答案 0 :(得分:1)

最终得到了自己;所以在某个地方我发现能够从任何文件中访问Joomla的大部分基本功能,你只需要包含2个文件:

/includes/defines.php
/includes/framework.php

然后你就像这样初始化框架:

$framework = & JFactory::getApplication('site');
$framework->initialise();

然后我导入包含所有数据库/电子邮件功能的模型:

JLoader::import('joomla.application.component.model');
JLoader::import('modelname', 'path_to_my/models');

$model= JModel::getInstance('ModelName', 'ComponentnameModel');

现在我可以从我的IPN处理程序访问该模型(以及数据库)中的方法。

答案 1 :(得分:1)

我刚刚在我的网站上遇到了与paypal组件类似的问题,并找出了503通知的来源。

此问题可能与您网站的在线/离线状态有关。如果您的网站处于离线状态(意味着您必须以管理员身份登录以查看您的网站)并且您尚未登录(PayPal也未登录),Joomla正在生成标准消息,显示“

此网站已停止维护。 请稍后再回来查看。

此消息通过503通知发送。

根据您的组件的开发方式,您的网站可以处理来自PayPal的ipn消息,同时仍然向PayPal发送503错误。

希望这会帮助你。

答案 2 :(得分:0)

对于组件com_mycomponent,mycomponent.php应该看起来像

// 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();

在controller.php中,然后使用

class MyComponentCOntroller extends JController{

    function processPaypalPayment(){

        //paste your code here
    }

}

在Paypal中将您的IPN设置为:

http://mysite.com/?option=com_mycomponent&task=processPaypalPayment