kptive/payment-sips-bundle

提供访问 ATOS SIPS 解决方案的支付包

安装量: 22,776

依赖项: 0

建议者: 0

安全: 0

星标: 1

关注者: 2

分支: 0

类型:symfony-bundle

v1.0.2 2015-01-29 16:49 UTC

This package is not auto-updated.

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


README

Build Status

KptivePaymentSipsBundle 通过 JMSPaymentCoreBundle 提供访问 Atos Worldline SIPS 支付解决方案的接口。

以下支付服务由 Atos SIPS 提供

  • Merc@net (BNP Parisbas)
  • Cyberplus (Banque Populaire)
  • Elys Net (HSBC)
  • Scellius (La Banque Postale)
  • SogenActif (Société Générale)
  • Webaffaires (Crédit du Nord)
  • Sherlocks (LCL)
  • Citelis (Crédit Mutuel)
  • ...

这意味着该包应该可以与它们中的任何一个无缝工作。

安装

步骤 1

运行

$ php composer.phar require kptive/payment-sips-bundle

或者,在更新您的供应商之前,将以下内容添加到您的 composer.json

{
    "require": {
        "kptive/payment-sips-bundle": "*@dev"
    }
}

步骤 2

在您的 AppKernel 类中注册该包。您还必须注册 JMSPaymentCoreBundle 并对其进行配置。

<?php
// app/AppKernel.php

    public function registerBundles()
    {
        $bundles = array(
            // ...
            new JMS\Payment\CoreBundle\JMSPaymentCoreBundle(),
            new Kptive\PaymentSipsBundle\KptivePaymentSipsBundle(),
        );

        // ...
    }

    // ...

步骤 3

将您的 SIPS 文件夹内容复制到 app/sips/。如果您想放在其他地方,只需编辑 pathfile 的配置值和二进制文件位置(见下文)。

您还需要根据您的 pathfile 中的指定复制或放置您自己的标志图像到正确位置。

配置

kptive_payment_sips:
    config:
        merchant_id: "082584341411111"
        merchant_country: fr
        normal_return_url: %base_url%/checkout/complete
        cancel_return_url: %base_url%/checkout/cancel
        automatic_response_url: %base_url%/checkout/notification
        pathfile: %kernel.root_dir%/config/sips/param/pathfile
        currency_code: 978
    bin:
        request_bin: %kernel.root_dir%/config/sips/bin/static/request
        response_bin: %kernel.root_dir%/config/sips/bin/static/response

用法

假设您有一个 AcmePaymentBundle,并且您使用 Acme\PaymentBundle\Entity\Order 类处理您的订单。

<?php

namespace Acme\PaymentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Payment\CoreBundle\Entity\PaymentInstruction;

/**
 * @ORM\Table(name="acme_order")
 */
class Order
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="JMS\Payment\CoreBundle\Entity\PaymentInstruction")
     */
    private $paymentInstruction;

    /**
     * @ORM\Column(type="decimal", precision=10, scale=2)
     */
    private $amount;

    /**
     * @ORM\Column(type="datetime", name="payed_at", nullable=true)
     */
    private $payedAt;

    // ...

    public function getId()
    {
        return $this->id;
    }

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

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

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

        return $this;
    }

    public function getPayedAt()
    {
        return $this->payedAt;
    }

    public function setPayedAt($payedAt)
    {
        $this->payedAt = $payedAt;

        return $this;
    }

创建一个带有 details 动作的控制器。这是您的客户可以查看并确认订单的地方。

<?php

namespace Acme\PaymentBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use JMS\Payment\CoreBundle\Entity\PaymentInstruction;
use Acme\PaymentBundle\Entity\Order;

/**
 * @Route("/checkout")
 */
class CheckoutController extends Controller
{
    // ...

