diff --git a/.travis.yml b/.travis.yml index 2c574d6a..47a52c8a 100755 --- a/.travis.yml +++ b/.travis.yml @@ -48,6 +48,16 @@ matrix: env: - DEPS=HIGH - LEVEL=UNIT + - name: "php 7.4 (install) - unit" + php: 7.4 + env: + - DEPS=NO + - LEVEL=UNIT + - name: "php 7.4 (update) - unit" + php: 7.4 + env: + - DEPS=HIGH + - LEVEL=UNIT cache: directories: - $HOME/.composer/cache diff --git a/CHANGELOG.md b/CHANGELOG.md index fe4e1008..0c86e36a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.2.7.0][1.2.7.0] + +### Added +* Http headers to debug log. +* PID to debug log. +* PHP7.4 support. +* Handles for automatic testing to examples. + +### Changed +* Update example implementation for Hire Purchase direct debit payment type (FlexiPay® Rate). +* Write log messages from examples to examples\log\example.log instead of error.log. +* Several minor changes. + +### Fix +* Ensure locale strings comply to standard. + ## [1.2.6.0][1.2.6.0] ### Added @@ -364,3 +380,4 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a [1.2.5.0]: https://github.com/heidelpay/heidelpayPHP/compare/1.2.4.0..1.2.5.0 [1.2.5.1]: https://github.com/heidelpay/heidelpayPHP/compare/1.2.5.0..1.2.5.1 [1.2.6.0]: https://github.com/heidelpay/heidelpayPHP/compare/1.2.5.1..1.2.6.0 +[1.2.7.0]: https://github.com/heidelpay/heidelpayPHP/compare/1.2.6.0..1.2.7.0 diff --git a/README.md b/README.md index 5094b82e..db96b851 100755 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ [![PHP 7.1](https://img.shields.io/badge/php-7.1-blue.svg)](http://www.php.net) [![PHP 7.2](https://img.shields.io/badge/php-7.2-blue.svg)](http://www.php.net) [![PHP 7.3](https://img.shields.io/badge/php-7.3-blue.svg)](http://www.php.net) +[![PHP 7.4](https://img.shields.io/badge/php-7.4-blue.svg)](http://www.php.net) ![Logo](https://dev.heidelpay.com/devHeidelpay_400_180.jpg) diff --git a/composer.json b/composer.json index 364df00b..5835fbd4 100755 --- a/composer.json +++ b/composer.json @@ -10,11 +10,11 @@ } ], "require": { - "php": "~7.0.0|~7.1.0|~7.2.0|~7.3.0", + "php": "~7.0.0|~7.1.0|~7.2.0|~7.3.0|~7.4.0", "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^6.5", + "phpunit/phpunit": ">6.5 <8.0", "codacy/coverage": "^1.4", "friendsofphp/php-cs-fixer": "^2.0" }, diff --git a/examples/ExampleDebugHandler.php b/examples/ExampleDebugHandler.php index 7470e992..ed3102cd 100755 --- a/examples/ExampleDebugHandler.php +++ b/examples/ExampleDebugHandler.php @@ -28,12 +28,16 @@ class ExampleDebugHandler implements DebugHandlerInterface { + const LOG_TYPE_APPEND_TO_FILE = 3; + /** * {@inheritDoc} + * + * ATTENTION: Please make sure the destination file is writable. */ public function log(string $message) { - // ATTENTION: Uncomment following line to write debug messages to the error log of your web server. - //error_log($message); + /** @noinspection ForgottenDebugOutputInspection */ + error_log($message . "\n", self::LOG_TYPE_APPEND_TO_FILE, __DIR__ . '/log/example.log'); } } diff --git a/examples/Failure.php b/examples/Failure.php index 6e91d18e..067a06aa 100755 --- a/examples/Failure.php +++ b/examples/Failure.php @@ -29,7 +29,7 @@ -

Failure

+

Failure

