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

发布于 2024-11-29 16:27:19 字数 3098 浏览 0 评论 0原文

我不确定这个问题的标题是否涵盖了我的意思。 在我编写的这个 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 仍然可以正常工作,但组件未“执行”。我以前从未使用过curl,所以也许这是脚本中的错误?

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 rewrote 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我不在是我 2024-12-06 16:27:19

终于自己得到了;所以我在某个地方发现,要能够从任何文件访问 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 处理程序访问该模型(以及数据库)中的方法。

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.

清浅ˋ旧时光 2024-12-06 16:27:19

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

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

该网站因维护而关闭。
请尽快回来查看。

此消息与 503 通知一起发送。

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

希望这对您有帮助。

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.

何其悲哀 2024-12-06 16:27:19

对于组件 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();

Incontroller.php,然后使用

class MyComponentCOntroller extends JController{

    function processPaypalPayment(){

        //paste your code here
    }

}

In Paypal 将您的 IPN 设置为:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文