josaliba/paypal-ipn-bundle

用于检索和记录 PayPal 即时支付通知(PayPal IPN)的 Symfony2 扩展包

安装: 313

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 45

类型:symfony-bundle

dev-master 2017-06-18 20:51 UTC

This package is not auto-updated.

Last update: 2024-09-29 04:25:51 UTC


README

概述

symfony2-paypal-ipn 是一个用于处理 PayPal IPN(即时支付通知)服务的 Symfony2 扩展包。该扩展包作为 PayPal IPN 服务的监听器,并使用 Doctrine 将传入的订单记录到您的数据库中。发送订单确认邮件也很简单(有关详细信息,请参阅 [示例 Twig 邮件控制器] twigcontroller)。

symfony2-paypal-ipn 可在 Packagist packagistKnpBundles knpbundles 以及 GitHub 上找到。

描述

symfony2-paypal-ipn 是 [codeigniter-paypal-ipn] codeigniterpaypalipn 的直接移植,一个面向 CodeIgniter 用户的等效库,也由 Orderly Ltd. 提供。

此库(在 Symfony 术语中称为 "bundle")专注于 "支付后" 工作流程,即支付完成后 PayPal 向 IPN 控制器发送即时支付通知调用所需的处理。

此库处理

  1. 验证 IPN 调用
  2. 记录 IPN 调用
  3. 从 IPN 调用中提取订单和行项目信息
  4. 解释 PayPal 的支付状态
  5. 将订单和行项目存储到数据库中
  6. 触发事件,以便其他扩展包可以执行其操作

所有预支付功能(例如,将结账信息发送到 PayPal)和自定义支付后工作流程(例如,发送电子邮件)都留给读者作为练习。如果您需要一个更通用的 Symfony2 工具包来处理 PayPal,请参阅 [JMSPaymentPaypalBundle] jmspaymentbundle

此库还支持从支付数据传输(PDT)获取状态。

依赖关系

Symfony PayPal IPN 扩展包依赖于 Symfony2 symfony2、[Doctrine 2.0] doctrine2.0 和 curl。

还提供了一个使用 Twig twig 模板语言的示例订单确认电子邮件。

安装

1. 从 GitHub 安装

我们将直接将 PayPalIPNBundle 安装到您的 Symfony vendor 目录中

$ cd {{YOUR SYMFONY APP}}/vendor
$ git clone git://github.com/orderly/symfony2-paypal-ipn.git
...
$ mv symfony2-paypal-ipn orderly

现在,至关重要的 OrderlyPayPalIpnBundle.php 文件应该已经在此处可用

{{YOUR SYMFONY APP}}/vendor/orderly/src/Orderly/PaypalIpnBundle/OrderlyPayPalIpnBundle.php

2. 注册扩展包

现在我们需要注册新的扩展包。编辑您的 AppKernel.php 文件

{{YOUR SYMFONY APP}}/app/AppKernel.php 

并在 registerBundles() 方法中 $bundles 数组的末尾添加以下行

new Orderly\PayPalIpnBundle\OrderlyPayPalIpnBundle(),

现在编辑您的 autoload.php 文件

{{YOUR SYMFONY APP}}/app/autoload.php 

并在您的 registerNamespaces() 调用末尾添加以下行

'Orderly'          => __DIR__.'/../vendor/orderly/src',

3. 部署数据库表

使用PayPalIPN Bundle,您可以选择将数据存储在MySQL这样的合理数据库中,或者使用MongoDB。下一节提供了如何使用两种不同系统的信息。

3.1 使用ORM(MySQL)部署数据库表

如果您打算使用MySQL这样的合理数据库系统,您必须配置驱动程序以使用Doctrine ORM。您可以通过将以下配置添加到您的包配置中来实现这一点

orderly_pay_pal_ipn:
    # ... Rest of the configuration
    drivers:
        orm:
            object_manager: doctrine.orm.entity_manager
            classes: ~

