Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7e5ab60
Check that files are valid for all supported versions
AJenbo Mar 13, 2024
e428a6e
Correct signature for Trustly_Data_JSONRPCNotificationResponse::setSi…
AJenbo Mar 13, 2024
56319d8
Add missing properties
AJenbo Mar 13, 2024
291b386
Check for basic issues (level 0) with PHPStan
AJenbo Mar 13, 2024
906e85d
Make action command compatible with PHPStan 0.9 (PHP 7.0)
AJenbo Mar 13, 2024
34a2756
Add composer generated files to .gitignore
AJenbo Mar 13, 2024
88d67cd
Correct return type for various methodes with null return
AJenbo Mar 13, 2024
26199d0
Correct number of given argument
AJenbo Mar 13, 2024
c42c90c
Fix error message on openssl_error_string() failure
AJenbo Mar 13, 2024
d7c5f07
Bump PHPStan to level 1
AJenbo Mar 13, 2024
98470b9
Correct signature of nullable arguments
AJenbo Mar 13, 2024
27651cd
Correct args where the name was not specificed correctly
AJenbo Mar 13, 2024
c282e57
Correct missing return types
AJenbo Mar 13, 2024
b9e4626
Correct signature of Trustly_Api::serializeData()
AJenbo Mar 13, 2024
b3cc799
Corrrect signature of Trustly_Api::verifyTrustlySignedResponse()
AJenbo Mar 13, 2024
8b6a01a
Bump PHPStan to level 2
AJenbo Mar 13, 2024
7de88f9
Correct decleration of properties
AJenbo Mar 13, 2024
75fa569
Correct signature of signMerchantRequest
AJenbo Mar 13, 2024
dbc79b0
Make Trustly_Api_Unsigned::call() compatible with Trustly_Api::call()
AJenbo Mar 13, 2024
401f1b7
Bump PHPStan level to 3
AJenbo Mar 13, 2024
d712dd4
defined() to check if const is defined
AJenbo Mar 13, 2024
5d232e8
Fix error message for unknown cURL errors
AJenbo Mar 13, 2024
107a255
Correct signature of Trustly_Data::useMerchantPrivateKey()
AJenbo Mar 13, 2024
b5e867c
Remove redundant cast
AJenbo Mar 13, 2024
e7fb675
Bump PHPStan level to 5
AJenbo Mar 13, 2024
f522115
Add missing types
AJenbo Mar 13, 2024
03b74d5
Correct return type of Trustly_Data::set()
AJenbo Mar 13, 2024
4f72e69
Add return type to Trustly_Api::call()
AJenbo Mar 13, 2024
96a3940
Bump PHPStan level to 6
AJenbo Mar 13, 2024
4f5c963
Correct signature of Trustly_Data::json()
AJenbo Mar 13, 2024
aa26097
Narrow validation of curl_exec()
AJenbo Mar 13, 2024
27fff7d
Bump PHPStan level to 8
AJenbo Mar 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/Lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Lint

on:
push:
branches:
- master
pull_request:
types: [opened, synchronize]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer:v2

- name: Lint
run: |
error=0
for file in $(find Trustly -type f -name "*.php"); do
php -l -n $file | grep -v "No syntax errors detected" && error=1
done
if [ $error -eq 1 ]; then
echo "Syntax errors were found."
exit 1
else
echo "No syntax errors were detected."
fi

- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cache/composer/files
key: ${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ matrix.php }}-

- name: Check dependencies
run: composer install

