PHP
The Paysafe PHP SDK is designed to simplify integration with the Paysafe Payments API, providing a type-safe, convenient wrapper around the platform’s RESTful endpoints. It handles the foundational tasks required for secure and reliable API communication, including connection management, authentication, encryption, tokenization, data validation, and exception handling.
Paysafe’s server-side SDKs significantly streamline the integration process, reducing the development effort required to interact with the REST APIs. The PHP SDK is fully compatible with the dependency management tool Composer, enabling seamless inclusion in any PHP-based project. Although integrating the SDK into your payment flows is optional, it offers numerous advantages:
- Comprehensive API coverage: The library encompasses the latest set of APIs, as outlined in our Developer Portal, ensuring compatibility with the most recent features and enhancements.
- Auto-generated models and request structures: The SDK provides pre-defined models and request parameter structures, mitigating the need for manual construction of API payloads and reducing the likelihood of errors.
- Intelligent request handling: The SDK includes built-in mechanisms for automatic request retries, improving resilience and reliability by mitigating transient failures and network-related issues.
- Advanced exception management: The SDK incorporates robust exception-handling mechanisms for API responses, simplifying error detection and recovery while ensuring seamless transaction processing
By leveraging the SDK, you can expedite integration, enhance maintainability, and focus on core business logic rather than low-level API interactions.
The following diagram shows where the SDKs fit into the Paysafe API integration flow:
Before you begin
Contact your business relationship manager or send an email to integrations@paysafe.com for your Merchant Portal credentials.
To obtain the Secret API key from the Merchant Portal:
- Log in to the Merchant Portal.
- Go to Developer > API Keys.
- For the Secret Key, you are required to authenticate once more.
- When the key is revealed, click the Copy icon to copy the API key.
- Your API key will have the format username:password, for example:
MerchantXYZ:B-tst1-0-51ed39e4-312d02345d3f123120881dff9bb4020a89e8ac44cdfdcecd702151182fdc952272661d290ab2e5849e31bb03deede9
Notes:
- Use the same API key for all payment methods.
- The API key is case-sensitive and sent using HTTP Basic Authentication
For more information, see Authentication.
Installation
Requirements
- PHP 7.4 or later
Composer
You can use Composer. Follow the installation instructions if you do not already have Composer installed.
composer require paysafe/paymentsapi-php
In your PHP script, make sure you include the autoloader:
require __DIR__ . '/vendor/autoload.php';
Alternatively, you can download the release from GitHub.
Dependencies
The Paysafe PHP SDK requires the following extensions to work properly:
- Guzzle - HTTP client
- Symfony Serializer - JSON serializer/ deserializer
- mbstring (Multibyte String)
If you use Composer, these dependencies will be handled automatically. If you choose to install manually, you must ensure that these extensions are available.
Guzzle
Guzzle is a microframework that serves as an abstraction layer for PHP HTTP clients, making it easy to send HTTP requests and integrate with web services. It can work with various HTTP handlers, including cURL, PHP's stream wrapper, sockets, and non-blocking libraries like React. By default, Guzzle uses cURL as its HTTP handler.
Standard cURL requires a lot of boilerplate code for HTTP calls, and its syntax is much more verbose than Guzzle's, which offers more concise and readable code.
Features
- Clean, high-level API for handling GET, POST, PUT, and DELETE requests.
- Can send both synchronous and asynchronous requests using the same interface.
- Uses PSR-7 (PHP Standard Recommendation #7) interfaces for requests, responses, and streams. This allows you to utilize other PSR-7 compatible libraries with Guzzle.
- Abstracts the underlying HTTP transport, allowing you to write environment and transport-agnostic code without a hard dependency on cURL, PHP streams, sockets, or non-blocking event loops.
- Automatically throws exceptions for HTTP errors such as 4xx and 5xx, making it easier to catch issues.
- Middleware support for logging, retries, and caching.
- Easier to manage timeouts, authentication, proxies and custom SSL certificates.
Symfony Serializer/ PropertyAccess
Symfony Serializer is more robust than the native PHP function json_encode()for transforming data structures to PHP objects and vice versa. While json_encode() works well for simple data structures and flat arrays or objects with public properties, it struggles with nested objects, private/ protected properties, and advanced control over serialization logic.
Features
- Handles nested objects - deep object graphs, relationships.
- Private/ protected property handling via normalizers & reflection.
- Custom naming strategies - like camelCase in PHP Objects to snake_case in APIs.
mbstring
mbstring provides specific string functions for handling multibyte encodings in PHP. Additionally, mbstring manages character encoding conversion between the possible encoding pairs. It is designed to support Unicode-based encodings, such as UTF-8, as well as many single-byte encodings for ease of use.
Usage
PaysafeClient
The PaysafeClient class serves as the primary entry point for interacting with the Paysafe API. It provides access to various services and methods required to execute specific API requests.
The client can be configured to operate in either the LIVE or TEST environment, depending on your integration needs.
You can instantiate a PaysafeClient using the provided constructor, allowing for flexible and readable client configuration:
$paysafeClient = new PaysafeClient('test_api_key', Environment::TEST);
This PaysafeClient instance will use the default client configuration (connect and response timeouts, automatic retries, proxy & SSL context).
PaysafeClientadditional API client configurations:
$paysafeClient = new PaysafeClient();
$paysafeClient->setApiKey('API Key');
$paysafeClient->setEnvironment(Environment::LIVE);
$paysafeClient->setConnectTimeout(10);
$paysafeClient->setResponseTimeout(10);
$paysafeClient->setMaxAutomaticRetries(5);
$paysafeClient->setProxy("http://custom-proxy:8080");
$paysafeClient->setSslContext([
'cert' => '/path/to/client-cert.pem',
'key' => '/path/to/client-key.pem',
'ca' => '/path/to/ca-cert.pem'
])
If some values are not provided, default values from PaysafeClient will be used.
API Key
The Base64-encoded version of the secret API key is used to authenticate with the Payments API. For more information about obtaining your API Keys, see Before you begin.
Please keep your api key in a safe location, for example, load it from HashiCorp vault or Kubernetes Secrets, etc.
Environment
The environment is used to select the environment for tokenization. The accepted environments are PROD (Paysafe Production environment) and TEST (Paysafe Merchant Test or Sandbox environment).
Do not use real card numbers or other payment instrument details in the Merchant Test environment. Test/ Sandbox is not compliant with Payment Card Industry Data Security Standards (PCI-DSS) and does not protect cardholder/ payee information. Any upload of real cardholder data is strictly prohibited, as described in the Terms of Use.
Automatic retries
The client can be configured to automatically retry GET requests that have failed due to network problems or other unpredictable events. By default, such requests are retried three times, with a maximum of five retries allowed.
Connect and response timeouts
The client can be configured to use the provided connect and response timeouts. Values must be provided in milliseconds. We recommend setting the value cautiously, as some requests may take longer to process.
The default values are:
- 30 seconds for connect timeout
- 60 seconds for response timeout
Proxy
The client allows for custom proxies. A proxy object can be provided directly in the client, or through setters.
First, set up the proxy:
$proxy = 'http://custom-proxy:8080'
Provide the proxy through a PaysafeClient configuration array:
$config = array(
'apiKey' => 'apiKey',
'environment' => 'TEST',
'proxy' => $proxy')
$paysafeClient = new PaysafeClient($config);
Or, provide the proxy through a setter:
$paysafeClient = new PaysafeClient('test_api_key', 'TEST');
$paysafeClient->setProxy($proxy)
Additionally, the proxy can be automatically discerned from system properties:
putenv('http_proxyHost=localhost');
putenv('http_proxyPort=8443');
putenv('http_proxyUser=squid');
putenv('http_proxyPassword=ward');
In both cases, you do not need to provide a specific proxy object to the builder, as PaysafeClient will automatically recognize and use system properties for the proxy.
SSLContext
The client also supports custom SSLContext. For example, custom SSLContext can be created as follows:
$sslOptions = [
'cert' => '/path/to/client-cert.pem',
'key' => '/path/to/client-key.pem',
'ca' => '/path/to/ca-cert.pem'
];
$paysafeClient = new PaysafeClient();
$paysafeClient->setSslContext($sslOptions);
Transaction flows
Check the status of the Payments API
As a first step, you can check the status of the Payments API by calling:
$paysafeClient = new PaysafeClient('API KEY', Environment::TEST);
$monitorResponse = $paysafeClient->monitorService()->monitor();
assertEquals("READY", $monitorResponse->getStatus());
Create a payment handle
The first step in creating a new transaction is to create a payment handle. A payment handle represents tokenized information about the payment method that you set up for a customer. Once the payment handle is created, you can include the paymentHandleToken in a new Payment, Standalone Credit, Original Credit, or Verification request.
To create a payment handle, please use a unique merchant reference number for each request.
$paymentHandleRequest = new PaymeRequest();
$paymentHandleRequestMerchantRefNum(MERCHANT_REF_NUM)
->setTransactionType("PAYMENTS")
->setTransactionType(TransactionType::PAYMENT)
->setAmount(500)
->setCurrencyCode(CurrencyCode::USD)
->setAccountId("1009688230");
// ThreeDs Details
$threeDs = new ThreeDs();
$threeDs->setMerchantUrl("https://api.qa.paysafe.com/checkout/v2/index.html#/desktop")
->setDeviceChannel("BROWSER")
->setMessageCategory("PAYMENT")
->setTransactionIntent(TransactionIntent::CHECK_ACCEPTANCE)
->setAuthenticationPurpose(AuthenticationPurpose::PAYMENT_TRANSACTION);
$orderItemDetails = new OrderItemDetails();
$orderItemDetails->setPreOrderItemAvailabilityDate("2014-01-26")
->setPreOrderPurchaseIndicator("MERCHANDISE_AVAILABLE")
->setReorderItemsIndicator("FIRST_TIME_ORDER")
->setShippingIndicator("SHIP_TO_BILLING_ADDRESS");
$threeDs->setOrderItemDetails($orderItemDetails);
$paymentHandleRequest->setThreeDs($threeDs);
// Card Details
$cardExpiry = new CardExpiry();
$cardExpiry->setMonth(10)
->setYear(10);
$card = new Card();
$card->setCardNum("4000000000001026")
->setCardExpiry($cardExpiry)
->setCvv("111")
->setIssuingCountry("US");
$paymentHandleRequest->setCard($card);
// Billing Details
$billingDetails = new BillingDetails();
$billingDetails->setNickName("Home")
->setStreet("Street name")
->setCity("City Name")
->setState("AL")
->setCountry("US")
->setZip("94404");
$paymentHandleRequest->setBillingDetails($billingDetails);
// Return Links
$returnLinks = [];
$returnLink1 = new ReturnLink();
$returnLink1->setRel('DEFAULT')
->setHref('https://usgaminggamblig.com/payment/return/')
->setMethod('GET');
$returnLinks[] = $returnLink1;
$returnLink2 = new ReturnLink();
$returnLink2->setRel('ON_COMPLETED')
->setHref('https://usgaminggamblig.com/payment/return/success')
->setMethod('GET');
$returnLinks[] = $returnLink2;
$returnLink3 = new ReturnLink();
$returnLink3->setRel('ON_FAILED')
->setHref('https://usgaminggamblig.com/payment/return/failed')
->setMethod('GET');
$returnLinks[] = $returnLink3;
$paymentHandleRequest->setReturnLinks($returnLinks);
// Array initialization for backward compatibility & developer friendliness
$params = array(
'merchantRefNum' => "merchantRefNum",
'transaction' => "PAYMENT",
'amount' => "1250",
'currencyCode' => "BR",
'threeDs' => array(...),
'billingDetails' => array(...),
'card' => array(...),
);
$paymentHandleRequest = new PaymentHandleRequest($params);
$paymentHandleRequest = new PaymentHandleRequest();
$paymentHandleRequest->setMerchantRefNum(MERCHANT_REF_NUM)
->setTransactionType(TransctionType::PAYMENT)
->setTransactionType(PaymentType::SKRILL)
->setAmount(500)
->setCurrencyCode(CurrencyCode::USD)
->setAccountId("1009688230");
// Skrill Details
$skrill = new Skrill();
$skrill->setConsumerId('greg_neteller@mailinator.com')
->setEmailSubject('Payout for XYZ')
->setLanguage('AT')
->setLogoUrl('http://www.paysafe.com/icon.jpg')
->setCountryCode('DE');
$paymentHandleRequest->setSkrill($skrill);
// Billing Details
$billingDetails = new BillingDetails();
$billingDetails->setNickName("Home")
->setStreet("Street name")
->setCity("City Name")
->setState("AL")
->setCountry("US")
->setZip("94404");
$paymentHandleRequest->setBillingDetails($billingDetails);
// Return Links
$returnLinks = [];
$returnLink1 = new ReturnLink();
$returnLink1->setRel('DEFAULT')
->setHref('https://usgaminggamblig.com/payment/return/')
->setMethod('GET');
$returnLinks[] = $returnLink1;
$returnLink2 = new ReturnLink();
$returnLink2->setRel('ON_COMPLETED')
->setHref('https://usgaminggamblig.com/payment/return/success')
->setMethod('GET');
$returnLinks[] = $returnLink2;
$returnLink3 = new ReturnLink();
$returnLink3->setRel('ON_FAILED')
->setHref('https://usgaminggamblig.com/payment/return/failed')
->setMethod('GET');
$returnLinks[] = $returnLink3;
$paymentHandleRequest->setReturnLinks($returnLinks);
After which, you can call the corresponding method to create a payment handle:
try {
$paymentHandle = $paysafeClient->paymentHandleService()->createPaymentHandle(paymentHandleRequest);
}
catch (PaysafeSdkException e) {
echo "PaysafeSDKException: ". $e->getMessage();
}
Process payments
To process a payment, you can create a payment request using the provided builder and submit it:
$merchantDescriptor = new MerchantDescriptor();
$merchantDescriptor->dynamicDescriptor('test')
->phone('1000000000');
$paymentRequest = new PaymentRequest();
$paymentRequest->merchantRefNum('YOUR_UNIQUE_MERCHANT_REF_NUMBER')
->amount(500)
->paymentHandleToken('SC2INoYvSe2MzQuB')
->currencyCode('USD')
->settleWithAuth(false)
->customerIp('127.0.0.1')
->currencyCode('USD')
->merchantDescriptor($merchantDescriptor)
->customerIp('172.0.0.1');
try {
$payment = $paysafeClient->paymentService()->processPayment($paymentRequest);
}
catch (PaysafeSdkException $e) {
echo "PaysafeSDKException: ". $e->getMessage();
}
If you want to authorize and settle the payment in a single request, use settleWithAuthset to true.
If you want to authorize and settle the payment separately, use settleWithAuthset to false.
The returned payment object will include an id, a unique identifier for the payment (whether settled or not). This id can be used to process settlements or refunds.
Process settlements
To process a settlement for a payment request created with settleWithAuth (false), you need to create a settlement request:
$paymentId = $payment->getId();
$settlementRequest = new SettlementRequest();
$settlementRequest->merchantRefNum('YOUR_UNIQUE_MERCHANT_REF_NUMBER')
->amount(500);
try {
$settlement = $paysafeClient->settlementService()->processSettlement($paymentId, $settlementRequest);
} catch (PaysafeSdkException $e) {
echo "PaysafeSDKException: " . $e->getMessage();
}
Process refunds
To process a refund, you need to create a refund request:
$refundRequest = new RefundRequest();
$refundRequest->merchantRefNum('YOUR_UNIQUE_MERCHANT_REF_NUMBER')
->amount(500)
->dupCheck(true);
If the payment was settled immediately, use:
$paymentId = $payment->getId();
If the payment was settled manually, by processing a settlement, use:
$paymentId = $settlement->getId();
Finally, execute the refund request:
try {
$refund = $paysafeClient->refundService()->processRefund($id, $refundRequest);
} catch (PaysafeSdkException $e) {
echo "PaysafeSDKException: " . $e->getMessage();
}
Using undocumented parameters
The Paysafe PHP SDK is strongly typed and designed to support all officially released API fields. However, the Payments API may occasionally include new, undocumented, or experimental properties that are not part of the public API. These properties are typically in a testing phase and may take some time to be reflected in the SDKs.
To use such parameters in classes representing API payloads (for example PaymentHandleRequest), we have provided the additionalParameters field, which can be added one by one or as a complete map.
Request additional parameters
// Add a new additional parameter
public function addAdditionalParameter(string $key, $value): self
{
if ($this->additionalParameters === null) {
$this->additionalParameters = [];
}
$this->additionalParameters[$key] = $value;
return $this;
}
//Add a new additional parameter to the list
public function addAdditionalParameters(array $additionalParameters): self
{
if ($this->additionalParameters === null) {
$this->additionalParameters = [];
}
$this->additionalParameters = array_merge($this->additionalParameters, $additionalParameters);
return $this;
}
Usage
paymentHandleRequest->addAdditionalParameter('booleanParameter', true);
paymentHandleRequest->addAdditionalParameter("arrayParameter",[
'city' => 'London',
'country' => 'United Kingdom',
'phone' => '+2139243'
]);
Request customizations
Besides client-level customizations, the following values can also be customized at the request level:
- automaticRetries
- connectTimeout
- responseTimeout
- simulator header - used only in the TEST environment, for POST, PUT, PATCH, DELETE requests.
To customize a request, provide the RequestOptions object in method calls:
$paymentHandleRequest = new PaymentHandleRequest();
$requestOptions = new RequestOptions();
$requestOptions->setMaxAutomaticRetries(3);
$requestOptions->setConnectTimeout(5);
$requestOptions->setResponseTimeout(10);
$requestOptions->simulator(PaymentSimulator::INTERNAL);
$paysafeClient = new PaysafeClient('API_KEY', Environment::TEST)
$paymentHandle = $paysafeClient->paymentHandleService->createPaymentHandle(paymentHandleRequest, requestOptions);
If one of the values is not provided (in this case, responseTimeout), the value from PaysafeClient will be used.
Exceptions
The Paysafe PHP SDK encapsulates major API errors thrown by the Payments API, providing fine-grained control over exception handling. This abstraction simplifies error management, making it easier to identify, handle, and recover from API failures efficiently. By leveraging structured exception handling, you can navigate errors more effectively, ensuring smoother integration and enhanced application resilience.
Most exceptions in the SDK wrap Paysafe’s API Error object, as explained in the Payments API Reference, providing a standardized and consistent approach to error reporting and resolution.
The Correlation ID included in the exception can be shared with Paysafe for further debugging and issue investigation. This unique identifier allows our support and engineering teams to trace specific requests, analyze failures, and provide quicker resolutions, ensuring efficient troubleshooting and enhanced support responsiveness
All exceptions thrown by the PaysafeClient are subclasses of PaysafeSdkException.php. Specific HTTP response codes or situations are mapped to corresponding exceptions for clearer and more structured error handling:
Exception | Use case |
---|---|
InvalidCredentialsException | 401 HTTP Code |
InvalidRequestException | 400 HTTP Code |
PermissionsException | 403 HTTP Code |
RequestConflictException | 409 HTTP Code |
RequestDeclinedException | 402 HTTP Code |
APIException | 500+ HTTP Code |
APIConnectionException | Not able to connect to Paysafe APIs |
IllegalArgumentException | When any supplied argument is wrong |
PaysafeSdkException | Generic exception |
The following fields may be included in each exception, when available:
- internalCorrelationId - unique ID returned by the Payments API that can be provided to the Paysafe Support team as a reference for investigation.
- code - HTTP status code returned by the Payments API.
- error - contains details about the error, returned by the Payments API.
InvalidCredentialsException
Thrown when the Authentication credentials are wrong. Please revalidate the API key or contact Paysafe for the correct API key.
{
code = 401, // Http Status Code
correlationId ="9a59e6ba-5635-4d1d-8e4e-8c390bb0da34", // Paysafe API Request Correlation ID
error = PaysafeError {
code: 5279 //The error code. Also shown in the X-Application-Status-Code response header
message: "Invalid credentials"
details: ["The authentication credentials are invalid"]
}}
InvalidRequestException
Thrown when the request contains invalid fields, is missing required fields, or has an incorrect request state. Please reverify the API request parameters based on the Error Details provided.
{
code = 400, // Http Status Code
correlationId ="9a59e6ba-5635-4d1d-8e4e-8c390bb0da34", // Paysafe API Request Correlation ID
error = PaysafeError {
code: 5068 //The error code. Also shown in the X-Application-Status-Code response header
message: "Field error(s)"
details: ["Either you submitted a request that is missing a mandatory field or the value of a field does not match the format expected"]
fieldErrors: [{
field: "paymentHandle",
error: "Payment handle provided is not permitted for Payments because of its state"
}]
}}
UnauthorizedException
Thrown when the API cannot be accessed using the provided API key. Please reverify the API key or contact Paysafe support for assistance.
{
code = 403, // Http Status Code
correlationId ="9a59e6ba-5635-4d1d-8e4e-8c390bb0da34", // Paysafe API Request Correlation ID
error = PaysafeError {
code: 5270 //The error code. Also shown in the X-Application-Status-Code response header
message: "Unauthorized access"
details: ["The credentials provided with the request do not have permission to access the data requested"]
}}