下一步是更新/创建PayPalIpnBundle所需的数据库表。有两种不同的方式部署这三个数据库表

使用Symfony控制台

您可以在项目控制台中使用以下命令安装表

$ php app/console doctrine:schema:update --force

注意,这种方法不会复制SQL文件中找到的表字段注释。

手动运行MySQL脚本

或者,您可以对数据库运行create_mysql_tables.sql MySQL文件。您可以在以下位置找到该文件

Orderly/PayPalIpnBundle/Resources/config

如果您选择此选项,您可能希望在运行之前修改每个表的DEFAULT CHARSET(目前设置为“utf8”)。

3.2 使用ODM(MongoDB)部署数据库表

要使用MongoDB作为数据存储,在激活ODM驱动程序之前,请确保在您的配置部分之前安装了DoctrineMongoDBBundle。有关如何配置包的更多信息,请参阅Symfony2网站

orderly_pay_pal_ipn:
    #....
    drivers:
        odm:
            object_manager: doctrine.odm.mongodb.document_manager
            classes: ~

注意:完整的配置示例可以在4.1 使用MongoDB后端下找到

创建数据库表

通过运行以下命令,您将创建/更新MonogoDB集合

$ php app/console doctrine:mongodb:update --force

4. 配置

现在我们需要配置包。将以下内容添加到您的Symfony2 YAML配置文件app/config/config.yml

# PaypalIpnBundle Configuration
orderly_pay_pal_ipn:

    # If set to false then service loads settings with "sandbox_" prefix
    islive:  false

    # Constants for the live environment (default settings in Configuration.php)
    email:    sales@CHANGEME.com
    url:      https://www.paypal.com/cgi-bin/webscr
    proxy:    ~
    debug:    %kernel.debug%
    pdttoken: pdt-token

    # Constants for the sandbox environment (default settings in Configuration.php)
    sandbox_email:       system_CHANGEME_biz@CHANGEME.com
    sandbox_url:         https://www.sandbox.paypal.com/cgi-bin/webscr
    sandbox_proxy:       ~
    sandbox_debug:       true
    sandbox_response:    VERIFIED
    sandbox_pdttoken:    pdt-token
    sandbox_pdtresponse:
        payment_status: Completed
        mc_gross: 123.00

    drivers:
        orm:
            object_manager: doctrine.orm.entity_manager
            classes: ~

确保更新emailsandbox_email设置为您自己的PayPal账户。

islive设置为false时,可以激活以下配置

  • sandbox_response允许您模拟IPN Paypal的响应。如果您不设置其值,您的服务器将击中PayPal服务器,并很可能返回INVALID。
  • sandbox_pdtresponse允许您模拟PDT Paypal的响应。如果您不设置其值,您的服务器将击中PayPal服务器,并很可能返回FAIL。要模拟值,只需传递一个键值对列表,服务器将返回。

关于debug设置的说明:如果设置为true,则PayPalIpnBundle将存储包含IPN数据的最后IPN访问(即POST变量)到数据库中。然后当您直接访问不带数据的IPN URL时,它将重新加载缓存的数据。因此,它实际上是一种“回放”模式,允许您直接检查validateIPN() IPN处理器正在做什么。

4.1 使用MongoDB后端

要使用具有MongoDB后端的IPN监听器,将驱动程序部分更改为odm并提供您的MongoDB对象管理器的名称。以下是一个基本配置示例。

# PaypalIpnBundle Configuration
orderly_pay_pal_ipn:

    # If set to false then service loads settings with "sandbox_" prefix
    islive:  false

    # Constants for the live environment (default settings in Configuration.php)
    email:    sales@CHANGEME.com
    url:      https://www.paypal.com/cgi-bin/webscr
    proxy:    ~
    debug:    %kernel.debug%
    pdttoken: pdt-token

    # Constants for the sandbox environment (default settings in Configuration.php)
    sandbox_email:       system_CHANGEME_biz@CHANGEME.com
    sandbox_url:         https://www.sandbox.paypal.com/cgi-bin/webscr
    sandbox_proxy:       ~
    sandbox_debug:       true
    sandbox_response:    VERIFIED
    sandbox_pdttoken:    pdt-token
    sandbox_pdtresponse:
        payment_status: Completed
        mc_gross: 123.00

    drivers:
        odm:
            object_manager: doctrine.odm.mongodb.document_manager
            classes: ~