- name: PHPStan
if: ${{ startsWith(matrix.php, '7.') || startsWith(matrix.php, '8.') }}
run: |
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyze Trustly --no-progress --level 7
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
example/var/
/vendor
/composer.lock
75 changes: 44 additions & 31 deletions Trustly/Api/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ abstract class Trustly_Api {
*
* @var string FQHN
*/
protected $api_host = NULL;
protected $api_host;
/**
* API port used for communication.
*
* @var integer Normally either 443 (https) or 80 (http)
*/
protected $api_port = NULL;
protected $api_port;
/**
* Inidicator wether the API host is communicating using https
*
Expand All @@ -63,10 +63,13 @@ abstract class Trustly_Api {
*
* @see Trustly_Api::getLastRequest()
*
* @var array Last API call in data form.
* @var ?Trustly_Data_Request Last API call in data form.
*/
public $last_request = NULL;

/** @var mixed */
public $trustly_publickey = NULL;

/**
* API Constructor
*
Expand All @@ -89,9 +92,9 @@ abstract class Trustly_Api {
public function __construct($host='trustly.com', $port=443, $is_https=TRUE) {
$this->api_is_https = $is_https;

if($this->loadTrustlyPublicKey($host, $port, $is_https) === FALSE) {
if($this->loadTrustlyPublicKey($host, $port) === FALSE) {
$error = openssl_error_string();
throw new InvalidArgumentException("Cannot load Trustly public key file for host $host".(isset($error)?", error $error":''));
throw new InvalidArgumentException("Cannot load Trustly public key file for host $host".($error?", error $error":''));
}

/* Make sure the curl extension is loaded so we can open URL's */
Expand Down Expand Up @@ -139,9 +142,9 @@ public function loadTrustlyPublicKey($host, $port) {
*
* @link https://eu.developers.trustly.com/doc/reference/authentication
*
* @param array $data Input data to serialize
* @param mixed $data Input data to serialize
*
* @return array The input data in a serialized form
* @return string The input data in a serialized form
*/
public function serializeData($data) {
if(is_array($data)) {
Expand All @@ -167,13 +170,13 @@ public function serializeData($data) {
*
* @link https://eu.developers.trustly.com/doc/reference/authentication
*
* @param string $method Method in the API call
* @param ?string $method Method in the API call
*
* @param string $uuid UUID in the API call
* @param ?string $uuid UUID in the API call
*
* @param string $signature in the API call
* @param ?string $signature in the API call
*
* @param array $data in the API call
* @param mixed $data in the API call
*
* @return boolean Indicating wether or not the host key was used for
* signing this data.
Expand Down Expand Up @@ -204,7 +207,7 @@ protected function verifyTrustlySignedData($method, $uuid, $signature, $data) {
* Trustly_Data_Response) has been signed with the correct key when
* originating from the host
*
* @param Trustly_Data_Response $response Response from the API call.
* @param Trustly_Data_JSONRPCSignedResponse $response Response from the API call.
*
* @return boolean Indicating if the data was indeed properly signed by the
* API we think we are talking to
Expand All @@ -223,7 +226,7 @@ public function verifyTrustlySignedResponse($response) {
* Trustly_Data_JSONRPCNotificationRequest) has been signed with the
* correct key originating from the host
*
* @param Trustly_Data_JSONRPCNotificationRequest incoming notification
* @param Trustly_Data_JSONRPCNotificationRequest $notification incoming notification
*
* @return boolean Indicating if the data was indeed properly signed by the
* API we think we are talking to
Expand All @@ -243,15 +246,17 @@ public function verifyTrustlySignedNotification($notification) {
* @throws InvalidArgumentException If the public key for the API host
* cannot be loaded.
*
* @param string $host API host used for communication. Fully qualified
* @param ?string $host API host used for communication. Fully qualified
* hostname. When integrating with our public API this is typically
* either 'test.trustly.com' or 'trustly.com'. NULL means do not change.
*
* @param integer $port Port on API host used for communicaiton. Normally
* @param ?integer $port Port on API host used for communicaiton. Normally
* 443 for https, or 80 for http. NULL means do not change.
*
* @param bool $is_https Indicator wether the port on the API host expects
* @param ?bool $is_https Indicator wether the port on the API host expects
* https. NULL means do not change.
*
* @return void
*/
public function setHost($host=NULL, $port=NULL, $is_https=NULL) {
if(!isset($host)) {
Expand All @@ -264,7 +269,7 @@ public function setHost($host=NULL, $port=NULL, $is_https=NULL) {

if($this->loadTrustlyPublicKey($host, $port) === FALSE) {
$error = openssl_error_string();
throw new InvalidArgumentException("Cannot load Trustly public key file for host $host".(isset($error)?", error $error":''));
throw new InvalidArgumentException("Cannot load Trustly public key file for host $host".($error?", error $error":''));
}

if(isset($is_https)) {
Expand All @@ -275,11 +280,11 @@ public function setHost($host=NULL, $port=NULL, $is_https=NULL) {
/**
* Setup and return a curl handle for submitting data to the API peer.
*
* @param string $url The URL to communicate with
* @param ?string $url The URL to communicate with
*
* @param string $postdata The (optional) data to post.
* @param ?string $postdata The (optional) data to post.
*
* @return Array($body, $response_code)
* @return array{string, int} Array($body, $response_code)
*/
public function post($url=NULL, $postdata=NULL) {
/* Do note that that if you are going to POST JSON you need to set the
Expand All @@ -295,13 +300,13 @@ public function post($url=NULL, $postdata=NULL) {
curl_setopt($curl, CURLOPT_PORT, $this->api_port);

if($this->api_is_https) {
if(@CURLOPT_PROTOCOLS != 'CURLOPT_PROTOCOLS') {
if(defined('CURLOPT_PROTOCOLS')) {
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
}
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE);
} else {
if(@CURLOPT_PROTOCOLS != 'CURLOPT_PROTOCOLS') {
if(defined('CURLOPT_PROTOCOLS')) {
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP);
}
}
Expand All @@ -313,9 +318,9 @@ public function post($url=NULL, $postdata=NULL) {
curl_setopt($curl, CURLOPT_URL, $url);

$body = curl_exec($curl);
if($body === FALSE) {
if(!is_string($body)) {
$error = curl_error($curl);
if($error === NULL) {
if(!$error) {
$error = 'Failed to connect to the Trusly API';
}
throw new Trustly_ConnectionException($error);
Expand Down Expand Up @@ -378,7 +383,7 @@ public function post($url=NULL, $postdata=NULL) {
/**
* Return a properly formed url to communicate with this API.
*
* @return URL pointing to the API peer.
* @return string URL pointing to the API peer.
*/
public function baseURL() {
if($this->api_is_https) {
Expand All @@ -392,9 +397,9 @@ public function baseURL() {
/**
* Return a URL to the API to the given request path.
*
* @param Trustly_Data_Request $request Data to send in the request
* @param ?Trustly_Data_Request $request Data to send in the request
*
* @return URL to the API peer with the given query path.
* @return string URL to the API peer with the given query path.
*/
public function url($request=NULL) {
return $this->baseURL() . $this->urlPath($request);
Expand All @@ -404,7 +409,7 @@ public function url($request=NULL) {
/**
* Return the last request that we attempted to make via this API
*
* @return array Last request data structure.
* @return ?Trustly_Data_Request Last request data structure.
*/
public function getLastRequest() {
return $this->last_request;
Expand Down Expand Up @@ -465,6 +470,7 @@ public function notificationResponse($request, $success=TRUE) {
*
* @param Trustly_Data_Request $request Outgoing data request.
*
* @return Trustly_Data_JSONRPCResponse
*/
public function call($request) {
if($this->insertCredentials($request) !== TRUE) {
Expand All @@ -473,6 +479,9 @@ public function call($request) {
$this->last_request = $request;

$jsonstr = $request->json();
if($jsonstr === FALSE) {
throw new Trustly_DataException('Unable to json encode payload');
}

$url = $this->url($request);
list($body, $response_code) = $this->post($url, $jsonstr);
Expand All @@ -484,9 +493,9 @@ public function call($request) {
/**
* Return a boolean value formatted for communicating with the API.
*
* @param boolean $value Boolean value to encode
* @param ?boolean $value Boolean value to encode
*
* @return API encoded boolean value
* @return ?string API encoded boolean value
*/
protected function apiBool($value) {
if(isset($value)) {
Expand All @@ -506,7 +515,7 @@ protected function apiBool($value) {
*
* See specific class implementing the call for more information.
*
* @param Trustly_Data_Request $request Data to send in the request
* @param ?Trustly_Data_Request $request Data to send in the request
*
* @return string The URL path
*/
Expand All @@ -524,6 +533,8 @@ abstract protected function urlPath($request=NULL);
* @param string $body The body recieved in response to the request
*
* @param integer $response_code the HTTP response code for the call
*
* @return Trustly_Data_JSONRPCResponse
*/
abstract protected function handleResponse($request, $body, $response_code);

Expand All @@ -535,6 +546,8 @@ abstract protected function handleResponse($request, $body, $response_code);
*
* @param Trustly_Data_Request $request Request to be used in the outgoing
* call
*
* @return bool
*/
abstract protected function insertCredentials($request);

Expand Down
Loading