diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 0937d477..21431622 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -1,15 +1,15 @@ in(__DIR__.'/src') - ->in(__DIR__.'/test'); + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/test'); $config = new PhpCsFixer\Config(); return $config ->setUsingCache(false) ->setRules( array( - '@PSR2' => true, + '@PSR12' => true, 'no_blank_lines_after_phpdoc' => true, 'phpdoc_add_missing_param_annotation' => true, 'native_function_casing' => true, @@ -21,11 +21,11 @@ 'multiline_whitespace_before_semicolons' => true, 'no_singleline_whitespace_before_semicolons' => true, 'no_spaces_around_offset' => true, - 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_comma_in_singleline' => true, 'no_unused_imports' => true, 'normalize_index_brace' => true, 'phpdoc_align' => true, 'phpdoc_separation' => true, ) ) - ->setFinder($finder); \ No newline at end of file + ->setFinder($finder); diff --git a/CHANGELOG.md b/CHANGELOG.md index fa002924..a6b61392 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ 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). +## [3.3.0](https://github.com/unzerdev/php-sdk/compare/3.2.0..3.3.0) +### Added +* Chargeback transaction type. + * Add class `\UnzerSDK\Resources\TransactionTypes\Chargeback`. + * Add methods `\UnzerSDK\Unzer::fetchChargeback` and `\UnzerSDK\Unzer::fetchChargebackById` to fetch chargeback information. +* Add `\UnzerSDK\Resources\PaymentTypes\PayU` payment type. +* Add example for PayU payment type. + ## [3.2.0](https://github.com/unzerdev/php-sdk/compare/3.1.0..3.2.0) ### Added diff --git a/examples/PayU/Constants.php b/examples/PayU/Constants.php new file mode 100644 index 00000000..9fd1ff03 --- /dev/null +++ b/examples/PayU/Constants.php @@ -0,0 +1,28 @@ +setDebugMode(true)->setDebugHandler(new ExampleDebugHandler()); + + // Create a charge transaction to get the redirectUrl. + $transaction = new \UnzerSDK\Resources\TransactionTypes\Charge(12.32, 'PLN', RETURN_CONTROLLER_URL); + $unzer->performCharge($transaction, $paymentTypeId); + + // You'll need to remember the paymentId for later in the ReturnController + $_SESSION['PaymentId'] = $transaction->getPaymentId(); + $_SESSION['ShortId'] = $transaction->getShortId(); + + // Redirect to the PayU page + if (!$transaction->isError() && $transaction->getRedirectUrl() !== null) { + redirect($transaction->getRedirectUrl()); + } + + // Check the result message of the charge to find out what went wrong. + $merchantMessage = $transaction->getMessage()->getCustomer(); +} catch (UnzerApiException $e) { + $merchantMessage = $e->getMerchantMessage(); + $clientMessage = $e->getClientMessage(); +} catch (RuntimeException $e) { + $merchantMessage = $e->getMessage(); +} +redirect(FAILURE_URL, $merchantMessage, $clientMessage); diff --git a/examples/PayU/index.php b/examples/PayU/index.php new file mode 100644 index 00000000..ec92b301 --- /dev/null +++ b/examples/PayU/index.php @@ -0,0 +1,87 @@ + + + + + + + Unzer UI Examples + + + + + + + + +

Click here to open our test data in new tab.