5. 设置路由(可选但推荐)

要告诉Symfony的路由系统在哪里找到我们的示例控制器,首先打开以下文件

{{YOUR SYMFONY APP}}/app/config/routing.yml

使用Twig发送订单确认

假设您想使用Twig发送订单确认电子邮件,添加以下控制器

OrderlyPayPalIpnBundleEmail:
    resource: "@OrderlyPayPalIpnBundle/Controller/TwigNotificationEmailController.php"
    type:     annotation
    prefix:   /ipn/

您的站点现在将监听传入的即时付款通知,在URL上

http://{{YOUR DOMAIN}}/ipn/ipn-twig-email-notification

请注意,提供的示例电子邮件模板依赖于 Twig 的 [number_format] numberformat 过滤器,该过滤器于 2012 年 12 月添加(您可能需要更新 Twig 版本来使用此功能)。别忘了告诉 PayPal 您的新 PayPal IPN URL。

仅记录订单但不发送通知

或者,如果您只想在数据库中记录订单(而不发送任何通知),那么请在此控制器中添加以下内容

OrderlyPayPalIpnBundleNoEmail:
    resource: "@OrderlyPayPalIpnBundle/Controller/NoNotificationController.php"
    type:     annotation
    prefix:   /ipn/

您的网站现在将监听 incoming IPN

http://{{YOUR DOMAIN}}/ipn/ipn-no-notification

别忘了告诉 PayPal 您的新 PayPal IPN URL。

免责声明:提供的示例控制器完全是示例。请在将此捆绑包投入生产之前,用您自己的业务逻辑更新其中一个或多个示例文件。

接收 PDT 变量

这是您的 PDT 调用的示例。

namespace Your\OwnBundle;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class YourPaypalController extends Controller {
    /**
     * Your return action from Paypal.
     */
    public function completeAction() {
        $tx = $this->getRequest()->get('tx');
        if (!$tx) {
            // Redirect to a non-found page
            return $this->redirect($this->generateUrl('notFound'));
        }

        $pdt = $this->get('orderly_pay_pal_pdt');
        $pdtArray = $pdt->getPdt($tx);

        $status = 'unknown';
        if (isset($pdtArray['payment_status'])) {
            $status = $pdtArray['payment_status'];
        }

        return $this->render('YourOwnBundle:YourPaypal:complete.html.twig',
            array('status' => $status)
        );
    }
}

8. 订阅事件(如果您需要自定义处理)

在接收到 IPN 并确认其有效后,将分派一个包含传入 IPN 的事件。然后您可以订阅一个监听器并执行您需要的任何操作。使用以下内容更改您的 config.yml

services:
    # ...

    paypal_im_received:
        class: Your\OwnBundle\Event\YourPayPalListener
        arguments: ["@doctrine.orm.entity_manager"]
        tags:
            - { name: kernel.event_listener, event: paypal.ipn.receive, method: onIPNReceive }

现在您只需要编写您的自定义监听器

namespace Your\OwnBundle\Event;

use Orderly\PayPalIpnBundle\Event\PayPalEvent;
use Doctrine\Common\Persistence\ObjectManager;

class YourPayPalListener {

    private $om;

    public function __construct(ObjectManager $om) {
        $this->om = $om;
    }

    public function onIPNReceive(PayPalEvent $event) {
        $ipn = $event->getIPN();
        // do your stuff
    }
}

11. 测试和调试

现在是测试的时候了。首先,确保将 islive 设置为 false,并将 sandbox_debug 设置为 true。

