kptive / payment-sips-bundle
提供访问 ATOS SIPS 解决方案的支付包
Requires
- php: >=5.3.2
- jms/payment-core-bundle: ~1.0
- psr/log: ~1.0
Requires (Dev)
This package is not auto-updated.
Last update: 2024-09-14 14:50:23 UTC
README
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 或实现自己的。
警告:这些示例没有考虑安全性。不要忘记检查订单的所有权!
致谢
- KptiveStudio http://kptivestudio.com
- Hubert Moutot hubert.moutot@gmail.com
非常感谢Johannes M Schmitt为其出色的JMSPayementCoreBundle。感谢https://github.com/Kitano/KitanoPaymentSipsBundle提供的灵感。
许可协议
KptivePaymentSipsBundle遵循MIT许可协议发布。详情请参阅捆绑的LICENSE文件。