Symfony Payum-捕获时已调度事件?

Symfony Payum-捕获时已调度事件?,symfony,events,payum,Symfony,Events,Payum,我想知道Payum(或PayumBundle)是否在捕获付款时发送事件? 目的是向客户发送确认电子邮件 我发现文档中没有任何内容,在源代码中只发现了三个事件: payum.gateway.pre_执行 payum.gateway.execute payum.gateway.post_执行 但我想这和付款本身没有关系。顺便说一句,它似乎从来没有发送与条纹付款 谢谢。默认情况下,Payum不会发送任何事件。它被设计成通过一个扩展来扩展。例如,如果您想在实例推送通知(Paypal IPN)上执行一

我想知道Payum(或PayumBundle)是否在捕获付款时发送事件? 目的是向客户发送确认电子邮件

我发现文档中没有任何内容,在源代码中只发现了三个事件:

  • payum.gateway.pre_执行
  • payum.gateway.execute
  • payum.gateway.post_执行
但我想这和付款本身没有关系。顺便说一句,它似乎从来没有发送与条纹付款


谢谢。

默认情况下,Payum不会发送任何事件。它被设计成通过一个扩展来扩展。例如,如果您想在实例推送通知(Paypal IPN)上执行一些操作,您可以添加如下所述的扩展:


还有一个扩展。您必须手动创建它并添加到payum。

默认情况下,payum不会发送任何事件。它被设计成通过一个扩展来扩展。例如,如果您想在实例推送通知(Paypal IPN)上执行一些操作,您可以添加如下所述的扩展:


还有一个扩展。您必须手动创建它并添加到payum。

我遇到了相同的问题:在某些支付操作上调度自定义事件。在我的例子中,我想处理授权和捕获操作

我注意到,对于一个付款操作,Payum请求可能会被处理多次,这就是为什么我需要将我的付款标记为已处理,以便只发送一次我的自定义事件(付款目的:$customPaymentEventDispatched属性)

这是我的支付实体:

<?php

namespace MyApp\PaymentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Payment as BasePayment;

class Payment extends BasePayment
{
    // ...

    // Not persisted
    protected $payable;
    protected $customPaymentEventDispatched = false;

    // ...

    public function setPayable($payable)
    {
        $this->payable = $payable;

        return $this;
    }

    public function getPayable()
    {
        return $this->payable;
    }

    public function markAsCustomPaymentEventDispatched()
    {
        $this->customPaymentEventDispatched = true;

        return $this;
    }

    public function isCustomPaymentEventDispatched()
    {
        return $this->customPaymentEventDispatched;
    }
}
以及侦听器的代码:

<?php

namespace MyApp\PaymentBundle\EventListener;

use Payum\Core\Bridge\Symfony\Event\ExecuteEvent;
use Payum\Core\Request\Authorize;
use Payum\Core\Request\BaseGetStatus;
use Payum\Core\Request\Capture;
use Payum\Core\Model\PaymentInterface;
use Payum\Core\Request\GetHumanStatus;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use MyApp\PaymentBundle\Entity\Payment;
use MyApp\PaymentBundle\Event\PayablePaymentStatusChangeEvent;
use MyApp\PaymentBundle\PaymentEvents;

class PaymentListener
{
    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function onPayumGatewayPostexecute(ExecuteEvent $event, $eventName, EventDispatcherInterface $eventDispatcher)
    {
        $request = $event->getContext()->getRequest();

        // Exclude Payum GetStatus request
        // => protect from infinite loop as following code execute one GetStatus request
        if ($request instanceof BaseGetStatus) {
            return;
        }
        // Request types requiring dispatching an event
        if (!($request instanceof Authorize || $request instanceof Capture)) {
            return;
        }

        $payment = $request->getFirstModel();
        if (!$payment instanceof PaymentInterface) {
            return;
        }

        $event->getContext()->getGateway()->execute($status = new GetHumanStatus($payment));

        if (!$payment->isCustomPaymentEventDispatched()) {
            if ($request instanceof Capture && $status->isCaptured())
            {
                $payable = $payment->getPayable();

                $this->logger->info('Dispatching PAYMENT_SUCCESS for '.$payable->__toString());

                $tmEvent = new PayablePaymentStatusChangeEvent($payment->getPayable());
                $eventDispatcher->dispatch(PaymentEvents::PAYMENT_PENDING, $tmEvent);

                $payment->markAsCustomPaymentEventDispatched();
            }
            elseif ($request instanceof Authorize && $status->isAuthorized())
            {
                $payable = $payment->getPayable();

                $this->logger->info('Dispatching PAYMENT_PENDING for '.$payable->__toString());

                $tmEvent = new PayablePaymentStatusChangeEvent($payment->getPayable());
                $eventDispatcher->dispatch(PaymentEvents::PAYMENT_PENDING, $tmEvent);

                $payment->markAsCustomPaymentEventDispatched();
            }
        }
    }
}

我遇到了同样的问题:在某些支付操作上调度自定义事件。在我的例子中,我想处理授权和捕获操作

我注意到,对于一个付款操作,Payum请求可能会被处理多次,这就是为什么我需要将我的付款标记为已处理,以便只发送一次我的自定义事件(付款目的:$customPaymentEventDispatched
属性)

这是我的支付实体:

<?php

namespace MyApp\PaymentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Payment as BasePayment;