一旦启用调试,您可以这样测试

  • 像平常一样进行结账流程,进行 PayPal 沙盒支付等
  • PayPal 将将 IPN POST 数据发送到您的新 PayPal IPN URL
  • 检查 PayPal IPN 历史记录以确定成功或失败(例如 HTTP 状态代码 500)
  • 检查您是否收到了订单确认电子邮件(如果您发送了的话)
  • 检查订单和行项目是否已存储在您的数据库中

如果您在检查中遇到任何问题,则下一步是手动在浏览器中调用您的 IPN URL,看看会发生什么(例如 PHP 或 Symfony 错误,或者可能是数据库或 Twig 未找到错误)。这是因为第 3 步中解释的调试 "重放" 功能。接下来

  • 修复错误
  • 重复

22. 完整配置

# PaypalIpnBundle Configuration
orderly_pay_pal_ipn:

    # If set to false then service loads settings with "sandbox_" prefix
    islive:  false

    # Constants for the live environment (default settings in Configuration.php)
    email:    sales@CHANGEME.com
    url:      https://www.paypal.com/cgi-bin/webscr
    proxy:    ~
    debug:    %kernel.debug%
    pdttoken: pdt-token

    # Constants for the sandbox environment (default settings in Configuration.php)
    sandbox_email:       system_CHANGEME_biz@CHANGEME.com
    sandbox_url:         https://www.sandbox.paypal.com/cgi-bin/webscr
    sandbox_proxy:       ~
    sandbox_debug:       true
    sandbox_response:    VERIFIED
    sandbox_pdttoken:    pdt-token
    sandbox_pdtresponse:
        payment_status: Completed
        mc_gross: 123.00

    drivers: # Define one driver only.
        orm:
            object_manager: doctrine.orm.entity_manager
            classes:
                ipn_log: Orderly\PayPalIpnBundle\Entity\IpnLog
                ipn_order_items: Orderly\PayPalIpnBundle\Entity\IpnOrderItems
                ipn_orders: Orderly\PayPalIpnBundle\Entity\IpnOrders
        # OR for MongoDB support
        odm:
            object_manager: doctrine.odm.mongodb.document_manager
            classes:
                ipn_log: Orderly\PayPalIpnBundle\Document\IpnLog
                ipn_order_items: Orderly\PayPalIpnBundle\Document\IpnOrderItems
                ipn_orders: Orderly\PayPalIpnBundle\Document\IpnOrders

支持和错误

对于支持请求,请发送电子邮件至 [Orderly Ltd] orderlyemail。如果您认为库中存在错误,或者您希望添加的功能缺失,请提交一个 [新 GitHub 问题] newissue

鸣谢

此库是 [Codeigniter PayPal IPN 库] codeigniterpaypalipn 的移植,由 Orderly Ltd 发布。

感谢所有对 symfony2-paypal-ipn 的贡献者

免责声明和警告

Orderly Ltd 对 Symfony2 PayPal IPN Bundle 造成的任何处理错误或由此产生的任何经济损失不承担任何责任。

特别是,这个库并不满足PayPal IPN的要求来

验证实际付款金额是否与您打算收取的金额相符。虽然这并不是一个IPN问题,但如果您不加密按钮,其他人可能会截获原始传输并更改价格。没有这个检查,您可能会接受低于预期的付款。

(此验证步骤不在此捆绑包的范围内,因为这需要与您的产品目录集成。)

此外,此库也没有正确处理退款。通常退款会存储在ipn_orders中作为新的订单行,余额为负,但这甚至也不是100%可预测的。

版权

symfony2-paypal-ipn版权所有(c)2012 Orderly Ltd。

许可

根据Apache License,版本2.0(以下简称“许可证”);除非遵守许可证,否则您不得使用此文件。您可以在以下地址获得许可证副本:

https://apache.ac.cn/licenses/LICENSE-2.0

除非适用法律要求或书面同意,否则根据许可证分发的软件按“原样”分发,不提供任何明示或暗示的保证或条件。有关许可证的具体语言、许可权限和限制,请参阅许可证。