0

Symfony 2.8 にアプリケーションがあり、payum 経由で支払いを取得するときにエラーが発生します - omnipay-bridge および omnipay/targetpay です。

prepareAction を呼び出すと、targetpay Web サイトの外部支払いフォームにリダイレクトされます。キャンセルすると (キャンセル = テストモードで支払う)、次の例外を除いて自分のサイトにリダイレクトされます。

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 を作成しました:

エンティティ 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);
    }
}

コントローラ 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);
    }

} 

例外のスタック トレース

あなたの専門知識をありがとう!

4

0 に答える 0