haibo5 / payone-sdk
用于PAYONE支付集成的SDK。
README
介绍
PAYONE支付集成SDK可以帮助您将支付集成到您的应用程序中。该SDK利用了PAYONE服务器API,它功能丰富但较为老旧,直接使用可能不太舒适。
功能
- 现代界面和强大的概念,让使用此SDK成为一种享受
- 灵活的设计和可扩展的结构,以适应定制解决方案
- 简单而强大的使用PAYONE服务器API
- 自动处理PAYONE通知
- 安全生成带有状态数据负载的重定向URL,用于重定向支付
要求
- 至少需要 PHP 7.1
- Composer依赖管理器
尽管SDK使用了Composer,但它对其他包的依赖并不广泛。目前,唯一的依赖是PSR接口。
许可证
PAYONE支付集成SDK是开源软件,许可协议为MIT许可证。
安装SDK
只需运行 composer require cakasim/payone-sdk
就可以通过Composer安装SDK。
核心概念
SDK基于几个核心原则,这些原则使得它易于使用且易于集成。
- 合理的默认值。 一个有用且功能性的默认配置允许轻松启动SDK,而无需对依赖进行大量初始化。
- 控制反转。 使用构造函数参数注入的简单IoC实现允许中央修改相关组件。
- 服务。 服务类使SDK的各个组件及其功能可访问。
PSR接口
PSR接口的使用允许高度适应已经提供PSR兼容组件的现有系统。
SDK使用了以下PSR接口
使用SDK
本节解释了如何使用SDK。给出了各种代码示例。为了清晰起见,省略了通用代码组件(例如,使用声明)。
构建SDK
要使用SDK,必须实例化主类Sdk
。有三种不同的方法可以实现。
变体1 - 使用所有默认值
这个变体是最容易开始的。SDK将使用所有默认值构建,这需要您安装一些默认的PSR实现包
cakasim/payone-sdk-http-message
(PSR-7,PSR-17)cakasim/payone-sdk-stream-client
(PSR-18)cakasim/payone-sdk-silent-logger
(PSR-3)
现在,您只需一行代码就可以构建SDK
$sdk = new Sdk();
变体2 - 通过提供其他绑定来替换默认值
为了更改默认值,您可以覆盖默认容器绑定以使用您自己的或甚至第三方的实现。这使SDK能够深度集成到任何已提供PSR实现的现有环境中。
// Create the SDK container builder which lets you provide custom bindings $containerBuilder = new ContainerBuilder(); $container = $containerBuilder->getContainer(); // Use the methods of $container to override default bindings ... // For example, provide your own PSR-18 HTTP client implementation $container->bind(\Psr\Http\Client\ClientInterface::class, MyPsr18Client::class); // Or use an already instantiated PSR-3 logger, maybe provided by you // or any PSR-3 compatible third-party package like monolog/monolog. // Assume $logger is any PSR-3 compatible logger instance. $container->bindInstance(\Psr\Log\LoggerInterface::class, $logger); // Finally, construct the SDK and provide your customized container $sdk = new Sdk($containerBuilder->buildContainer());
变体3 - 深度集成到现有的IoC环境中
通常,您会遇到一个已经存在的PSR-11兼容的IoC容器,该容器提供构造函数参数DI。在这种情况下,您可以完全用现有的容器替换SDK容器。
您必须自行提供所有必要的绑定。查看 src/ContainerBuilder.php
源代码以了解所需的绑定。
配置现有的容器后,您可以将其用于实例化 SDK。
// Assume $existingContainer is an already configured container $sdk = new Sdk($existingContainer);
在以下所有示例中,我们假设变量 $sdk
包含 Sdk
实例。
配置 SDK
SDK 需要设置各种配置参数。这些参数必须通过 Config
类提供。一些参数有合理的默认值,而其他则需要设置。请查看下表,其中列出了所有参数。
以下示例显示了如何设置所有必需的参数。
$config = $sdk->getConfig(); // Your API credentials $config->set('api.merchant_id', 'your_merchant_id'); $config->set('api.portal_id', 'your_portal_id'); $config->set('api.sub_account_id', 'your_sub_account_id'); $config->set('api.key', 'your_api_key'); // General API config options $config->set('api.integrator_name', 'YourProjectName'); $config->set('api.integrator_version', '1.0.0'); // The redirect URL template, $token will be replaced by the actual token value. $config->set('redirect.url', 'https://example.com/redirect/$token'); // Redirect token security settings $config->set('redirect.token_encryption_key', 'your_secret_encryption_key'); $config->set('redirect.token_signing_key', 'your_secret_signing_key');
发送 API 请求
以下示例显示了如何发送一个简单的 API 请求,该请求预先授权借记支付。不需要设置全局 API 参数(例如您的 API 凭证),因为 SDK 在发送实际请求之前会使用配置设置它们。
// Create your request / response objects $response = new \Cakasim\Payone\Sdk\Api\Message\Response(); $request = new \Cakasim\Payone\Sdk\Api\Message\Payment\AuthorizationRequest([ // Perform a pre-authorization which reserves the amount, // a follow-up request will be necessary to actually capture the amount 'request' => 'preauthorization', // Set the type of payment to debit payment // https://docs.payone.com/display/public/PLATFORM/clearingtype+-+definition 'clearingtype' => 'elv', // Set the IBAN for the debit payment // Here you may generate a valid test IBAN: // http://randomiban.com 'iban' => 'DE91500105176688925818', ]); // Set the transaction currency // https://docs.payone.com/display/public/PLATFORM/currency+-+definition $request->setCurrency('EUR'); // Set amount to 15049 fractional monetary units of transaction currency, // for currency EUR this represents 150,49 € $request->setAmount(15049); // Set your transaction reference which identifies the transaction // in your system (e.g. the order number within an online shop) // https://docs.payone.com/display/public/PLATFORM/reference+-+definition $request->setReference('1A2B3C4D5E'); // Send the request to PAYONE $sdk->getApiService()->sendRequest($request, $response); // Do something with the response echo serialize($response);
处理 PAYONE 通知
使用 SDK,可以轻松处理 PAYONE 通知。SDK 在验证和映射通知方面采取了重要步骤。
// Register notification handlers $sdk->getNotificationService()->registerHandler(new class() implements HandlerInterface { public function handleNotification(ContextInterface $context): void { $message = $context->getMessage(); if ($message instanceof TransactionStatusInterface) { // handle the TX status notification echo "Received TX action {$message->getAction()}"; } } }); // Get the server request factory to create a request from the current environment /** @var ServerRequestFactoryInterface $requestFactory */ $requestFactory = $sdk->getContainer()->get(ServerRequestFactoryInterface::class); $request = $requestFactory->createServerRequest($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'], $_SERVER); // Process the server request $sdk->getNotificationService()->processRequest($request);
重定向服务
对于某些支付方式,客户将被重定向到第三方服务(PayPal、Sofortüberweisung 等)以进行身份验证和授权支付。
SDK 可以为您设置 API 请求参数 successurl
、errorurl
和 backurl
,以指定客户在完成第三方服务流程后将被重定向到的目标 URL。此外,SDK 还将在目标 URL 中附加一个令牌。
该令牌包含元数据(例如创建时间戳)以及您可以设置的自定义数据。令牌本身将被加密并签名,这确保了对有效负载数据的保护,防止未经授权的访问和修改。此外,SDK 会验证令牌的年龄,并确保其不超过配置的最大年龄。
将重定向参数应用于 API 请求
以下示例显示了如何将重定向参数应用于(预)授权 API 请求。API 响应状态为 REDIRECT
,并包含一个必须用于重定向客户的 redirecturl
参数。在某些情况下,重定向可能不是必需的,该示例也涵盖了这一点。
use Cakasim\Payone\Sdk\Api\Message\Parameter\BackUrlAwareInterface; use Cakasim\Payone\Sdk\Api\Message\Parameter\ErrorUrlAwareInterface; use Cakasim\Payone\Sdk\Api\Message\Parameter\SuccessUrlAwareInterface; use Cakasim\Payone\Sdk\Api\Message\Payment\AuthorizationRequest; // Use an inline class to customize the API request. // The inline class is tagged with the interfaces to support redirect URL parameters. // This is how the SDK knows which redirect URL parameters are supported and should // be added to the request by passing it to applyRedirectParameters() later on. $request = new class() extends AuthorizationRequest implements SuccessUrlAwareInterface, ErrorUrlAwareInterface, BackUrlAwareInterface { public function __construct() { parent::__construct([ // Perform an authorization of a credit card payment, // this means the card will be charged immediately. 'request' => 'authorization', 'clearingtype' => 'cc', // This identifies the credit card of your customer and is valid within your account scope only. // You will obtain this value during a credit card check which should be done in the context // of the PAYONE Client API (e.g. in the browser of the customer). This is good for you because // you are not getting in touch with the actual credit card data of your customer. // https://docs.payone.com/pages/releaseview.action?pageId=1214583 'pseudocardpan' => '...', ]); // Set other mandatory parameters $this->setCurrency('EUR'); $this->setAmount(1499); $this->setReference('9Z8Y7X6W5V'); } }; // Use an inline class to customize the API response $response = new class() extends \Cakasim\Payone\Sdk\Api\Message\Response { public function getRedirectUrl(): ?string { // Return a valid redirect URL or null return $this->getStatus() === 'REDIRECT' ? $this->getParameter('redirecturl') : null; } }; // Add redirect parameters to the request $sdk->getRedirectService()->applyRedirectParameters($request, [ // Provide any custom payload data and encode it securely within the token value 'order_id' => '9Z8Y7X6W5V', // ... ]); // Send API request to PAYONE $sdk->getApiService()->sendRequest($request, $response); // Get the redirect URL. The value can be null which (in this particular case) // indicates that no redirect is necessary because not every credit card payment // authorization requires a redirect. $redirectUrl = $response->getRedirectUrl(); // Check if we have to redirect the customer if ($redirectUrl !== null) { // At this point the customer must be redirected to $redirectUrl. // Basically send a status code of 302 and a Location header with the // value of $redirectUrl. http_response_code(302); header("Location: {$redirectUrl}"); exit; } // At this point no redirect was done, just process the payment // ...
处理重定向令牌
如果客户返回到您的应用,您首先需要读取重定向令牌。SDK 不对如何执行此操作做出任何假设。基本上,使用简单的查询参数是一个合理且完全有效的方法。
请查看以下示例,该示例展示了如何处理令牌并访问令牌有效负载数据。
use Cakasim\Payone\Sdk\Redirect\Context\ContextInterface; use Cakasim\Payone\Sdk\Redirect\Handler\HandlerInterface; // Get the token from the request URL $token = '...'; $handler = new class() implements HandlerInterface { public function handleRedirect(ContextInterface $context): void { // Get the decoded token from the redirect context $token = $context->getToken(); // Read your custom token payload data $orderId = $token->get('order_id'); // Proceed with your business logic ... } }; $sdk->getRedirectService()->registerHandler($handler); $sdk->getRedirectService()->processRedirect($token);