payone-gmbh / pcp-serversdk-php
PHP SDK to communicate with the PAYONE Commerce Platform server-to-server API
Requires
- php: ~8.2||~8.3||~8.4||~8.5
- ext-curl: *
- ext-json: *
- ext-mbstring: *
- guzzlehttp/guzzle: ^7.3
- guzzlehttp/psr7: ^1.7 || ^2.0
- phpdocumentor/reflection-docblock: ^5.4
- symfony/property-access: ^7.1
- symfony/property-info: ^7.1
- symfony/serializer: ^7.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.65.0
- phpstan/phpstan: ^1.12.10
- phpunit/phpunit: ^11.5.1
Conflicts
- symfony/console: >=8.0
- symfony/event-dispatcher: >=8.0
- symfony/filesystem: >=8.0
- symfony/finder: >=8.0
- symfony/options-resolver: >=8.0
- symfony/process: >=8.0
- symfony/stopwatch: >=8.0
- symfony/string: >=8.0
- symfony/type-info: >=8.0
- dev-main
- v1.8.0
- 1.4.0
- 0.1.0
- dev-develop
- dev-chore/update-composer-files
- dev-release/1.8.0
- dev-feature/add-request-response-hooks
- dev-release/1.7.0
- dev-release/1.5.0
- dev-release/1.4.0
- dev-release/1.3.1
- dev-release/1.3.0
- dev-release/1.2.1
- dev-release/1.2.0
- dev-release/1.1.0
- dev-release/1.0.1
- dev-release/1.0.0
- dev-release/0.1.0
- dev-innovation_day_implementation
This package is auto-updated.
Last update: 2026-04-01 10:48:22 UTC
README
- A convenient PHP wrapper around API calls and responses:
- marshals PHP request objects to HTTP requests
- unmarshals HTTP responses to PHP response objects or PHP exceptions
- handling of all the details concerning authentication
- handling of required metadata
For a general introduction to the API and various checkout flows, see the documentation: - General introduction to the PAYONE Commerce Platform - Overview of the checkout flows - Available payment methods
Table of Contents
Requirements
This SDK requires PHP 8.2 or later.
Installation
This SDK is currently not released on packagist. You can install it from GitHub by specifying a vcs repository within your composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/PAYONE-GmbH/PCP-ServerSDK-php"
}
],
"require": {
"payone-gmbh/pcp-serversdk-php": "dev-main"
}
}
These snippets specify the main branch, which contains the latest release. You can specify a version by inserting a git tag vX.Y.Z instead of main. Make sure to prepend the git branch or tag with dev-. For an in depth explanation take a look at the Composer documentation.
Usage
General
To use this SDK, you need to construct a CommunicatorConfiguration which encapsulates everything needed to connect to the PAYONE Commerce Platform.
<?php use PayoneCommercePlatform\Sdk\CommunicatorConfiguration; /** @var CommunicatorConfiguration */ $config = new CommunicatorConfiguration( apiKey: getenv('API_KEY'), apiSecret: getenv('API_SECRET'), host: CommunicatorConfiguration::getPredefinedHosts()['prod']['url'], integrator: 'YOUR COMPANY NAME', );
As shown above, you can use CommunicatorConfiguration::getPredefinedHosts() for information on the available environments. With the configuration you can create an API client for each reource you want to interact with. For example to create a commerce case you can use the CommerceCaseApiClient.
<?php use PayoneCommercePlatform\Sdk\ApiClient\CommerceCaseApiClient; $client = new CommerceCaseApiClient($config);
Each client has typed parameters for the payloads and responses. You can use phpstan to verify the types of the parameters and return values or look for TypeError thrown at runtime. All payloads are availble as PHP classes within the PayoneCommercePlatform\Sdk\Models namespace. The SDK will automatically marshal the PHP objects to JSON and send it to the API. The response will be unmarshalled to a PHP object internally.
To create an empty commerce case you can use the CreateCommerceCaseRequest class:
<?php use PayoneCommercePlatform\Sdk\Models\CreateCommerceCaseResponse; use PayoneCommercePlatform\Sdk\Models\CreateCommerceCaseRequest; /** @var CreateCommerceCaseResponse */ $response = $client->createCommerceCase('YOUR_MERCHANT_ID', new CreateCommerceCaseRequest());
The models are directly map to the API as described in the PAYONE Commerce Platform API Reference. For an in depth example you can take a look at the demo app.
Error Handling
When making a request, any client instance may throw a PayoneCommercePlatform\Sdk\Errors\ApiException. There are two subtypes of this exception:
PayoneCommercePlatform\Sdk\Errors\ApiErrorResponseException: This exception is thrown when the API returns an well-formed error response. These errors are provided as an array ofPayoneCommercePlatform\Sdk\Models\APIErrorinstances via thegetErrors()method on the exception. They usually contain useful information about what is wrong in your request or the state of the resource.PayoneCommercePlatform\Sdk\Errors\ApiResponseRetrievalException: This exception is a catch-all exception for any error that cannot be turned into a helpful error response. This includes network errors, malformed responses or other errors that are not directly related to the API.
Client Side
For most payment methods, some information from the client is needed, e.g. payment information given by Apple when a payment via ApplePay suceeds. PAYONE provides client side SDKs which helps you interact the third party payment providers. You can find these SDKs under the Payone GitHub organization. Either way ensure to never store or even send credit card information to your server. The PAYONE Commerce Platform never needs access to the credit card information. The client side is responsible for safely retrieving a credit card token. This token must be used with this SDK.
This SDK makes no assumptions about how networking between the client and your PHP server is handled. If need to serialize a model to JSON or deserialize a client side request from a JSON string to a model you can use the static serializeJson() and deserializeJson() methods on the BaseApiClient class:
<?php use PayoneCommercePlatform\Sdk\ApiClient\BaseApiClient; use PayoneCommercePlatform\Sdk\Models\ApplePay\AppelPayPayment; // to json // make sure to add some useful data $applePayPayment = new ApplePayPayment(); $json = BaseApiClient::serializeJson($model); // ...and back $applePayPaymentRequest = BaseApiClient::deserializeJson($json, ApplePayPayment::class);
As every API clients inherits from BaseApiClient you can use these methods on every client class directly.
<?php use PayoneCommercePlatform\Sdk\ApiClient\PaymentInformationApiClient; use PayoneCommercePlatform\Sdk\Models\AmountOfMoney; $amountOfMoney = new AmountOfMoney(amount: 3199, currencyCode: 'EUR'); PaymentInformationApiClient::serializeJson($amountOfMoney); // returns: // '{ "amount": 3199, currencyCode: "EUR" }'
Apple Pay
When a client successfully makes a payment via ApplePay, it receives a ApplePayPayment. This structure is accessible as a model as PayoneCommercePlatform\Sdk\Models\ApplePay\ApplePayPayment. The model is a direct representation of the ApplePayPayment. You can use the deserializeJson() method to convert a JSON string from a client an ApplePayPayment object.
<?php use PayoneCommercePlatform\Sdk\ApiClient\BaseApiClient; // receive json as a string from the client with your favorite networking library or server framework /** @var string */ $json = getJsonStringFromRequestSomehow(); $applePayPayment = BaseApiClient::deserializeJson($json, ApplePayPayment::class);
You can use the PayoneCommercePlatform\Sdk\Transformer\ApplePayTransformer to map an ApplePayPayment to a MobilePaymentMethodSpecificInput which can be used for payment executions or order requests. The transformer has a static method transformApplePayPaymentToMobilePaymentMethodSpecificInput() which takes an ApplePayPayment and returns a MobilePaymentMethodSpecificInput. The transformer does not check if the reponse is complete. If anything is missing the field will be set to null.
<?php use PayoneCommercePlatform\Sdk\Transformer\ApplePayTransformer; $mobilePaymentMethodSpecificInput = ApplePayTransformer::transformApplePayPaymentToMobilePaymentMethodSpecificInput($applePayPayment);
HTTP Client Customization
The SDK allows you to customize the underlying Guzzle HTTP client used for API requests. This provides flexibility to configure timeouts, add interceptors, set up proxies, implement custom authentication mechanisms, and more.
Overview
HTTP client customization enables you to:
- Configure custom timeouts and connection settings
- Set up proxy servers for corporate environments
- Add custom headers and authentication
- Implement request/response middleware for logging or monitoring
- Configure SSL/TLS settings
- Add retry logic and error handling
Global HTTP Client Configuration
You can set a global HTTP client that will be used by all API clients by passing it to the CommunicatorConfiguration:
<?php use GuzzleHttp\Client; use PayoneCommercePlatform\Sdk\CommunicatorConfiguration; use PayoneCommercePlatform\Sdk\ApiClient\CommerceCaseApiClient; // Create a custom Guzzle client with specific configuration $customHttpClient = new Client([ 'timeout' => 30, 'connect_timeout' => 10, 'verify' => true, 'headers' => [ 'User-Agent' => 'MyApp/1.0' ] ]); // Pass the custom client to the configuration $config = new CommunicatorConfiguration( apiKey: getenv('API_KEY'), apiSecret: getenv('API_SECRET'), host: CommunicatorConfiguration::getPredefinedHosts()['prod']['url'], integrator: 'YOUR COMPANY NAME', httpClient: $customHttpClient ); // All API clients created with this configuration will use the custom HTTP client $commerceCaseClient = new CommerceCaseApiClient($config);
Client-Specific HTTP Client Configuration
You can also set a custom HTTP client for individual API clients, which will override the global configuration:
<?php use GuzzleHttp\Client; use PayoneCommercePlatform\Sdk\ApiClient\CommerceCaseApiClient; // Create a client-specific HTTP client $clientSpecificHttpClient = new Client([ 'timeout' => 60, // Different timeout for this specific client 'proxy' => 'http://proxy.example.com:8080' ]); // Pass the client-specific HTTP client to the API client constructor $commerceCaseClient = new CommerceCaseApiClient($config, $clientSpecificHttpClient); // Or set it after construction $commerceCaseClient->setHttpClient($clientSpecificHttpClient);
Advanced Configuration Examples
HTTP Client with Middleware
<?php use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; // Create a handler stack and add middleware $stack = HandlerStack::create(); // Add logging middleware $stack->push(Middleware::mapRequest(function ($request) { error_log("Making request to: " . $request->getUri()); return $request; })); // Add retry middleware for failed requests $stack->push(Middleware::retry(function ($retries, $request, $response, $exception) { return $retries < 3 && ($exception || ($response && $response->getStatusCode() >= 500)); })); // Create HTTP client with the custom handler stack $httpClientWithMiddleware = new Client([ 'handler' => $stack, 'timeout' => 30, 'headers' => [ 'X-SDK-Version' => '1.3.0' ] ]); $config = new CommunicatorConfiguration( apiKey: getenv('API_KEY'), apiSecret: getenv('API_SECRET'), httpClient: $httpClientWithMiddleware );
Proxy Configuration
<?php use GuzzleHttp\Client; // Configure HTTP client with proxy settings $proxyHttpClient = new Client([ 'proxy' => [ 'http' => 'http://proxy.example.com:8080', 'https' => 'https://proxy.example.com:8080', ], 'timeout' => 30, 'verify' => '/path/to/ca-bundle.crt' // Custom CA bundle ]); $config = new CommunicatorConfiguration( apiKey: getenv('API_KEY'), apiSecret: getenv('API_SECRET'), httpClient: $proxyHttpClient );
Priority Logic
The SDK uses the following priority order when determining which HTTP client to use:
- Client-specific HTTP client (highest priority) - Set via constructor parameter or
setHttpClient()method - Global HTTP client - Set in
CommunicatorConfiguration - Default Guzzle client (lowest priority) - Used when no custom client is configured
This allows you to have a global configuration for most clients while still being able to customize specific clients when needed.
Backward Compatibility
The HTTP client customization feature maintains full backward compatibility:
- Existing code continues to work without any changes
- Default behavior remains unchanged when no custom HTTP client is provided
- All existing tests continue to pass
Common Use Cases
Corporate Environment with Proxy
$corporateClient = new Client([ 'proxy' => getenv('CORPORATE_PROXY'), 'timeout' => 45, 'verify' => '/etc/ssl/certs/ca-certificates.crt' ]);
Development Environment with Debugging
$debugClient = new Client([ 'timeout' => 120, // Longer timeout for debugging 'debug' => true, // Enable debug output 'verify' => false // Disable SSL verification for local testing ]);
Production Environment with Monitoring
$stack = HandlerStack::create(); $stack->push(Middleware::mapRequest(function ($request) { // Log request metrics to monitoring system return $request; })); $productionClient = new Client([ 'handler' => $stack, 'timeout' => 15, 'connect_timeout' => 5 ]);
Authentication Token Retrieval
To interact with certain client-side SDKs (such as the credit card tokenizer), you need to generate a short-lived authentication JWT token for your merchant. This token can be retrieved using the SDK as follows:
<?php use PayoneCommercePlatform\Sdk\ApiClient\AuthenticationApiClient; use PayoneCommercePlatform\Sdk\CommunicatorConfiguration; $apiKey = getenv('API_KEY'); $apiSecret = getenv('API_SECRET'); $merchantId = getenv('MERCHANT_ID'); $config = new CommunicatorConfiguration( apiKey: $apiKey, apiSecret: $apiSecret, integrator: 'YOUR COMPANY NAME' ); $authClient = new AuthenticationApiClient($config); $token = $authClient->getAuthenticationTokens($merchantId); echo "JWT Token: " . $token->getToken() . "\n"; echo "Token ID: " . $token->getId() . "\n"; echo "Created: " . $token->getCreationDate() . "\n"; echo "Expires: " . $token->getExpirationDate() . "\n";
This token can then be used for secure operations such as initializing the credit card tokenizer or other client-side SDKs that require merchant authentication. The token is valid for a limited time (10 minutes) and should be handled securely.
Note: The getAuthenticationTokens method requires a valid merchantId. Optionally, you can provide an X-Request-ID header for tracing requests.
Demo App
This repository contains a demo app that showcases how to implement common use cases, like a Step-by-Step Checkout and an One-Stop-Checkout. For each use case the demo app contains a protected method in the top level class DemoApp. You can run the app to execute the code within in the sandbox API. This is a good way to test, if your setup is correct.
Before running the app ensure you have run composer install and composer dumb-autoload within the demo app directory (./examples/demo-app). By default, all API calls are sent to the pre-production environment of the PAYONE Commerce Platform. Note that the created entities cannot be completely deleted.
You can run it within the demo app directory via php src/DemoApp.php, make sure to provide all necessary environment variables:
API_KEYa valid api key for the PAYONE Commerce PlatformAPI_SECRETa valid api secret for the PAYONE Commerce PlatformMERCHANT_IDthe merchant id which is needed to identify entities, e.g. commerce cases and checkouts, that belong to you.
Contributing
See Contributing
Development
Ensure you have PHP 8.2 or higher installed. You will need composer and xdebug. A pretty version of the coverage report will be placed in coverage, after running composer run-script coverage-report.
Structure of this repository
This repository consists out of the following components:
- The source code of the SDK itself:
/src - The source code of the unit and integration tests (including the examples):
/tests - The source code for demos is located
examples/*. Make sure to runcomposer installandcomposer dumb-autoloadbefore. Within the specific demo before launching it.
Release
This SDK follows semantic versioning (semver). To relase a new version, create a branch release/X.Y.Z and run prepare_release.sh X.Y.Z. The script automatically updates the SDK_VERSION property within the CommunicatorConfiguration class and the version field in the root composer.json, package.json and package-lock.json file. After that the changes are automatically committed and tagged as vX.Y.Z.
After calling the prepare_release.sh script, it is recommended to manually trigger the changelog generation script (which uses conventional-changelog).
-
Conventional Commit Messages:
- Ensure all commit messages follow the conventional commit format, which helps in automatic changelog generation.
- Commit messages should be in the format:
type(scope): subject.
-
Enforcing Commit Messages:
- We enforce conventional commit messages using Lefthook with commitlint.
- This setup ensures that all commit messages are validated before they are committed.
-
Generate Changelog:
- Run the changelog generation script to update the
CHANGELOG.mdfile:npm run changelog
- Review and commit the updated changelog before proceeding with the release.
- Run the changelog generation script to update the
When the release is ready, a PR should be created for release branch. Select develop as the base branch. After merging into develop, merge develop into main.
Optional: Creating a GitHub Release
Once you've pushed your latest changes to the repository, developers can start using the latest version by pulling it from GitHub. However, to make the release more visible and provide detailed release notes, you can optionally create a GitHub release.
- Navigate to the Releases Page: Go to the "Releases" section of your repository on GitHub.
- Draft a New Release: Click "Draft a new release".
- Tag the Release: Select the version tag that corresponds to the commit you want to release (e.g.,
v0.1.0). If the tag doesn't exist, you can create it here. - Release Title: Add a descriptive title for the release (e.g.,
v0.1.0 - Initial Release). - Auto-Generated Release Notes: GitHub can automatically generate release notes based on merged pull requests and commit history. You can review these notes, adjust the content, and highlight important changes.
- Publish the Release: Once you're satisfied with the release notes, click "Publish release".
Creating a GitHub release is optional but beneficial, as it provides additional context and visibility for your users. Developers can then reference this specific release tag in their composer.json file when adding the package as a dependency.
For detailed guidance, refer to the GitHub documentation on managing releases.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Thank you for using our SDK for Online Payments! If you have any questions or need further assistance, feel free to open an issue or contact us.