+ +
+
+
+ +
+
+ + + + diff --git a/examples/index.php b/examples/index.php index 8022e363..da0dfd20 100755 --- a/examples/index.php +++ b/examples/index.php @@ -295,6 +295,18 @@ function printMessage($type, $title, $text) Try +
+
+
+ PayU +
+
+
+
+
+ Try +
+
diff --git a/phpunit.xml b/phpunit.xml index 58ad4061..df900576 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,5 +1,6 @@ - + verbose="true" + xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> + + + src/ + + disabled skip - - - src/ - - - \ No newline at end of file + diff --git a/src/Adapter/ApplepayAdapter.php b/src/Adapter/ApplepayAdapter.php index df936cf8..c458d64f 100644 --- a/src/Adapter/ApplepayAdapter.php +++ b/src/Adapter/ApplepayAdapter.php @@ -1,4 +1,5 @@ - /** * Returns the API name of the resource. * @@ -220,10 +220,6 @@ public function getAdditionalAttributes() return $this->additionalAttributes; } - // - - // - /** * {@inheritDoc} */ @@ -258,7 +254,7 @@ public function getUri(bool $appendId = true, string $httpMethod = HttpAdapterIn /** * This method updates the properties of the resource. * - * @param $object + * @param $object * @param stdClass $response */ private static function updateValues($object, stdClass $response): void @@ -292,10 +288,6 @@ private static function updateValues($object, stdClass $response): void } } - // - - // - /** * @return ResourceService * @@ -334,10 +326,6 @@ protected function fetchResource(AbstractUnzerResource $resource): void $this->getResourceService()->fetchResource($resource); } - // - - // - /** * Specify data which should be serialized to JSON * @@ -436,10 +424,6 @@ private static function setItemProperty($item, $key, $value): void } } - // - - // - /** * Return the resources which should be referenced by ID within the resource section of the resource data. * Override this to define the linked resources. @@ -500,8 +484,6 @@ public function getExternalId(): ?string return null; } - ///** - /** * Exposes properties * diff --git a/src/Resources/Basket.php b/src/Resources/Basket.php index 2ca18544..c6b75d1d 100755 --- a/src/Resources/Basket.php +++ b/src/Resources/Basket.php @@ -20,11 +20,13 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; use UnzerSDK\Resources\EmbeddedResources\BasketItem; use stdClass; + use function count; class Basket extends AbstractUnzerResource @@ -62,7 +64,7 @@ class Basket extends AbstractUnzerResource /** @var string $note */ protected $note; - /** @var array $basketItems */ + /** @var BasketItem[] $basketItems */ private $basketItems; /** @@ -87,8 +89,6 @@ public function __construct( $this->setBasketItems($basketItems); } - // - /** * @return float * @@ -292,10 +292,6 @@ public function getBasketItemByIndex(int $index): ?BasketItem return $this->basketItems[$index] ?? null; } - // - - // - /** * Add the dynamically set meta data. * {@inheritDoc} @@ -362,6 +358,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI $this->setBasketItems($items); } } - - // } diff --git a/src/Resources/Customer.php b/src/Resources/Customer.php index fb84e5fc..e4b7c884 100755 --- a/src/Resources/Customer.php +++ b/src/Resources/Customer.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -28,6 +29,7 @@ use UnzerSDK\Resources\EmbeddedResources\CompanyInfo; use UnzerSDK\Traits\HasGeoLocation; use stdClass; + use function in_array; class Customer extends AbstractUnzerResource @@ -82,8 +84,6 @@ public function __construct() $this->shippingAddress = new Address(); } - // - /** * @return string|null */ @@ -332,10 +332,6 @@ public function setLanguage(?string $language): Customer return $this; } - // - - // - /** * {@inheritDoc} */ @@ -344,10 +340,6 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE return 'customers'; } - // - - // - /** * {@inheritDoc} */ diff --git a/src/Resources/CustomerFactory.php b/src/Resources/CustomerFactory.php index 449fecea..c0a2c043 100644 --- a/src/Resources/CustomerFactory.php +++ b/src/Resources/CustomerFactory.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Constants\CompanyCommercialSectorItems; diff --git a/src/Resources/EmbeddedResources/Address.php b/src/Resources/EmbeddedResources/Address.php index 4e3f08f8..3edef11b 100755 --- a/src/Resources/EmbeddedResources/Address.php +++ b/src/Resources/EmbeddedResources/Address.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -47,8 +48,6 @@ class Address extends AbstractUnzerResource /** @var string|null shippingType */ protected $shippingType; - // - /** * @return string|null */ @@ -181,6 +180,4 @@ public function setShippingType(?string $shippingType): Address $this->shippingType = $shippingType; return $this; } - - // } diff --git a/src/Resources/EmbeddedResources/Amount.php b/src/Resources/EmbeddedResources/Amount.php index 138b1908..c3fb4b3a 100755 --- a/src/Resources/EmbeddedResources/Amount.php +++ b/src/Resources/EmbeddedResources/Amount.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -34,8 +35,6 @@ class Amount extends AbstractUnzerResource /** @var string $currency */ private $currency; - // - /** * @return float */ @@ -130,6 +129,4 @@ protected function setCurrency(string $currency): self $this->currency = $currency; return $this; } - - // } diff --git a/src/Resources/EmbeddedResources/ApplePayHeader.php b/src/Resources/EmbeddedResources/ApplePayHeader.php index 4cbea510..49df710d 100644 --- a/src/Resources/EmbeddedResources/ApplePayHeader.php +++ b/src/Resources/EmbeddedResources/ApplePayHeader.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; diff --git a/src/Resources/EmbeddedResources/BasketItem.php b/src/Resources/EmbeddedResources/BasketItem.php index 75fb3d3f..3eee5442 100755 --- a/src/Resources/EmbeddedResources/BasketItem.php +++ b/src/Resources/EmbeddedResources/BasketItem.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -113,8 +114,6 @@ public function __construct( $this->setAmountPerUnit($amountPerUnit); } - // - /** * @return string|null */ @@ -422,6 +421,4 @@ public function setType(?string $type): BasketItem $this->type = $type; return $this; } - - // } diff --git a/src/Resources/EmbeddedResources/CardDetails.php b/src/Resources/EmbeddedResources/CardDetails.php index 0f401238..eade4175 100644 --- a/src/Resources/EmbeddedResources/CardDetails.php +++ b/src/Resources/EmbeddedResources/CardDetails.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -47,8 +48,6 @@ class CardDetails extends AbstractUnzerResource /** @var string|null $issuerPhoneNumber */ protected $issuerPhoneNumber; - // - /** * @return string|null */ @@ -181,6 +180,4 @@ protected function setIssuerPhoneNumber(?string $issuerPhoneNumber): CardDetails $this->issuerPhoneNumber = $issuerPhoneNumber; return $this; } - - // } diff --git a/src/Resources/EmbeddedResources/CardTransactionData.php b/src/Resources/EmbeddedResources/CardTransactionData.php index 62cf8f2d..05e6710b 100644 --- a/src/Resources/EmbeddedResources/CardTransactionData.php +++ b/src/Resources/EmbeddedResources/CardTransactionData.php @@ -22,6 +22,7 @@ * @package UnzerSDK * */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; diff --git a/src/Resources/EmbeddedResources/CompanyInfo.php b/src/Resources/EmbeddedResources/CompanyInfo.php index 32870a2e..b841ce8c 100644 --- a/src/Resources/EmbeddedResources/CompanyInfo.php +++ b/src/Resources/EmbeddedResources/CompanyInfo.php @@ -20,11 +20,13 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Constants\CompanyCommercialSectorItems; use UnzerSDK\Resources\AbstractUnzerResource; use stdClass; + use function is_string; class CompanyInfo extends AbstractUnzerResource @@ -47,8 +49,6 @@ class CompanyInfo extends AbstractUnzerResource /** @var CompanyOwner|null $owner */ protected $owner; - // - /** * @return string|null */ @@ -164,10 +164,6 @@ public function setOwner(?CompanyOwner $owner): CompanyInfo return $this; } - // - - // - /** * Create instances of necessary properties to handle API responses. * @@ -182,10 +178,6 @@ public function instantiateObjectsFromResponse(stdClass $response): void } } - // - - // - /** * Removes some restricted symbols from the given value. * @@ -201,6 +193,4 @@ private function removeRestrictedSymbols(?string $value) return str_replace(['<', '>'], '', $value); } - - // } diff --git a/src/Resources/EmbeddedResources/CompanyOwner.php b/src/Resources/EmbeddedResources/CompanyOwner.php index 6d185cb1..d06edb18 100644 --- a/src/Resources/EmbeddedResources/CompanyOwner.php +++ b/src/Resources/EmbeddedResources/CompanyOwner.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -35,8 +36,6 @@ class CompanyOwner extends AbstractUnzerResource /** @var string|null $birthdate */ protected $birthdate; - // - /** * @return string|null */ @@ -93,6 +92,4 @@ public function setBirthdate(?string $birthdate): CompanyOwner $this->birthdate = $birthdate; return $this; } - - // } diff --git a/src/Resources/EmbeddedResources/GeoLocation.php b/src/Resources/EmbeddedResources/GeoLocation.php index fa9d6762..50b40979 100644 --- a/src/Resources/EmbeddedResources/GeoLocation.php +++ b/src/Resources/EmbeddedResources/GeoLocation.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -32,8 +33,6 @@ class GeoLocation extends AbstractUnzerResource /** @var string|null $countryCode */ private $countryCode; - // - /** * @return string|null */ @@ -81,6 +80,4 @@ protected function setCountryIsoA2(?string $countryCode): GeoLocation { return $this->setCountryCode($countryCode); } - - // } diff --git a/src/Resources/EmbeddedResources/Message.php b/src/Resources/EmbeddedResources/Message.php index 88265ac8..b36e5d78 100755 --- a/src/Resources/EmbeddedResources/Message.php +++ b/src/Resources/EmbeddedResources/Message.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; @@ -35,8 +36,6 @@ class Message extends AbstractUnzerResource /** @var string $merchant */ private $merchant = ''; - // - /** * @return string */ @@ -93,6 +92,4 @@ protected function setMerchant(?string $merchant): Message $this->merchant = $merchant; return $this; } - - // } diff --git a/src/Resources/EmbeddedResources/Paylater/InstallmentPlan.php b/src/Resources/EmbeddedResources/Paylater/InstallmentPlan.php index 79802328..87815ec1 100644 --- a/src/Resources/EmbeddedResources/Paylater/InstallmentPlan.php +++ b/src/Resources/EmbeddedResources/Paylater/InstallmentPlan.php @@ -161,8 +161,6 @@ protected function setInstallmentRates(array $installmentRates): InstallmentPlan return $this; } - // - /** * {@inheritDoc} */ @@ -178,6 +176,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI $this->setInstallmentRates($rates); } } - - // } diff --git a/src/Resources/EmbeddedResources/Paylater/InstallmentRate.php b/src/Resources/EmbeddedResources/Paylater/InstallmentRate.php index 78db53ea..f08875eb 100644 --- a/src/Resources/EmbeddedResources/Paylater/InstallmentRate.php +++ b/src/Resources/EmbeddedResources/Paylater/InstallmentRate.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources\Paylater; class InstallmentRate diff --git a/src/Resources/EmbeddedResources/RiskData.php b/src/Resources/EmbeddedResources/RiskData.php index 8bc5048c..9a964fed 100644 --- a/src/Resources/EmbeddedResources/RiskData.php +++ b/src/Resources/EmbeddedResources/RiskData.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Constants\CustomerGroups; diff --git a/src/Resources/EmbeddedResources/ShippingData.php b/src/Resources/EmbeddedResources/ShippingData.php index cc650bb0..5b1e37b1 100644 --- a/src/Resources/EmbeddedResources/ShippingData.php +++ b/src/Resources/EmbeddedResources/ShippingData.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources\EmbeddedResources */ + namespace UnzerSDK\Resources\EmbeddedResources; use UnzerSDK\Resources\AbstractUnzerResource; diff --git a/src/Resources/InstalmentPlan.php b/src/Resources/InstalmentPlan.php index 4e2298f2..7f3cf011 100644 --- a/src/Resources/InstalmentPlan.php +++ b/src/Resources/InstalmentPlan.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use DateTime; @@ -116,8 +117,6 @@ public function __construct( $this->lastRate = $lastRate; } - // - /** * @return string|null */ @@ -404,10 +403,6 @@ protected function setInstallmentRates(array $installmentRates): InstalmentPlan return $this; } - // - - // - /** * {@inheritDoc} */ @@ -436,6 +431,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI $this->setInstallmentRates($rates); } } - - // } diff --git a/src/Resources/InstalmentPlans.php b/src/Resources/InstalmentPlans.php index a44f6070..7dce0df2 100644 --- a/src/Resources/InstalmentPlans.php +++ b/src/Resources/InstalmentPlans.php @@ -22,6 +22,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use DateTime; @@ -65,8 +66,6 @@ public function __construct( $this->setOrderDate($orderDate); } - // - /** * @return float */ @@ -162,10 +161,6 @@ public function setOrderDate($orderDate): InstalmentPlans return $this; } - // - - // - /** * Returns the parameter array containing the values for the query string. * @@ -218,6 +213,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI $this->setPlans($plans); } } - - // } diff --git a/src/Resources/Keypair.php b/src/Resources/Keypair.php index 84d8a169..698ecb3b 100755 --- a/src/Resources/Keypair.php +++ b/src/Resources/Keypair.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -62,8 +63,6 @@ class Keypair extends AbstractUnzerResource /** @var bool $validateBasket */ private $validateBasket; - // - /** * @return string|null */ @@ -263,10 +262,6 @@ protected function setValidateBasket(?bool $validateBasket): Keypair return $this; } - // - - // - /** * @inheritDoc */ @@ -293,6 +288,4 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE { return parent::getResourcePath($httpMethod) . ($this->isDetailed() ? '/types' : ''); } - - // } diff --git a/src/Resources/Metadata.php b/src/Resources/Metadata.php index 2e313559..d78a64fe 100755 --- a/src/Resources/Metadata.php +++ b/src/Resources/Metadata.php @@ -20,13 +20,15 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; +use stdClass; + use function count; use function in_array; use function is_callable; -use stdClass; class Metadata extends AbstractUnzerResource { @@ -35,8 +37,6 @@ class Metadata extends AbstractUnzerResource protected $shopType; protected $shopVersion; - // - /** * @return string|null */ @@ -104,10 +104,6 @@ public function getMetadata(string $name) return $this->metadata[$name] ?? null; } - //> - - // - /** * Add the dynamically set meta data. * {@inheritDoc} @@ -133,6 +129,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI } } } - - // } diff --git a/src/Resources/PaylaterInstallmentPlans.php b/src/Resources/PaylaterInstallmentPlans.php index d9b151e9..b34c6a7e 100644 --- a/src/Resources/PaylaterInstallmentPlans.php +++ b/src/Resources/PaylaterInstallmentPlans.php @@ -22,6 +22,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -71,8 +72,6 @@ public function setAmount(float $amount): PaylaterInstallmentPlans return $this; } - // - /** * @return string */ @@ -167,10 +166,6 @@ protected function getQueryString(): string return '?' . http_build_query($this->getQueryArray()); } - // - - // - /** * Returns the parameter array containing the values for the query string. * @@ -222,6 +217,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI $this->setPlans($plans); } } - - // } diff --git a/src/Resources/Payment.php b/src/Resources/Payment.php index 724e4ccc..80430184 100755 --- a/src/Resources/Payment.php +++ b/src/Resources/Payment.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -34,6 +35,7 @@ use UnzerSDK\Resources\TransactionTypes\Authorization; use UnzerSDK\Resources\TransactionTypes\Cancellation; use UnzerSDK\Resources\TransactionTypes\Charge; +use UnzerSDK\Resources\TransactionTypes\Chargeback; use UnzerSDK\Resources\TransactionTypes\Payout; use UnzerSDK\Resources\TransactionTypes\Shipment; use UnzerSDK\Services\IdService; @@ -65,9 +67,13 @@ class Payment extends AbstractUnzerResource /** @var array $shipments */ private $shipments = []; - /** @var array $charges */ + /** @var Charge[] $charges */ private $charges = []; + /** @var Chargeback[] $chargebacks */ + private $chargebacks = []; + + /** * Associative array using the ID of the cancellations as the key. * @@ -82,6 +88,7 @@ class Payment extends AbstractUnzerResource */ private $refunds = []; + /** @var Customer $customer */ private $customer; @@ -110,8 +117,6 @@ public function __construct($parent = null) $this->setParentResource($parent); } - // - /** * Returns the redirectUrl set by the API. * @@ -135,6 +140,22 @@ protected function setRedirectUrl(?string $redirectUrl): Payment return $this; } + /** + * @return Chargeback[] + */ + public function getChargebacks(): array + { + return $this->chargebacks; + } + + /** + * @param array $chargebacks + */ + public function setChargebacks(array $chargebacks): void + { + $this->chargebacks = $chargebacks; + } + /** * Retrieves the Authorization object of this payment. * Fetches the Authorization if it has not been fetched before and the lazy flag is not set. @@ -231,6 +252,20 @@ public function addCharge(Charge $charge): self return $this; } + /** + * Adds a Charge object to this Payment and stores it in the charges array. + * + * @param Charge $chargeback + * + * @return $this + */ + private function addChargeback(Chargeback $chargeback): self + { + $chargeback->setPayment($this); + $this->chargebacks[] = $chargeback; + return $this; + } + /** * Retrieves a Charge object from the charges array of this Payment object by its Id. * Fetches the Charge if it has not been fetched before and the lazy flag is not set. @@ -259,6 +294,38 @@ public function getCharge(string $chargeId, bool $lazy = false): ?Charge return null; } + /** + * Retrieves a Chargeback object from the chargebacks array of this Payment object by its ID. + * Fetches the Charge if it has not been fetched before and the lazy flag is not set. + * Returns null if the Charge does not exist. + * + * @param string $chargeId The ID of the Charge to be retrieved. + * @param bool $lazy Enables lazy loading if set to true which results in the object not being updated via + * API and possibly containing just the meta data known from the Payment object response. + * + * @return Charge|null The retrieved Charge object or null if it does not exist. + * + * @throws UnzerApiException An UnzerApiException 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 getChargeback(string $chargebackId, ?string $chargeId, bool $lazy = false): ?Chargeback + { + /** @var Chargeback $chargeback */ + foreach ($this->chargebacks as $chargeback) { + $parentResource = $chargeback->getParentResource(); + if ($chargeback->getId() === $chargebackId) { + if ($parentResource instanceof Charge && $parentResource->getId() !== $chargeId) { + continue; + } + if (!$lazy) { + $this->getResource($chargeback); + } + return $chargeback; + } + } + return null; + } + /** * Retrieves a Charge object by its index in the charges array. * Fetches the Charge if it has not been fetched before and the lazy flag is not set. @@ -721,10 +788,6 @@ public function addReversal(Cancellation $reversal): Payment return $this; } - // - - // - /** * {@inheritDoc} */ @@ -764,10 +827,6 @@ public function getExternalId(): ?string return $this->getOrderId(); } - // - - // - /** * Performs a Cancellation transaction on the Payment. * If no amount is given a full cancel will be performed i. e. all Charges and Authorizations will be cancelled. @@ -842,10 +901,6 @@ public function ship(string $invoiceId = null, string $orderId = null) return $this->getUnzerObject()->ship($this, $invoiceId, $orderId); } - // - - // - /** * @param array $transactions * @@ -878,6 +933,9 @@ private function updateResponseTransactions(array $transactions = []): void case TransactionTypes::PAYOUT: $this->updatePayoutTransaction($transaction); break; + case TransactionTypes::CHARGEBACK: + $this->updateChargebackTransaction($transaction); + break; default: // skip break; @@ -1082,5 +1140,46 @@ private function updatePayoutTransaction(stdClass $transaction): void $payout->handleResponse($transaction); } - // + /** + * This updates the local chargeback object referenced by this Payment with the given chargeback transaction from the + * Payment response. + * + * @param stdClass $transaction The transaction from the Payment response containing the chargeback data. + * + * @throws UnzerApiException An UnzerApiException 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. + */ + private function updateChargebackTransaction(stdClass $transaction): void + { + // does chargeback refer to a specific charge transaction + // Get/create charge instance, if yes. + // does chargeback already exist? + // Add chargeback to charge transaction + $isPaymentChargeback = IdService::isPaymentChargeback($transaction->url); + $chargebackId = IdService::getResourceIdFromUrl($transaction->url, IdStrings::CHARGEBACK); + + + if (!$isPaymentChargeback) { + $chargeId = IdService::getResourceIdFromUrl($transaction->url, IdStrings::CHARGE); + $chargeback = $this->getChargeback($chargebackId, $chargeId, true); + $charge = $this->getCharge($chargeId, true); + if (!$chargeback instanceof Chargeback) { + $chargeback = (new Chargeback())->setId($chargebackId); + $this->addChargeback($chargeback); + + if ($charge instanceof Charge) { + $charge->addChargeback($chargeback); + $chargeback->setParentResource($charge); + } + } + } else { + $chargeback = $this->getChargeback($chargebackId, null, true); + if (!$chargeback instanceof Chargeback) { + $chargeback = (new Chargeback())->setId($chargebackId); + $this->addChargeback($chargeback); + } + } + + $chargeback->handleResponse($transaction); + } } diff --git a/src/Resources/PaymentTypes/Alipay.php b/src/Resources/PaymentTypes/Alipay.php index e39f6d99..edb1f35e 100755 --- a/src/Resources/PaymentTypes/Alipay.php +++ b/src/Resources/PaymentTypes/Alipay.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/Applepay.php b/src/Resources/PaymentTypes/Applepay.php index 4a4c4366..ab441431 100644 --- a/src/Resources/PaymentTypes/Applepay.php +++ b/src/Resources/PaymentTypes/Applepay.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use stdClass; @@ -80,8 +81,6 @@ public function __construct( $this->header = $header; } - // - /** * @inheritDoc */ diff --git a/src/Resources/PaymentTypes/Bancontact.php b/src/Resources/PaymentTypes/Bancontact.php index 86a59e16..cb012b9a 100644 --- a/src/Resources/PaymentTypes/Bancontact.php +++ b/src/Resources/PaymentTypes/Bancontact.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/BasePaymentType.php b/src/Resources/PaymentTypes/BasePaymentType.php index 80a438b3..bcc8a5fe 100755 --- a/src/Resources/PaymentTypes/BasePaymentType.php +++ b/src/Resources/PaymentTypes/BasePaymentType.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -47,7 +48,6 @@ public function isInvoiceType(): bool return false; } - // public function supportsDirectPaymentCancel(): bool { return static::SUPPORT_DIRECT_PAYMENT_CANCEL; @@ -76,6 +76,4 @@ public function getTransactionParams(): array { return []; } - - // } diff --git a/src/Resources/PaymentTypes/Card.php b/src/Resources/PaymentTypes/Card.php index 2ae0d1e4..19258907 100755 --- a/src/Resources/PaymentTypes/Card.php +++ b/src/Resources/PaymentTypes/Card.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -77,8 +78,6 @@ public function __construct(?string $number, ?string $expiryDate, string $email $this->setEmail($email); } - // - /** * @return string */ @@ -234,10 +233,6 @@ public function setEmail(?string $email): Card return $this; } - // - - // - /** * Rename internal property names to external property names. * @@ -265,6 +260,4 @@ public function handleResponse(stdClass $response, string $method = HttpAdapterI $this->cardDetails->handleResponse($response->cardDetails); } } - - // } diff --git a/src/Resources/PaymentTypes/EPS.php b/src/Resources/PaymentTypes/EPS.php index 4771d5f2..0133eb99 100755 --- a/src/Resources/PaymentTypes/EPS.php +++ b/src/Resources/PaymentTypes/EPS.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; @@ -31,8 +32,6 @@ class EPS extends BasePaymentType /** @var string $bic */ protected $bic; - // - /** * @return string|null */ @@ -51,6 +50,4 @@ public function setBic(?string $bic): self $this->bic = $bic; return $this; } - - // } diff --git a/src/Resources/PaymentTypes/Giropay.php b/src/Resources/PaymentTypes/Giropay.php index e754c336..6fe470f2 100755 --- a/src/Resources/PaymentTypes/Giropay.php +++ b/src/Resources/PaymentTypes/Giropay.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/Ideal.php b/src/Resources/PaymentTypes/Ideal.php index cc0bd565..193f31b1 100755 --- a/src/Resources/PaymentTypes/Ideal.php +++ b/src/Resources/PaymentTypes/Ideal.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; @@ -31,8 +32,6 @@ class Ideal extends BasePaymentType /** @var string $bic */ protected $bic; - // - /** * @return string|null */ @@ -51,6 +50,4 @@ public function setBic(?string $bic): self $this->bic = $bic; return $this; } - - // } diff --git a/src/Resources/PaymentTypes/InstallmentSecured.php b/src/Resources/PaymentTypes/InstallmentSecured.php index 0f675a22..8363ce25 100644 --- a/src/Resources/PaymentTypes/InstallmentSecured.php +++ b/src/Resources/PaymentTypes/InstallmentSecured.php @@ -77,8 +77,6 @@ public function selectInstalmentPlan(?InstalmentPlan $plan): self return $this; } - // - /** * @return string|null */ @@ -135,6 +133,4 @@ public function setAccountHolder(?string $accountHolder): self $this->accountHolder = $accountHolder; return $this; } - - // } diff --git a/src/Resources/PaymentTypes/Invoice.php b/src/Resources/PaymentTypes/Invoice.php index a1a95cf6..b4e9ab61 100755 --- a/src/Resources/PaymentTypes/Invoice.php +++ b/src/Resources/PaymentTypes/Invoice.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/InvoiceSecured.php b/src/Resources/PaymentTypes/InvoiceSecured.php index 0f0dda03..8107aa3c 100644 --- a/src/Resources/PaymentTypes/InvoiceSecured.php +++ b/src/Resources/PaymentTypes/InvoiceSecured.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectChargeWithCustomer; diff --git a/src/Resources/PaymentTypes/Klarna.php b/src/Resources/PaymentTypes/Klarna.php index 93f9a18e..a36d828d 100644 --- a/src/Resources/PaymentTypes/Klarna.php +++ b/src/Resources/PaymentTypes/Klarna.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; class Klarna extends BasePaymentType diff --git a/src/Resources/PaymentTypes/PIS.php b/src/Resources/PaymentTypes/PIS.php index 981ca6ef..5f58bcb1 100755 --- a/src/Resources/PaymentTypes/PIS.php +++ b/src/Resources/PaymentTypes/PIS.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/PayU.php b/src/Resources/PaymentTypes/PayU.php new file mode 100644 index 00000000..dba121a7 --- /dev/null +++ b/src/Resources/PaymentTypes/PayU.php @@ -0,0 +1,32 @@ +holder = $accountHolder; } - // - /** * @return string|null */ @@ -154,6 +152,4 @@ public function setHolder(?string $holder): self $this->holder = $holder; return $this; } - - // } diff --git a/src/Resources/PaymentTypes/PaylaterInvoice.php b/src/Resources/PaymentTypes/PaylaterInvoice.php index ae0a9f08..4b677a63 100644 --- a/src/Resources/PaymentTypes/PaylaterInvoice.php +++ b/src/Resources/PaymentTypes/PaylaterInvoice.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; class PaylaterInvoice extends BasePaymentType diff --git a/src/Resources/PaymentTypes/Paypage.php b/src/Resources/PaymentTypes/Paypage.php index 3c5d1bdb..24768337 100644 --- a/src/Resources/PaymentTypes/Paypage.php +++ b/src/Resources/PaymentTypes/Paypage.php @@ -21,6 +21,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -40,6 +41,7 @@ use UnzerSDK\Traits\HasOrderId; use RuntimeException; use stdClass; + use function in_array; class Paypage extends BasePaymentType @@ -117,8 +119,6 @@ public function __construct(float $amount, string $currency, string $returnUrl) $this->setReturnUrl($returnUrl); } - // - /** * @return float */ @@ -621,10 +621,6 @@ public function setExemptionType(string $exemptionType): Paypage return $this; } - // - - // - /** * {@inheritDoc} * Change resource path. @@ -720,8 +716,6 @@ public function getLinkedResources(): array ]; } - // - /** * Updates the referenced payment object if it exists and if this is not the payment object itself. * This is called from the crud methods to update the payments state whenever anything happens. diff --git a/src/Resources/PaymentTypes/Paypal.php b/src/Resources/PaymentTypes/Paypal.php index ee5ba4ad..735c02fd 100755 --- a/src/Resources/PaymentTypes/Paypal.php +++ b/src/Resources/PaymentTypes/Paypal.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use RuntimeException; @@ -40,8 +41,6 @@ class Paypal extends BasePaymentType /** @var string|null $email */ protected $email; - // - /** * @return string|null */ @@ -61,8 +60,6 @@ public function setEmail(string $email): Paypal return $this; } - // - /** * Activates recurring payment for Paypal. * diff --git a/src/Resources/PaymentTypes/Prepayment.php b/src/Resources/PaymentTypes/Prepayment.php index 4c7d8470..6cd4a42a 100755 --- a/src/Resources/PaymentTypes/Prepayment.php +++ b/src/Resources/PaymentTypes/Prepayment.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/Przelewy24.php b/src/Resources/PaymentTypes/Przelewy24.php index 85974f6b..61c4da6d 100755 --- a/src/Resources/PaymentTypes/Przelewy24.php +++ b/src/Resources/PaymentTypes/Przelewy24.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/SepaDirectDebit.php b/src/Resources/PaymentTypes/SepaDirectDebit.php index f35659dc..4fff8512 100755 --- a/src/Resources/PaymentTypes/SepaDirectDebit.php +++ b/src/Resources/PaymentTypes/SepaDirectDebit.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; @@ -49,8 +50,6 @@ public function __construct(?string $iban) $this->iban = $iban; } - // - /** * @return string|null */ @@ -107,6 +106,4 @@ public function setHolder(?string $holder): self $this->holder = $holder; return $this; } - - // } diff --git a/src/Resources/PaymentTypes/SepaDirectDebitSecured.php b/src/Resources/PaymentTypes/SepaDirectDebitSecured.php index da2bb1c1..e1394d71 100644 --- a/src/Resources/PaymentTypes/SepaDirectDebitSecured.php +++ b/src/Resources/PaymentTypes/SepaDirectDebitSecured.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectChargeWithCustomer; @@ -49,8 +50,6 @@ public function __construct(?string $iban) $this->iban = $iban; } - // - /** * @return string|null */ @@ -107,6 +106,4 @@ public function setHolder(?string $holder): self $this->holder = $holder; return $this; } - - // } diff --git a/src/Resources/PaymentTypes/Sofort.php b/src/Resources/PaymentTypes/Sofort.php index 504c0473..5f51494d 100755 --- a/src/Resources/PaymentTypes/Sofort.php +++ b/src/Resources/PaymentTypes/Sofort.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/PaymentTypes/Wechatpay.php b/src/Resources/PaymentTypes/Wechatpay.php index 4ea8a085..761d2232 100755 --- a/src/Resources/PaymentTypes/Wechatpay.php +++ b/src/Resources/PaymentTypes/Wechatpay.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\PaymentTypes */ + namespace UnzerSDK\Resources\PaymentTypes; use UnzerSDK\Traits\CanDirectCharge; diff --git a/src/Resources/Recurring.php b/src/Resources/Recurring.php index 95a1f3cf..84b4a1e5 100644 --- a/src/Resources/Recurring.php +++ b/src/Resources/Recurring.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -58,8 +59,6 @@ public function __construct(string $paymentType, string $returnUrl) $this->paymentTypeId = $paymentType; } - // - /** * @return string */ @@ -117,10 +116,6 @@ protected function setRedirectUrl(?string $redirectUrl): Recurring return $this; } - // - - // - /** * {@inheritDoc} */ @@ -134,6 +129,4 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE return implode('/', $parts); } - - // } diff --git a/src/Resources/TransactionTypes/AbstractTransactionType.php b/src/Resources/TransactionTypes/AbstractTransactionType.php index 9ab48503..8e2c9a5c 100755 --- a/src/Resources/TransactionTypes/AbstractTransactionType.php +++ b/src/Resources/TransactionTypes/AbstractTransactionType.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\TransactionTypes */ + namespace UnzerSDK\Resources\TransactionTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -52,13 +53,9 @@ abstract class AbstractTransactionType extends AbstractUnzerResource use HasAdditionalTransactionData; use HasDate; - // /** @var Payment $payment */ private $payment; - // - - // /** * Return the payment property. @@ -108,10 +105,6 @@ public function getRedirectUrl(): ?string return $this->payment->getRedirectUrl(); } - // - - // - /** * {@inheritDoc} * @@ -161,8 +154,6 @@ public function getLinkedResources(): array ]; } - // - /** * Updates the referenced payment object if it exists and if this is not the payment object itself. * This is called from the crud methods to update the payments state whenever anything happens. diff --git a/src/Resources/TransactionTypes/Authorization.php b/src/Resources/TransactionTypes/Authorization.php index 293ccc78..7e445834 100755 --- a/src/Resources/TransactionTypes/Authorization.php +++ b/src/Resources/TransactionTypes/Authorization.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\TransactionTypes */ + namespace UnzerSDK\Resources\TransactionTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -74,8 +75,6 @@ public function __construct(float $amount = null, string $currency = null, strin $this->setReturnUrl($returnUrl); } - // - /** * @return float|null */ @@ -246,10 +245,6 @@ protected function setPDFLink(?string $PDFLink): Authorization return $this; } - // - - // - /** * {@inheritDoc} */ @@ -258,8 +253,6 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE return 'authorize'; } - // - /** * Full cancel of this authorization. * diff --git a/src/Resources/TransactionTypes/Cancellation.php b/src/Resources/TransactionTypes/Cancellation.php index 0a94e9a0..512d77b8 100755 --- a/src/Resources/TransactionTypes/Cancellation.php +++ b/src/Resources/TransactionTypes/Cancellation.php @@ -20,12 +20,14 @@ * * @package UnzerSDK\TransactionTypes */ + namespace UnzerSDK\Resources\TransactionTypes; use UnzerSDK\Adapter\HttpAdapterInterface; use UnzerSDK\Constants\CancelReasonCodes; use UnzerSDK\Resources\Payment; use UnzerSDK\Resources\PaymentTypes\InstallmentSecured; + use function in_array; class Cancellation extends AbstractTransactionType @@ -67,8 +69,6 @@ public function __construct(float $amount = null) $this->setAmount($amount); } - // - /** * Returns the cancellationAmount (equals grossAmount in case of Installment Secured). * @@ -86,7 +86,7 @@ public function getAmount(): ?float * * @return Cancellation */ - public function setAmount(?float $amount): Cancellation + public function setAmount(?float $amount): self { $this->amount = $amount !== null ? round($amount, 4) : null; return $this; @@ -186,10 +186,6 @@ public function setAmountVat(?float $amountVat): Cancellation return $this; } - // - - // - /** * {@inheritDoc} */ @@ -212,6 +208,4 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE { return 'cancels'; } - - // } diff --git a/src/Resources/TransactionTypes/Charge.php b/src/Resources/TransactionTypes/Charge.php index 005b2ca8..5edae7ee 100755 --- a/src/Resources/TransactionTypes/Charge.php +++ b/src/Resources/TransactionTypes/Charge.php @@ -20,12 +20,14 @@ * * @package UnzerSDK\TransactionTypes */ + namespace UnzerSDK\Resources\TransactionTypes; use UnzerSDK\Adapter\HttpAdapterInterface; use UnzerSDK\Exceptions\UnzerApiException; use UnzerSDK\Traits\HasAccountInformation; use UnzerSDK\Traits\HasCancellations; +use UnzerSDK\Traits\HasChargebacks; use UnzerSDK\Traits\HasRecurrenceType; use RuntimeException; @@ -34,6 +36,7 @@ class Charge extends AbstractTransactionType use HasCancellations; use HasRecurrenceType; use HasAccountInformation; + use HasChargebacks; /** @var float $amount */ protected $amount; @@ -64,8 +67,6 @@ public function __construct(float $amount = null, string $currency = null, strin $this->setReturnUrl($returnUrl); } - // - /** * @return float|null */ @@ -185,10 +186,6 @@ public function setCard3ds(?bool $card3ds): Charge return $this; } - // - - // - /** * {@inheritDoc} */ @@ -197,8 +194,6 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE return 'charges'; } - // - /** * Full cancel of this authorization. * Returns the last cancellation object if charge is already canceled. diff --git a/src/Resources/TransactionTypes/Chargeback.php b/src/Resources/TransactionTypes/Chargeback.php new file mode 100644 index 00000000..81831db7 --- /dev/null +++ b/src/Resources/TransactionTypes/Chargeback.php @@ -0,0 +1,110 @@ +setAmount($amount); + } + + /** + * @return float|null + */ + public function getAmount(): ?float + { + return $this->amount; + } + + /** + * Sets the cancellationAmount (equals grossAmount in case of Installment Secured). + * + * @param float|null $amount + * + * @return Cancellation + */ + public function setAmount(?float $amount): self + { + $this->amount = $amount !== null ? round($amount, 4) : null; + return $this; + } + + /** + * @return string + */ + public function getCurrency(): string + { + return $this->currency; + } + + /** + * @param string $currency + */ + public function setCurrency(string $currency): void + { + $this->currency = $currency; + } + + /** + * @return string|null + */ + public function getPaymentReference(): ?string + { + return $this->paymentReference; + } + + /** + * @param string|null $paymentReference + * + * @return Cancellation + */ + public function setPaymentReference(?string $paymentReference): Chargeback + { + $this->paymentReference = $paymentReference; + return $this; + } + + /** + * {@inheritDoc} + */ + protected function getResourcePath(string $httpMethod = HttpAdapterInterface::REQUEST_GET): string + { + return 'chargebacks'; + } +} diff --git a/src/Resources/TransactionTypes/Payout.php b/src/Resources/TransactionTypes/Payout.php index e0fa0fbd..ff32bd7c 100644 --- a/src/Resources/TransactionTypes/Payout.php +++ b/src/Resources/TransactionTypes/Payout.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\TransactionTypes */ + namespace UnzerSDK\Resources\TransactionTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -52,8 +53,6 @@ public function __construct(float $amount = null, string $currency = null, $retu $this->setReturnUrl($returnUrl); } - // - /** * @return float|null */ @@ -130,10 +129,6 @@ public function setPaymentReference($referenceText): Payout return $this; } - // - - // - /** * {@inheritDoc} */ @@ -141,6 +136,4 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE { return 'payouts'; } - - // } diff --git a/src/Resources/TransactionTypes/Shipment.php b/src/Resources/TransactionTypes/Shipment.php index bf524b8f..84599047 100755 --- a/src/Resources/TransactionTypes/Shipment.php +++ b/src/Resources/TransactionTypes/Shipment.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\TransactionTypes */ + namespace UnzerSDK\Resources\TransactionTypes; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -29,8 +30,6 @@ class Shipment extends AbstractTransactionType /** @var float|null $amount */ protected $amount; - // - /** * @return float|null */ @@ -44,16 +43,12 @@ public function getAmount(): ?float * * @return Shipment */ - public function setAmount(?float $amount): Shipment + public function setAmount(?float $amount): self { $this->amount = $amount !== null ? round($amount, 4) : null; return $this; } - // - - // - /** * {@inheritDoc} */ @@ -61,6 +56,4 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE { return 'shipments'; } - - // } diff --git a/src/Resources/Webhook.php b/src/Resources/Webhook.php index a0f19219..d2746ab3 100755 --- a/src/Resources/Webhook.php +++ b/src/Resources/Webhook.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; @@ -44,8 +45,6 @@ public function __construct(string $url = '', string $event = '') $this->event = $event; } - // - /** * @return string|null */ @@ -84,10 +83,6 @@ public function setEvent(string $event): Webhook return $this; } - // - - // - /** * {@inheritDoc} */ @@ -95,6 +90,4 @@ protected function getResourcePath(string $httpMethod = HttpAdapterInterface::RE { return 'webhooks'; } - - // } diff --git a/src/Resources/Webhooks.php b/src/Resources/Webhooks.php index c609f91e..c1076a8d 100755 --- a/src/Resources/Webhooks.php +++ b/src/Resources/Webhooks.php @@ -22,12 +22,14 @@ * * @package UnzerSDK\Resources */ + namespace UnzerSDK\Resources; use UnzerSDK\Adapter\HttpAdapterInterface; use UnzerSDK\Constants\WebhookEvents; use RuntimeException; use stdClass; + use function in_array; class Webhooks extends AbstractUnzerResource @@ -53,8 +55,6 @@ public function __construct(string $url = '', array $eventList = []) $this->eventList = $eventList; } - // - /** * @return string */ @@ -103,8 +103,6 @@ public function getWebhookList(): array return $this->webhooks; } - // - /** * @param stdClass $response * @param string $method diff --git a/src/Services/CancelService.php b/src/Services/CancelService.php index 13a40991..f380ac12 100644 --- a/src/Services/CancelService.php +++ b/src/Services/CancelService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; use RuntimeException; @@ -32,6 +33,7 @@ use UnzerSDK\Resources\TransactionTypes\Cancellation; use UnzerSDK\Resources\TransactionTypes\Charge; use UnzerSDK\Unzer; + use function in_array; use function is_string; @@ -50,8 +52,6 @@ public function __construct(Unzer $unzer) $this->unzer = $unzer; } - //getUnzer()->getResourceService(); } - // - - // - /** * {@inheritDoc} */ @@ -105,10 +101,6 @@ public function cancelAuthorizationByPayment($payment, float $amount = null): Ca return $this->cancelAuthorization($authorization, $amount); } - // - - // - /** * {@inheritDoc} */ @@ -149,10 +141,6 @@ public function cancelCharge( return $cancellation; } - // - - // - /** * {@inheritDoc} */ @@ -350,10 +338,6 @@ public function cancelChargedPayment($payment, ?Cancellation $cancellation = nul return $cancellation; } - // - - // - /** * Throws exception if the passed exception is not to be ignored while cancelling charges or authorization. * @@ -416,6 +400,4 @@ private function calculateMaxReversalAmount(Charge $charge, float $receiptAmount { return round($charge->getAmount() - $receiptAmount - $charge->getCancelledAmount(), 4); } - - // } diff --git a/src/Services/EnvironmentService.php b/src/Services/EnvironmentService.php index e1084fbd..ba9ff512 100755 --- a/src/Services/EnvironmentService.php +++ b/src/Services/EnvironmentService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; use function in_array; diff --git a/src/Services/HttpService.php b/src/Services/HttpService.php index 62fc0ca7..14f6c380 100755 --- a/src/Services/HttpService.php +++ b/src/Services/HttpService.php @@ -29,7 +29,9 @@ use UnzerSDK\Unzer; use UnzerSDK\Resources\AbstractUnzerResource; use RuntimeException; + use function in_array; + use const PHP_VERSION; class HttpService @@ -44,8 +46,6 @@ class HttpService /** @var EnvironmentService $environmentService */ private $environmentService; - // - /** * Returns the currently set HttpAdapter. * If it is not set it will create a CurlRequest by default and return it. @@ -95,12 +95,10 @@ public function setEnvironmentService(EnvironmentService $environmentService): H return $this; } - // - /** * send post request to payment server * - * @param $uri string|null uri of the target system + * @param $uri string|null uri of the target system * @param ?AbstractUnzerResource $resource * @param string $httpMethod * @param string $apiVersion diff --git a/src/Services/IdService.php b/src/Services/IdService.php index 423fe2cc..241d1d92 100755 --- a/src/Services/IdService.php +++ b/src/Services/IdService.php @@ -20,11 +20,13 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; -use function count; use RuntimeException; +use function count; + class IdService { /** @@ -44,7 +46,7 @@ class IdService public static function getResourceIdFromUrl(string $url, string $idString, bool $onlyLast = false): string { $matches = []; - $pattern = '/\/([s|p]{1}-' . $idString . '-[a-z\d]+)\/?' . ($onlyLast ? '$':'') . '/'; + $pattern = '/\/([s|p]{1}-' . $idString . '-[a-z\d]+)\/?' . ($onlyLast ? '$' : '') . '/'; preg_match($pattern, $url, $matches); if (count($matches) < 2) { @@ -69,6 +71,21 @@ public static function isPaymentCancellation(string $url): string return preg_match($pattern, $url) === 1; } + /** + * Determine base on the chargeback URL if the transaction refers directly to the payment or not. + * + * @param string $url + * + * @return string + * + * @throws RuntimeException + */ + public static function isPaymentChargeback(string $url): string + { + $pattern = '/\/payments\/[s|p]{1}-pay-[a-z\d]+\/(charges|authorize)\/chargebacks\/[s|p]{1}-cbk-[a-z\d]+/'; + return preg_match($pattern, $url) === 1; + } + /** * Behaves like getResourceIdFromUrl but does not throw exception but returns null if the id can not be detected. * diff --git a/src/Services/PaymentService.php b/src/Services/PaymentService.php index ac1c9fbe..61678242 100755 --- a/src/Services/PaymentService.php +++ b/src/Services/PaymentService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; use DateTime; @@ -60,8 +61,6 @@ public function __construct(Unzer $unzer) $this->unzer = $unzer; } - //getUnzer()->getResourceService(); } - // - - // - - // - public function performAuthorization( Authorization $authorization, $paymentType, @@ -163,10 +156,6 @@ public function authorize( return $authorization; } - // - - // - /** * {@inheritDoc} */ @@ -280,10 +269,6 @@ public function performChargeOnPayment($payment, Charge $charge): Charge return $charge; } - // - - // - /** * {@inheritDoc} */ @@ -310,10 +295,6 @@ public function payout( return $payout; } - // - - // - /** * {@inheritDoc} */ @@ -326,12 +307,6 @@ public function ship($payment, string $invoiceId = null, string $orderId = null) return $shipment; } - // - - // - - // - /** * {@inheritDoc} */ @@ -356,10 +331,6 @@ public function initPayPageAuthorize( return $this->initPayPage($paypage, TransactionTypes::AUTHORIZATION, $customer, $basket, $metadata); } - // - - // - /** * {@inheritDoc} */ @@ -387,10 +358,6 @@ public function fetchPaylaterInstallmentPlans( return $this->unzer->getResourceService()->fetchResource($plans); } - // - - // - /** * Creates the PayPage for the requested transaction method. * @@ -437,6 +404,4 @@ private function createPayment($paymentType): AbstractUnzerResource { return (new Payment($this->unzer))->setPaymentType($paymentType); } - - // } diff --git a/src/Services/ResourceNameService.php b/src/Services/ResourceNameService.php index 63e91987..f1754468 100755 --- a/src/Services/ResourceNameService.php +++ b/src/Services/ResourceNameService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; class ResourceNameService diff --git a/src/Services/ResourceService.php b/src/Services/ResourceService.php index 2ceb088a..6c0acccc 100755 --- a/src/Services/ResourceService.php +++ b/src/Services/ResourceService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; use DateTime; @@ -33,8 +34,10 @@ use UnzerSDK\Resources\PaymentTypes\Klarna; use UnzerSDK\Resources\PaymentTypes\PaylaterInstallment; use UnzerSDK\Resources\PaymentTypes\Paypage; +use UnzerSDK\Resources\PaymentTypes\PayU; use UnzerSDK\Resources\PaymentTypes\PostFinanceCard; use UnzerSDK\Resources\PaymentTypes\PostFinanceEfinance; +use UnzerSDK\Resources\TransactionTypes\Chargeback; use UnzerSDK\Unzer; use UnzerSDK\Interfaces\ResourceServiceInterface; use UnzerSDK\Resources\AbstractUnzerResource; @@ -71,6 +74,7 @@ use UnzerSDK\Traits\CanRecur; use RuntimeException; use stdClass; + use function in_array; use function is_string; @@ -89,8 +93,6 @@ public function __construct(Unzer $unzer) $this->unzer = $unzer; } - // - - // - /** * Send request to API. * @@ -231,10 +229,6 @@ public function fetchResourceByUrl($url) return $resource; } - // - - // - /** * Create the resource on the api. * @@ -357,10 +351,6 @@ public function fetchResource(AbstractUnzerResource $resource, string $apiVersio return $resource; } - // - - // - /** * Fetch an Payout object by its paymentId. * Payout Ids are not global but specific to the payment. @@ -382,10 +372,6 @@ public function fetchPayout($payment): Payout return $payout; } - // - - // - /** * {@inheritDoc} */ @@ -410,10 +396,6 @@ public function activateRecurringPayment($paymentType, string $returnUrl, string throw new RuntimeException('Recurring is not available for the given payment type.'); } - // - - // - /** * Fetches the payment object if the id is given. * Else it just returns the given payment argument as-is. @@ -475,10 +457,6 @@ public function fetchPaymentByOrderId(string $orderId): Payment return $paymentObject; } - // - - // - /** * {@inheritDoc} */ @@ -489,10 +467,6 @@ public function fetchKeypair(bool $detailed = false): Keypair return $keyPair; } - // - - // - /** * {@inheritDoc} */ @@ -517,10 +491,6 @@ public function fetchMetadata($metadata): Metadata return $metadataObject; } - // - - // - /** * {@inheritDoc} */ @@ -563,10 +533,6 @@ public function updateBasket(Basket $basket): Basket return $basket; } - // - - // - /** * {@inheritDoc} */ @@ -600,10 +566,6 @@ public function updatePaymentType(BasePaymentType $paymentType): BasePaymentType return $returnPaymentType; } - // - - // - /** * {@inheritDoc} */ @@ -684,10 +646,6 @@ public function deleteCustomer($customer): void $this->deleteResource($customerObject); } - // - - // - /** * {@inheritDoc} */ @@ -705,9 +663,6 @@ public function fetchAuthorization($payment): Authorization return $authorize; } - // - - // public function fetchCharge(Charge $charge): Charge { $this->fetchResource($charge); @@ -730,9 +685,30 @@ public function fetchChargeById($payment, string $chargeId): Charge return $charge; } - // + /** + * {@inheritDoc} + */ + public function fetchChargeback(Chargeback $chargeback): Chargeback + { + $this->fetchResource($chargeback); + return $chargeback; + } - // + /** + * {@inheritDoc} + */ + public function fetchChargebackById(string $paymentId, string $chargebackId, ?string $chargeId): Chargeback + { + $paymentObject = $this->fetchPayment($paymentId); + $chargeback = $paymentObject->getChargeback($chargebackId, $chargeId, true); + + if (!$chargeback instanceof Chargeback) { + throw new RuntimeException('The chargeback object could not be found.'); + } + + $this->fetchResource($chargeback); + return $chargeback; + } /** * {@inheritDoc} @@ -805,12 +781,6 @@ public function fetchPaymentReversal($payment, string $cancellationId): Cancella return $this->fetchResource($cancel); } - - - // - - // - /** * {@inheritDoc} */ @@ -820,10 +790,6 @@ public function fetchShipment($payment, string $shipmentId): Shipment return $paymentObject->getShipment($shipmentId); } - // - - // - /** * {@inheritDoc} * @@ -839,8 +805,6 @@ public function fetchConfig(BasePaymentType $paymentType, ?Config $config = null return $this->fetchResource($configObject); } - // - /** * Creates a payment type instance from a typeId string. * @@ -897,6 +861,9 @@ public static function getTypeInstanceFromIdString($typeId): BasePaymentType case IdStrings::PAYLATER_INVOICE: $paymentType = new PaylaterInvoice(); break; + case IdStrings::PAYU: + $paymentType = new PayU(); + break; case IdStrings::PIS: $paymentType = new PIS(); break; diff --git a/src/Services/ValueService.php b/src/Services/ValueService.php index 737e4688..3f121dea 100644 --- a/src/Services/ValueService.php +++ b/src/Services/ValueService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; use function is_float; @@ -43,7 +44,7 @@ public static function limitFloats($value) /** * Mask a value. * - * @param $value + * @param $value * @param string $maskSymbol * * @return string diff --git a/src/Services/WebhookService.php b/src/Services/WebhookService.php index fd87e324..c0b356ac 100755 --- a/src/Services/WebhookService.php +++ b/src/Services/WebhookService.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Services */ + namespace UnzerSDK\Services; use UnzerSDK\Unzer; @@ -28,9 +29,10 @@ use UnzerSDK\Resources\AbstractUnzerResource; use UnzerSDK\Resources\Webhook; use UnzerSDK\Resources\Webhooks; -use function is_string; use RuntimeException; +use function is_string; + class WebhookService implements WebhookServiceInterface { /** @var Unzer $unzer */ @@ -50,8 +52,6 @@ public function __construct(Unzer $unzer) $this->resourceService = $unzer->getResourceService(); } - // - /** * @return Unzer */ @@ -90,10 +90,6 @@ public function setResourceService(ResourceServiceInterface $resourceService): W return $this; } - // - - // - /** * {@inheritDoc} */ @@ -145,10 +141,6 @@ public function deleteWebhook($webhook) return $this->resourceService->deleteResource($webhookObject); } - // - - // - /** * {@inheritDoc} */ @@ -185,10 +177,6 @@ public function registerMultipleWebhooks(string $url, array $events): array return $webhooks->getWebhookList(); } - // - - // - /** * {@inheritDoc} */ @@ -219,6 +207,4 @@ public function readInputStream() { return file_get_contents('php://input'); } - - // } diff --git a/src/Traits/CanAuthorize.php b/src/Traits/CanAuthorize.php index 1a2dbce2..82ab56dd 100755 --- a/src/Traits/CanAuthorize.php +++ b/src/Traits/CanAuthorize.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; diff --git a/src/Traits/CanAuthorizeWithCustomer.php b/src/Traits/CanAuthorizeWithCustomer.php index 42ff51bc..0baa54a2 100755 --- a/src/Traits/CanAuthorizeWithCustomer.php +++ b/src/Traits/CanAuthorizeWithCustomer.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; @@ -36,9 +37,9 @@ trait CanAuthorizeWithCustomer * Authorize an amount with the given currency. * Throws UnzerApiException if the transaction could not be performed (e.g. increased risk etc.). * - * @param $amount - * @param $currency - * @param $returnUrl + * @param $amount + * @param $currency + * @param $returnUrl * @param Customer|string $customer * @param string|null $orderId * @param Metadata|null $metadata diff --git a/src/Traits/CanDirectCharge.php b/src/Traits/CanDirectCharge.php index 34f579c4..62fd9af5 100755 --- a/src/Traits/CanDirectCharge.php +++ b/src/Traits/CanDirectCharge.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; @@ -36,9 +37,9 @@ trait CanDirectCharge * Charge an amount with the given currency. * Throws UnzerApiException if the transaction could not be performed (e.g. increased risk etc.). * - * @param $amount - * @param $currency - * @param $returnUrl + * @param $amount + * @param $currency + * @param $returnUrl * @param Customer|string|null $customer * @param string|null $orderId * @param Metadata|string|null $metadata diff --git a/src/Traits/CanDirectChargeWithCustomer.php b/src/Traits/CanDirectChargeWithCustomer.php index c815f521..52780e3f 100755 --- a/src/Traits/CanDirectChargeWithCustomer.php +++ b/src/Traits/CanDirectChargeWithCustomer.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; diff --git a/src/Traits/CanPayout.php b/src/Traits/CanPayout.php index 0616cdca..0e64b89c 100644 --- a/src/Traits/CanPayout.php +++ b/src/Traits/CanPayout.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; diff --git a/src/Traits/CanPayoutWithCustomer.php b/src/Traits/CanPayoutWithCustomer.php index 6d390151..d03fccad 100644 --- a/src/Traits/CanPayoutWithCustomer.php +++ b/src/Traits/CanPayoutWithCustomer.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; diff --git a/src/Traits/CanRecur.php b/src/Traits/CanRecur.php index e005f297..92dc7ca7 100644 --- a/src/Traits/CanRecur.php +++ b/src/Traits/CanRecur.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; @@ -55,8 +56,6 @@ public function activateRecurring($returnUrl, $recurrenceType = null): Recurring throw new RuntimeException('Error: Recurring can not be enabled on this type.'); } - // - /** * @return bool */ @@ -75,6 +74,4 @@ protected function setRecurring(bool $active): self $this->recurring = $active; return $this; } - - // } diff --git a/src/Traits/HasCancellations.php b/src/Traits/HasCancellations.php index 8b39bcaa..824942a6 100755 --- a/src/Traits/HasCancellations.php +++ b/src/Traits/HasCancellations.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Exceptions\UnzerApiException; @@ -33,8 +34,6 @@ trait HasCancellations /** @var array $cancellations */ private $cancellations = []; - // - /** * @return array */ @@ -93,6 +92,4 @@ public function getCancellation(string $cancellationId, bool $lazy = false): ?Ca } return null; } - - // } diff --git a/src/Traits/HasChargebacks.php b/src/Traits/HasChargebacks.php new file mode 100644 index 00000000..28d42f95 --- /dev/null +++ b/src/Traits/HasChargebacks.php @@ -0,0 +1,95 @@ +chargebacks; + } + + /** + * @param array $chargebacks + * + * @return self + */ + public function setChargebacks(array $chargebacks): self + { + $this->chargebacks = $chargebacks; + return $this; + } + + /** + * @param Chargeback $chargeback + * + * @return self + */ + public function addChargeback(Chargeback $chargeback): self + { + if ($this instanceof UnzerParentInterface) { + $chargeback->setParentResource($this); + } + $this->chargebacks[] = $chargeback; + return $this; + } + + /** + * Return specific Chargeback object or null if it does not exist. + * + * @param string $chargebackId The id of the chargeback object + * @param boolean $lazy + * + * @return Chargeback|null The chargeback or null if none could be found. + * + * @throws RuntimeException A RuntimeException is thrown when there is an error while using the SDK. + * @throws UnzerApiException An UnzerApiException is thrown if there is an error returned on API-request. + */ + public function getChargeback(string $chargebackId, bool $lazy = false): ?Chargeback + { + /** @var Chargeback $chargeback */ + foreach ($this->chargebacks as $chargeback) { + if ($chargeback->getId() === $chargebackId) { + if (!$lazy && $this instanceof UnzerParentInterface) { + /** @var AbstractUnzerResource $this*/ + $this->getResource($chargeback); + } + return $chargeback; + } + } + return null; + } +} diff --git a/src/Traits/HasCustomerMessage.php b/src/Traits/HasCustomerMessage.php index fabbb998..804ea0f4 100644 --- a/src/Traits/HasCustomerMessage.php +++ b/src/Traits/HasCustomerMessage.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Resources\EmbeddedResources\Message; @@ -29,8 +30,6 @@ trait HasCustomerMessage /** @var Message $message */ private $message; - // - /** * @return Message */ @@ -42,6 +41,4 @@ public function getMessage(): Message return $this->message; } - - // } diff --git a/src/Traits/HasDate.php b/src/Traits/HasDate.php index 0d9bf9e7..9f51f92e 100644 --- a/src/Traits/HasDate.php +++ b/src/Traits/HasDate.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use DateTime; @@ -30,8 +31,6 @@ trait HasDate /** @var DateTime $date */ private $date; - // - /** * This returns the date of the Transaction as string. * @@ -55,6 +54,4 @@ public function setDate(string $date): self $this->date = new DateTime($date); return $this; } - - // } diff --git a/src/Traits/HasGeoLocation.php b/src/Traits/HasGeoLocation.php index 2e27bad2..216ba2c4 100644 --- a/src/Traits/HasGeoLocation.php +++ b/src/Traits/HasGeoLocation.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Resources\EmbeddedResources\GeoLocation; @@ -29,8 +30,6 @@ trait HasGeoLocation /** @var GeoLocation $geoLocation */ private $geoLocation; - // - /** * @return GeoLocation */ @@ -52,6 +51,4 @@ public function setGeoLocation(GeoLocation $geoLocation): self $this->geoLocation = $geoLocation; return $this; } - - // } diff --git a/src/Traits/HasInvoiceId.php b/src/Traits/HasInvoiceId.php index 7cff2388..47cb8daa 100755 --- a/src/Traits/HasInvoiceId.php +++ b/src/Traits/HasInvoiceId.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; trait HasInvoiceId @@ -27,8 +28,6 @@ trait HasInvoiceId /** @var string $invoiceId */ protected $invoiceId; - // - /** * @return string|null */ @@ -47,6 +46,4 @@ public function setInvoiceId(?string $invoiceId): self $this->invoiceId = $invoiceId; return $this; } - - // } diff --git a/src/Traits/HasOrderId.php b/src/Traits/HasOrderId.php index 5dca1496..bbf12034 100755 --- a/src/Traits/HasOrderId.php +++ b/src/Traits/HasOrderId.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; trait HasOrderId @@ -27,8 +28,6 @@ trait HasOrderId /** @var string $orderId */ protected $orderId; - // - /** * @return string|null */ @@ -47,6 +46,4 @@ public function setOrderId(?string $orderId): self $this->orderId = $orderId; return $this; } - - // } diff --git a/src/Traits/HasPaymentState.php b/src/Traits/HasPaymentState.php index fcfc22df..9fe6597f 100755 --- a/src/Traits/HasPaymentState.php +++ b/src/Traits/HasPaymentState.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use UnzerSDK\Constants\PaymentState; @@ -30,8 +31,6 @@ trait HasPaymentState /** @var int */ private $state = 0; - // - /** * Return true if the state is pending. * @@ -102,10 +101,6 @@ public function isCreate(): bool return $this->getState() === PaymentState::STATE_CREATE; } - // - - // - /** * Returns the current state code (ref. Constants/PaymentState). * @@ -140,6 +135,4 @@ protected function setState(int $state): self $this->state = $state; return $this; } - - // } diff --git a/src/Traits/HasRecurrenceType.php b/src/Traits/HasRecurrenceType.php index 5e30c248..5602cf78 100644 --- a/src/Traits/HasRecurrenceType.php +++ b/src/Traits/HasRecurrenceType.php @@ -28,8 +28,6 @@ trait HasRecurrenceType { - // - /** * @return string|null */ @@ -56,6 +54,4 @@ public function setRecurrenceType(string $recurrenceType): self return $this; } - - // } diff --git a/src/Traits/HasStates.php b/src/Traits/HasStates.php index dc789d77..6ddfe148 100644 --- a/src/Traits/HasStates.php +++ b/src/Traits/HasStates.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; use RuntimeException; @@ -39,8 +40,6 @@ trait HasStates /** @var bool $isResumed */ private $isResumed = false; - // - /** * @return bool */ @@ -117,8 +116,6 @@ public function setIsResumed(bool $isResumed): self return $this; } - // - /** * Map the 'status' that is used for transactions in the transaction list of a payment resource. * The actual transaction resource only has the isSuccess, isPending and isError property. diff --git a/src/Traits/HasTraceId.php b/src/Traits/HasTraceId.php index f2c5fd48..651d8ec8 100644 --- a/src/Traits/HasTraceId.php +++ b/src/Traits/HasTraceId.php @@ -21,6 +21,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; trait HasTraceId @@ -28,8 +29,6 @@ trait HasTraceId /** @var string $traceId */ private $traceId; - // - /** * @return string|null */ @@ -48,6 +47,4 @@ protected function setTraceId(string $traceId): self $this->traceId = $traceId; return $this; } - - // } diff --git a/src/Traits/HasUniqueAndShortId.php b/src/Traits/HasUniqueAndShortId.php index 6d867c4d..97567222 100644 --- a/src/Traits/HasUniqueAndShortId.php +++ b/src/Traits/HasUniqueAndShortId.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; trait HasUniqueAndShortId @@ -30,8 +31,6 @@ trait HasUniqueAndShortId /** @var string $shortId */ private $shortId; - // - /** * @return string|null */ @@ -69,6 +68,4 @@ protected function setShortId(string $shortId): self $this->shortId = $shortId; return $this; } - - // } diff --git a/src/Traits/IsInvoiceType.php b/src/Traits/IsInvoiceType.php index 2774a1bb..618028b1 100644 --- a/src/Traits/IsInvoiceType.php +++ b/src/Traits/IsInvoiceType.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Traits */ + namespace UnzerSDK\Traits; trait IsInvoiceType diff --git a/src/Unzer.php b/src/Unzer.php index 1b08f80f..eec6a382 100644 --- a/src/Unzer.php +++ b/src/Unzer.php @@ -21,6 +21,7 @@ * * @package UnzerSDK */ + namespace UnzerSDK; use DateTime; @@ -49,6 +50,7 @@ use UnzerSDK\Resources\TransactionTypes\Authorization; use UnzerSDK\Resources\TransactionTypes\Cancellation; use UnzerSDK\Resources\TransactionTypes\Charge; +use UnzerSDK\Resources\TransactionTypes\Chargeback; use UnzerSDK\Resources\TransactionTypes\Payout; use UnzerSDK\Resources\TransactionTypes\Shipment; use UnzerSDK\Resources\Webhook; @@ -64,7 +66,7 @@ class Unzer implements UnzerParentInterface, PaymentServiceInterface, ResourceSe public const BASE_URL = 'api.unzer.com'; public const API_VERSION = 'v1'; public const SDK_TYPE = 'UnzerPHP'; - public const SDK_VERSION = '3.2.0'; + public const SDK_VERSION = '3.3.0'; /** @var string $key */ private $key; @@ -119,8 +121,6 @@ public function __construct(string $key, ?string $locale = '') $this->httpService = new HttpService(); } - // - /** * Returns the set private key used to connect to the API. * @@ -344,10 +344,6 @@ public function setHttpService(HttpService $httpService): Unzer return $this; } - // - - // - /** * Returns this Unzer instance. * @@ -366,12 +362,6 @@ public function getUri(bool $appendId = true, string $httpMethod = HttpAdapterIn return ''; } - // - - // - - // - /** * {@inheritDoc} */ @@ -380,9 +370,6 @@ public function activateRecurringPayment($paymentType, string $returnUrl, string return $this->resourceService->activateRecurringPayment($paymentType, $returnUrl, $recurrenceType); } - // - - // /** * {@inheritDoc} */ @@ -390,9 +377,6 @@ public function fetchPayPage($payPage): Paypage { return $this->resourceService->fetchPayPage($payPage); } - // - - // /** * {@inheritDoc} @@ -410,10 +394,6 @@ public function fetchPaymentByOrderId(string $orderId): Payment return $this->resourceService->fetchPaymentByOrderId($orderId); } - // - - // - /** * {@inheritDoc} */ @@ -422,10 +402,6 @@ public function fetchKeypair(bool $detailed = false): Keypair return $this->resourceService->fetchKeypair($detailed); } - // - - // - /** * {@inheritDoc} */ @@ -442,10 +418,6 @@ public function fetchMetadata($metadata): Metadata return $this->resourceService->fetchMetadata($metadata); } - // - - // - /** * {@inheritDoc} */ @@ -470,10 +442,6 @@ public function updateBasket(Basket $basket): Basket return $this->resourceService->updateBasket($basket); } - // - - // - /** * {@inheritDoc} */ @@ -498,10 +466,6 @@ public function fetchPaymentType(string $typeId): BasePaymentType return $this->resourceService->fetchPaymentType($typeId); } - // - - // - /** * {@inheritDoc} */ @@ -550,10 +514,6 @@ public function deleteCustomer($customer): void $this->resourceService->deleteCustomer($customer); } - // - - // - /** * {@inheritDoc} */ @@ -562,10 +522,6 @@ public function fetchAuthorization($payment): Authorization return $this->resourceService->fetchAuthorization($payment); } - // - - // - /** * {@inheritDoc} */ @@ -582,9 +538,18 @@ public function fetchCharge(Charge $charge): Charge return $this->resourceService->fetchCharge($charge); } - // + /** + * {@inheritDoc} + */ + public function fetchChargebackById(string $paymentId, string $charebackId, ?string $chargeId): Chargeback + { + return $this->resourceService->fetchChargebackById($paymentId, $charebackId, $chargeId); + } - // + public function fetchChargeback(Chargeback $chargeback): Chargeback + { + return $this->resourceService->fetchResource($chargeback); + } /** * {@inheritDoc} @@ -634,10 +599,6 @@ public function fetchPaymentReversal($payment, string $cancellationId): Cancella return $this->resourceService->fetchPaymentReversal($payment, $cancellationId); } - // - - // - /** * {@inheritDoc} */ @@ -646,10 +607,6 @@ public function fetchShipment($payment, string $shipmentId): Shipment return $this->resourceService->fetchShipment($payment, $shipmentId); } - // - - // - /** * {@inheritDoc} */ @@ -658,10 +615,6 @@ public function fetchPayout($payment): Payout return $this->resourceService->fetchPayout($payment); } - // - - // - /** * {@inheritDoc} */ @@ -726,14 +679,6 @@ public function fetchResourceFromEvent(string $eventJson = null): AbstractUnzerR return $this->webhookService->fetchResourceFromEvent($eventJson); } - // - - // - - // - - // - /** * {@inheritDoc} */ @@ -785,10 +730,6 @@ public function authorize( ); } - // - - // - /** * {@inheritDoc} */ @@ -864,10 +805,6 @@ public function performChargeOnPayment($payment, Charge $charge): Charge return $this->paymentService->performChargeOnPayment($payment, $charge); } - // - - // - /** * {@inheritDoc} */ @@ -884,10 +821,6 @@ public function cancelAuthorizationByPayment($payment, float $amount = null): Ca return $this->cancelService->cancelAuthorizationByPayment($payment, $amount); } - // - - // - /** * {@inheritDoc} */ @@ -911,10 +844,6 @@ public function cancelPaymentAuthorization($payment, float $amount = null): ?Can return $this->cancelService->cancelPaymentAuthorization($payment, $amount); } - // - - // - /** * {@inheritDoc} */ @@ -964,10 +893,6 @@ public function cancelChargedPayment($payment, ?Cancellation $cancellation = nul ->cancelChargedPayment($payment, $cancellation); } - // - - // - /** * {@inheritDoc} */ @@ -976,10 +901,6 @@ public function ship($payment, string $invoiceId = null, string $orderId = null) return $this->paymentService->ship($payment, $invoiceId, $orderId); } - // - - // - /** * {@inheritDoc} */ @@ -1009,10 +930,6 @@ public function payout( ); } - // - - // - /** * {@inheritDoc} */ @@ -1037,10 +954,6 @@ public function initPayPageAuthorize( return $this->paymentService->initPayPageAuthorize($paypage, $customer, $basket, $metadata); } - // - - // - /** * {@inheritDoc} */ @@ -1054,17 +967,11 @@ public function fetchInstallmentPlans( ->fetchInstallmentPlans($amount, $currency, $effectiveInterest, $orderDate); } - // - - public function fetchPaylaterInstallmentPlans(InstallmentPlansQuery $plansRequest):PaylaterInstallmentPlans + public function fetchPaylaterInstallmentPlans(InstallmentPlansQuery $plansRequest): PaylaterInstallmentPlans { return $this->getPaymentService()->fetchPaylaterInstallmentPlans($plansRequest); } - // - - // - /** * {@inheritDoc} * @@ -1075,10 +982,6 @@ public function fetchConfig(BasePaymentType $paymentType, ?Config $config = null return $this->getResourceService()->fetchConfig($paymentType, $config); } - // - - // - /** * Writes the given string to the registered debug handler if debug mode is enabled. * @@ -1093,6 +996,4 @@ public function debugLog($message): void } } } - - // } diff --git a/src/Validators/ExpiryDateValidator.php b/src/Validators/ExpiryDateValidator.php index ab768bd7..894dead8 100755 --- a/src/Validators/ExpiryDateValidator.php +++ b/src/Validators/ExpiryDateValidator.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Validators */ + namespace UnzerSDK\Validators; class ExpiryDateValidator diff --git a/src/Validators/PrivateKeyValidator.php b/src/Validators/PrivateKeyValidator.php index 19b13b97..b3c529ce 100755 --- a/src/Validators/PrivateKeyValidator.php +++ b/src/Validators/PrivateKeyValidator.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Validators */ + namespace UnzerSDK\Validators; use function count; diff --git a/src/Validators/PublicKeyValidator.php b/src/Validators/PublicKeyValidator.php index 125645bb..9efd355d 100755 --- a/src/Validators/PublicKeyValidator.php +++ b/src/Validators/PublicKeyValidator.php @@ -20,6 +20,7 @@ * * @package UnzerSDK\Validators */ + namespace UnzerSDK\Validators; use function count; diff --git a/test/BaseIntegrationTest.php b/test/BaseIntegrationTest.php index e3b69b0e..83f9d760 100644 --- a/test/BaseIntegrationTest.php +++ b/test/BaseIntegrationTest.php @@ -1,4 +1,5 @@ getUnzerObject()->setKey(TestEnvironmentService::getTestPrivateKey(true)); } + + /** + * @return void + */ + protected function useLegacyKey(): void + { + $this->getUnzerObject()->setKey(TestEnvironmentService::getLegacyTestPrivateKey()); + } } diff --git a/test/BasePaymentTest.php b/test/BasePaymentTest.php index 57c51fe4..07d49fc6 100755 --- a/test/BasePaymentTest.php +++ b/test/BasePaymentTest.php @@ -1,4 +1,5 @@ useLegacyKey(); $basket = $this->createBasket(); $this->assertNotEmpty($basket->getId()); diff --git a/test/integration/BasketV2Test.php b/test/integration/BasketV2Test.php index e86bb7bb..d6f05497 100644 --- a/test/integration/BasketV2Test.php +++ b/test/integration/BasketV2Test.php @@ -1,4 +1,5 @@ useLegacyKey(); $basket = $this->createV2Basket(); $this->assertNotEmpty($basket->getId()); diff --git a/test/integration/ConfigTest.php b/test/integration/ConfigTest.php index 2136021a..dddb11e2 100644 --- a/test/integration/ConfigTest.php +++ b/test/integration/ConfigTest.php @@ -1,4 +1,5 @@ useLegacyKey(); $charge = $this->createCharge(123.44); $payment = $this->unzer->fetchPayment($charge->getPaymentId()); $this->assertTrue($payment->isCompleted()); @@ -123,6 +126,7 @@ public function fullCancelOnPaymentWithAuthorizeAndMultipleChargesShouldBePossib */ public function partialCancelAndFullCancelOnSingleCharge(): void { + $this->useLegacyKey(); $charge = $this->createCharge(222.33); $payment = $this->unzer->fetchPayment($charge->getPaymentId()); $this->assertTrue($payment->isCompleted()); @@ -467,6 +471,7 @@ public function fullCancelOnPaidInvoiceSecuredPaymentShouldBePossible(): void */ public function cancelMoreThanWasCharged(): void { + $this->useLegacyKey(); $charge = $this->createCharge(50.0); $payment = $this->unzer->fetchPayment($charge->getPaymentId()); $this->assertTrue($payment->isCompleted()); diff --git a/test/integration/PaymentTest.php b/test/integration/PaymentTest.php index e9dab252..4aa3a573 100755 --- a/test/integration/PaymentTest.php +++ b/test/integration/PaymentTest.php @@ -1,4 +1,5 @@ unzer->createPaymentType(new Bancontact()); $this->unzer->authorize(100.0, 'EUR', $bancontact, self::RETURN_URL); } - + /** * Verify that Bancontact is chargeable * diff --git a/test/integration/PaymentTypes/CardTest.php b/test/integration/PaymentTypes/CardTest.php index 749d6a32..44e50da8 100755 --- a/test/integration/PaymentTypes/CardTest.php +++ b/test/integration/PaymentTypes/CardTest.php @@ -1,4 +1,5 @@ assertEquals($recurrenceType, $fetchedCharge->getRecurrenceType()); } - + /** * Verify that an invalid email cause an UnzerApiException. * @@ -248,7 +250,7 @@ public function cardCanBeUpdatedWithEmail() // then /** @var Card $updatedCard */ $updatedCard = $this->unzer->fetchPaymentType($fetchedCard->getId()); - $this->assertRegExp('/0000$/', $updatedCard->getNumber()); + $this->assertMatchesRegularExpression('/0000$/', $updatedCard->getNumber()); $this->assertEquals('test2@test.com', $updatedCard->getEmail()); } diff --git a/test/integration/PaymentTypes/EPSTest.php b/test/integration/PaymentTypes/EPSTest.php index 89d2ed2b..4a1104d3 100755 --- a/test/integration/PaymentTypes/EPSTest.php +++ b/test/integration/PaymentTypes/EPSTest.php @@ -1,4 +1,5 @@ unzer->createPaymentType($hddMock); - $this->assertRegExp('/^s-hdd-[.]*/', $hddMock->getId()); + $this->assertMatchesRegularExpression('/^s-hdd-[.]*/', $hddMock->getId()); // Then $fetchedType = $this->unzer->fetchPaymentType($hddMock->getId()); $this->assertInstanceOf(InstallmentSecured::class, $fetchedType); - $this->assertRegExp('/^s-hdd-[.]*/', $fetchedType->getId()); + $this->assertMatchesRegularExpression('/^s-hdd-[.]*/', $fetchedType->getId()); return $fetchedType; } diff --git a/test/integration/PaymentTypes/IdealTest.php b/test/integration/PaymentTypes/IdealTest.php index 0e6a7040..8c43bcc5 100755 --- a/test/integration/PaymentTypes/IdealTest.php +++ b/test/integration/PaymentTypes/IdealTest.php @@ -1,4 +1,5 @@ unzer->createPaymentType($ivgMock); $this->assertInstanceOf(InvoiceSecured::class, $ivgType); - $this->assertRegExp('/^s-ivg-[.]*/', $ivgType->getId()); + $this->assertMatchesRegularExpression('/^s-ivg-[.]*/', $ivgType->getId()); $fetchedType = $this->unzer->fetchPaymentType($ivgType->getId()); $this->assertInstanceOf(InvoiceSecured::class, $fetchedType); - $this->assertRegExp('/^s-ivg-[.]*/', $fetchedType->getId()); + $this->assertMatchesRegularExpression('/^s-ivg-[.]*/', $fetchedType->getId()); return $fetchedType; } diff --git a/test/integration/PaymentTypes/InvoiceSecuredTest.php b/test/integration/PaymentTypes/InvoiceSecuredTest.php index cfc87b8a..0da18dcf 100644 --- a/test/integration/PaymentTypes/InvoiceSecuredTest.php +++ b/test/integration/PaymentTypes/InvoiceSecuredTest.php @@ -1,4 +1,5 @@ unzer->createPaymentType(new PayU()); + $this->assertInstanceOf(PayU::class, $paymentType); + $this->assertNotNull($paymentType->getId()); + + /** @var PayU $fetchedType */ + $fetchedType = $this->unzer->fetchPaymentType($paymentType->getId()); + $this->assertInstanceOf(PayU::class, $fetchedType); + $this->assertEquals($paymentType->expose(), $fetchedType->expose()); + $this->assertNotEmpty($fetchedType->getGeoLocation()->getClientIp()); + + return $fetchedType; + } + + /** + * Verify PayU is chargeable. + * + * @test + * + * @param PayU $paymentType + * @param mixed $currency + * + * @return Charge + * + * @dataProvider supportedCurrencies + * + * @depends payUShouldBeCreatableAndFetchable + */ + public function payUShouldBeAbleToCharge($currency, PayU $paymentType): Charge + { + $charge = new Charge(100.0, $currency, self::RETURN_URL); + $this->getUnzerObject()->performCharge($charge, $paymentType); + + $this->assertNotNull($charge); + $this->assertNotEmpty($charge->getId()); + $this->assertNotEmpty($charge->getRedirectUrl()); + + return $charge; + } + + /** + * Verify payU is not authorizable. + * + * @test + * + * @param PayU $payU + * + * @depends payUShouldBeCreatableAndFetchable + */ + public function payUShouldNotBeAuthorizable(PayU $payU): void + { + $this->expectException(UnzerApiException::class); + $this->expectExceptionCode(ApiResponseCodes::API_ERROR_TRANSACTION_AUTHORIZE_NOT_ALLOWED); + + $authorization = new Authorization(100.0, 'CHF', self::RETURN_URL); + $this->unzer->performAuthorization($authorization, $payU); + } + + public function supportedCurrencies(): array + { + return [ + 'PLN' => ['PLN'], + 'CZK' => ['CZK'] + ]; + } +} diff --git a/test/integration/PaymentTypes/PaylaterInstallmentTest.php b/test/integration/PaymentTypes/PaylaterInstallmentTest.php index 89eeb2c1..3506da24 100644 --- a/test/integration/PaymentTypes/PaylaterInstallmentTest.php +++ b/test/integration/PaymentTypes/PaylaterInstallmentTest.php @@ -39,6 +39,7 @@ use UnzerSDK\Resources\TransactionTypes\Cancellation; use UnzerSDK\Resources\TransactionTypes\Charge; use UnzerSDK\test\BaseIntegrationTest; + use function count; class PaylaterInstallmentTest extends BaseIntegrationTest @@ -94,7 +95,7 @@ public function fetchingPlansUsesB2CCustomerAsDefaultIfEmpty(): void $plans = $this->unzer->fetchPaylaterInstallmentPlans($paylaterInstallmentPlans); $this->assertTrue($plans->isSuccess()); } - + /** * Verify Api error is handled as Exception. * diff --git a/test/integration/PaymentTypes/PaylaterInvoiceTest.php b/test/integration/PaymentTypes/PaylaterInvoiceTest.php index 7edc27c7..882258d8 100644 --- a/test/integration/PaymentTypes/PaylaterInvoiceTest.php +++ b/test/integration/PaymentTypes/PaylaterInvoiceTest.php @@ -1,4 +1,5 @@ unzer->fetchPaymentType($invoice->getId()); $this->assertInstanceOf(PaylaterInvoice::class, $fetchedInvoice); $this->assertEquals($invoice->getId(), $fetchedInvoice->getId()); - $this->assertRegExp('/^s-piv-[.]*/', $fetchedInvoice->getId()); + $this->assertMatchesRegularExpression('/^s-piv-[.]*/', $fetchedInvoice->getId()); return $invoice; } diff --git a/test/integration/PaymentTypes/PaypageTest.php b/test/integration/PaymentTypes/PaypageTest.php index 2679d6fb..cd66108d 100644 --- a/test/integration/PaymentTypes/PaypageTest.php +++ b/test/integration/PaymentTypes/PaypageTest.php @@ -1,4 +1,5 @@ unzer->createPaymentType($ddgMock); - $this->assertRegExp('/^s-ddg-[.]*/', $ddgMock->getId()); + $this->assertMatchesRegularExpression('/^s-ddg-[.]*/', $ddgMock->getId()); // Then $fetchedType = $this->unzer->fetchPaymentType($ddgMock->getId()); $this->assertInstanceOf(SepaDirectDebitSecured::class, $fetchedType); - $this->assertRegExp('/^s-ddg-[.]*/', $fetchedType->getId()); + $this->assertMatchesRegularExpression('/^s-ddg-[.]*/', $fetchedType->getId()); return $fetchedType; } diff --git a/test/integration/PaymentTypes/SepaDirectDebitTest.php b/test/integration/PaymentTypes/SepaDirectDebitTest.php index afa87948..bd23bb7f 100755 --- a/test/integration/PaymentTypes/SepaDirectDebitTest.php +++ b/test/integration/PaymentTypes/SepaDirectDebitTest.php @@ -1,4 +1,5 @@ useLegacyKey(); + } + /** * Verify sepa direct debit can be created. * diff --git a/test/integration/PaymentTypes/SofortTest.php b/test/integration/PaymentTypes/SofortTest.php index a710facf..6cd6aafc 100755 --- a/test/integration/PaymentTypes/SofortTest.php +++ b/test/integration/PaymentTypes/SofortTest.php @@ -1,4 +1,5 @@ useLegacyKey(); /** @var SepaDirectDebit $dd */ $dd = $this->unzer->createPaymentType(new SepaDirectDebit('DE89370400440532013000')); $this->assertFalse($dd->isRecurring()); diff --git a/test/integration/SetMetadataTest.php b/test/integration/SetMetadataTest.php index 7e399597..692df112 100755 --- a/test/integration/SetMetadataTest.php +++ b/test/integration/SetMetadataTest.php @@ -1,4 +1,5 @@ useLegacyKey(); + } + /** * Verify charge can be fetched by id. * diff --git a/test/integration/TransactionTypes/CancelTest.php b/test/integration/TransactionTypes/CancelTest.php index 575b7345..23622d54 100644 --- a/test/integration/TransactionTypes/CancelTest.php +++ b/test/integration/TransactionTypes/CancelTest.php @@ -1,4 +1,5 @@ useLegacyKey(); $charge = $this->createCharge(); $cancel = $charge->cancel(); $fetchedCancel = $this->unzer->fetchRefundById($charge->getPayment()->getId(), $charge->getId(), $cancel->getId()); @@ -78,6 +81,7 @@ public function refundShouldBeFetchableViaUnzerObject(): void */ public function refundShouldBeFetchableViaPaymentObject(): void { + $this->useLegacyKey(); $charge = $this->createCharge(); $cancel = new Cancellation(); $this->getUnzerObject()->cancelChargedPayment($charge->getPayment(), $cancel); @@ -109,6 +113,7 @@ public function authorizationCancellationsShouldBeFetchableViaPaymentObject(): v */ public function chargeCancellationsShouldBeFetchableViaPaymentObject(): void { + $this->useLegacyKey(); $charge = $this->createCharge(); $refund = $charge->cancel(); $fetchedPayment = $this->unzer->fetchPayment($charge->getPayment()->getId()); @@ -125,6 +130,7 @@ public function chargeCancellationsShouldBeFetchableViaPaymentObject(): void */ public function cancelStatusIsSetCorrectly(): void { + $this->useLegacyKey(); $charge = $this->createCharge(); $reversal = $charge->cancel(); $this->assertSuccess($reversal); diff --git a/test/integration/TransactionTypes/ChargeAfterAuthorizationTest.php b/test/integration/TransactionTypes/ChargeAfterAuthorizationTest.php index 5316c594..250a69fd 100644 --- a/test/integration/TransactionTypes/ChargeAfterAuthorizationTest.php +++ b/test/integration/TransactionTypes/ChargeAfterAuthorizationTest.php @@ -1,4 +1,5 @@ useLegacyKey(); $paymentType = $this->unzer->createPaymentType(new SepaDirectDebit('DE89370400440532013000')); $charge = $this->unzer->charge(100.0, 'EUR', $paymentType->getId(), self::RETURN_URL); $this->assertTransactionResourceHasBeenCreated($charge); @@ -58,6 +61,7 @@ public function chargeShouldWorkWithTypeId(): void */ public function chargeShouldWorkWithTypeObject(): void { + $this->useLegacyKey(); $paymentType = $this->unzer->createPaymentType(new SepaDirectDebit('DE89370400440532013000')); $charge = $this->unzer->charge(100.0, 'EUR', $paymentType, self::RETURN_URL); $this->assertTransactionResourceHasBeenCreated($charge); @@ -73,6 +77,7 @@ public function chargeShouldWorkWithTypeObject(): void */ public function chargeStatusIsSetCorrectly(): void { + $this->useLegacyKey(); $this->assertSuccess($this->createCharge()); } diff --git a/test/integration/TransactionTypes/PaylaterCancelTest.php b/test/integration/TransactionTypes/PaylaterCancelTest.php index aa8354bd..7a737468 100644 --- a/test/integration/TransactionTypes/PaylaterCancelTest.php +++ b/test/integration/TransactionTypes/PaylaterCancelTest.php @@ -1,4 +1,5 @@ useLegacyKey(); $sepa = new SepaDirectDebit('DE89370400440532013000'); $this->unzer->createPaymentType($sepa); $payout = $sepa->payout(100.0, 'EUR', self::RETURN_URL); @@ -100,7 +103,7 @@ public function payoutCanBeCalledForSepaDirectDebitSecuredType(): void $this->assertEquals(self::RETURN_URL, $payout->getReturnUrl()); $this->assertAmounts($payment, 0, 0, -100, 0); } - + /** * Verify Payout transaction is fetched with Payment resource. * diff --git a/test/integration/TransactionTypes/ShipmentTest.php b/test/integration/TransactionTypes/ShipmentTest.php index f539d79e..80b1055f 100644 --- a/test/integration/TransactionTypes/ShipmentTest.php +++ b/test/integration/TransactionTypes/ShipmentTest.php @@ -1,4 +1,5 @@ setId('MyPaymentId'); $this->assertIsEmptyArray($payment->getCharges()); $this->assertIsEmptyArray($payment->getShipments()); @@ -928,6 +933,8 @@ public function handleResponseShouldUpdateChargeTransactions(): void $this->assertIsEmptyArray($payment->getCharges()); $this->assertIsEmptyArray($payment->getShipments()); $this->assertIsEmptyArray($payment->getCancellations()); + $this->assertIsEmptyArray($payment->getChargebacks()); + $this->assertNull($payment->getPayout()); $this->assertNull($payment->getAuthorization()); } @@ -960,6 +967,90 @@ public function handleResponseShouldUpdateAuthorizationFromResponse(): void $this->assertEquals(10.321, $authorization->getAmount()); } + /** + * Verify handleResponse updates existing chargebacks from response. + * + * @test + */ + public function handleResponseShouldUpdateChargebackFromResponse(): void + { + $resourceServiceMock = $this->getMockBuilder(ResourceService::class) + ->disableOriginalConstructor()->onlyMethods(['getResource'])->getMock(); + + $unzer = (new Unzer('s-priv-123'))->setResourceService($resourceServiceMock); + $payment = (new Payment()) + ->setParentResource($unzer) + ->setId('MyPaymentId'); + + $paymentJson = JsonProvider::getJsonFromFile('paymentWithMultipleChargebacks.json'); + $response = new stdClass(); + + $payment->handleResponse(json_decode($paymentJson)); + + $chargebacks = $payment->getChargebacks(true); + $charges = $payment->getCharges(); + $this->assertCount(2, $charges); + $this->assertCount(2, $chargebacks); + + $chargeback1 = $chargebacks[0]; + $this->assertInstanceOf(Chargeback::class, $chargeback1); + $this->assertInstanceOf(Charge::class, $chargeback1->getParentResource()); + $this->assertEquals(0.5, $chargeback1->getAmount()); + + $chargeback2 = $chargebacks[1]; + $this->assertInstanceOf(Chargeback::class, $chargeback2); + $this->assertInstanceOf(Charge::class, $chargeback2->getParentResource()); + $this->assertEquals(0.5, $chargeback2->getAmount()); + + // Charges contain chargeback reference. + $charge1 = $charges[0]; + $this->assertCount(1, $charge1->getChargebacks()); + + $charge2 = $charges[1]; + $this->assertCount(1, $charge1->getChargebacks()); + } + + /** + * Verify handleResponse updates existing chargebacks from response. + * + * @test + */ + public function chargebackOnPaymentShouldBeHandledProperly(): void + { + $resourceServiceMock = $this->getMockBuilder(ResourceService::class) + ->disableOriginalConstructor()->onlyMethods(['getResource', 'fetchResource'])->getMock(); + + $unzer = (new Unzer('s-priv-123'))->setResourceService($resourceServiceMock); + $payment = (new Payment()) + ->setParentResource($unzer) + ->setId('MyPaymentId'); + + $paymentResponse = JsonProvider::getJsonFromFile('paymentWithDirectChargeback.json'); + $payment->handleResponse(json_decode($paymentResponse, false)); + + $chargebacks = $payment->getChargebacks(true); + $charges = $payment->getCharges(); + $this->assertCount(2, $charges); + $this->assertCount(2, $chargebacks); + + $chargeback1 = $chargebacks[0]; + $this->assertInstanceOf(Chargeback::class, $chargeback1); + $this->assertInstanceOf(Payment::class, $chargeback1->getParentResource()); + $this->assertEquals(0.5, $chargeback1->getAmount()); + + $chargeback2 = $chargebacks[1]; + $this->assertInstanceOf(Chargeback::class, $chargeback2); + $this->assertInstanceOf(Payment::class, $chargeback2->getParentResource()); + $this->assertEquals(0.5, $chargeback2->getAmount()); + + // Charges contain chargeback reference. + $charge1 = $charges[0]; + $this->assertCount(0, $charge1->getChargebacks()); + + $charge2 = $charges[1]; + $this->assertCount(0, $charge2->getChargebacks()); + } + /** * Verify handleResponse adds authorization from response. * diff --git a/test/unit/Resources/PaymentTypes/ApplePayTest.php b/test/unit/Resources/PaymentTypes/ApplePayTest.php index 8e8e467f..4e438ca2 100644 --- a/test/unit/Resources/PaymentTypes/ApplePayTest.php +++ b/test/unit/Resources/PaymentTypes/ApplePayTest.php @@ -1,4 +1,5 @@ assertEquals('client ip', $geoLocation->getClientIp()); $this->assertEquals('country code', $geoLocation->getCountryCode()); - $cardDetails = new stdClass; + $cardDetails = new stdClass(); $cardDetails->cardType = 'my card type'; $cardDetails->account = 'CREDIT'; $cardDetails->countryIsoA2 = 'DE'; diff --git a/test/unit/Resources/PaymentTypes/EPSTest.php b/test/unit/Resources/PaymentTypes/EPSTest.php index 16b4ace1..f998d422 100755 --- a/test/unit/Resources/PaymentTypes/EPSTest.php +++ b/test/unit/Resources/PaymentTypes/EPSTest.php @@ -1,4 +1,5 @@ assertNull($chargeback->getAmount()); + $this->assertEmpty($chargeback->getPaymentReference()); + + $chargeback = new Chargeback(123.4); + $this->assertEquals(123.4, $chargeback->getAmount()); + + $chargeback->setAmount(567.8); + $this->assertEquals(567.8, $chargeback->getAmount()); + + $chargeback->setPaymentReference('my Payment Reference'); + $this->assertEquals('my Payment Reference', $chargeback->getPaymentReference()); + } + + /** + * Verify json response is handled properly + * + * @test + */ + public function jsonResponseShouldBeHandledProperly() + { + $responseObject = json_decode(JsonProvider::getJsonFromFile('chargeback.json')); + + $chargeback = (new Chargeback())->setPayment(new Payment()); + $this->assertFalse($chargeback->isSuccess()); + $this->assertNull($chargeback->getId()); + $this->assertNull($chargeback->getUniqueId()); + $this->assertNull($chargeback->getShortId()); + $this->assertNull($chargeback->getTraceId()); + $this->assertNull($chargeback->getAmount()); + $this->assertNull($chargeback->getDate()); + $this->assertEmpty($chargeback->getMessage()->getCustomer()); + $this->assertEmpty($chargeback->getMessage()->getMerchant()); + + $chargeback->handleResponse($responseObject); + + $this->assertEquals('s-cbk-1', $chargeback->getId()); + $this->assertEquals('31HA0xyz', $chargeback->getUniqueId()); + $this->assertEquals('1234.1234.1234', $chargeback->getShortId()); + $this->assertEquals('trace-123', $chargeback->getTraceId()); + $this->assertEquals(119.0000, $chargeback->getAmount()); + $this->assertEquals('2023-02-28 08:00:00', $chargeback->getDate()); + $this->assertEquals('Your payments have been successfully processed.', $chargeback->getMessage()->getCustomer()); + $this->assertEquals('Transaction succeeded', $chargeback->getMessage()->getMerchant()); + + $this->assertEquals('s-pay-123', $chargeback->getPaymentId()); + } + + /** + * verify fetching Chargeback by id without charge ID uses expected endpoint. + * + * @test + */ + public function fetchChargebackByIdWithoutChargeId(): void + { + $responseObject = json_decode(JsonProvider::getJsonFromFile('paymentWithDirectChargeback.json')); + $chargebackJson = JsonProvider::getJsonFromFile('chargeback.json'); + + $unzer = (new Unzer('s-priv-123')); + $payment = (new Payment()) + ->setParentResource($unzer) + ->setId('MyPaymentId'); + + // Mock http service + $httpServiceMock = $this->getMockBuilder(HttpService::class) + ->disableOriginalConstructor()->onlyMethods(['send'])->getMock(); + + $httpServiceMock->expects($this->once()) + ->method('send') + ->with('/payments/s-pay-329982/chargebacks/s-cbk-1') + ->willReturn($chargebackJson); + + // Mock Resource service + $resourceServiceMock = $this->getMockBuilder(ResourceService::class) + ->disableOriginalConstructor()->onlyMethods(['getResource', 'fetchPayment', 'fetchPaymentType'])->getMock(); + $resourceServiceMock->method('fetchPaymentType')->willReturn(new PaylaterInvoice()); + $resourceServiceMock->expects($this->once())->method('fetchPayment')->willReturn($payment); + + $unzer->setResourceService($resourceServiceMock) + ->setHttpService($httpServiceMock); + + $payment->handleResponse($responseObject); + + $fetchedChargeback = $unzer->fetchChargebackById('MyPaymentId', 's-cbk-1', null); + $this->assertEquals('s-cbk-1', $fetchedChargeback->getId()); + $this->assertEquals('31HA0xyz', $fetchedChargeback->getUniqueId()); + $this->assertEquals('1234.1234.1234', $fetchedChargeback->getShortId()); + $this->assertEquals('trace-123', $fetchedChargeback->getTraceId()); + $this->assertInstanceOf(Payment::class, $fetchedChargeback->getParentResource()); + } + + /** + * verify fetching Chargeback by id without charge ID uses expected endpoint. + * + * @test + * + * @dataProvider fetchChargebackByIdDP + * + * @param mixed $chargeId + * @param mixed $expectedUri + */ + public function fetchChargebackById($chargeId, $expectedUri): void + { + $responseObject = json_decode(JsonProvider::getJsonFromFile('paymentWithMultipleChargebacks.json')); + $chargebackJson = JsonProvider::getJsonFromFile('chargeback.json'); + + $unzer = (new Unzer('s-priv-123')); + $payment = (new Payment()) + ->setParentResource($unzer); + + // Mock http service + $httpServiceMock = $this->getMockBuilder(HttpService::class) + ->disableOriginalConstructor()->onlyMethods(['send'])->getMock(); + + $httpServiceMock->expects($this->once()) + ->method('send') + ->with($expectedUri) + ->willReturn($chargebackJson); + + // Mock Resource service + $resourceServiceMock = $this->getMockBuilder(ResourceService::class) + ->disableOriginalConstructor()->onlyMethods(['getResource', 'fetchPayment', 'fetchPaymentType'])->getMock(); + $resourceServiceMock->method('fetchPaymentType')->willReturn(new PaylaterInvoice()); + $resourceServiceMock->expects($this->once())->method('fetchPayment')->willReturn($payment); + + $unzer->setResourceService($resourceServiceMock) + ->setHttpService($httpServiceMock); + + $payment->handleResponse($responseObject); + + $fetchedChargeback = $unzer->fetchChargebackById('s-pay-123', 's-cbk-1', $chargeId); + $this->assertEquals('s-cbk-1', $fetchedChargeback->getId()); + $this->assertEquals('31HA0xyz', $fetchedChargeback->getUniqueId()); + $this->assertEquals('1234.1234.1234', $fetchedChargeback->getShortId()); + $this->assertEquals('trace-123', $fetchedChargeback->getTraceId()); + $this->assertInstanceOf(Charge::class, $fetchedChargeback->getParentResource()); + } + + public function fetchChargebackByIdDP(): array + { + return [ + 'first chargeback' => [ + 's-chg-1', + '/payments/s-pay-123/charges/s-chg-1/chargebacks/s-cbk-1' + ], + 'second chargeback' => [ + 's-chg-2', + '/payments/s-pay-123/charges/s-chg-2/chargebacks/s-cbk-1' + ] + ]; + } +} diff --git a/test/unit/Resources/TransactionTypes/DummyTransactionType.php b/test/unit/Resources/TransactionTypes/DummyTransactionType.php index 800da81b..e7740006 100755 --- a/test/unit/Resources/TransactionTypes/DummyTransactionType.php +++ b/test/unit/Resources/TransactionTypes/DummyTransactionType.php @@ -1,4 +1,5 @@ assertNull($cardData->getLiability()); $this->assertEquals('recurrenceType', $cardData->getRecurrenceType()); } - + /** * CardData should be exposed correctly. * diff --git a/test/unit/Traits/HasCancellationsTest.php b/test/unit/Traits/HasCancellationsTest.php index ada017ba..cfb3a939 100755 --- a/test/unit/Traits/HasCancellationsTest.php +++ b/test/unit/Traits/HasCancellationsTest.php @@ -1,4 +1,5 @@