There has been an error completing the payment. getPaymentId(); - $_SESSION['PDFLink'] = $authorize->getPDFLink(); // Redirect to the success or failure depending on the state of the transaction if ($authorize->isSuccess()) { diff --git a/examples/HirePurchaseDirectDebit/confirm.php b/examples/HirePurchaseDirectDebit/confirm.php index fb58d3e4..a2620399 100644 --- a/examples/HirePurchaseDirectDebit/confirm.php +++ b/examples/HirePurchaseDirectDebit/confirm.php @@ -24,6 +24,11 @@ * @package heidelpayPHP\examples */ +use heidelpayPHP\examples\ExampleDebugHandler; +use heidelpayPHP\Exceptions\HeidelpayApiException; +use heidelpayPHP\Heidelpay; +use heidelpayPHP\Resources\PaymentTypes\HirePurchaseDirectDebit; + /** Require the constants of this example */ require_once __DIR__ . '/Constants.php'; @@ -33,10 +38,45 @@ session_start(); -$externalOrderId = $_SESSION['externalOrderId'] ?? 'no external order id provided'; -$zgReferenceId = $_SESSION['zgReferenceId'] ?? 'no reference id provided'; -$PDFLink = $_SESSION['PDFLink'] ?? 'no link provided'; +$clientMessage = 'Something went wrong. Please try again later.'; +$merchantMessage = 'Something went wrong. Please try again later.'; + +function redirect($url, $merchantMessage = '', $clientMessage = '') +{ + $_SESSION['merchantMessage'] = $merchantMessage; + $_SESSION['clientMessage'] = $clientMessage; + header('Location: ' . $url); + die(); +} + +$paymentId = $_SESSION['PaymentId'] ?? null; +if ($paymentId === null) { + redirect(FAILURE_URL, 'Payment id is missing!', $clientMessage); +} + +// Catch API errors, write the message to your log and show the ClientMessage to the client. +try { + // Create a heidelpay object using your private key and register a debug handler if you want to. + $heidelpay = new Heidelpay(HEIDELPAY_PHP_PAYMENT_API_PRIVATE_KEY); + $heidelpay->setDebugMode(true)->setDebugHandler(new ExampleDebugHandler()); + $payment = $heidelpay->fetchPayment($paymentId); + + $PDFLink = $payment->getAuthorization()->getPDFLink(); + /** @var HirePurchaseDirectDebit $type */ + $type = $payment->getPaymentType(); + $totalAmount = $type->getTotalAmount(); + $totalPurchaseAmount = $type->getTotalPurchaseAmount(); + $totalInterestAmount = $type->getTotalInterestAmount(); + $currency = $payment->getAmount()->getCurrency(); +} catch (HeidelpayApiException $e) { + $merchantMessage = $e->getMerchantMessage(); + $clientMessage = $e->getClientMessage(); + redirect(FAILURE_URL, $merchantMessage, $clientMessage); +} catch (RuntimeException $e) { + $merchantMessage = $e->getMessage(); + redirect(FAILURE_URL, $merchantMessage, $clientMessage); +} ?> @@ -52,7 +92,6 @@ - @@ -68,10 +107,26 @@

+
+
+ Total Purchase Amount +
+
+ +
+ Total Interest Amount +
+
+ +
+ Total Amount +
+
+
Please download your rate plan here
-
Place order
+
Place order
diff --git a/examples/HirePurchaseDirectDebit/index.php b/examples/HirePurchaseDirectDebit/index.php index e6a4c1fa..4eb83908 100644 --- a/examples/HirePurchaseDirectDebit/index.php +++ b/examples/HirePurchaseDirectDebit/index.php @@ -34,14 +34,12 @@ - - - Heidelpay UI Examples - + + Heidelpay UI Examples - + diff --git a/examples/Pending.php b/examples/Pending.php index 095f1913..f7f0e1b0 100644 --- a/examples/Pending.php +++ b/examples/Pending.php @@ -29,7 +29,7 @@ -

Pending

+

Pending

The payment transaction has been completed, however the payment is pending.
In some cases (e. g. authorization transaction or invoice payments) this is normal.
diff --git a/examples/Success.php b/examples/Success.php index d7f3c0da..22125534 100755 --- a/examples/Success.php +++ b/examples/Success.php @@ -29,7 +29,7 @@ -