class Payment extends BasePayment
{
    // ...

    // Not persisted
    protected $payable;
    protected $customPaymentEventDispatched = false;

    // ...

    public function setPayable($payable)
    {
        $this->payable = $payable;

        return $this;
    }

    public function getPayable()
    {
        return $this->payable;
    }

    public function markAsCustomPaymentEventDispatched()
    {
        $this->customPaymentEventDispatched = true;

        return $this;
    }

    public function isCustomPaymentEventDispatched()
    {
        return $this->customPaymentEventDispatched;
    }
}
以及侦听器的代码:

<?php

namespace MyApp\PaymentBundle\EventListener;

use Payum\Core\Bridge\Symfony\Event\ExecuteEvent;
use Payum\Core\Request\Authorize;
use Payum\Core\Request\BaseGetStatus;
use Payum\Core\Request\Capture;
use Payum\Core\Model\PaymentInterface;
use Payum\Core\Request\GetHumanStatus;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use MyApp\PaymentBundle\Entity\Payment;
use MyApp\PaymentBundle\Event\PayablePaymentStatusChangeEvent;
use MyApp\PaymentBundle\PaymentEvents;

class PaymentListener
{
    protected $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function onPayumGatewayPostexecute(ExecuteEvent $event, $eventName, EventDispatcherInterface $eventDispatcher)
    {
        $request = $event->getContext()->getRequest();

        // Exclude Payum GetStatus request
        // => protect from infinite loop as following code execute one GetStatus request
        if ($request instanceof BaseGetStatus) {
            return;
        }
        // Request types requiring dispatching an event
        if (!($request instanceof Authorize || $request instanceof Capture)) {
            return;
        }

        $payment = $request->getFirstModel();
        if (!$payment instanceof PaymentInterface) {
            return;
        }

        $event->getContext()->getGateway()->execute($status = new GetHumanStatus($payment));

        if (!$payment->isCustomPaymentEventDispatched()) {
            if ($request instanceof Capture && $status->isCaptured())
            {
                $payable = $payment->getPayable();

                $this->logger->info('Dispatching PAYMENT_SUCCESS for '.$payable->__toString());

                $tmEvent = new PayablePaymentStatusChangeEvent($payment->getPayable());
                $eventDispatcher->dispatch(PaymentEvents::PAYMENT_PENDING, $tmEvent);

                $payment->markAsCustomPaymentEventDispatched();
            }
            elseif ($request instanceof Authorize && $status->isAuthorized())
            {
                $payable = $payment->getPayable();

                $this->logger->info('Dispatching PAYMENT_PENDING for '.$payable->__toString());

                $tmEvent = new PayablePaymentStatusChangeEvent($payment->getPayable());
                $eventDispatcher->dispatch(PaymentEvents::PAYMENT_PENDING, $tmEvent);

                $payment->markAsCustomPaymentEventDispatched();
            }
        }
    }
}

这就是检查是否捕获付款的方法:

use Payum\Core\Action\CapturePaymentAction;
use Payum\Core\Bridge\Symfony\Event\ExecuteEvent;
use Payum\Core\Request\Capture;
use Payum\Core\Request\GetHumanStatus;

class SuccessPaymentListener
{
    public function onPostExecute(ExecuteEvent $event) {
        $context = $event->getContext();
        $action = $context->getAction();
        $request = $context->getRequest();
        if ($action instanceof CapturePaymentAction && $request instanceof Capture) {
            $status = new GetHumanStatus($request->getToken());
            $gateway = $context->getGateway();
            $gateway->execute($status);
            if ($status->isCaptured()) {
                $payment = $status->getFirstModel();
                //here is your stuff
            }
        }
    }
}
services.yml:

app.payum.extension.event_dispatcher:
    class: Payum\Core\Bridge\Symfony\Extension\EventDispatcherExtension
    arguments: ["@event_dispatcher"]
    tags:
        - { name: payum.extension, all: true, prepend: false }

app.success_payment_listener:
    class: AppBundle\Listener\SuccessPaymentListener
    tags:
        - { name: kernel.event_listener, event: payum.gateway.post_execute, method: onPostExecute }

这就是您可以检查是否已捕获付款的方式:

use Payum\Core\Action\CapturePaymentAction;
use Payum\Core\Bridge\Symfony\Event\ExecuteEvent;
use Payum\Core\Request\Capture;
use Payum\Core\Request\GetHumanStatus;

class SuccessPaymentListener
{
    public function onPostExecute(ExecuteEvent $event) {
        $context = $event->getContext();
        $action = $context->getAction();
        $request = $context->getRequest();
        if ($action instanceof CapturePaymentAction && $request instanceof Capture) {
            $status = new GetHumanStatus($request->getToken());
            $gateway = $context->getGateway();
            $gateway->execute($status);
            if ($status->isCaptured()) {
                $payment = $status->getFirstModel();
                //here is your stuff
            }
        }
    }
}
services.yml:

app.payum.extension.event_dispatcher:
    class: Payum\Core\Bridge\Symfony\Extension\EventDispatcherExtension
    arguments: ["@event_dispatcher"]
    tags:
        - { name: payum.extension, all: true, prepend: false }

app.success_payment_listener:
    class: AppBundle\Listener\SuccessPaymentListener
    tags:
        - { name: kernel.event_listener, event: payum.gateway.post_execute, method: onPostExecute }