mishagodovanuk/payment_gateway
Composer 安装命令:
composer require mishagodovanuk/payment_gateway
包简介
Framework-agnostic mTLS HTTP client with HMAC-signed GET requests for payment gateway integrations
README 文档
README
PHP library for mutual TLS (client certificate) HTTP GET requests with HMAC integrity signatures on the query string. Suited for payment-style APIs that require transport security and request signing.
Requirements
- PHP 8.2+
- Extensions:
json,openssl - Composer
Install
composer require mishagodovanuk/payment_gateway
PHP namespace remains Mihod\PaymentGateway\ (Composer package name is mishagodovanuk/payment_gateway).
Configuration
Copy .env.example to .env and set certificate paths, key passphrase, and HMAC_SECRET. For BadSSL demos, use badssl.com/download (private key passphrase: badssl.com).
Environment variables override values from the .env file when both are present.
Optional HTTP client settings (Guzzle)
These are optional and have sane defaults:
HTTP_ERRORS:true|false(defaulttrue). When enabled, Guzzle throws exceptions on non-2xx responses.HTTP_TIMEOUT_SECONDS: float seconds (default30).HTTP_CONNECT_TIMEOUT_SECONDS: float seconds (default10).
Design (interfaces & DTOs)
Mihod\PaymentGateway\Signature\SignerInterface— canonical query string + MAC signature (HmacSigneris the default).Mihod\PaymentGateway\Http\MtlsTransportInterface— GET over mTLS (GuzzleMtlsTransportviaGuzzleClientFactory).Mihod\PaymentGateway\Dto\SignedHttpResponse— immutable result DTO for successful calls (status, body, headers).Mihod\PaymentGateway\SignedMtlsClientFactory— default wiring (Guzzle + HMAC signer).
SignedMtlsClient depends on these abstractions so you can swap implementations in tests or wire custom signers/transports in DI (Laravel, Symfony, Yii2, PHP-DI, etc.).
Usage
Manual / direct usage (no framework)
Use this when you run plain PHP (CLI script, cron, small tool) and you do not use Laravel, Symfony, or Yii.
1. Install the package
composer require mishagodovanuk/payment_gateway
2. Configure environment
Copy .env.example to .env next to your script (or anywhere you prefer). Set absolute paths to your PEM files, HMAC_SECRET, and optional SIGNATURE_HEADER_NAME / SIGNATURE_HASH_ALGO.
3. Call the client from a PHP file
Bootstrap Composer autoload, then either load config from that file or build it in code.
Option A — read settings from a .env file path (library parses the file; process $_ENV is merged so exported variables override the file):
<?php declare(strict_types=1); require __DIR__ . '/vendor/autoload.php'; use Mihod\PaymentGateway\SignedMtlsClient; use Mihod\PaymentGateway\SignedMtlsClientFactory; $client = (new SignedMtlsClientFactory())->fromEnvFile(__DIR__ . '/.env'); $response = $client->sendSignedGet('https://client.badssl.com/', [ 'transaction_id' => '12345', 'amount' => '99.99', 'currency' => 'USD', ]); echo $response->statusCode . PHP_EOL; echo $response->body . PHP_EOL;
Run: php your-script.php
Option B — pass configuration only in code (no .env file; good for one-off scripts if you accept hardcoded paths):
<?php declare(strict_types=1); require __DIR__ . '/vendor/autoload.php'; use Mihod\PaymentGateway\Config\ClientConfiguration; use Mihod\PaymentGateway\SignedMtlsClientFactory; $config = ClientConfiguration::fromArray([ 'MTLS_CLIENT_CERT' => '/absolute/path/client.pem', 'MTLS_CLIENT_KEY' => '/absolute/path/key.pem', 'MTLS_CLIENT_KEY_PASSPHRASE' => 'optional-or-empty', 'HMAC_SECRET' => 'your-shared-secret', 'MTLS_VERIFY_SSL' => 'true', 'SIGNATURE_HEADER_NAME' => 'X-Signature', ]); $client = (new SignedMtlsClientFactory())->create($config); $response = $client->sendSignedGet('https://api.example.com/check', ['id' => '1']);
Option C — use environment variables already set by the shell or systemd (no file path; merge into ClientConfiguration::fromArray($_ENV) after ensuring your process has the same variable names as in .env.example).
In all cases the flow is: build ClientConfiguration → SignedMtlsClientFactory::create($config) → sendSignedGet($url, $query) → SignedHttpResponse or an exception.
Laravel
Laravel already loads .env into $_ENV / config(). Map those values into ClientConfiguration once, register SignedMtlsClient as a singleton, then type-hint it in controllers, jobs, or commands.
1. Add keys to .env (same names as .env.example in this package, or your own — then map them).
2. Create config/payment_gateway.php:
<?php declare(strict_types=1); return [ 'mtls_client_cert' => env('MTLS_CLIENT_CERT'), 'mtls_client_key' => env('MTLS_CLIENT_KEY'), 'mtls_client_key_passphrase' => env('MTLS_CLIENT_KEY_PASSPHRASE', ''), 'hmac_secret' => env('HMAC_SECRET'), 'mtls_verify_ssl' => env('MTLS_VERIFY_SSL', 'true'), 'mtls_ca_bundle' => env('MTLS_CA_BUNDLE'), 'signature_header_name' => env('SIGNATURE_HEADER_NAME', 'X-Signature'), 'signature_hash_algo' => env('SIGNATURE_HASH_ALGO', 'sha256'), ];
3. Register the client in App\Providers\AppServiceProvider::register():
use Mihod\PaymentGateway\Config\ClientConfiguration; use Mihod\PaymentGateway\SignedMtlsClientFactory; $this->app->singleton(SignedMtlsClientFactory::class, function () { return new SignedMtlsClientFactory(); }); $this->app->singleton(\Mihod\PaymentGateway\SignedMtlsClient::class, function ($app) { $c = $app['config']->get('payment_gateway'); $config = ClientConfiguration::fromArray([ 'MTLS_CLIENT_CERT' => $c['mtls_client_cert'], 'MTLS_CLIENT_KEY' => $c['mtls_client_key'], 'MTLS_CLIENT_KEY_PASSPHRASE' => $c['mtls_client_key_passphrase'], 'HMAC_SECRET' => $c['hmac_secret'], 'MTLS_VERIFY_SSL' => $c['mtls_verify_ssl'], 'MTLS_CA_BUNDLE' => $c['mtls_ca_bundle'], 'SIGNATURE_HEADER_NAME' => $c['signature_header_name'], 'SIGNATURE_HASH_ALGO' => $c['signature_hash_algo'], ]); return $app->make(SignedMtlsClientFactory::class)->create($config); });
4. Inject where needed:
use Mihod\PaymentGateway\SignedMtlsClient; public function __construct(private readonly SignedMtlsClient $paymentGateway) {} public function check(): void { $response = $this->paymentGateway->sendSignedGet(config('app.gateway_url'), ['transaction_id' => '1']); }
Use php artisan config:cache in production so secrets are not read from .env on every request in the way env() does outside config files.
Symfony
Symfony injects parameters from .env via %env(...)%. The clean approach is a small factory service that builds ClientConfiguration and returns SignedMtlsClient.
1. Put variables in .env / .env.local with the same names as this package’s .env.example.
2. Define services (YAML or PHP). Example in config/services.yaml:
services: _defaults: autowire: true autoconfigure: true Mihod\PaymentGateway\Config\ClientConfiguration: factory: ['App\PaymentGateway\PaymentGatewayFactory', 'createConfiguration'] Mihod\PaymentGateway\SignedMtlsClient: factory: ['App\PaymentGateway\PaymentGatewayFactory', 'createClient'] arguments: $configuration: '@Mihod\PaymentGateway\Config\ClientConfiguration'
3. Implement App\PaymentGateway\PaymentGatewayFactory:
<?php declare(strict_types=1); namespace App\PaymentGateway; use Mihod\PaymentGateway\Config\ClientConfiguration; use Mihod\PaymentGateway\SignedMtlsClient; use Mihod\PaymentGateway\SignedMtlsClientFactory; final class PaymentGatewayFactory { public static function createConfiguration(): ClientConfiguration { return ClientConfiguration::fromArray([ 'MTLS_CLIENT_CERT' => $_ENV['MTLS_CLIENT_CERT'], 'MTLS_CLIENT_KEY' => $_ENV['MTLS_CLIENT_KEY'], 'MTLS_CLIENT_KEY_PASSPHRASE' => $_ENV['MTLS_CLIENT_KEY_PASSPHRASE'] ?? '', 'HMAC_SECRET' => $_ENV['HMAC_SECRET'], 'MTLS_VERIFY_SSL' => $_ENV['MTLS_VERIFY_SSL'] ?? 'true', 'MTLS_CA_BUNDLE' => $_ENV['MTLS_CA_BUNDLE'] ?? null, 'SIGNATURE_HEADER_NAME' => $_ENV['SIGNATURE_HEADER_NAME'] ?? 'X-Signature', 'SIGNATURE_HASH_ALGO' => $_ENV['SIGNATURE_HASH_ALGO'] ?? 'sha256', ]); } public static function createClient(ClientConfiguration $configuration): SignedMtlsClient { return (new SignedMtlsClientFactory())->create($configuration); } }
Symfony loads .env before the container runs, so $_ENV is populated. Alternatively, inject %env(MTLS_CLIENT_CERT)% as constructor arguments to the factory instead of reading $_ENV directly.
4. Inject SignedMtlsClient into controllers/services by type-hint.
Yii 2
Yii 2 uses a global application container (Yii::$container) and/or the components section of the application config.
1. Add env vars (e.g. via vlucas/phpdotenv in web/index.php before the app boots, or export them in the web server / PHP-FPM pool).
2. Register a singleton in config/web.php (and config/console.php if you use CLI):
<?php use Mihod\PaymentGateway\Config\ClientConfiguration; use Mihod\PaymentGateway\SignedMtlsClient; $config = [ // ... 'container' => [ 'definitions' => [ SignedMtlsClient::class => function () { $cfg = ClientConfiguration::fromArray([ 'MTLS_CLIENT_CERT' => getenv('MTLS_CLIENT_CERT') ?: '', 'MTLS_CLIENT_KEY' => getenv('MTLS_CLIENT_KEY') ?: '', 'MTLS_CLIENT_KEY_PASSPHRASE' => getenv('MTLS_CLIENT_KEY_PASSPHRASE') ?: '', 'HMAC_SECRET' => getenv('HMAC_SECRET') ?: '', 'MTLS_VERIFY_SSL' => getenv('MTLS_VERIFY_SSL') ?: 'true', 'MTLS_CA_BUNDLE' => getenv('MTLS_CA_BUNDLE') ?: null, 'SIGNATURE_HEADER_NAME' => getenv('SIGNATURE_HEADER_NAME') ?: 'X-Signature', 'SIGNATURE_HASH_ALGO' => getenv('SIGNATURE_HASH_ALGO') ?: 'sha256', ]); return new SignedMtlsClient($cfg); }, ], ], ];
3. Resolve the client where you need it:
$client = \Yii::$container->get(\Mihod\PaymentGateway\SignedMtlsClient::class); $response = $client->sendSignedGet($url, $query);
Or register a named component and use $this->paymentGateway in controllers if you wrap it in a thin service class.
Any framework (summary)
- Ensure certificate paths and
HMAC_SECRETare available to PHP (env, vault, or config). - Build
ClientConfiguration::fromArray([...])with keys exactly as in.env.example(or map your names to those keys). - Instantiate
SignedMtlsClientFactoryonce and buildSignedMtlsClientfrom configuration (or register it as a singleton). - Call
sendSignedGet($url, $query); handleSignedHttpResponseand Guzzle exceptions.
Signing uses a canonical query string: keys sorted, values cast to string, http_build_query(..., PHP_QUERY_RFC3986). Set SIGNATURE_HEADER_NAME to Authorization if your API expects that header instead of X-Signature.
Errors
- Invalid paths or secrets throw
Mihod\PaymentGateway\Exception\InvalidConfigurationException. - With
HTTP_ERRORS=true(default), non-2xx HTTP responses and transport failures throw Guzzle exceptions (e.g.GuzzleHttp\Exception\RequestException).
Tests
composer install
composer test:unit # no certificates required
Integration test / php try.php (real mTLS to BadSSL):
BadSSL ships one PEM file (certificate + encrypted private key). Use the same path for MTLS_CLIENT_CERT and MTLS_CLIENT_KEY, passphrase badssl.com.
composer run setup:badssl # downloads PEM + creates .env from .env.example if .env is missing
composer test:integration
php try.php
If you already have a .env, the script does not overwrite it — merge the printed MTLS_* lines manually, or remove .env and run setup:badssl again.
- Unit tests cover HMAC canonicalization and signing (no network).
- Integration test calls
https://client.badssl.com/when.envis valid; otherwise skipped.
Quality
Single command (recommended for CI or before you push):
composer quality # PHPCS → PHPStan → PHPUnit → Deptrac → PHPMD (src + tests)
Full suite including PhpMetrics (slower; HTML report under var/phpmetrics/):
composer quality:all
Individual checks:
composer cs-check # PHPCS PSR-12 (parallel, sniff codes) composer analyse # PHPStan level 9 composer deptrac # architectural layers composer phpmd # PHPMD on src/ composer phpmd:tests # PHPMD on tests/ (separate ruleset) composer metrics # PhpMetrics HTML → var/phpmetrics/ composer test:coverage # line + HTML coverage (needs Xdebug: xdebug.mode=coverage)
Tooling config lives next to composer.json (phpcs.xml.dist, phpstan.neon, phpmd.xml, phpmd-tests.xml, deptrac.yaml, phpunit.xml). Reports under var/ and coverage/ are gitignored.
Coverage report is written to coverage/html/index.html. Requires the Xdebug extension with coverage enabled (php -d xdebug.mode=coverage is set in the test:coverage script). PCOV is an alternative if you install pcov and use php -d pcov.enabled=1 instead.
The test suite targets 100% line, method, and class coverage for executable code under src/ (interfaces have no executable lines).
Test data providers
External datasets live under tests/DataProviders/ and are wired with #[DataProviderExternal(ClassName::class, 'methodName')]:
| Provider | Used by |
|---|---|
HmacSignerDataProvider |
HmacSignerTest — canonical query strings and HMAC digests |
ClientConfigurationDataProvider |
ClientConfigurationTest::testFromArrayThrowsInvalidConfiguration — invalid fromArray cases |
GuzzleClientFactoryDataProvider |
GuzzleClientFactoryTest::testCreateClientAppliesSslOptions — verify / CA / passphrase |
Tests that need instance-only temp files ($this->certFile in setUp()), one-off setup (chmod on a temp file), or a single assertion stay as plain test methods (YAGNI).
Specification
The package implements mTLS client transport, HMAC-signed GET over a canonical query string, .env-style configuration, PSR-4 layout, and unit plus integration tests.
mishagodovanuk/payment_gateway 适用场景与选型建议
mishagodovanuk/payment_gateway 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 05 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「payment」 「Guzzle」 「tls」 「hmac」 「mtls」 「client-certificate」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 mishagodovanuk/payment_gateway 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 mishagodovanuk/payment_gateway 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 mishagodovanuk/payment_gateway 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
OriginPHP Socket
Let's Encrypt / ACME client written in PHP for the CLI.
Cloudflare Middleware For Guzzle
Simplifies working with holaluz API endpoints
Wrapper for Slack Web API
Transport-agnostic TLS encryption for any connected stream
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 45
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-04-05