cube43 / ebics-client
PHP 库,用于通过 EBICS 协议与银行通信。
Requires
- php: ^8.1 || ^8.2 || ^8.3
- ext-dom: *
- ext-json: *
- ext-openssl: *
- ext-zlib: *
- phpseclib/phpseclib: ^2.0.45
- symfony/http-client: ^6.3.7
- thecodingmachine/safe: ^2.5
Requires (Dev)
- doctrine/coding-standard: ^12.0
- ocramius/package-versions: 2.8.0
- phpstan/phpstan: 1.10.47
- phpunit/phpunit: ^10.5.2
- psalm/plugin-phpunit: ^0.18.4
- symfony/console: 6.3.4
- vimeo/psalm: ^5.16.0
- vrbata/xml-validator: 2.0.1
Suggests
- andrew-svirin/mt942-php: If you need to parse format MT942 from VMK, STA requests.
- doctrine/orm: Saving info into database
- silarhi/cfonb-parser: If you need to parse CFONB datas from French Bank
- symfony/console: If you to play with ./vendor/bin/cube43-ebics-command
- dev-master
- 0.11.0
- 0.10.0
- 0.9.0
- 0.8.0
- dev-fixfdl / 0.7.x-dev
- 0.7.0
- 0.6.0
- 0.5.0
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.2
- 0.1.1
- 0.1.0
- dev-dependabot/composer/phpstan/phpstan-1.12.4
- dev-dependabot/composer/vimeo/psalm-tw-5.26.1
- dev-dependabot/composer/phpstan/phpstan-1.12.3
- dev-dependabot/composer/ocramius/package-versions-2.9.0
- dev-someclean
- dev-addformatoption
- dev-EbicsServerCallerInterface
- dev-php8.3
- dev-mdlint
- dev-update-deps
- dev-clean-fdl
- dev-update
- dev-generate-x509-without-entete
- dev-issue2
- dev-pslam
This package is auto-updated.
Last update: 2024-09-20 00:15:33 UTC
README
PHP 库,用于通过 EBICS 协议与银行通信。
许可证
cube43/ebics-client 基于 MIT 许可证授权,详情请见 LICENSE 文件。
注意
此库是对 andrew-svirin/ebics-client-php 的重构,以支持多个协议版本、单元测试和端到端测试。
支持的 EBICS 协议版本
- 2.4
- 2.5
- 3.0
支持的命令
- INI
- HIA
- HPB
- FDL
此库仅与 X509 认证的通信一起工作。
安装
composer require cube43/ebics-client
初始化客户端
您需要从您的银行获取以下信息
- 主机 ID
- 主机 URL
- 合作伙伴 ID
- 用户 ID
- 协议版本
$bankInfo = new \Cube43\Component\Ebics\BankInfo($HOST_ID, $HOST_URL, \Cube43\Component\Ebics\Version::v24(), $PARTNER_ID, $USER_ID); $keyring = new \Cube43\Component\Ebics\KeyRing('myPassword'); $x509OptionGenerator = new \Cube43\Component\Ebics\X509\DefaultX509OptionGenerator();
注意 : $HOST_ID, $HOST_URL, $PARTNER_ID, $USER_ID 和版本是由您和您的银行决定的。
使用方法
在执行您想要达成的操作(例如 FDL 调用)之前,您必须生成密钥并将其与服务器(INI、HIA 和 HPB 命令)通信。
INI 命令
INI 命令将生成类型 A 的证书并发送到 EBICS 服务器。在发出此请求后,您必须保存带有新生成证书的密钥环,因为以后将使用它。
$keyring = (new \Cube43\Component\Ebics\Command\INICommand())->__invoke($bankInfo, $keyring, $x509OptionGenerator); // save keyring
HIA 命令
HIA 命令将生成类型 e 和 x 的证书并发送到 EBICS 服务器。在发出此请求后,您必须保存带有新生成证书的密钥环,因为以后将使用它。
$keyring = (new \Cube43\Component\Ebics\Command\HIACommand())->__invoke($bankInfo, $keyring, $x509OptionGenerator); // save keyring
HPB 命令
HPB 命令将从 EBICS 服务器检索类型 e 和 x 的证书。在发出此请求后,您必须保存带有新检索证书的密钥环,因为以后将使用它。
$keyring = (new \Cube43\Component\Ebics\Command\HPBCommand())->__invoke($bankInfo, $keyring); // save keyring
一旦运行了 INI、HIA 和 HPB,您就可以使用 EBICS 协议了。
FDL 命令
<?php $response = (new \Cube43\Component\Ebics\Command\FDLCommand())->__invoke($bankInfo, $keyring, new FDLParams($fdlFromBank, 'FR', new DateTimeImmutable(), new DateTimeImmutable())); if ($response->data === null) { var_dump('no file'); } else { var_dump('file : ', $response->data); } $response = (new \Cube43\Component\Ebics\Command\FDLAknowledgementCommand())->__invoke($response);
保存密钥环
<?php $keyring = new \Cube43\Component\Ebics\KeyRing('myPassword'); $keyringAsArray = $keyring->jsonSerialize(); $keyringAsJson = json_encode($keyring); // put $keyringAsArray or $keyringAsJson in db, file etc...
唤醒密钥环
$keyring = \Cube43\Component\Ebics\KeyRing::fromArray($keyringAsArray, 'myPassword');
重要信息
本网站提供了一个 EBICS 服务器测试环境:[https://software.elcimai.com/efs/accueil-qualif.jsp](https://software.elcimai.com/efs/accueil-qualif.jsp)
生成证书和获取信件的完整示例
<?php use Cube43\Component\Ebics\BankInfo; use Cube43\Component\Ebics\KeyRing; use Cube43\Component\Ebics\Command\INICommand; use Cube43\Component\Ebics\Command\HIACommand; use Cube43\Component\Ebics\Command\HPBCommand; use Cube43\Component\Ebics\X509\DefaultX509OptionGenerator; use Cube43\Component\Ebics\Version; require 'vendor/autoload'; $bank = new BankInfo('EBIXQUAL', 'https://server-ebics.webank.fr:28103/WbkPortalFileTransfert/EbicsProtocol', Version::v24(), $partnerId, $userId); $keyRing = KeyRing::fromFile('keyring.json', 'myPassword'); $x509OptionGenerator = new DefaultX509OptionGenerator(); if (!$keyRing->hasUserCertificatA()) { $keyring = (new INICommand())->__invoke($bank, $keyRing, $x509OptionGenerator); file_put_contents('keyring.json', json_encode($keyring)); } if (!$keyRing->hasUserCertificateEAndX()) { $keyring = (new HIACommand())->__invoke($bank, KeyRing::fromFile('keyring.json', 'myPassword'), $x509OptionGenerator); file_put_contents('keyring.json', json_encode($keyring)); } if (!$keyRing->hasBankCertificate()) { $keyring = (new HPBCommand())->__invoke($bank, KeyRing::fromFile('keyring.json', 'myPassword')); file_put_contents('keyring.json', json_encode($keyring)); } echo ' <table class="table table-borderless"> <tbody> <tr> <td>User ID</td> <td>'.$bank->getUserId().'</td> </tr> <tr> <td>PartnerID</td> <td>'.$bank->getPartnerId().'</td> </tr> <tr> <td>Hash '.$keyring->getUserCertificateA()->getCertificatType()->toString().' ('.$keyring->getUserCertificateA()->getCertificatType()->getHash().')</td> <td> <div class="digest">'.nl2br($keyring->getUserCertificateA()->getCertificatX509()->digest()).'</div> </td> </tr> <tr> <td>Hash '.$keyring->getUserCertificateE()->getCertificatType()->toString().' ('.$keyring->getUserCertificateE()->getCertificatType()->getHash().')</td> <td> <div class="digest">'.nl2br($keyring->getUserCertificateE()->getCertificatX509()->digest()).'</div> </td> </tr> <tr> <td>Hash '.$keyring->getUserCertificateX()->getCertificatType()->toString().' ('.$keyring->getUserCertificateX()->getCertificatType()->getHash().')</td> <td> <div class="digest">'.nl2br($keyring->getUserCertificateX()->getCertificatX509()->digest()).'</div> </td> </tr> </tbody> </table> ';
使用 Doctrine2 而不是文件进行工作
/** * @ORM\Table(name="ebics") * @ORM\Entity() * * @Type() */ class Ebics { /** * @ORM\Column(type="uuid") * @ORM\Id */ private UuidInterface $id; /** @ORM\Column(type="string") */ private string $hostUrl; /** @ORM\Column(type="string") */ private string $partnerId; /** @ORM\Column(type="string") */ private string $userId; /** @ORM\Column(type="string") */ private string $hostId; /** @ORM\Column(type="json") */ private array $certificat; public function __construct( string $hostUrl, string $hostId, string $partnerId, string $userId ) { $this->id = Uuid::uuiv4(); $this->hostUrl = $hostUrl; $this->partnerId = $partnerId; $this->userId = $userId; $this->hostId = $hostId; $this->certificat = []; } public function getKeyring(): KeyRing { return KeyRing::fromArray($this->getCertificat(), (string) getenv('PASSWORD')); } public function getBank(): Bank { return new Bank($this->getHostId(), $this->getHostUrl(), Version::v24(), $this->getPartnerId(), $this->getUserId()); } public function setCertificat(KeyRing $keyRing): void { $this->certificat = json_decode(json_encode($keyRing->jsonSerialize()), true); } } $ebicsEntity = new Ebics('EBIXQUAL', 'https://server-ebics.webank.fr:28103/WbkPortalFileTransfert/EbicsProtocol', Version::v24(), $partnerId, $userId); $x509OptionGenerator = new DefaultX509OptionGenerator(); if (!$ebicsEntity->getKeyring()->hasUserCertificatA()) { $ebicsEntity->setCertificat((new INICommand())->__invoke($ebicsEntity->getBank(), $ebicsEntity->getKeyring(), $x509OptionGenerator)); } if (!$ebicsEntity->getKeyring()->hasUserCertificateEAndX()) { $ebicsEntity->setCertificat((new HIACommand())->__invoke($ebicsEntity->getBank(), $ebicsEntity->getKeyring(), $x509OptionGenerator)); } if (!$ebicsEntity->getKeyring()->hasBankCertificate()) { $ebicsEntity->setCertificat((new HPBCommand())->__invoke($ebicsEntity->getBank(), $ebicsEntity->getKeyring())); } ``