    /**
     * @Route("/details/{id}", name = "payment_details")
     * @Template()
     */
    public function detailsAction(Order $order)
    {
        $request = $this->get('request');
        $em = $this->get('doctrine')->getEntityManager();
        $router = $this->get('router');
        $ppc = $this->get('payment.plugin_controller');

        $confirm = new \StdClass();

        $form = $this->createFormBuilder($confirm)
            ->add('save', 'submit', array('label' => 'confirmer'))
            ->getForm();

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

            if ($form->isValid()) {
                $instruction = new PaymentInstruction($order->getAmount(), 978, 'sips');

                $ppc->createPaymentInstruction($instruction);

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

                return new RedirectResponse($router->generate('payment_gateway', array(
                    'id' => $order->getId(),
                )));
            }
        }

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

如您在前面动作中看到的,当用户确认订单时,我们将创建一个新的 PaymentInstruction(有关其工作方式的更多信息,请参阅 JMSPaymentCoreBundle 文档)。然后,用户将被重定向到 payment_gateway 路由。这是我们调用 SIPS API 以显示 SIPS 信用卡选择表单的地方。

让我们实现相应的动作

    /**
     * @Route("/gateway/{id}", name="payment_gateway")
     * @Template()
     */
    public function sipsGatewayAction(Order $order)
    {
        $client = $this->get('kptive_payment_sips.client');

        $config = array(
            'amount' => $order->getAmount() * 100,
            'order_id' => $order->getId(),
        );

        $sips = $client->request($config);

        return array('sips' => $sips);
    }

并在相应的视图中显示表单给用户

{# src/Acme/PaymentBundle/Resources/views/Checkout/sipsGateway.html.twig #}

{{ sips|raw }}

当用户在 SIPS 平台上完成支付工作流程后,他们将被重定向到您在包配置部分先前配置的 normal_return_url

让我们实现这个动作

    /**
     * @Route("/complete", name="payment_complete")
     * @Template()
     */
    public function completeAction(Request $request)
    {
        $data = $request->request->get('DATA');
        $em = $this->get('doctrine')->getEntityManager();
        $client = $this->get('kptive_payment_sips.client');

        $response = $client->handleResponseData($data);
        $order = $em->getRepository('KsPaymentBundle:Order')->find($response['order_id']);
        $instruction = $order->getPaymentInstruction();

        $result = $this->get('kptive_payment_sips.return_handler')->handle($instruction, $response);

        return array('order' => $order);
    }

目前,我们没有对订单做任何事情,我们只是处理银行响应并将支付标记为有效。

JMSPaymentCoreBundle 将触发一个 payment.state_change 事件。因此,我们将监听此事件并在一个 PaymentListener 中执行我们想要执行的所有有用的操作。

<?php

namespace Acme\PaymentBundle\EventListener;

use Doctrine\ORM\EntityManager;
use JMS\Payment\CoreBundle\PluginController\Event\PaymentStateChangeEvent;
use JMS\Payment\CoreBundle\Model\PaymentInterface;

class PaymentListener
{

    protected $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function onPaymentStateChange(PaymentStateChangeEvent $event)
    {
        if (PaymentInterface::STATE_DEPOSITED === $event->getNewState()) {
            $order = $this
                ->entityManager
                ->getRepository('AcmePaymentBundle:Order')
                ->findOneBy(array('paymentInstruction' => $event->getPaymentInstruction()));

            $order->setPayedAt(new \DateTime());

            // Do various things with the Order here
            // ...

            $this->entityManager->persist($order);
            $this->entityManager->flush();
        }
    }
}

将其注册为一个服务

        <service id="acme_payment.payment_listener" class="Acme\PaymentBundle\EventListener\PaymentListener">
            <tag name="kernel.event_listener" event="payment.state_change" method="onPaymentStateChange" />
            <argument type="service" id="doctrine.orm.entity_manager">
        </service>

就是这样!

如果您的客户不在银行平台点击“返回”按钮,将自动向配置的 automatic_response_url 发出请求。

您可以使用与 normal_return_url 相同的 URL 或实现自己的。

警告:这些示例没有考虑安全性。不要忘记检查订单的所有权!

致谢

非常感谢Johannes M Schmitt为其出色的JMSPayementCoreBundle。感谢https://github.com/Kitano/KitanoPaymentSipsBundle提供的灵感。

许可协议

KptivePaymentSipsBundle遵循MIT许可协议发布。详情请参阅捆绑的LICENSE文件。