Symfony2 - 付款捕获时的Payum / TargetPay错误

时间:2016-09-08 14:30:05

标签: symfony omnipay payum

我在Symfony 2.8中有一个应用程序,当我通过payum - omnipay-bridge和omnipay / targetpay捕获付款时出现错误。

当我致电prepareAction时,我会被重定向到targetpay网站上的外部付款表单。当我取消(取消=在testmode中付款)时,我被重定向回我的网站,但有以下例外:

Invalid input given. Should be an array or instance of \Traversable (500 Internal Server Error)

当我刷新页面时,我最终会在最终路线上结束' bsdb_payment_membership_status' (请参阅PaymentController),我的付款状态是' new'。我的付款流程出了什么问题?

我的composer.json看起来像这样:

 "payum/payum-bundle": "~2.0",
  "payum/omnipay-bridge": "~1.2",
  "omnipay/targetpay": "~2.1",

我的config.yml看起来像这样:

payum:
    security:
        token_storage:
            Bsdb\BsdbPaymentBundle\Entity\PaymentToken: { doctrine: orm }

    storages:
        Bsdb\BsdbPaymentBundle\Entity\PaymentDetails: { doctrine: orm }

    gateways:
        bsdb_membership_payment:
            factory: omnipay
            type: "TargetPay_Mrcash"
            options:
                subAccountId: 123456
                testMode: true

我创建了一个自定义PaymentBundle: - 实体PaymentDetails - 实体PaymentToken - 带有prepareAction和captureDoneAction的Controller PaymentController

实体PaymentToken

namespace Bsdb\BsdbPaymentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Token;

/**
 * @ORM\Table
 * @ORM\Entity
 */
class PaymentToken extends Token
{
}

实体PaymentDetails

namespace Bsdb\BsdbPaymentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\ArrayObject;
use Application\Sonata\UserBundle\Entity\User;

/**
 * @ORM\Table(name="PaymentDetails")
 * @ORM\Entity
 */
class PaymentDetails extends ArrayObject
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     *
     * @var integer $id
     */
    protected $id;

    /**
     * @var User $user
     *
     * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
     * })
     */
    protected $user;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="started_at", type="datetime", nullable=true)
     */
    protected $startedAt;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="completed_at", type="datetime", nullable=true)
     */
    protected $completedAt;

    /**
     * Set start date:
     */
    public function __construct()
    {
        $this->setStartedAt(new \DateTime());
    }

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * @param User $user
     */
    public function setUser($user)
    {
        $this->user = $user;
    }

    /**
     * @return \DateTime
     */
    public function getStartedAt()
    {
        return $this->startedAt;
    }

    /**
     * @param \DateTime $startedAt
     */
    public function setStartedAt($startedAt)
    {
        $this->startedAt = $startedAt;
    }

    /**
     * @return \DateTime
     */
    public function getCompletedAt()
    {
        return $this->completedAt;
    }

    /**
     * @param \DateTime $completedAt
     */
    public function setCompletedAt($completedAt)
    {
        $this->completedAt = $completedAt;
    }

    public function getDetailsString()
    {
        return json_encode($this->details);
    }
}

Controller PaymentController

namespace Bsdb\BsdbPaymentBundle\Controller;

use Application\Sonata\UserBundle\Entity\User;
use Application\Sonata\UserBundle\Event\UserEvent;
use Application\Sonata\UserBundle\Service\UserGroupAttacher;
use Application\Sonata\UserBundle\UserEvents;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Payum\Core\Request\GetHumanStatus;
use Symfony\Component\HttpFoundation\JsonResponse;

class PaymentController extends Controller
{
    /**
     * @Route(name="bsdb_payment_membership_prepare", path="/membership/prepare")
     */
    public function prepareAction()
    {
        $paymentName = 'bsdb_membership_payment';
        $storage = $this->get('payum')->getStorage('Bsdb\BsdbPaymentBundle\Entity\PaymentDetails');
        $currentUser = $this->get('security.context')->getToken()->getUser();

        /** @var \Bsdb\BsdbPaymentBundle\Entity\PaymentDetails $paymentDetails */
        $paymentDetails = $storage->create();

        $paymentDetails['amount'] = $this->container->getParameter('premium.amount');
        $paymentDetails['description'] = $this->container->getParameter('premium.description');
        $paymentDetails['clientIp'] = $this->get('request')->getClientIp();
        $paymentDetails->setUser($currentUser);

        $storage->update($paymentDetails);

        $captureToken = $this->get('payum')->getTokenFactory()->createCaptureToken(
            $paymentName,
            $paymentDetails,
            'bsdb_payment_membership_captured' // the route to redirect after capture;
        );

        return $this->redirect($captureToken->getTargetUrl());
    }

    /**
     * @Route(name="bsdb_payment_membership_captured", path="/membership/captured")
     */
    public function captureDoneAction(Request $request)
    {
        $token = $this->get('payum')->getHttpRequestVerifier()->verify($request);
        $gateway = $this->get('payum')->getGateway($token->getGatewayName());

        $gateway->execute($status = new GetHumanStatus($token));
        $payment = $status->getFirstModel();

        if ($status->isCaptured()) {
            /** @var User $user */
            $user = $this->getUser();
            $user->setLastPremiumUpgrade(new \DateTime());
            $user->setPremiumExpiresAt(new \DateTime(sprintf('+%s days', $this->container->getParameter('premium.expiration.period'))));

            // Set group
            $entityManager = $this->getDoctrine()->getManager();
            $groupAttachter = new UserGroupAttacher($entityManager);
            $groupAttachter->attachUserGroup($user, $this->container->getParameter('premium.group'));

            // Update payment data:
            $payment->setCompletedAt(new \DateTime());

            // Save:
            $entityManager->persist($user);
            $entityManager->flush();

            // Trigger events for emails and stuff:
            $event = new UserEvent($user);
            $this->get('event_dispatcher')->dispatch(UserEvents::USER_PREMIUM_PURCHASED, $event);
        }

        return $this->redirect($this->generateUrl('bsdb_payment_membership_status', array('status' => $status->getValue())));
    }

    /**
     * @Route(name="bsdb_payment_membership_status", path="/membership/status/{status}")
     * @Template()
     */
    public function paidAction($status)
    {
        return array('status' => $status);
    }

} 

Stack trace of exception

感谢您的专业知识!

0 个答案:

没有答案