From 937b3616e83880fb728b9c036f96bdd4f071afdc Mon Sep 17 00:00:00 2001 From: securesubmit-buildmaster Date: Tue, 4 Oct 2022 08:06:46 -0400 Subject: [PATCH] OctopusDeploy release: 5.0.3 --- CHANGELOG.md | 4 + metadata.xml | 2 +- .../GpApiAuthorizationRequestBuilder.php | 3 +- .../GpApi/GpApiReportRequestBuilder.php | 10 ++ src/Entities/Reporting/PayLinkSummary.php | 13 +- src/Entities/Reporting/SearchCriteria.php | 4 + .../Reporting/SearchCriteriaBuilder.php | 28 +++-- src/Mapping/GpApiMapping.php | 45 +++++-- .../Gateways/GpApiConnector/PayLinkTest.php | 111 ++++++++++++++++-- 9 files changed, 188 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e32c730..54f97472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## Latest version #### Enhancements: +- GP-API: PayLink enhancements + +## v5.0.2 (09/29/2022) +#### Enhancements: - GP-API: Add fraud management feature - GP-ECOM: Billing/Shipping country value should be ISO2 country code - GP-API: Add missing request properties for /transactions and /initiate endpoints diff --git a/metadata.xml b/metadata.xml index 723f1e57..6c06b3ea 100644 --- a/metadata.xml +++ b/metadata.xml @@ -1,3 +1,3 @@ - 5.0.2 + 5.0.3 \ No newline at end of file diff --git a/src/Builders/RequestBuilder/GpApi/GpApiAuthorizationRequestBuilder.php b/src/Builders/RequestBuilder/GpApi/GpApiAuthorizationRequestBuilder.php index bb66af1b..337c5d2a 100644 --- a/src/Builders/RequestBuilder/GpApi/GpApiAuthorizationRequestBuilder.php +++ b/src/Builders/RequestBuilder/GpApi/GpApiAuthorizationRequestBuilder.php @@ -129,8 +129,7 @@ public function buildRequest(BaseBuilder $builder, $config) $requestData['reference'] = $builder->clientTransactionId; $requestData['name'] = $payLink->name; $requestData['description'] = $builder->description; - $requestData['shippable'] = isset($payLink->isShippable) ? - json_encode($payLink->isShippable) : false; + $requestData['shippable'] = $payLink->isShippable == true ? 'YES' : 'NO'; $requestData['shipping_amount'] = StringUtils::toNumeric($payLink->shippingAmount); $requestData['expiration_date'] = !empty($payLink->expirationDate) ? (new \DateTime($payLink->expirationDate))->format('Y-m-d\TH:i:s\Z') : null; diff --git a/src/Builders/RequestBuilder/GpApi/GpApiReportRequestBuilder.php b/src/Builders/RequestBuilder/GpApi/GpApiReportRequestBuilder.php index d37a4256..24d4ef4d 100644 --- a/src/Builders/RequestBuilder/GpApi/GpApiReportRequestBuilder.php +++ b/src/Builders/RequestBuilder/GpApi/GpApiReportRequestBuilder.php @@ -221,6 +221,16 @@ public function buildRequest(BaseBuilder $builder, $config) $builder->searchBuilder->endDate->format('Y-m-d') : null; $queryParams['order'] = $builder->order; $queryParams['order_by'] = $builder->payLinkOrderBy; + $queryParams['status'] = $builder->searchBuilder->payLinkStatus; + $queryParams['usage_mode'] = $builder->searchBuilder->paymentMethodUsageMode; + $queryParams['name'] = $builder->searchBuilder->displayName; + $queryParams['amount'] = StringUtils::toNumeric($builder->searchBuilder->amount);; + $queryParams['description'] = $builder->searchBuilder->description; + $queryParams['reference'] = $builder->searchBuilder->referenceNumber; + $queryParams['country'] = $builder->searchBuilder->country; + $queryParams['currency'] = $builder->searchBuilder->currency; + $queryParams['expiration_date'] = !empty($builder->searchBuilder->expirationDate) ? + $builder->searchBuilder->expirationDate->format('Y-m-d') : null; break; default: return null; diff --git a/src/Entities/Reporting/PayLinkSummary.php b/src/Entities/Reporting/PayLinkSummary.php index ff14a6b2..70e4c90e 100644 --- a/src/Entities/Reporting/PayLinkSummary.php +++ b/src/Entities/Reporting/PayLinkSummary.php @@ -98,6 +98,9 @@ class PayLinkSummary */ public $shippable; + /** @var string */ + public $shippingAmount; + /** * The number of times a link has been viewed. * @var string @@ -117,10 +120,18 @@ class PayLinkSummary */ public $images; + /** + * @var string + */ + public $amount; + + /** @var string */ + public $currency; + /** * List of transactions attached to this payment link * * @var array */ - public $transactions; + public $transactions = []; } \ No newline at end of file diff --git a/src/Entities/Reporting/SearchCriteria.php b/src/Entities/Reporting/SearchCriteria.php index 15819830..1a52a74e 100644 --- a/src/Entities/Reporting/SearchCriteria.php +++ b/src/Entities/Reporting/SearchCriteria.php @@ -78,4 +78,8 @@ class SearchCriteria extends Enum const RISK_ASSESSMENT_MODE = 'riskAssessmentMode'; const RISK_ASSESSMENT_RESULT = 'riskAssessmentResult'; const RISK_ASSESSMENT_REASON_CODE = 'riskAssessmentReasonCode'; + const PAYLINK_STATUS = 'payLinkStatus'; + const PAYMENT_METHOD_USAGE_MODE = 'paymentMethodUsageMode'; + const DESCRIPTION = 'description'; + const EXPIRATION_DATE = 'expirationDate'; } diff --git a/src/Entities/Reporting/SearchCriteriaBuilder.php b/src/Entities/Reporting/SearchCriteriaBuilder.php index 15f2f8dc..4cc35aa6 100644 --- a/src/Entities/Reporting/SearchCriteriaBuilder.php +++ b/src/Entities/Reporting/SearchCriteriaBuilder.php @@ -9,7 +9,9 @@ use GlobalPayments\Api\Entities\Enums\DisputeStatus; use GlobalPayments\Api\Entities\Enums\FraudFilterMode; use GlobalPayments\Api\Entities\Enums\FraudFilterResult; +use GlobalPayments\Api\Entities\Enums\PayLinkStatus; use GlobalPayments\Api\Entities\Enums\PaymentEntryMode; +use GlobalPayments\Api\Entities\Enums\PaymentMethodUsageMode; use GlobalPayments\Api\Entities\Enums\PaymentType; use GlobalPayments\Api\Entities\Enums\PaymentMethodName; use GlobalPayments\Api\Entities\Enums\ReasonCode; @@ -479,6 +481,25 @@ class SearchCriteriaBuilder */ public $paymentMethod; + /** + * This is the PayLink id + * + * @var string + */ + public $payLinkId; + + /** @var PaymentMethodUsageMode */ + public $paymentMethodUsageMode; + + /** @var string */ + public $description; + + /** @var \DateTime */ + public $expirationDate; + + /** @var PayLinkStatus */ + public $payLinkStatus; + /** ****************************** * Open banking search criteria * ********************************/ @@ -498,13 +519,6 @@ class SearchCriteriaBuilder */ public $returnPii; - /** - * This is the PayLink id - * - * @var string - */ - public $payLinkId; - /** END Open Banking search criteria */ diff --git a/src/Mapping/GpApiMapping.php b/src/Mapping/GpApiMapping.php index d0298200..35ec55e7 100644 --- a/src/Mapping/GpApiMapping.php +++ b/src/Mapping/GpApiMapping.php @@ -2,6 +2,7 @@ namespace GlobalPayments\Api\Mapping; +use _PHPStan_76800bfb5\Nette\Utils\DateTime; use GlobalPayments\Api\Entities\AlternativePaymentResponse; use GlobalPayments\Api\Entities\BatchSummary; use GlobalPayments\Api\Entities\CardIssuerResponse; @@ -703,7 +704,7 @@ public static function mapResponseAPM($response) if (!empty($response->payment_method->authorization)) { $authorization = $response->payment_method->authorization; $apm->authStatus = !empty($authorization->status) ? $authorization->status : null; - $apm->authAmount = !empty($authorization->amount) ? $authorization->amount : null; + $apm->authAmount = !empty($authorization->amount) ? StringUtils::toAmount($authorization->amount) : null; $apm->authAck = !empty($authorization->ack) ? $authorization->ack : null; $apm->authCorrelationReference = !empty($authorization->correlation_reference) ? $authorization->correlation_reference : null; @@ -731,37 +732,42 @@ public static function mapResponseAPM($response) public static function mapPayLinkSummary($response) { $summary = new PayLinkSummary(); - - $summary->id = $response->id ?? null; $summary->merchantId = $response->merchant_id ?? null; $summary->merchantName = $response->merchant_name ?? null; $summary->accountId = $response->account_id ?? null; $summary->accountName = $response->account_name ?? null; + $summary->id = $response->id ?? null; $summary->url = $response->url ?? null; $summary->status = $response->status ?? null; $summary->type = $response->type ?? null; - $summary->allowedPaymentMethods = $response->allowed_payment_methods ?? null; //@TODO check $summary->usageMode = $response->usage_mode ?? null; - $summary->usageCount = $response->usage_count ?? null; + $summary->usageLimit = $response->usage_limit ?? null; //@TODO $summary->reference = $response->reference ?? null; $summary->name = $response->name ?? null; $summary->description = $response->description ?? null; - $summary->shippable = $response->shippable ?? null; $summary->viewedCount = $response->viewed_count ?? null; $summary->expirationDate = !empty($response->expiration_date) ? new \DateTime($response->expiration_date) : null; + + $summary->shippable = $response->shippable ?? null; + $summary->usageCount = $response->usage_count ?? null; $summary->images = $response->images ?? null; + $summary->shippingAmount = $response->shipping_amount ?? null; if (!empty($response->transactions)) { - foreach ($response->transactions as $transaction) { - $summary->transactions[] = self::createTransactionSummary($transaction); + $summary->amount = StringUtils::toAmount($response->transactions->amount) ?? null; + $summary->currency = $response->transactions->currency ?? null; + $summary->allowedPaymentMethods = $response->transactions->allowed_payment_methods ?? null; //@TODO check + if (!empty($response->transactions->transaction_list)) { + foreach ($response->transactions->transaction_list as $transaction) { + $summary->transactions[] = self::createTransactionSummary($transaction); + } } } return $summary; } - public static function mapPayLinkResponse($response) { $payLinkResponse = new PayLinkResponse(); @@ -775,9 +781,9 @@ public static function mapPayLinkResponse($response) $payLinkResponse->reference = $response->reference ?? null; $payLinkResponse->name = $response->name ?? null; $payLinkResponse->description = $response->description ?? null; - $payLinkResponse->isShippable = $response->shippable ?? null; $payLinkResponse->viewedCount = $response->viewed_count ?? null; $payLinkResponse->expirationDate = !empty($response->expiration_date) ? new \DateTime($response->expiration_date) : null; + $payLinkResponse->isShippable = $response->shippable ?? null; return $payLinkResponse; } @@ -793,9 +799,8 @@ private static function createTransactionSummary($response) { $transaction = new TransactionSummary(); $transaction->transactionId = isset($response->id) ? $response->id : null; -// $transaction->transactionDate = $response->time_created; - $transaction->transactionDate = !empty($response->time_created) ? - new \DateTime($response->time_created) : ''; + $timeCreated = self::validateStringDate($response->time_created); + $transaction->transactionDate = !empty($timeCreated) ? new \DateTime($timeCreated) : ''; $transaction->transactionStatus = $response->status; $transaction->transactionType = $response->type; $transaction->channel = !empty($response->channel) ? $response->channel : null; @@ -806,6 +811,20 @@ private static function createTransactionSummary($response) return $transaction; } + private static function validateStringDate($date) + { + try { + new \DateTime($date); + } catch (\Exception $e) { + $errors = \DateTime::getLastErrors(); + if (isset($errors['error_count']) && $errors['error_count'] > 0) { + return current(explode('.', $date)); + } + } + + return $date; + } + /** * Map the result codes directly from the card issuer. * diff --git a/test/Integration/Gateways/GpApiConnector/PayLinkTest.php b/test/Integration/Gateways/GpApiConnector/PayLinkTest.php index d9549367..77747812 100644 --- a/test/Integration/Gateways/GpApiConnector/PayLinkTest.php +++ b/test/Integration/Gateways/GpApiConnector/PayLinkTest.php @@ -2,6 +2,7 @@ namespace GlobalPayments\Api\Tests\Integration\Gateways\GpApiConnector; +use _PHPStan_76800bfb5\Nette\Utils\DateTime; use GlobalPayments\Api\Entities\Address; use GlobalPayments\Api\Entities\BrowserData; use GlobalPayments\Api\Entities\Enums\AddressType; @@ -23,6 +24,7 @@ use GlobalPayments\Api\Entities\Exceptions\ApiException; use GlobalPayments\Api\Entities\GpApi\AccessTokenInfo; use GlobalPayments\Api\Entities\PayLinkData; +use GlobalPayments\Api\Entities\Reporting\DataServiceCriteria; use GlobalPayments\Api\Entities\Reporting\PayLinkSummary; use GlobalPayments\Api\Entities\Reporting\SearchCriteria; use GlobalPayments\Api\Entities\Transaction; @@ -46,6 +48,7 @@ class PayLinkTest extends TestCase private $card; private $shippingAddress; private $browserData; + private $payLinkId; public function setup() : void { @@ -95,6 +98,15 @@ public function setup() : void $this->browserData->challengWindowSize = ChallengeWindowSize::WINDOWED_600X400; $this->browserData->timeZone = "0"; $this->browserData->userAgent = "Mozilla/5.0 (Windows NT 6.1; Win64, x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"; + + $response = PayLinkService::findPayLink(1, 1) + ->orderBy(PayLinkSortProperty::TIME_CREATED, SortDirection::ASC) + ->where(SearchCriteria::START_DATE, $this->startDate) + ->andWith(SearchCriteria::END_DATE, $this->endDate) + ->execute(); + if (count($response->result) == 1) { + $this->payLinkId = $response->result[0]->id; + } } public function setUpConfig() @@ -620,11 +632,12 @@ public function testCreatePayLink_MissingCurrency() public function testEditPayLink_MissingUsageMode() { + $this->assertNotNull($this->payLinkId); $this->payLink->usageMode = null; $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount($this->amount) ->withPayLinkData($this->payLink) ->withDescription('Update Paylink description') @@ -639,11 +652,12 @@ public function testEditPayLink_MissingUsageMode() public function testEditPayLink_MissingName() { + $this->assertNotNull($this->payLinkId); $this->payLink->name = null; $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount($this->amount) ->withPayLinkData($this->payLink) ->withDescription('Update Paylink description') @@ -659,11 +673,12 @@ public function testEditPayLink_MissingName() public function testEditPayLink_MissingType() { + $this->assertNotNull($this->payLinkId); $this->payLink->type = null; $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount($this->amount) ->withPayLinkData($this->payLink) ->withDescription('Update Paylink description') @@ -678,11 +693,12 @@ public function testEditPayLink_MissingType() public function testEditPayLink_MissingUsageLimit() { + $this->assertNotNull($this->payLinkId); $this->payLink->usageLimit = null; $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount($this->amount) ->withPayLinkData($this->payLink) ->withDescription('Update Paylink description') @@ -697,16 +713,17 @@ public function testEditPayLink_MissingUsageLimit() public function testEditPayLink_MissingDescription() { + $this->assertNotNull($this->payLinkId); $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount($this->amount) ->withPayLinkData($this->payLink) ->execute(); } catch (ApiException $e) { $exceptionCaught = true; - $this->assertEquals('40005', $e->responseCode); $this->assertEquals('Status Code: MANDATORY_DATA_MISSING - Request expects the following field description', $e->getMessage()); + $this->assertEquals('40005', $e->responseCode); } finally { $this->assertTrue($exceptionCaught); } @@ -714,9 +731,10 @@ public function testEditPayLink_MissingDescription() public function testEditPayLink_MissingPayLinkData() { + $this->assertNotNull($this->payLinkId); $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount($this->amount) ->withDescription('Update Paylink description') ->execute(); @@ -730,9 +748,10 @@ public function testEditPayLink_MissingPayLinkData() public function testEditPayLink_MissingAmount() { + $this->assertNotNull($this->payLinkId); $exceptionCaught = false; try { - PayLinkService::edit(GenerationUtils::getGuid()) + PayLinkService::edit($this->payLinkId) ->withAmount(null) ->withPayLinkData($this->payLink) ->withDescription('Update Paylink description') @@ -763,6 +782,82 @@ public function testEditPayLink_RandomPayLinkId() } } + public function testFindPayLinkByStatus() + { + $response = PayLinkService::findPayLink(1, 10) + ->orderBy(PayLinkSortProperty::TIME_CREATED, SortDirection::ASC) + ->where(SearchCriteria::START_DATE, $this->startDate) + ->andWith(SearchCriteria::END_DATE, $this->endDate) + ->andWith(SearchCriteria::PAYLINK_STATUS, PayLinkStatus::EXPIRED) + ->execute(); + + $this->assertNotNull($response); + $this->assertNotEmpty($response->result); + /** @var PayLinkSummary $randomPayLink */ + $randomPayLink = $response->result[array_rand($response->result)]; + $this->assertNotNull($randomPayLink); + $this->assertInstanceOf(PayLinkSummary::class, $randomPayLink); + $this->assertEquals(PayLinkStatus::EXPIRED, $randomPayLink->status); + } + + public function testFindPayLinkUsageModeAndName() + { + $name = 'iphone 14'; + $response = PayLinkService::findPayLink(1, 10) + ->orderBy(PayLinkSortProperty::TIME_CREATED, SortDirection::ASC) + ->where(SearchCriteria::START_DATE, $this->startDate) + ->andWith(SearchCriteria::END_DATE, $this->endDate) + ->andWith(SearchCriteria::PAYMENT_METHOD_USAGE_MODE, PaymentMethodUsageMode::SINGLE) + ->andWith(SearchCriteria::DISPLAY_NAME, $name) + ->execute(); + + $this->assertNotNull($response); + $this->assertNotEmpty($response->result); + /** @var PayLinkSummary $randomPayLink */ + $randomPayLink = $response->result[array_rand($response->result)]; + $this->assertNotNull($randomPayLink); + $this->assertInstanceOf(PayLinkSummary::class, $randomPayLink); + $this->assertEquals(PaymentMethodUsageMode::SINGLE, $randomPayLink->usageMode); + $this->assertEquals($name, $randomPayLink->name); + } + + public function testFindPayLinkByAmount() + { + $amount = 10.00; + $response = PayLinkService::findPayLink(1, 10) + ->orderBy(PayLinkSortProperty::TIME_CREATED, SortDirection::ASC) + ->where(SearchCriteria::START_DATE, $this->startDate) + ->andWith(SearchCriteria::END_DATE, $this->endDate) + ->andWith(DataServiceCriteria::AMOUNT, $amount) + ->execute(); + + $this->assertNotNull($response); + $this->assertNotEmpty($response->result); + /** @var PayLinkSummary $randomPayLink */ + $randomPayLink = $response->result[array_rand($response->result)]; + $this->assertNotNull($randomPayLink); + $this->assertInstanceOf(PayLinkSummary::class, $randomPayLink); + $this->assertEquals($amount, $randomPayLink->amount); + } + public function testFindPayLinkByExpireDate() + { + $date = new \DateTime('2024-05-09'); + $response = PayLinkService::findPayLink(1, 10) + ->orderBy(PayLinkSortProperty::TIME_CREATED, SortDirection::ASC) + ->where(SearchCriteria::START_DATE, $this->startDate) + ->andWith(SearchCriteria::END_DATE, $this->endDate) + ->andWith(SearchCriteria::EXPIRATION_DATE, $date) + ->execute(); + + $this->assertNotNull($response); + $this->assertNotEmpty($response->result); + /** @var PayLinkSummary $randomPayLink */ + $randomPayLink = $response->result[array_rand($response->result)]; + $this->assertNotNull($randomPayLink); + $this->assertInstanceOf(PayLinkSummary::class, $randomPayLink); + $this->assertEquals($date->format('Y-m-d'), $randomPayLink->expirationDate->format('Y-m-d')); + } + private function assertPayLinkResponse(Transaction $response) { $this->assertEquals('SUCCESS', $response->responseCode);