yproximite / payum-system-pay
Payum 的 SP Plus 网关
v2.1.1
2022-10-31 12:21 UTC
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16
- payum/core: ^1.5.1
- php-http/guzzle6-adapter: ^1.0
- phpstan/phpstan: ^0.11.1
- phpstan/phpstan-strict-rules: ^0.11.0
- phpunit/phpunit: ^7.5
- twig/twig: ^2.6
This package is auto-updated.
Last update: 2024-09-19 22:17:59 UTC
README
一个用于使用SystemPay(一个法国支付系统)的 Payum 网关
要求
- PHP 7.2+
- Payum
- 可选 PayumBundle 和 Symfony 3 或 4+
安装
$ 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_algorithm
以 algo-
开头?
我们想使用 sha1
或 hmac-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 的付款(我们应该发送一个介于 000000
和 999999
之间的交易 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; }