olssonm / swish-php
Swish API 包装器。兼容 Laravel
Requires
- php: ^8.1
- guzzlehttp/guzzle: ^6.3.1 || ^7.0
- nesbot/carbon: ^2 || ^3
- ramsey/uuid: ^4.2
Requires (Dev)
- ergebnis/composer-normalize: ^2.43
- orchestra/testbench: ^8.0 || ^9.0
- pestphp/pest: ^1.0 || ^2.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^8.3 || ^9.3 || ^10.0
- squizlabs/php_codesniffer: ^3.5
Suggests
- illuminate/contracts: Required to use the Laravel integration (^10.0|^11.0).
- illuminate/support: Required to use the Laravel integration (^10.0|^11.0).
This package is auto-updated.
Last update: 2024-09-12 20:23:55 UTC
README
PHP 中 Swish-API 的简单易用包装器。还包括用于快速设置 Laravel 的提供者和外观。
先决条件
此包支持 PHP ^8.1。已针对 Laravel 10 和 11 进行测试。PHP 需要编译了 cURL 和 SSL 扩展(在大多数情况下,它们应该默认可用)。
使用较旧的 PHP 或 Laravel 版本?请查看此包的 v1 和 v2 版本。
安装
composer require olssonm/swish-php
设置
您需要访问您的 Swish 证书才能在生产中使用此包。然而,在开发期间,您可以使用他们的测试/商户 Swish 模拟器环境,而不必成为 Swish 客户。
有关他们在 MSS 环境中测试的更多信息,请参阅他们的 官方文档。有关使用/创建 Swish 证书的快速概述,请参阅此处(瑞典语)(瑞典语)。
创建客户端时,您必须设置您正在使用的环境(否则默认为生产环境,https://cpc.getswish.net/swish-cpcapi/api/
),您可以使用以下选项之一
Client::TEST_ENDPOINT // https://mss.cpc.getswish.net/swish-cpcapi/api/ Client::PRODUCTION_ENDPOINT // https://cpc.getswish.net/swish-cpcapi/api/ Client::SANDBOX_ENDPOINT // https://staging.getswish.pub.tds.tieto.com/swish-cpcapi/api/
use Olssonm\Swish\Certificate; use Olssonm\Swish\Client; $certificate = new Certificate( '/path/to/client.pem', 'client-passphrase', '/path/to/root.pem', // Can also be omitted for "true" to verify peer '/path/to/signing.key', // Path to signing certificate, only used for payouts 'signing-passphrase' // Only used for payouts ); $client = new Client($certificate, $endpoint = Client::TEST_ENDPOINT)
重要
证书路径应该是绝对的。您可以使用 realpath -s YOUR_CERT.pem
来实现这一点。
Laravel
使用 Laravel 服务提供者和外观,您可以更优雅地处理包。只需要求包并发布配置
php artisan vendor:publish --provider="Olssonm\Swish\Providers\SwishServiceProvider"
在 /config/swish.php
中,您可以根据需要进行设置
return [ 'certificates' => [ 'client' => env('SWISH_CLIENT_CERTIFICATE_PATH'), 'password' => env('SWISH_CLIENT_CERTIFICATE_PASSWORD'), 'root' => env('SWISH_ROOT_CERTIFICATE_PATH', true), 'signing' => env('SWISH_SIGNING_CERTIFICATE_PATH', null), 'signing_password' => env('SWISH_CLIENT_SIGNING_PASSWORD', null), ], 'endpoint' => env('SWISH_URL', \Olssonm\Swish\Client::PRODUCTION_ENDPOINT), ];
这也可以是一个保存您的付款人别名、回调 URL 等的好地方,然后您可以使用 config('swish.payee_alias')
等方式访问它们。
用法
创建 Swish 付款的典型情况。
use Olssonm\Swish\Certificate; use Olssonm\Swish\Client; use Olssonm\Swish\Payment; $certificate = new Certificate( '/path/to/client.pem', 'client-passphrase' ); $client = new Client($certificate); // Create a new payment-object $payment = new Payment([ 'callbackUrl' => 'https://callback.url', 'payeePaymentReference' => 'XVY77', 'payeeAlias' => '123xxxxx', 'payerAlias' => '321xxxxx', 'amount' => '100', 'currency' => 'SEK', 'message' => 'A purchase of my product', ]); // Perform the request $response = $client->create($payment); // $response->id = '11A86BE70EA346E4B1C39C874173F088' // $response->location = 'https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests/11A86BE70EA346E4B1C39C874173F088' // $response->paymentRequestToken = 'a-unique-token'
使用 Laravel,您还可以使用外观并节省一些代码(在此示例中,Olssonm\Swish\Facades\Swish
已别名为 Swish
)
use Swish; use Olssonm\Swish\Payment; $response = Swish::create(new Payment([ 'callbackUrl' => 'https://callback-url.com', 'payeePaymentReference' => 'XVY77', 'payeeAlias' => '123xxxxx', 'payerAlias' => '321xxxxx', 'amount' => '100', 'currency' => 'SEK', 'message' => 'My product', ]));
支付和退款
提示
始终在使用客户端时使用支付和退款类,即使只需要操作 ID,例如
$payment = $client->get(Payment(['id' => '5D59DA1B1632424E874DDB219AD54597']));
支付
提示
有关 支付 的更多信息,请参阅官方文档
支付需要使用 SHA512 进行散列并使用签名证书进行签名后才能发送到 Swish - 不要担心,此包将自动处理大部分工作。只需确保已设置签名证书的路径即可
$certificate = new Certificate( '/path/to/client.pem', 'client-passphrase', true, '/path/to/signing.key', 'signing-passphrase' ); $client = new Client($certificate); $payout = $client->create(new Payout([]));
此外,您的证书(注意:您的签名证书,而不是您的客户端证书)序列号需要提供。您可以使用以下任一方法
$certificate = new Certificate(/**/); $payout = new Payout([ 'signingCertificateSerialNumber' => $certificate->getSerial() ])
或自己分配(查看 gist 以提取序列号)
$payout = new Payout([ 'signingCertificateSerialNumber' => '4512B3EBDA6E3CE6BFB14ABA6274A02C' ])
重要
请注意,Payouts 使用 payoutInstructionUUID
而不是 ID
,您应该 自行设置以跟踪它。如果它缺失,则在创建时将自动设置。
关于 IDs/UUIDs
本包使用 Swish API 的 v2 版本,UUID 由商家设置。本包将自动处理所有这些方面,但您可以手动设置 ID/instructionUUID(无论是 Swish 的格式还是默认的 v4 格式)。
$id = 'EBB5C73503084E3C9AEA8A270AEBFE15'; // or $id = 'ebb5c735-0308-4e3c-9aea-8a270aebfe15'; $payment = new Payment([ 'id' => $id ]);
在动态生成 UUID 时,本包使用 Ramsey/Uuid 生成 RFC4122(v4)UUID。如果选择自行设置 UUID,Swish 接受 V1、3、4 和 5 UUID。
如果使用无效的 UUID,将抛出 Olssonm\Swish\Exceptions\InvalidUuidException
。
注意
无论您是设置自己的 UUID 还是让包处理生成,UUID 总会自动格式化为 Swish 格式(去除连字符并转换为大写)。
可用方法
本包处理与 Swish 相关的常见任务;检索、创建和取消付款。检索和创建付款、退款以及退款可以创建和检索。所有这些操作都是通过 Olssonm\Swish\Client
实现的;
$client->get(Payment $payment | Refund $refund | Payout $payout); $client->create(Payment $payment | Refund $refund | Payout $payout); $client->cancel(Payment $payment);
异常处理
遇到验证错误时,将抛出 Olssonm\Swish\Exceptions\ValidationException
。对象将包含请求、响应以及 getErrorCode()
和 getErrorMessage()
辅助函数。
try { $response = $client->create($payment); } catch (ValidationException $exception) { $errors = $exception->getErrors(); foreach ($errors as $error) { $error->errorCode; // AM03 $error->errorMessage; // Invalid or missing Currency. } }
对于 4xx
错误,将抛出 \Olssonm\Swish\Exceptions\ClientException
,而对于 5xx
错误,将抛出 \Olssonm\Swish\Exceptions\ServerException
。这两个异常都实现了 Guzzle 的 BadResponseException
,这使得在需要时可以访问请求和响应对象。
回调
Swish 建议不要使用 payments
端点来获取付款或退款的状态(即使他们在一些示例中使用它...),而应使用回调。
本包包括一个简单的辅助函数,用于从包含 Swish 所有数据的回调中检索 Payment
、Refund
或 Payout
对象。
use Olssonm\Swish\Callback; $paymentOrRefund = Callback::parse(); // get_class($paymentOrRefund) = \Olssonm\Swish\Payment::class, \Olssonm\Swish\Refund::class, \Olssonm\Swish\Payout::class
辅助函数自动检索当前 HTTP 请求(通过 file_get_contents('php://input')
)。但是,如果您需要(例如,如果您已经有了 Laravel 请求对象),也可以注入自己的数据。
class SwishController { public function Callback(Request $request) { $data = Callback::parse($request->getContent()); if(get_class($data) == \Olssonm\Swish\Payment::class) { // Handle payment callback } else if(get_class($data) == \Olssonm\Swish\Refund::class) { // Handle refund callback } else if(get_class($data) == \Olssonm\Swish\Payout::class) { // Handle payout callback } } }
在真实世界的场景中,您可能希望为退款、付款和支付使用不同的回调 URL,以避免像上面示例中那样的不必要解析。
注意
请注意,Swish 的回调既未加密也未进行编码,相反,您应确保回调来自一个 有效的 IP 范围。
许可证
MIT 许可证(MIT)。有关更多信息,请参阅 LICENSE。
© 2022-2024 Marcus Olsson。