eo/jms-payment-extra-bundle

JMSPaymentCoreBundle的MongoDB支持

v0.1.1 2014-07-15 02:23 UTC

This package is auto-updated.

Last update: 2024-09-23 23:55:14 UTC


README

为JMSPaymentCoreBundle提供doctrine mongodb odm支持。

自行承担风险:最近有两篇相当高调的MongoDB报告显示其处于非常不利的地位。大多数批评集中在性能问题和数据丢失的结合上。

先决条件

此版本的包需要Symfony 2.1+,JMS Payment Core和Doctrine MongoDB。

安装

步骤1:使用composer下载EoJmsPaymentExtraBundle

在composer.json中添加EoJmsPaymentExtraBundle

{
    "require": {
        "eo/jms-payment-extra-bundle": "dev-master"
    }
}

现在,运行以下命令让composer下载包

$ php composer.phar update eo/jms-payment-extra-bundle

Composer将包安装到项目的vendor/eo目录中。

步骤2:启用包

在内核中启用包

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Eo\JmsPaymentExtraBundle\EoJmsPaymentExtraBundle(),
    );
}

用法

我们假设您已经创建了一个订单对象或类似的对象。这可能看起来像

<?php

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Eo\JmsPaymentExtraBundle\Document\PaymentInstruction;

class Order
{
    /**
     * @ODM\ReferenceOne(targetDocument="Eo\JmsPaymentExtraBundle\Document\PaymentInstruction")
     */
    protected $paymentInstruction;

    /**
     * @ODM\String
     * @ODM\Index(options={"unique"=true, "safe"=true, "sparse"=true})
     */
    protected $orderNumber;

    /**
     * @ODM\Int
     */
    private $amount;

    // ...

    public function __construct($amount, $orderNumber)
    {
        $this->amount = $amount;
        $this->orderNumber = $orderNumber;
    }

    public function getOrderNumber()
    {
        return $this->orderNumber;
    }

    public function getAmount()
    {
        return $this->amount;
    }

    public function getPaymentInstruction()
    {
        return $this->paymentInstruction;
    }

    public function setPaymentInstruction(PaymentInstruction $instruction)
    {
        $this->paymentInstruction = $instruction;
    }

    // ...
}

订单对象或类似对象不是强制性的,但由于它通常是可用的,因此我们将在本章中使用它进行演示。

选择支付方式

通常,您想给潜在客户一些支付选项。为此,JMSPaymentCoreBundle提供了一个特殊的表单类型 jms_choose_payment_method,我们将利用它。

<?php

use Eo\JmsPaymentExtraBundle\Document\Payment;
use JMS\Payment\CoreBundle\PluginController\Result;
use JMS\Payment\CoreBundle\Plugin\Exception\ActionRequiredException;
use JMS\Payment\CoreBundle\Plugin\Exception\Action\VisitUrl;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * @Route("/payments")
 */
class PaymentController
{
    /**
     * @Route("/{orderNumber}/details", name = "payment_details")
     * @Template
     */
    public function detailsAction(Order $order)
    {
        $request = $this->get('request');
        $router = $this->get('router');
        $dm = $this->get('doctrine.odm.mongodb.document_manager');
        $ppc = $this->get('eo_jms_payment_extra.ppc_document');

        $form = $this->get('form.factory')->create('jms_choose_payment_method', null, array(
            'amount'   => $order->getAmount(),
            'currency' => 'EUR',
            'default_method' => 'payment_paypal', // Optional
            'predefined_data' => array(
                'paypal_express_checkout' => array(
                    'return_url' => $router->generate('payment_complete', array(
                        'orderNumber' => $order->getOrderNumber(),
                    ), true),
                    'cancel_url' => $router->generate('payment_cancel', array(
                        'orderNumber' => $order->getOrderNumber(),
                    ), true)
                ),
            ),
        ));

        if ('POST' === $request->getMethod()) {
            $form->bindRequest($request);

            if ($form->isValid()) {
                $ppc->createPaymentInstruction($instruction = $form->getData());

                $order->setPaymentInstruction($instruction);
                $dm->persist($order);
                $dm->flush($order);

                return new RedirectResponse($router->generate('payment_complete', array(
                    'orderNumber' => $order->getOrderNumber(),
                )));
            }
        }

        return array(
            'form' => $form->createView()
        );
    }
}

存入款项

在上一个部分中,我们已创建我们的PaymentInstruction。现在,我们将看到我们如何实际上将款项存入我们的账户。如上所述,在detailsAction中,我们重定向用户到payment_complete路由,我们将在控制器中创建相应的操作

<?php

use Eo\JmsPaymentExtraBundle\Document\Payment;
use JMS\Payment\CoreBundle\PluginController\Result;
use JMS\Payment\CoreBundle\Plugin\Exception\ActionRequiredException;
use JMS\Payment\CoreBundle\Plugin\Exception\Action\VisitUrl;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;

/**
 * @Route("/payments")
 */
class PaymentController
{
    // ... see previous section

    /**
     * @Route("/{orderNumber}/complete", name = "payment_complete")
     */
    public function completeAction(Order $order)
    {
        $request = $this->get('request');
        $router = $this->get('router');
        $dm = $this->get('doctrine.odm.mongodb.document_manager');
        $ppc = $this->get('eo_jms_payment_extra.ppc_document');

        $instruction = $order->getPaymentInstruction();
        if (null === $pendingTransaction = $instruction->getPendingTransaction()) {
            $payment = $ppc->createPayment($instruction->getId(), $instruction->getAmount() - $instruction->getDepositedAmount());
        } else {
            $payment = $pendingTransaction->getPayment();
        }

        $result = $ppc->approveAndDeposit($payment->getId(), $payment->getTargetAmount());
        if (Result::STATUS_PENDING === $result->getStatus()) {
            $ex = $result->getPluginException();

            if ($ex instanceof ActionRequiredException) {
                $action = $ex->getAction();

                if ($action instanceof VisitUrl) {
                    return new RedirectResponse($action->getUrl());
                }

                throw $ex;
            }
        } else if (Result::STATUS_SUCCESS !== $result->getStatus()) {
            throw new \RuntimeException('Transaction was not successful: '.$result->getReasonCode());
        }

        // payment was successful, do something interesting with the order
    }
}

可用服务

eo_jms_payment_extra.ppc_document

提供的Doctrine MongoDB ODM文档

Eo\JmsPaymentExtraBundle\Document\Credit

Eo\JmsPaymentExtraBundle\Document\ExtendedData

Eo\JmsPaymentExtraBundle\Document\FinancialTransaction

Eo\JmsPaymentExtraBundle\Document\Payment

Eo\JmsPaymentExtraBundle\Document\PaymentInstruction