Success

+

Success

The payment has been successfully completed. -

+
Try
@@ -76,7 +76,7 @@ You can set a Card type to recurring in order to register it and charge later as well as implement recurring payments. -
+
Try
@@ -88,7 +88,7 @@
-
+
Try
@@ -100,7 +100,7 @@
-
+
Try
@@ -112,7 +112,7 @@
-
+
Try
@@ -124,7 +124,7 @@
-
+
Try
@@ -136,7 +136,7 @@
-
+
Try
@@ -148,7 +148,7 @@
-
+
Try
@@ -160,7 +160,7 @@
-
+
Try
@@ -172,7 +172,7 @@
-
+
Try
@@ -186,7 +186,7 @@ Please refer to the example of Invoice Factoring if you don't want to add the customer via payment form. -
+
Try
@@ -200,7 +200,7 @@ Please refer to the example of Invoice guaranteed if you want to add the customer data withing the payment form. -
+
Try
@@ -213,7 +213,7 @@ You can try authorize and direct charge. -
+
Try
@@ -226,7 +226,7 @@ You can set a Pay Pal type to recurring in order to register it and charge later as well as implement recurring payments. -
+
Try
@@ -238,7 +238,7 @@
-
+
Try
@@ -250,7 +250,7 @@
-
+
Try
@@ -262,7 +262,7 @@
-
+
Try
@@ -274,7 +274,7 @@
-
+
Try
@@ -292,7 +292,7 @@
Documentation
-
+
Try
@@ -309,7 +309,7 @@
Documentation
-
+
Try
diff --git a/examples/log/.gitkeep b/examples/log/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/Constants/ApiResponseCodes.php b/src/Constants/ApiResponseCodes.php index 76392b8c..fc6d5b08 100755 --- a/src/Constants/ApiResponseCodes.php +++ b/src/Constants/ApiResponseCodes.php @@ -66,6 +66,7 @@ class ApiResponseCodes const API_ERROR_AMOUNT_IS_MISSING = 'API.340.200.130'; const API_ERROR_CUSTOMER_DOES_NOT_EXIST = 'API.410.100.100'; const API_ERROR_CUSTOMER_ID_ALREADY_EXISTS = 'API.410.200.010'; + const API_ERROR_ADDRESS_NAME_TO_LONG = 'API.410.200.031'; const API_ERROR_CUSTOMER_CAN_NOT_BE_FOUND = 'API.500.100.100'; const API_ERROR_REQUEST_DATA_IS_INVALID = 'API.500.300.999'; const API_ERROR_RECURRING_PAYMENT_NOT_SUPPORTED = 'API.500.550.004'; diff --git a/src/Heidelpay.php b/src/Heidelpay.php index 500a08e2..828a747c 100755 --- a/src/Heidelpay.php +++ b/src/Heidelpay.php @@ -64,7 +64,7 @@ class Heidelpay implements HeidelpayParentInterface, PaymentServiceInterface, Re const BASE_URL = 'api.heidelpay.com'; const API_VERSION = 'v1'; const SDK_TYPE = 'HeidelpayPHP'; - const SDK_VERSION = '1.2.6.0'; + const SDK_VERSION = '1.2.7.0'; /** @var string $key */ private $key; @@ -97,14 +97,16 @@ class Heidelpay implements HeidelpayParentInterface, PaymentServiceInterface, Re * Construct a new heidelpay object. * * @param string $key The private key your received from your heidelpay contact person. - * @param string $locale The locale of the customer defining defining the translation. + * @param string $locale The locale of the customer defining defining the translation (e.g. 'en-GB' or 'de-DE'). + * + * @link https://docs.heidelpay.com/docs/web-integration#section-localization-and-languages * * @throws RuntimeException A RuntimeException will be thrown if the key is not of type private. */ public function __construct($key, $locale = null) { $this->setKey($key); - $this->locale = $locale; + $this->setLocale($locale); $this->resourceService = new ResourceService($this); $this->paymentService = new PaymentService($this); @@ -158,14 +160,14 @@ public function getLocale() /** * Sets the customer locale. * - * @param string $locale The customer locale to set. - * Refer to the documentation under https://docs.heidelpay.com for a list of supported values. + * @param string|null $locale The customer locale to set. + * Ref. https://docs.heidelpay.com for a list of supported values. * * @return Heidelpay This heidelpay object. */ public function setLocale($locale): Heidelpay { - $this->locale = $locale; + $this->locale = str_replace('_', '-', $locale); return $this; } @@ -1022,7 +1024,7 @@ public function debugLog($message) if ($this->isDebugMode()) { $debugHandler = $this->getDebugHandler(); if ($debugHandler instanceof DebugHandlerInterface) { - $debugHandler->log($message); + $debugHandler->log('(' . (string)(getmypid()) . ') ' . $message); } } } diff --git a/src/Resources/PaymentTypes/BasePaymentType.php b/src/Resources/PaymentTypes/BasePaymentType.php index 6b75aa14..a5ecec47 100755 --- a/src/Resources/PaymentTypes/BasePaymentType.php +++ b/src/Resources/PaymentTypes/BasePaymentType.php @@ -28,6 +28,16 @@ abstract class BasePaymentType extends AbstractHeidelpayResource { + /** + * Return true for invoice types. + * + * @return bool + */ + public function isInvoiceType(): bool + { + return false; + } + // /** diff --git a/src/Resources/PaymentTypes/Invoice.php b/src/Resources/PaymentTypes/Invoice.php index 432c8d58..a2a0aa7c 100755 --- a/src/Resources/PaymentTypes/Invoice.php +++ b/src/Resources/PaymentTypes/Invoice.php @@ -25,8 +25,10 @@ namespace heidelpayPHP\Resources\PaymentTypes; use heidelpayPHP\Traits\CanDirectCharge; +use heidelpayPHP\Traits\IsInvoiceType; class Invoice extends BasePaymentType { use CanDirectCharge; + use IsInvoiceType; } diff --git a/src/Resources/PaymentTypes/InvoiceFactoring.php b/src/Resources/PaymentTypes/InvoiceFactoring.php index 2aff7ac0..d35207ef 100755 --- a/src/Resources/PaymentTypes/InvoiceFactoring.php +++ b/src/Resources/PaymentTypes/InvoiceFactoring.php @@ -25,8 +25,10 @@ namespace heidelpayPHP\Resources\PaymentTypes; use heidelpayPHP\Traits\CanDirectChargeWithCustomer; +use heidelpayPHP\Traits\IsInvoiceType; class InvoiceFactoring extends BasePaymentType { use CanDirectChargeWithCustomer; + use IsInvoiceType; } diff --git a/src/Resources/PaymentTypes/InvoiceGuaranteed.php b/src/Resources/PaymentTypes/InvoiceGuaranteed.php index 71b29a90..2f4a2547 100755 --- a/src/Resources/PaymentTypes/InvoiceGuaranteed.php +++ b/src/Resources/PaymentTypes/InvoiceGuaranteed.php @@ -25,8 +25,10 @@ namespace heidelpayPHP\Resources\PaymentTypes; use heidelpayPHP\Traits\CanDirectChargeWithCustomer; +use heidelpayPHP\Traits\IsInvoiceType; class InvoiceGuaranteed extends BasePaymentType { use CanDirectChargeWithCustomer; + use IsInvoiceType; } diff --git a/src/Services/HttpService.php b/src/Services/HttpService.php index deab41ba..c659321e 100755 --- a/src/Services/HttpService.php +++ b/src/Services/HttpService.php @@ -78,7 +78,7 @@ public function setHttpAdapter(HttpAdapterInterface $httpAdapter): HttpService public function getEnvironmentService(): EnvironmentService { if (!$this->environmentService instanceof EnvironmentService) { - $this->environmentService = new EnvironmentService(); + $this->environmentService = new EnvironmentService(); } return $this->environmentService; } @@ -119,9 +119,10 @@ public function send( $heidelpayObj = $resource->getHeidelpayObject(); // perform request - $url = $this->getEnvironmentUrl($uri); + $url = $this->getEnvironmentUrl($uri); $payload = $resource->jsonSerialize(); - $this->initRequest($heidelpayObj, $url, $payload, $httpMethod); + $headers = $this->composerHttpHeaders($heidelpayObj); + $this->initRequest($url, $payload, $httpMethod, $headers); $httpAdapter = $this->getAdapter(); $response = $httpAdapter->execute(); $responseCode = $httpAdapter->getResponseCode(); @@ -131,7 +132,7 @@ public function send( try { $this->handleErrors($responseCode, $response); } finally { - $this->debugLog($heidelpayObj, $payload, $responseCode, $httpMethod, $url, $response); + $this->debugLog($heidelpayObj, $payload, $headers, $responseCode, $httpMethod, $url, $response); } return $response; @@ -140,31 +141,18 @@ public function send( /** * Initializes and returns the http request object. * - * @param Heidelpay $heidelpay - * @param string $uri - * @param string $payload - * @param string $httpMethod + * @param string $uri + * @param string $payload + * @param string $httpMethod + * @param $httpHeaders * * @throws RuntimeException */ - private function initRequest(Heidelpay $heidelpay, $uri, $payload, $httpMethod) + private function initRequest($uri, $payload, $httpMethod, $httpHeaders) { $httpAdapter = $this->getAdapter(); $httpAdapter->init($uri, $payload, $httpMethod); $httpAdapter->setUserAgent(Heidelpay::SDK_TYPE); - - // Set HTTP-headers - $locale = $heidelpay->getLocale(); - $key = $heidelpay->getKey(); - $httpHeaders = [ - 'Authorization' => 'Basic ' . base64_encode($key . ':'), - 'Content-Type' => 'application/json', - 'SDK-VERSION' => Heidelpay::SDK_VERSION, - 'SDK-TYPE' => Heidelpay::SDK_TYPE - ]; - if (!empty($locale)) { - $httpHeaders['Accept-Language'] = $locale; - } $httpAdapter->setHeaders($httpHeaders); } @@ -185,15 +173,15 @@ private function handleErrors($responseCode, $response) $responseObject = json_decode($response, false); if ($responseCode >= 400 || isset($responseObject->errors)) { - $code = null; - $errorId = null; + $code = null; + $errorId = null; $customerMessage = $code; $merchantMessage = $customerMessage; if (isset($responseObject->errors[0])) { - $errors = $responseObject->errors[0]; + $errors = $responseObject->errors[0]; $merchantMessage = $errors->merchantMessage ?? ''; $customerMessage = $errors->customerMessage ?? ''; - $code = $errors->code ?? ''; + $code = $errors->code ?? ''; } if (isset($responseObject->id)) { $errorId = $responseObject->id; @@ -209,15 +197,24 @@ private function handleErrors($responseCode, $response) /** * @param Heidelpay $heidelpayObj * @param string $payload + * @param mixed $headers * @param int $responseCode * @param string $httpMethod * @param string $url * @param string|null $response */ - public function debugLog(Heidelpay $heidelpayObj, $payload, $responseCode, $httpMethod, string $url, $response) - { + public function debugLog( + Heidelpay $heidelpayObj, + $payload, + $headers, + $responseCode, + $httpMethod, + string $url, + $response + ) { $heidelpayObj->debugLog($httpMethod . ': ' . $url); $writingOperations = [HttpAdapterInterface::REQUEST_POST, HttpAdapterInterface::REQUEST_PUT]; + $heidelpayObj->debugLog('Headers: ' . json_encode($headers, JSON_UNESCAPED_SLASHES)); if (in_array($httpMethod, $writingOperations, true)) { $heidelpayObj->debugLog('Request: ' . $payload); } @@ -250,4 +247,26 @@ private function getEnvironmentUrl($uri): string $envUrl[] = Heidelpay::BASE_URL; return 'https://' . implode('-', $envUrl) . '/' . Heidelpay::API_VERSION . $uri; } + + /** + * @param Heidelpay $heidelpay + * + * @return array + */ + public function composerHttpHeaders(Heidelpay $heidelpay): array + { + $locale = $heidelpay->getLocale(); + $key = $heidelpay->getKey(); + $httpHeaders = [ + 'Authorization' => 'Basic ' . base64_encode($key . ':'), + 'Content-Type' => 'application/json', + 'SDK-VERSION' => Heidelpay::SDK_VERSION, + 'SDK-TYPE' => Heidelpay::SDK_TYPE + ]; + if (!empty($locale)) { + $httpHeaders['Accept-Language'] = $locale; + } + + return $httpHeaders; + } } diff --git a/src/Traits/IsInvoiceType.php b/src/Traits/IsInvoiceType.php new file mode 100644 index 00000000..3d67a0cf --- /dev/null +++ b/src/Traits/IsInvoiceType.php @@ -0,0 +1,36 @@ + + * + * @package heidelpayPHP\Traits + */ +namespace heidelpayPHP\Traits; + +trait IsInvoiceType +{ + /** + * Return true for invoice types. + */ + public function isInvoiceType(): bool + { + return true; + } +} diff --git a/test/integration/CustomerTest.php b/test/integration/CustomerTest.php index cc6d5e0d..d99338ef 100755 --- a/test/integration/CustomerTest.php +++ b/test/integration/CustomerTest.php @@ -369,6 +369,30 @@ public function customerShouldBeFetchedByCustomerIdAndUpdatedIfItAlreadyExists() $this->assertEquals($customer->getId(), $newCustomerData->getId()); } + /** + * Verify customer address can take a name as long as both first and lastname concatenated. + * + * @test + * + * @throws HeidelpayApiException A HeidelpayApiException is thrown if there is an error returned on API-request. + * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK. + */ + public function addressNameCanHoldFirstAndLastNameConcatenated() + { + $customerId = 'customer' . self::generateRandomId(); + $customer = $this->getMaximumCustomerInclShippingAddress()->setCustomerId($customerId); + $longName = 'firstfirstfirstfirstfirstfirstfirstfirst lastlastlastlastlastlastlastlastlastlast'; + $customer->getShippingAddress()->setName($longName); + $this->heidelpay->createCustomer($customer); + $this->assertEquals($longName, $customer->getShippingAddress()->getName()); + + $veryLongName = $longName . 'X'; + $customer->getShippingAddress()->setName($veryLongName); + $this->expectException(HeidelpayApiException::class); + $this->expectExceptionCode(ApiResponseCodes::API_ERROR_ADDRESS_NAME_TO_LONG); + $this->heidelpay->updateCustomer($customer); + } + // // diff --git a/test/integration/ExceptionTest.php b/test/integration/ExceptionTest.php index 82759712..008f359a 100755 --- a/test/integration/ExceptionTest.php +++ b/test/integration/ExceptionTest.php @@ -60,7 +60,7 @@ public function apiExceptionShouldHoldClientMessage() } try { - $this->heidelpay->setLocale('de_DE'); + $this->heidelpay->setLocale('de-DE'); $this->heidelpay->authorize(1.0, 'EUR', $giropay, self::RETURN_URL); } catch (HeidelpayApiException $e) { $this->assertInstanceOf(HeidelpayApiException::class, $e); diff --git a/test/unit/HeidelpayTest.php b/test/unit/HeidelpayTest.php index f393abf8..fc864eaa 100755 --- a/test/unit/HeidelpayTest.php +++ b/test/unit/HeidelpayTest.php @@ -68,11 +68,11 @@ public function constructorShouldInitPropertiesProperly() $this->assertEquals('s-priv-1234', $heidelpay->getKey()); $this->assertEquals(null, $heidelpay->getLocale()); - $heidelpaySwiss = new Heidelpay('s-priv-1234', 'de_CH'); - $this->assertEquals('de_CH', $heidelpaySwiss->getLocale()); + $heidelpaySwiss = new Heidelpay('s-priv-1234', 'de-CH'); + $this->assertEquals('de-CH', $heidelpaySwiss->getLocale()); - $heidelpayGerman = new Heidelpay('s-priv-1234', 'de_DE'); - $this->assertEquals('de_DE', $heidelpayGerman->getLocale()); + $heidelpayGerman = new Heidelpay('s-priv-1234', 'de-DE'); + $this->assertEquals('de-DE', $heidelpayGerman->getLocale()); } /** diff --git a/test/unit/Services/HttpServiceTest.php b/test/unit/Services/HttpServiceTest.php index 71a61b45..712ff2c3 100755 --- a/test/unit/Services/HttpServiceTest.php +++ b/test/unit/Services/HttpServiceTest.php @@ -188,28 +188,44 @@ public function sendShouldLogDebugMessagesIfDebugModeAndHandlerAreSet() { $httpServiceMock = $this->getMockBuilder(HttpService::class)->setMethods(['getAdapter'])->getMock(); - $adapterMock = $this->getMockBuilder(CurlAdapter::class)->setMethods( - ['init', 'setUserAgent', 'setHeaders', 'execute', 'getResponseCode', 'close'] - )->getMock(); + $adapterMock = $this->getMockBuilder(CurlAdapter::class)->setMethods(['init', 'setUserAgent', 'setHeaders', 'execute', 'getResponseCode', 'close'])->getMock(); $adapterMock->method('execute')->willReturn('{"response":"myResponseString"}'); $adapterMock->method('getResponseCode')->willReturnOnConsecutiveCalls('200', '201'); $httpServiceMock->method('getAdapter')->willReturn($adapterMock); $loggerMock = $this->getMockBuilder(DummyDebugHandler::class)->setMethods(['log'])->getMock(); - $loggerMock->expects($this->exactly(5))->method('log')->withConsecutive( + $loggerMock->expects($this->exactly(7))->method('log')->withConsecutive( [ $this->callback( static function ($string) { - return str_replace(['dev-api', 'stg-api'], 'api', $string) === 'GET: https://api.heidelpay.com/v1/my/uri/123'; + return str_replace(['dev-api', 'stg-api'], 'api', $string) === '(' . (string)(getmypid()) . ') GET: https://api.heidelpay.com/v1/my/uri/123'; }) ], - ['Response: (200) {"response":"myResponseString"}'], [ $this->callback( static function ($string) { - return str_replace(['dev-api', 'stg-api'], 'api', $string) === 'POST: https://api.heidelpay.com/v1/my/uri/123'; + $matches = []; + preg_match('/^(?:\([\d]*\) Headers: )({.*})/', $string, $matches); + $elements = json_decode($matches[1], true); + return array_key_exists('Authorization', $elements) && array_key_exists('Content-Type', $elements) && + array_key_exists('SDK-TYPE', $elements) && array_key_exists('SDK-VERSION', $elements); + }) + ], + ['(' . (string)(getmypid()) . ') Response: (200) {"response":"myResponseString"}'], + [ $this->callback( + static function ($string) { + return str_replace(['dev-api', 'stg-api'], 'api', $string) === '(' . (string)(getmypid()) . ') POST: https://api.heidelpay.com/v1/my/uri/123'; + }) + ], + [ $this->callback( + static function ($string) { + $matches = []; + preg_match('/^(?:\([\d]*\) Headers: )({.*})/', $string, $matches); + $elements = json_decode($matches[1], true); + return array_key_exists('Authorization', $elements) && array_key_exists('Content-Type', $elements) && + array_key_exists('SDK-TYPE', $elements) && array_key_exists('SDK-VERSION', $elements); }) ], - ['Request: {"dummyResource": "JsonSerialized"}'], - ['Response: (201) {"response":"myResponseString"}'] + ['(' . (string)(getmypid()) . ') Request: {"dummyResource": "JsonSerialized"}'], + ['(' . (string)(getmypid()) . ') Response: (201) {"response":"myResponseString"}'] ); /** @var DebugHandlerInterface $loggerMock */