yproximite/payum-system-pay

Payum 的 SP Plus 网关

v2.1.1 2022-10-31 12:21 UTC

README

一个用于使用SystemPay(一个法国支付系统)的 Payum 网关

Latest Stable Version Build Status

要求

安装

$ composer require yproximite/payum-system-pay

配置

使用 PayumBundle(Symfony)

首先在服务定义中注册网关工厂

# config/services.yaml or app/config/services.yml
services:
    yproximite.system_pay_gateway_factory:
        class: Payum\Core\Bridge\Symfony\Builder\GatewayFactoryBuilder
        arguments: [Yproximite\Payum\SystemPay\SystemPayGatewayFactory]
        tags:
            - { name: payum.gateway_factory_builder, factory: system_pay }

然后配置网关

# config/packages/payum.yaml or app/config/config.yml

payum:
  gateways:
    system_pay:
      factory: system_pay
      vads_site_id: 'change it' # required 
      certif_prod: 'change it' # required 
      certif_test: 'change it' # required 
      sandbox: true
      hash_algorithm: 'algo-sha1' # or 'algo-hmac-sha256'

使用 Payum

<?php
//config.php

use Payum\Core\PayumBuilder;
use Payum\Core\Payum;

/** @var Payum $payum */
$payum = (new PayumBuilder())
    ->addDefaultStorages()

    ->addGateway('gatewayName', [
        'factory'        => 'system_pay',
        'vads_site_id'   => 'change it', // required
        'certif_prod'    => 'change it', // required
        'certif_test'    => 'change it', // required
        'sandbox'        => true,
        'hash_algorithm' => 'algo-sha1' // or 'algo-hmac-sha256'
    ])

    ->getPayum()
;

为什么 hash_algorithmalgo- 开头?

我们想使用 sha1hmac-256,但目前存在一个 Payum 限制,它尝试调用 sha1,因为它是一个有效的可调用对象。

作为解决方案,我们想到的唯一简单方法是使用 algo- 作为前缀。由于 algo-sha1 不是一个有效的可调用对象,因此没有 Payum 问题,一切运行良好。

使用方法

确保您的 Payment 实体覆盖 getNumber() 方法如下

<?php

namespace App\Entity\Payment;

use Doctrine\ORM\Mapping as ORM;
use Payum\Core\Model\Payment as BasePayment;

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

    /**
     * {@inheritdoc}
     */
    public function getNumber()
    {
        return (string) $this->id;
    }
}

这样做后,库将能够选择付款的 ID 并将其用于与 System Pay 的付款(我们应该发送一个介于 000000999999 之间的交易 ID)。

分期付款

如果您计划支持分期付款,则需要在您的代码中某处调用 Payment#setPartialAmount 以跟踪每次付款的金额。

<?php
class Payment extends BasePayment
{
    // ...

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    protected $partialAmount;

    public function getPartialAmount(): ?int
    {
        return $this->partialAmount;
    }

    public function setPartialAmount(?int $partialAmount): void
    {
        $this->partialAmount = $partialAmount;
    }
}

使用方法

<?php

use App\Entity\Payment;
use Yproximite\Payum\SystemPay\Api;
use Yproximite\Payum\SystemPay\PaymentConfigGenerator;

// Define the periods
$periods = [
    ['amount' => 1000, 'date' => new \DateTime()],
    ['amount' => 2000, 'date' => (new \DateTime())->add(new \DateInterval('P1M'))],
    ['amount' => 3000, 'date' => (new \DateTime())->add(new \DateInterval('P2M'))],
];

// Compute total amount
$totalAmount = array_sum(array_column($periods, 'amount'));

// Compute `paymentConfig` fields that will be sent to the API
// It will generates something like this: MULTI_EXT:20190102=1000;20190202=2000;20190302=3000
$paymentConfig = (new PaymentConfigGenerator())->generate($periods);

// Then create payments
$storage = $payum->getStorage(Payment::class);
$payments = [];

foreach ($periods as $period) {
    $payment = $storage->create();
    $payment->setTotalAmount($totalAmount);
    $payment->setPartialAmount($period['amount']);

    $details = $payment->getDetails();
    $details[Api::FIELD_VADS_PAYMENT_CONFIG] = $generatedPaymentConfig;
    $payment->setDetails($details);

    $storage->update($payment);
    $payments[] = $payment;
}