From 9b0d4b4abccd9352faa7543fc2259e8b3c708145 Mon Sep 17 00:00:00 2001 From: securesubmit-buildmaster Date: Tue, 27 Jun 2023 08:07:16 -0400 Subject: [PATCH] OctopusDeploy release: 8.0.2 --- CHANGELOG.md | 8 + metadata.xml | 2 +- src/Builders/PayFacBuilder.php | 92 ++++- src/Entities/Address.php | 7 + src/Entities/Enums/TransactionType.php | 5 +- src/Entities/PayFac/BusinessData.php | 13 +- src/Entities/PayFac/DeviceAttributeInfo.php | 22 + src/Entities/PayFac/DeviceDetails.php | 25 +- src/Entities/PayFac/DeviceOrder.php | 23 ++ src/Entities/PayFac/UserPersonalData.php | 66 ++- src/Gateways/PorticoConnector.php | 8 +- src/Gateways/ProPayConnector.php | 333 ++++++++++----- src/ServiceConfigs/Gateways/PorticoConfig.php | 1 + src/Services/HostedService.php | 2 +- src/Services/PayFacService.php | 38 +- .../PAX/SubGroups/AmountResponse.php | 2 +- .../GpEcomConnector/Hpp/GpEcomHppClient.php | 2 +- .../Gateways/GpEcomConnector/HppTestCase.php | 24 ++ .../Gateways/ProPay/ProPayAccountTests.php | 391 +++++++++++------- .../Gateways/ProPay/ProPayFundsTests.php | 52 +-- .../ProPay/ProPayGetInformationTests.php | 44 +- .../Gateways/ProPay/ProPayNetworkTests.php | 52 +-- .../ProPay/TestData/TestAccountData.php | 202 +++++++-- .../ProPay/TestData/selfSignedCertificate.crt | 5 +- .../Gateways/Terminals/PAX/PaxCreditTests.php | 16 +- 25 files changed, 1005 insertions(+), 430 deletions(-) create mode 100644 src/Entities/PayFac/DeviceAttributeInfo.php create mode 100644 src/Entities/PayFac/DeviceOrder.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 44412836..5b0995e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ # Changelog ## Latest Version +#### Enhancements: +- Profac: Additional transaction support added | Account Management | Spilt Fund | Network Transaction +- PAX Devices: Improved some tests + +#### Bug Fixes: +- GP-ECOM: Fix type confusion vulnerability on sha1hash for hppResponse + +## v8.0.1 (05/30/2023) #### Bug Fixes: - Portico/Heartland: fix 'AllowDup' flag not included with some CreditReturn transactions diff --git a/metadata.xml b/metadata.xml index 12b8f891..32c28ba9 100644 --- a/metadata.xml +++ b/metadata.xml @@ -1,3 +1,3 @@ - 8.0.1 + 8.0.2 \ No newline at end of file diff --git a/src/Builders/PayFacBuilder.php b/src/Builders/PayFacBuilder.php index 8c1bdd80..e4d0ff88 100644 --- a/src/Builders/PayFacBuilder.php +++ b/src/Builders/PayFacBuilder.php @@ -1,9 +1,9 @@ */ @@ -105,6 +121,15 @@ class PayFacBuilder extends BaseBuilder /** @var AddressCollection */ public $addresses; + /** + * Required for partners ordering Portico devices. Valid values: + * [ UTC, PT, MST, MT, CT, ET, HST, AT, AST, AKST, ACT, EET, EAT, MET, NET, PLT, + * IST, BST, VST, CTT, JST, ACT, AET, SST, NST, MIT, CNT, AGT, CAT] + * + * @var string + */ + public $timezone; + const UPLOAD_FILE_TYPES = [ 'tif', 'tiff', 'bmp', 'jpg', 'jpeg', 'gif', 'png', 'doc', 'docx' ]; @@ -134,11 +159,9 @@ public function execute($configName = 'default') { parent::execute($configName); $client = ServicesContainer::instance()->getPayFac($configName); - if ( - method_exists($client, "hasBuiltInMerchantManagementService") && - $client->hasBuiltInMerchantManagementService() - ) { - return $client->processBoardingUser($this); + if (method_exists($client, "hasBuiltInMerchantManagementService") + && $client->hasBuiltInMerchantManagementService()) { + return $client->processBoardingUser($this); } return $client->processPayFac($this); @@ -246,7 +269,8 @@ protected function setupValidations() $this->validations->of(TransactionType::SPLIT_FUNDS) ->with(TransactionModifier::NONE) - ->check('transNum')->isNotNull() + ->check('accountNumber')->isNotNull() + ->check('amount')->isNotNull() ->check('receivingAccountNumber')->isNotNull(); $this->validations->of(TransactionType::REVERSE_SPLITPAY) @@ -274,7 +298,7 @@ protected function setupValidations() * * var Object GlobalPayments\Api\Entities\PayFac\BankAccountData; */ - public function withBankAccountData(BankAccountData $bankAccountData, $paymentMethodFunction = null) + public function withBankAccountData(BankAccountData $bankAccountData, $paymentMethodFunction = null) { $this->bankAccountData = $bankAccountData; if (!empty($paymentMethodFunction)) { @@ -336,7 +360,7 @@ public function withUserPersonalData(UserPersonalData $userPersonalData) return $this; } - public function withCreditCardData($creditCardInformation, $paymentMethodFunction = null) + public function withCreditCardData($creditCardInformation, $paymentMethodFunction = null) { $this->creditCardInformation = $creditCardInformation; if (!empty($paymentMethodFunction)) { @@ -352,7 +376,13 @@ public function withACHData($achInformation) $this->achInformation = $achInformation; return $this; } - + + public function withMailingAddress($mailingAddressInformation) + { + $this->mailingAddressInformation = $mailingAddressInformation; + return $this; + } + public function withSecondaryBankAccountData($secondaryBankInformation) { $this->secondaryBankInformation = $secondaryBankInformation; @@ -413,7 +443,7 @@ public function withRenewalAccountData($renewalAccountData) /* * Document details - * + * * var GlobalPayments\Api\Entities\PayFac\UploadDocumentData */ public function withUploadDocumentData($uploadDocumentData) @@ -463,7 +493,7 @@ public function withCCAmount($ccAmount) $this->ccAmount = $ccAmount; return $this; } - + public function withRequireCCRefund($requireCCRefund) { $this->requireCCRefund = $requireCCRefund; @@ -493,13 +523,43 @@ public function withSourceEmail($sourceEmail) $this->sourceEmail = $sourceEmail; return $this; } - + + public function withGatewayTransactionId($gatewayTransactionId) + { + $this->gatewayTransactionId = $gatewayTransactionId; + return $this; + } + + public function withGlobaltransId($globaltransId) + { + $this->globaltransId = $globaltransId; + return $this; + } + + public function withGlobalTransSource($globalTransSource) + { + $this->globalTransSource = $globalTransSource; + return $this; + } + + public function withCardBrandTransactionId($cardBrandTransactionId) + { + $this->cardBrandTransactionId = $cardBrandTransactionId; + return $this; + } + public function withDeviceDetails($deviceDetails) { $this->deviceDetails = $deviceDetails; return $this; } + public function withDeviceData($deviceData) + { + $this->deviceData = $deviceData; + return $this; + } + public function withDescription($description) { $this->description = $description; @@ -586,4 +646,10 @@ public function withAddress(Address $address, $type = AddressType::BILLING) return $this; } + + public function withTimeZone($timezone) + { + $this->timezone = $timezone; + return $this; + } } diff --git a/src/Entities/Address.php b/src/Entities/Address.php index 49ebef93..e5eca98f 100644 --- a/src/Entities/Address.php +++ b/src/Entities/Address.php @@ -69,6 +69,13 @@ class Address */ public $postalCode; + /** + * Consumer's phone. + * + * @var string + */ + public $phone; + /** * Consumer's country. * diff --git a/src/Entities/Enums/TransactionType.php b/src/Entities/Enums/TransactionType.php index 65dd0d4c..276e7cb8 100644 --- a/src/Entities/Enums/TransactionType.php +++ b/src/Entities/Enums/TransactionType.php @@ -57,12 +57,13 @@ class TransactionType extends Enum const REVERSE_SPLITPAY = 281474976710656; //1 << 48; const SPLIT_FUNDS = 562949953421312; //1 << 49; const GET_ACCOUNT_DETAILS = 1125899906842624; //1 << 50; - const GET_ACCOUNT_BALANCE = 2251799813685248; //1 << 51; + const GET_ACCOUNT_BALANCE = 2251799813685248; //1 << 51; const DETOKENIZE = 4503599627370496; //1 << 52 const DISPUTE_ACCEPTANCE = 9007199254740992; // 1 << 53 const DISPUTE_CHALLENGE = 18014398509481984; // 1 << 54 const REAUTH = 36028797018963968; // 1 << 55 const CONFIRM = 72057594037927936; // 1 << 56 const PAYLINK_UPDATE = 144115188075855872; // 1 << 57 - const TRANSFER_FUNDS = 288230376151711744; // // 1 << 58 + const TRANSFER_FUNDS = 288230376151711744; // 1 << 58 + const DEVICE_ORDER = 576460752303423488; // 1 << 59 } diff --git a/src/Entities/PayFac/BusinessData.php b/src/Entities/PayFac/BusinessData.php index d28809f9..6dca8256 100644 --- a/src/Entities/PayFac/BusinessData.php +++ b/src/Entities/PayFac/BusinessData.php @@ -15,8 +15,8 @@ class BusinessData /** * This field can be used to provide DBA information on an account. ProPay accounts can be - configured to display DBA on cc statements. (Note most banks' CC statements allow for 29 - characters so 255 max length is not advised.) + * configured to display DBA on cc statements. (Note most banks' CC statements allow for 29 + * characters so 255 max length is not advised.) * * @var string */ @@ -80,8 +80,13 @@ class BusinessData * @var GlobalPayments\Api\Entities\Address */ public $businessAddress; - - + + /* Business Type + * + * @var string + */ + public $businessType; + public function __construct() { $this->businessAddress = new Address(); diff --git a/src/Entities/PayFac/DeviceAttributeInfo.php b/src/Entities/PayFac/DeviceAttributeInfo.php new file mode 100644 index 00000000..b10445ed --- /dev/null +++ b/src/Entities/PayFac/DeviceAttributeInfo.php @@ -0,0 +1,22 @@ +attributes = new DeviceAttributeInfo(); + } + + /** + * @param DeviceDetails $value + * + * @return void + */ + public function append($value) : void + { + if (!$value instanceof DeviceDetails) { + throw new ArgumentException("Invalid argument type"); + } + parent::append($value); + } } diff --git a/src/Entities/PayFac/DeviceOrder.php b/src/Entities/PayFac/DeviceOrder.php new file mode 100644 index 00000000..6bfbf09a --- /dev/null +++ b/src/Entities/PayFac/DeviceOrder.php @@ -0,0 +1,23 @@ + if userId is not -provided. + * provided. * * @var string */ public $userId; - + + /** + * Signup IP Address + * + * @var string + */ + public $ipSignup; + + /** + * The submerchant is attesting that they are a US citizen. + * + * @var bool + */ + public $uSCitizen; + + /** + * Ownership or a controlling interest in the entity that have not already been disclosed + * elsewhere in the application process + * + * @var bool + */ + public $bOAttestation; + + /** + * The IP address of the device that was used to agree to ProPay's Terms and + * Conditions + * + * @var string + */ + public $termsAcceptanceIP; + + /** + * The timestamp associated with the agreement to ProPay's Terms and Conditions + * + * @var string + */ + public $termsAcceptanceTimeStamp; + + /** + * This refers to the version of our terms and conditions that was provided to the submerchant for + * review and to which they are agreeing. + * + * @var string + */ + public $termsVersion; + /** * Business Physical Address * @@ -164,15 +209,16 @@ class UserPersonalData public $type; /** - * Indicates to Global Payments where the user(example: merchant) wants to receive notifications of certain events that occur - * on the Global Payments system. + * Indicates to Global Payments where the user(example: merchant) wants to receive notifications of certain events + * that occur on the Global Payments system. * * @var string */ public $notificationStatusUrl; /** - * The merchants tax identification number. For example, in the US the (EIN) Employer Identification Number would be used. + * The merchants tax identification number. For example, in the US the (EIN) + * Employer Identification Number would be used. * * @var string */ diff --git a/src/Gateways/PorticoConnector.php b/src/Gateways/PorticoConnector.php index 14290abc..98d8518b 100644 --- a/src/Gateways/PorticoConnector.php +++ b/src/Gateways/PorticoConnector.php @@ -163,8 +163,11 @@ public function processAuthorization(AuthorizationBuilder $builder) if ( $builder->paymentMethod->paymentMethodType !== PaymentMethodType::GIFT && $builder->paymentMethod->paymentMethodType !== PaymentMethodType::ACH - && ($builder->transactionType === TransactionType::AUTH - || $builder->transactionType === TransactionType::SALE) + && ( + $builder->transactionType === TransactionType::AUTH + || $builder->transactionType === TransactionType::SALE + || $builder->transactionType === TransactionType::REFUND + ) ) { if ( $builder->paymentMethod->paymentMethodType !== PaymentMethodType::RECURRING @@ -182,6 +185,7 @@ public function processAuthorization(AuthorizationBuilder $builder) $builder->transactionModifier === TransactionModifier::NONE && $builder->paymentMethod->paymentMethodType !== PaymentMethodType::EBT && $builder->paymentMethod->paymentMethodType !== PaymentMethodType::RECURRING + && $builder->transactionType !== TransactionType::REFUND ) { $block1->appendChild( $xml->createElement( diff --git a/src/Gateways/ProPayConnector.php b/src/Gateways/ProPayConnector.php index 5efef5e1..bc66123b 100644 --- a/src/Gateways/ProPayConnector.php +++ b/src/Gateways/ProPayConnector.php @@ -10,6 +10,7 @@ use GlobalPayments\Api\Entities\Exceptions\UnsupportedTransactionException; use GlobalPayments\Api\Entities\PayFac\AccountPermissions; use GlobalPayments\Api\Entities\PayFac\BusinessData; +use GlobalPayments\Api\Entities\PayFac\DeviceDetails; use GlobalPayments\Api\Entities\PayFac\FlashFundsPaymentCardData; use GlobalPayments\Api\Entities\PayFac\UploadDocumentData; use GlobalPayments\Api\Entities\PayFac\UserPersonalData; @@ -17,7 +18,6 @@ use GlobalPayments\Api\Entities\PayFac\RenewAccountData; use GlobalPayments\Api\Entities\PayFac\SingleSignOnData; use GlobalPayments\Api\Entities\PayFac\OwnerDetailsResponseData; -use GlobalPayments\Api\Entities\PayFac\DeviceDetails; use GlobalPayments\Api\Entities\User; class ProPayConnector extends XmlGateway implements IPayFacProvider @@ -25,60 +25,90 @@ class ProPayConnector extends XmlGateway implements IPayFacProvider public $certStr; public $termId; public $selfSignedCert; - + public function processPayFac(PayFacBuilder $builder) { $this->updateGatewaySettings($builder); - + $xml = new DOMDocument(); $transaction = $xml->createElement('XMLRequest'); - + // Credentials $transaction->appendChild($xml->createElement('certStr', $this->certStr)); $transaction->appendChild($xml->createElement('termid', $this->termId)); $transaction->appendChild($xml->createElement('class', 'partner')); - + // Transaction $xmlTrans = $xml->createElement('XMLTrans'); $xmlTrans->appendChild($xml->createElement('transType', $this->mapRequestType($builder))); - + $this->hydrateCommonFields($xml, $xmlTrans, $builder); - + + if ($builder->requireCCRefund) { + $xmlTrans->appendChild($xml->createElement('requireCCRefund', $builder->requireCCRefund == true + ? 'Y' : 'N')); + } + if ($builder->transactionType === TransactionType::CREATE_ACCOUNT) { $this->hydrateAccountDetails($xml, $xmlTrans, $builder); } elseif ($builder->transactionType === TransactionType::EDIT) { $this->hydrateAccountEditDetails($xml, $xmlTrans, $builder); - } elseif ($builder->transactionType === TransactionType::RENEW_ACCOUNT && !empty($builder->renewalAccountData)) { + } elseif ( + $builder->transactionType === TransactionType::RENEW_ACCOUNT + && !empty($builder->renewalAccountData) + ) { $this->hydrateAccountRenewDetails($xml, $xmlTrans, $builder->renewalAccountData); - } elseif ($builder->transactionType === TransactionType::UPDATE_OWNERSHIP_DETAILS - && !empty($builder->beneficialOwnerData)) { + } elseif ( + $builder->transactionType === TransactionType::UPDATE_OWNERSHIP_DETAILS + && !empty($builder->beneficialOwnerData) + ) { $this->hydrateBeneficialOwnerData($xml, $xmlTrans, $builder->beneficialOwnerData); } elseif (!empty($builder->uploadDocumentData)) { $this->hydrateUploadDocument($xml, $xmlTrans, $builder->uploadDocumentData); } elseif (!empty($builder->singleSignOnData)) { $this->hydrateSingleSignOnData($xml, $xmlTrans, $builder->singleSignOnData); - } elseif ($builder->transactionType === TransactionType::UPDATE_BANK_ACCOUNT_OWNERSHIP - && !empty($builder->beneficialOwnerData)) { - $this->updateBankAccountOwnershipInfo($xml, $xmlTrans, $builder->beneficialOwnerData); + } elseif ( + $builder->transactionType === TransactionType::UPDATE_BANK_ACCOUNT_OWNERSHIP + && !empty($builder->beneficialOwnerData) + ) { + $this->updateBankAccountOwnershipInfo($xml, $xmlTrans, $builder->beneficialOwnerData); } elseif (!empty($builder->flashFundsPaymentCardData)) { $this->hydrateFlashFundsData($xml, $xmlTrans, $builder->flashFundsPaymentCardData); - } elseif ($builder->transactionType === TransactionType::GET_ACCOUNT_DETAILS - && empty($builder->accountNumber)) { + } elseif ( + $builder->transactionType === TransactionType::GET_ACCOUNT_DETAILS + && empty($builder->accountNumber) + ) { if (!empty($builder->externalId)) { $xmlTrans->appendChild($xml->createElement('externalId', $builder->externalId)); } elseif (!empty($builder->sourceEmail)) { $xmlTrans->appendChild($xml->createElement('sourceEmail', $builder->sourceEmail)); } } - + + if (!empty($builder->timezone)) { + $xmlTrans->appendChild($xml->createElement('Timezone', $builder->timezone)); + } + + if ($builder->transactionType === TransactionType::DEVICE_ORDER && !empty($builder->deviceOrder)) { + $this->hydrateDeviceOrderData($xml, $xmlTrans, $builder->deviceOrder); + } + + if (!empty($builder->deviceDetails)) { + $this->hydrateDeviceOrderData($xml, $xmlTrans, $builder->deviceDetails); + } + + if (!empty($builder->deviceData)) { + $this->hydrateDeviceData($xml, $xmlTrans, $builder->deviceData); + } + $transaction->appendChild($xmlTrans); - + $requestXML = $xml->saveXML($transaction); $response = $this->doTransaction($requestXML); - + return $this->mapResponse($builder, $response); } - + public function mapRequestType($builder) { switch ($builder->transactionType) { @@ -122,18 +152,20 @@ public function mapRequestType($builder) return "13"; case TransactionType::GET_ACCOUNT_BALANCE: return "14"; + case TransactionType::DEVICE_ORDER: + return "430"; default: throw new UnsupportedTransactionException(); } } - + public function mapResponse($builder, $rawResponse) { $root = $this->xml2object($rawResponse); - + $responseCode = !empty($root->status) ? $root->status : 'Invalid Status code'; - - if ($responseCode != '00') { + + if ($responseCode != '00' && $responseCode != '66') { throw new GatewayException( sprintf( 'Unexpected Gateway Response: %s. ', @@ -141,14 +173,14 @@ public function mapResponse($builder, $rawResponse) ) ); } - + $response = new Transaction(); $response->payFacData = $this->populateProPayResponse($root); $response->responseCode = (string) $root->status; - + return $response; } - + /** * Converts a XML string to a simple object for use, * removing extra nodes that are not necessary for @@ -164,39 +196,39 @@ protected function xml2object($xml) $xml, 'SimpleXMLElement' ); - + return !empty($envelope->XMLTrans) ? $envelope->XMLTrans : null; - + throw new \Exception('XML from gateway could not be parsed'); } - - + private function hydrateAccountDetails($xml, $xmlTrans, PayFacBuilder $builder) { if (!empty($builder->userPersonalData)) { $this->hydrateUserPersonalData($xml, $xmlTrans, $builder->userPersonalData); } - + if (!empty($builder->businessData)) { $this->hydrateBusinessData($xml, $xmlTrans, $builder->businessData); } - + if (!empty($builder->beneficialOwnerData)) { $this->hydrateBeneficialOwnerData($xml, $xmlTrans, $builder->beneficialOwnerData); } - + if (!empty($builder->grossBillingInformation)) { $this->hydrateGrossBillingData($xml, $xmlTrans, $builder->grossBillingInformation); } - + + $this->hydrateBankDetails($xml, $xmlTrans, $builder); + if (!empty($builder->deviceDetails)) { - $this->hydrateDeviceQuantity($xml, $xmlTrans, $builder->deviceDetails); + $this->hydrateDeviceQuantity($xml, $xmlTrans, $builder->deviceDetails); } - - $this->hydrateBankDetails($xml, $xmlTrans, $builder); + $this->hydratOtherDetails($xml, $xmlTrans, $builder); } - + private function hydrateAccountEditDetails($xml, $xmlTrans, PayFacBuilder $builder) { if (!empty($builder->password)) { @@ -217,35 +249,39 @@ private function hydrateAccountEditDetails($xml, $xmlTrans, PayFacBuilder $build //update bank details if any $this->hydrateBankDetails($xml, $xmlTrans, $builder); } - + private function hydrateAccountRenewDetails($xml, $xmlTrans, RenewAccountData $renewalAccountData) { $elementMap = [ 'tier' => !empty($renewalAccountData->tier) ? $renewalAccountData->tier : '', - + 'CVV2' => !empty($renewalAccountData->creditCard->cvn) ? $renewalAccountData->creditCard->cvn : '', 'ccNum' => !empty($renewalAccountData->creditCard->number) ? $renewalAccountData->creditCard->number : '', - 'expDate' => !empty($renewalAccountData->creditCard->expMonth) ? $renewalAccountData->creditCard->getShortExpiry() : '', + 'expDate' => !empty($renewalAccountData->creditCard->expMonth) + ? $renewalAccountData->creditCard->getShortExpiry() : '', 'zip' => !empty($renewalAccountData->zipCode) ? $renewalAccountData->zipCode : '', - - 'PaymentBankAccountNumber' => !empty($renewalAccountData->paymentBankAccountNumber) ? $renewalAccountData->paymentBankAccountNumber : '', - 'PaymentBankRoutingNumber' => !empty($renewalAccountData->paymentBankRoutingNumber) ? $renewalAccountData->paymentBankRoutingNumber : '', - 'PaymentBankAccountType' => !empty($renewalAccountData->paymentBankAccountType) ? $renewalAccountData->paymentBankAccountType : '', + + 'PaymentBankAccountNumber' => !empty($renewalAccountData->paymentBankAccountNumber) + ? $renewalAccountData->paymentBankAccountNumber : '', + 'PaymentBankRoutingNumber' => !empty($renewalAccountData->paymentBankRoutingNumber) + ? $renewalAccountData->paymentBankRoutingNumber : '', + 'PaymentBankAccountType' => !empty($renewalAccountData->paymentBankAccountType) + ? $renewalAccountData->paymentBankAccountType : '', ]; $this->createNewElements($xml, $xmlTrans, $elementMap); } - + private function hydrateBeneficialOwnerData($xml, $xmLtransaction, $beneficialOwnerData) { $ownerDetails = $xml->createElement('BeneficialOwnerData'); $ownerDetails->appendChild($xml->createElement('OwnerCount', $beneficialOwnerData->ownersCount)); - + if ($beneficialOwnerData->ownersCount > 0) { $ownersList = $xml->createElement('Owners'); - + foreach ($beneficialOwnerData->ownersList as $ownerInfo) { $newOwner = $xml->createElement('Owner'); - + $elements = [ 'FirstName' => !empty($ownerInfo->firstName) ? $ownerInfo->firstName : '', 'LastName' => !empty($ownerInfo->lastName) ? $ownerInfo->lastName : '', @@ -260,16 +296,16 @@ private function hydrateBeneficialOwnerData($xml, $xmLtransaction, $beneficialOw 'Title' => !empty($ownerInfo->title) ? $ownerInfo->title : '', 'Percentage' => !empty($ownerInfo->percentage) ? $ownerInfo->percentage : '' ]; - + $this->createNewElements($xml, $newOwner, $elements); $ownersList->appendChild($newOwner); } $ownerDetails->appendChild($ownersList); } - + $xmLtransaction->appendChild($ownerDetails); } - + private function hydrateBusinessData($xml, $transaction, BusinessData $businessData) { $propertyElementMap = [ @@ -287,17 +323,18 @@ private function hydrateBusinessData($xml, $transaction, BusinessData $businessD 'BusinessCity' => !empty($businessData->businessAddress->city) ? $businessData->businessAddress->city : '', 'BusinessCountry' => !is_null($businessData->businessAddress->country) ? $businessData->businessAddress->country : '', 'BusinessState' => !empty($businessData->businessAddress->state) ? $businessData->businessAddress->state : '', - 'BusinessZip' => !empty($businessData->businessAddress->postalCode) ? $businessData->businessAddress->postalCode : '' + 'BusinessZip' => !empty($businessData->businessAddress->postalCode) ? $businessData->businessAddress->postalCode : '', + 'BusinessType' => !empty($businessData->businessType) ? $businessData->businessType : '' ]; - + $this->createNewElements($xml, $transaction, $propertyElementMap); } - + private function hydrateUserPersonalData($xml, $transaction, UserPersonalData $userPersonalData) { $merchantAddress = $userPersonalData->userAddress; $mailingAddress = $userPersonalData->mailingAddress; - + $elementMap = [ 'firstName' => !empty($userPersonalData->firstName) ? $userPersonalData->firstName : '', 'mInitial' => !empty($userPersonalData->mInitial) ? $userPersonalData->mInitial : '', @@ -311,7 +348,7 @@ private function hydrateUserPersonalData($xml, $transaction, UserPersonalData $u 'currencyCode' => !empty($userPersonalData->currencyCode) ? $userPersonalData->currencyCode : '', 'tier' => !empty($userPersonalData->tier) ? $userPersonalData->tier : '', 'externalId' => !empty($userPersonalData->externalId) ? $userPersonalData->externalId : '', - + 'addr' => !empty($merchantAddress->streetAddress1) ? $merchantAddress->streetAddress1 : '', 'aptNum' => !empty($merchantAddress->streetAddress2) ? $merchantAddress->streetAddress2 : '', 'addr3' => !empty($merchantAddress->streetAddress3) ? $merchantAddress->streetAddress3 : '', @@ -319,55 +356,76 @@ private function hydrateUserPersonalData($xml, $transaction, UserPersonalData $u 'state' => !empty($merchantAddress->state) ? $merchantAddress->state : '', 'zip' => !empty($merchantAddress->postalCode) ? $merchantAddress->postalCode : '', 'country' => !is_null($merchantAddress->country) ? $merchantAddress->country : '', - + + 'IpSignup' => !empty($userPersonalData->ipSignup) ? $userPersonalData->ipSignup : '', + 'USCitizen' => $this->getValueByType($userPersonalData->uSCitizen), + 'bOAttestation' => $this->getValueByType($userPersonalData->termsAcceptanceIP), + 'TermsAcceptanceIP' => !empty($userPersonalData->termsAcceptanceIP) ? (string) $userPersonalData->termsAcceptanceIP : '', + 'TermsAcceptanceTimeStamp' => !empty($userPersonalData->termsAcceptanceTimeStamp) ? $userPersonalData->termsAcceptanceTimeStamp : '', + 'TermsVersion' => !empty($userPersonalData->termsVersion) ? $userPersonalData->termsVersion : '', + 'mailAddr' => !empty($mailingAddress->streetAddress1) ? $mailingAddress->streetAddress1 : '', - 'mailApt' => !empty($mailingAddress->streetAddress2) ? $mailingAddress->streetAddress2: '', + 'mailApt' => !empty($mailingAddress->streetAddress2) ? $mailingAddress->streetAddress2 : '', 'mailAddr3' => !empty($mailingAddress->streetAddress3) ? $mailingAddress->streetAddress3 : '', 'mailCity' => !empty($mailingAddress->city) ? $mailingAddress->city : '', 'mailCountry' => !is_null($mailingAddress->country) ? $mailingAddress->country : '', - 'mailState' => !empty($mailingAddress->state) ? $mailingAddress->state : '' , + 'mailState' => !empty($mailingAddress->state) ? $mailingAddress->state : '', 'mailZip' => !empty($mailingAddress->postalCode) ? $mailingAddress->postalCode : '', ]; - + $this->createNewElements($xml, $transaction, $elementMap); } - + + private function getValueByType($value) + { + if ($value == true) { + return "true"; + } + + if ($value == false) { + return "false"; + } + + return ''; + } + private function hydrateBankDetails($xml, $xmlTrans, $builder) { $elementMap = []; - + if (!empty($builder->creditCardInformation)) { $elementMap = [ - 'NameOnCard' => !empty($builder->creditCardInformation->cardHolderName) ? $builder->creditCardInformation->cardHolderName : '', + 'ccName' => !empty($builder->creditCardInformation->cardHolderName) ? $builder->creditCardInformation->cardHolderName : '', 'ccNum' => !empty($builder->creditCardInformation->number) ? $builder->creditCardInformation->number : '', + 'CVV2' => !empty($builder->creditCardInformation->cvv2) ? $builder->creditCardInformation->cvv2 : '', 'expDate' => !empty($builder->creditCardInformation->number) ? $builder->creditCardInformation->getShortExpiry() : '', ]; } - + if (!empty($builder->achInformation)) { $achInformation = [ 'PaymentBankAccountNumber' => !empty($builder->achInformation->accountNumber) ? $builder->achInformation->accountNumber : '', 'PaymentBankRoutingNumber' => !empty($builder->achInformation->routingNumber) ? $builder->achInformation->routingNumber : '', 'PaymentBankAccountType' => !empty($builder->achInformation->accountType) ? $builder->achInformation->accountType : '', ]; - + $elementMap = array_merge($elementMap, $achInformation); } - + if (!empty($builder->bankAccountData)) { $bankAccountData = [ 'AccountCountryCode' => !empty($builder->bankAccountData->accountCountryCode) ? $builder->bankAccountData->accountCountryCode : '', 'accountName' => !empty($builder->bankAccountData->accountName) ? $builder->bankAccountData->accountName : '', 'AccountNumber' => !empty($builder->bankAccountData->accountNumber) ? $builder->bankAccountData->accountNumber : '', 'AccountOwnershipType' => !empty($builder->bankAccountData->accountOwnershipType) ? $builder->bankAccountData->accountOwnershipType : '', - 'accountType' => !empty($builder->bankAccountData->accountType) ? $builder->bankAccountData->accountType : '', + 'AccountType' => !empty($builder->bankAccountData->accountType) ? $builder->bankAccountData->accountType : '', 'BankName' => !empty($builder->bankAccountData->bankName) ? $builder->bankAccountData->bankName : '', 'RoutingNumber' => !empty($builder->bankAccountData->routingNumber) ? $builder->bankAccountData->routingNumber : '', ]; - + $elementMap = array_merge($elementMap, $bankAccountData); } - + if (!empty($builder->secondaryBankInformation)) { $secondaryBankInformation = [ 'SecondaryAccountCountryCode' => !empty($builder->secondaryBankInformation->accountCountryCode) ? $builder->secondaryBankInformation->accountCountryCode : '', @@ -378,13 +436,13 @@ private function hydrateBankDetails($xml, $xmlTrans, $builder) 'SecondaryBankName' => !empty($builder->secondaryBankInformation->bankName) ? $builder->secondaryBankInformation->bankName : '', 'SecondaryRoutingNumber' => !empty($builder->secondaryBankInformation->routingNumber) ? $builder->secondaryBankInformation->routingNumber : '' ]; - + $elementMap = array_merge($elementMap, $secondaryBankInformation); } - + $this->createNewElements($xml, $xmlTrans, $elementMap); } - + private function hydratOtherDetails($xml, $xmlTrans, $builder) { //threatRiskData, significantOwnerData @@ -396,8 +454,8 @@ private function hydratOtherDetails($xml, $xmlTrans, $builder) 'AuthorizedSignerFirstName' => !empty($significantData->authorizedSignerFirstName) ? $significantData->authorizedSignerFirstName : '', 'AuthorizedSignerLastName' => !empty($significantData->authorizedSignerLastName) ? $significantData->authorizedSignerLastName : '', 'AuthorizedSignerTitle' => !empty($significantData->authorizedSignerTitle) ? $significantData->authorizedSignerTitle : '', - ]; - + ]; + if (!empty($significantData->significantOwnerData)) { $significantOwnerData = $significantData->significantOwnerData; $details = array_merge($details, [ @@ -414,10 +472,10 @@ private function hydratOtherDetails($xml, $xmlTrans, $builder) 'SignificantOwnerPercentage' => !empty($significantOwnerData->percentage) ? $significantOwnerData->percentage : '', ]); } - + $this->createNewElements($xml, $xmlTrans, $details); } - + private function hydrateGrossBillingData($xml, $transaction, $grossBilling) { $propertyElementMap = [ @@ -426,21 +484,21 @@ private function hydrateGrossBillingData($xml, $transaction, $grossBilling) 'GrossSettleState' => !empty($grossBilling->grossSettleAddress->state) ? $grossBilling->grossSettleAddress->state : '', 'GrossSettleZipCode' => !empty($grossBilling->grossSettleAddress->postalCode) ? $grossBilling->grossSettleAddress->postalCode : '', 'GrossSettleCountry' => !is_null($grossBilling->grossSettleAddress->country) ? $grossBilling->grossSettleAddress->country : '', - + 'GrossSettleCreditCardNumber' => !empty($grossBilling->grossSettleCreditCardData->number) ? $grossBilling->grossSettleCreditCardData->number : '', 'GrossSettleNameOnCard' => !empty($grossBilling->grossSettleCreditCardData->cardHolderName) ? $grossBilling->grossSettleCreditCardData->cardHolderName : '', 'GrossSettleCreditCardExpDate' => $grossBilling->grossSettleCreditCardData->getShortExpiry(), - + 'GrossSettleAccountCountryCode' => !is_null($grossBilling->grossSettleBankData->accountCountryCode) ? $grossBilling->grossSettleBankData->accountCountryCode : '', 'GrossSettleAccountHolderName' => !empty($grossBilling->grossSettleBankData->accountName) ? $grossBilling->grossSettleBankData->accountName : '', 'GrossSettleAccountNumber' => !empty($grossBilling->grossSettleBankData->accountNumber) ? $grossBilling->grossSettleBankData->accountNumber : '', 'GrossSettleAccountType' => !empty($grossBilling->grossSettleBankData->accountType) ? $grossBilling->grossSettleBankData->accountType : '', 'GrossSettleRoutingNumber' => !empty($grossBilling->grossSettleBankData->routingNumber) ? $grossBilling->grossSettleBankData->routingNumber : '' ]; - + $this->createNewElements($xml, $transaction, $propertyElementMap); } - + private function hydrateAccountPermissions($xml, $xmlTrans, AccountPermissions $accountPermissions) { $propertyElementMap = [ @@ -457,10 +515,32 @@ private function hydrateAccountPermissions($xml, $xmlTrans, AccountPermissions $ 'SoftLimitAchOffPercent' => !empty($accountPermissions->softLimitAchOffPercent) ? $accountPermissions->softLimitAchOffPercent : '', 'AchPaymentAchOffPercent' => !empty($accountPermissions->achPaymentAchOffPercent) ? $accountPermissions->achPaymentAchOffPercent : '', ]; - + + $this->createNewElements($xml, $xmlTrans, $propertyElementMap); + } + + private function hydrateDeviceOrderData($xml, $xmlTrans, $deviceData) + { + $propertyElementMap = [ + 'accntNum' => $deviceData->accountNumber, + 'shipTo' => $deviceData->shipTo, + 'shipToContact' => $deviceData->shipToContact, + 'shipToAddress' => $deviceData->shipToAddress, + 'shipToAddress2' => $deviceData->shipToAddress2, + 'shipToCity' => $deviceData->shipToCity, + 'shipToState' => $deviceData->shipToState, + 'shipToZip' => $deviceData->shipToZip, + 'shipToPhone' => $deviceData->shipToPhone, + 'cardholderName' => $deviceData->cardholderName, + 'ccNum' => $deviceData->ccNum, + 'expDate' => $deviceData->expDate, + 'cvv2' => $deviceData->cvv2, + 'billingZip' => $deviceData->billingZip, + ]; + $this->createNewElements($xml, $xmlTrans, $propertyElementMap); } - + private function createNewElements($xml, $transaction, $mapping) { foreach ($mapping as $tagName => $value) { @@ -484,7 +564,7 @@ private function setx509Certificate($certX509File) ); } } - + private function updateGatewaySettings($builder) { $certTransactions = [ @@ -494,12 +574,12 @@ private function updateGatewaySettings($builder) TransactionType::ADD_FUNDS, TransactionType::ADD_CARD_FLASH_FUNDS, ]; - + if (in_array($builder->transactionType, $certTransactions)) { $this->headers['X509Certificate'] = $this->setx509Certificate($this->selfSignedCert); } } - + private function hydrateUploadDocument($xml, $xmlTrans, UploadDocumentData $uploadDocumentData) { $fileType = pathinfo($uploadDocumentData->documentLocation, PATHINFO_EXTENSION); @@ -512,7 +592,7 @@ private function hydrateUploadDocument($xml, $xmlTrans, UploadDocumentData $uplo ]; $this->createNewElements($xml, $xmlTrans, $elementMap); } - + private function hydrateSingleSignOnData($xml, $xmlTrans, SingleSignOnData $singleSignOnData) { $elementMap = [ @@ -522,16 +602,16 @@ private function hydrateSingleSignOnData($xml, $xmlTrans, SingleSignOnData $sing ]; $this->createNewElements($xml, $xmlTrans, $elementMap); } - + private function updateBankAccountOwnershipInfo($xml, $xmLtransaction, $beneficialOwnerData) { $ownerDetails = $xml->createElement('BankAccountOwnerData'); - + if (!empty($beneficialOwnerData->ownersList)) { foreach ($beneficialOwnerData->ownersList as $key => $ownerInfo) { $ownerType = ($key === 0) ? 'PrimaryBankAccountOwner' : 'SecondaryBankAccountOwner'; $newOwner = $xml->createElement($ownerType); - + $elements = [ 'FirstName' => !empty($ownerInfo->firstName) ? $ownerInfo->firstName : '', 'LastName' => !empty($ownerInfo->lastName) ? $ownerInfo->lastName : '', @@ -544,15 +624,15 @@ private function updateBankAccountOwnershipInfo($xml, $xmLtransaction, $benefici 'Country' => !is_null($ownerInfo->ownerAddress->country) ? $ownerInfo->ownerAddress->country : '', 'Phone' => !empty($ownerInfo->phone) ? $ownerInfo->phone : '', ]; - + $this->createNewElements($xml, $newOwner, $elements); $ownerDetails->appendChild($newOwner); } } - + $xmLtransaction->appendChild($ownerDetails); } - + private function hydrateCommonFields($xml, $xmlTrans, $builder) { $elementMap = [ @@ -560,13 +640,16 @@ private function hydrateCommonFields($xml, $xmlTrans, $builder) 'amount' => !empty($builder->amount) ? $builder->amount : '', 'recAccntNum' => !empty($builder->receivingAccountNumber) ? $builder->receivingAccountNumber : '', 'allowPending' => !empty($builder->allowPending) ? 'Y' : '', - 'ccAmount' => !empty($builder->ccAmount) ? $builder->ccAmount : '', - 'requireCCRefund' => !empty($builder->requireCCRefund) ? 'Y' : 'N', - 'transNum' => !empty($builder->transNum) ? $builder->transNum : '' + 'ccAmount' => isset($builder->ccAmount) ? $builder->ccAmount : '', + 'transNum' => !empty($builder->transNum) ? $builder->transNum : '', + 'gatewayTransactionId' => !empty($builder->gatewayTransactionId) ? $builder->gatewayTransactionId : '', + 'globaltransId' => !empty($builder->globaltransId) ? $builder->globaltransId : '', + 'globalTransSource' => !empty($builder->globalTransSource) ? $builder->globalTransSource : '', + 'cardBrandTransactionId' => !empty($builder->cardBrandTransactionId) ? $builder->cardBrandTransactionId : '' ]; $this->createNewElements($xml, $xmlTrans, $elementMap); } - + private function hydrateFlashFundsData($xml, $xmlTrans, FlashFundsPaymentCardData $flashFundsData) { $elementMap = [ @@ -581,7 +664,7 @@ private function hydrateFlashFundsData($xml, $xmlTrans, FlashFundsPaymentCardDat ]; $this->createNewElements($xml, $xmlTrans, $elementMap); } - + private function populateProPayResponse($root) { $propayResponse = new PayFacResponseData(); @@ -611,18 +694,18 @@ private function populateProPayResponse($root) $propayResponse->masterPassCheckoutMerchantID = !empty($root->MasterPassCheckoutMerchantId) ? (string) $root->MasterPassCheckoutMerchantId : ''; $propayResponse->pendingAmount = !empty($root->pendingAmount) ? (string) $root->pendingAmount : ''; $propayResponse->reserveAmount = !empty($root->reserveAmount) ? (string) $root->reserveAmount : ''; - + $propayResponse->physicalAddress->streetAddress1 = !empty($root->addr) ? (string) $root->addr : ''; $propayResponse->physicalAddress->city = !empty($root->city) ? (string) $root->city : ''; $propayResponse->physicalAddress->state = !empty($root->state) ? (string) $root->state : ''; $propayResponse->physicalAddress->postalCode = !empty($root->zip) ? (string) $root->zip : ''; - + if (!empty($root->accntNum)) { $propayResponse->accountNumber = (string) $root->accntNum; } elseif (!empty($root->accountNum)) { $propayResponse->accountNumber = (string) $root->accountNum; } - + if (!empty($root->achOut)) { $propayResponse->aCHOut->enabled = !empty($root->achOut->enabled) ? (string) $root->achOut->enabled : ''; $propayResponse->aCHOut->limitRemaining = !empty($root->achOut->limitRemaining) ? (string) $root->achOut->limitRemaining : ''; @@ -630,7 +713,7 @@ private function populateProPayResponse($root) $propayResponse->aCHOut->feeType = !empty($root->achOut->feeType) ? (string) $root->achOut->feeType : ''; $propayResponse->aCHOut->accountLastFour = !empty($root->achOut->accountLastFour) ? (string) $root->achOut->accountLastFour : ''; } - + if (!empty($root->flashFunds)) { $propayResponse->flashFunds->enabled = !empty($root->flashFunds->enabled) ? (string) $root->flashFunds->enabled : ''; $propayResponse->flashFunds->limitRemaining = !empty($root->flashFunds->limitRemaining) ? (string) $root->flashFunds->limitRemaining : ''; @@ -638,7 +721,7 @@ private function populateProPayResponse($root) $propayResponse->flashFunds->feeType = !empty($root->flashFunds->feeType) ? (string) $root->flashFunds->feeType : ''; $propayResponse->flashFunds->accountLastFour = !empty($root->flashFunds->accountLastFour) ? (string) $root->flashFunds->accountLastFour : ''; } - + if (!empty($root->beneficialOwnerDataResult->Owner)) { foreach ($root->beneficialOwnerDataResult->Owner as $owner) { $ownerDetails = new OwnerDetailsResponseData(); @@ -648,23 +731,47 @@ private function populateProPayResponse($root) $propayResponse->beneficialOwnerDataResult[] = $ownerDetails; } } - + return $propayResponse; } - + private function hydrateDeviceQuantity($xml, $xmlTrans, DeviceDetails $deviceDetails) { $devicesList = $xml->createElement('Devices'); - $device = $xml->createElement('Device'); - $device->appendChild($xml->createElement('Quantity', $deviceDetails->quantity)); - $devicesList->appendChild($device); - - $xmlTrans->appendChild($devicesList); - - $xmlTrans->appendChild($xml->createElement('TimeZone', $deviceDetails->timezone)); + + foreach ($deviceDetails as $data) { + $device = $xml->createElement('Device'); + $device->appendChild($xml->createElement('Quantity', $data->quantity)); + $device->appendChild($xml->createElement('Name', $data->name)); + $devicesList->appendChild($device); + + $xmlTrans->appendChild($devicesList); + + if ($data->timezone) { + $xmlTrans->appendChild($xml->createElement('TimeZone', $data->timezone)); + } + } + } + + private function hydrateDeviceData($xml, $xmlTrans, DeviceDetails $deviceData) + { + $devicesList = $xml->createElement('Devices'); + + foreach ($deviceData as $data) { + $device = $xml->createElement('Device'); + $device->appendChild($xml->createElement('Quantity', $data->quantity)); + $device->appendChild($xml->createElement('Name', $data->name)); + $devicesList->appendChild($device); + + $xmlTrans->appendChild($devicesList); + + if ($data->timezone) { + $xmlTrans->appendChild($xml->createElement('TimeZone', $data->timezone)); + } + } } - public function processBoardingUser(PayFacBuilder $builder) : User + public function processBoardingUser(PayFacBuilder $builder): User { throw new UnsupportedTransactionException(sprintf('Method %s not supported', __METHOD__)); } diff --git a/src/ServiceConfigs/Gateways/PorticoConfig.php b/src/ServiceConfigs/Gateways/PorticoConfig.php index 9dbe989f..aa44b7d2 100644 --- a/src/ServiceConfigs/Gateways/PorticoConfig.php +++ b/src/ServiceConfigs/Gateways/PorticoConfig.php @@ -29,6 +29,7 @@ class PorticoConfig extends GatewayConfig //ProPay public $certificationStr; + public $terminalId; public $selfSignedCertLocation; public $proPayUS = true; diff --git a/src/Services/HostedService.php b/src/Services/HostedService.php index ecc5c3a7..0abbc8de 100644 --- a/src/Services/HostedService.php +++ b/src/Services/HostedService.php @@ -143,7 +143,7 @@ public function parseResponse($response, $encoded = false) $this->shaHashType ); - if ($hash != $shaHash) { + if ($hash !== $shaHash) { throw new ApiException("Incorrect hash. Please check your code and the Developers Documentation."); } diff --git a/src/Services/PayFacService.php b/src/Services/PayFacService.php index 752566a6..0079e266 100644 --- a/src/Services/PayFacService.php +++ b/src/Services/PayFacService.php @@ -28,9 +28,10 @@ public static function editAccount() { return new PayFacBuilder(TransactionType::EDIT); } + /* - * This method will reset a ProPay web login password. An email will be sent to the account email address on - * file from customerservice@propay.com containing a temporary password that can be used to login, + * This method will reset a ProPay web login password. An email will be sent to the account email address on + * file from customerservice@propay.com containing a temporary password that can be used to login, * but must be changed to something new by the user at that point. * */ @@ -38,18 +39,20 @@ public static function resetPassword() { return new PayFacBuilder(TransactionType::RESET_PASSWORD); } + /* - * This method will extend the expiration date of a ProPay account by one year. - * This may also be used to change the tier of an existing account. + * This method will extend the expiration date of a ProPay account by one year. + * This may also be used to change the tier of an existing account. * */ public static function renewAccount() { return new PayFacBuilder(TransactionType::RENEW_ACCOUNT); } + /* - * This method will update the beneficial owner data for the specified account number. - * This method should be used if the beneficial data was not sent. + * This method will update the beneficial owner data for the specified account number. + * This method should be used if the beneficial data was not sent. * while creating merchant. Note: this method can be used only when the OwnerCount value is passed while creating merchant. * */ @@ -57,19 +60,21 @@ public static function updateBeneficialOwnershipInfo() { return new PayFacBuilder(TransactionType::UPDATE_OWNERSHIP_DETAILS); } + /* - * This method will remove a ProPay account from an affiliation. The affiliation must have appropriate settings - * to enable this feature. + * This method will remove a ProPay account from an affiliation. The affiliation must have appropriate settings + * to enable this feature. * */ public static function disownAccount() { return new PayFacBuilder(TransactionType::DEACTIVATE); } + /* - * This method can be used to send an image file to ProPay, and is specifically designed to support the documents - * you use to dispute a credit card chargeback. This version of document upload has you "tag" the - * document to a specific transaction that has been charged-back + * This method can be used to send an image file to ProPay, and is specifically designed to support the documents + * you use to dispute a credit card chargeback. This version of document upload has you "tag" the + * document to a specific transaction that has been charged-back * */ public static function uploadDocumentChargeback() @@ -77,9 +82,9 @@ public static function uploadDocumentChargeback() return new PayFacBuilder(TransactionType::UPLOAD_CHARGEBACK_DOCUMENT); } /* - * This method can be used to send an image file to ProPay. The ProPay Risk team may request that you perform this - * action to underwrite an account that was denied via automated boarding, to increase the processing limit on - * accounts, or to provide data when we've had to put an accounts ability to process on hold. + * This method can be used to send an image file to ProPay. The ProPay Risk team may request that you perform this + * action to underwrite an account that was denied via automated boarding, to increase the processing limit on + * accounts, or to provide data when we've had to put an accounts ability to process on hold. * */ public static function UploadDocument() @@ -163,4 +168,9 @@ public static function getMerchantInfo($merchantId) ->withModifier(TransactionModifier::MERCHANT) ->withUserReference($userReference); } + + public static function orderDevice() + { + return new PayFacBuilder(TransactionType::DEVICE_ORDER); + } } diff --git a/src/Terminals/PAX/SubGroups/AmountResponse.php b/src/Terminals/PAX/SubGroups/AmountResponse.php index 48150b8a..74177197 100644 --- a/src/Terminals/PAX/SubGroups/AmountResponse.php +++ b/src/Terminals/PAX/SubGroups/AmountResponse.php @@ -42,7 +42,7 @@ public function __construct($messageReader) ]; foreach ($responseIndexMapping as $property => $index) { - $this->{$property} = (isset($response[$index])) + $this->{$property} = (isset($response[$index]) && !empty($response[$index])) ? TerminalUtils::reformatAmount($response[$index]) : ''; } diff --git a/test/Integration/Gateways/GpEcomConnector/Hpp/GpEcomHppClient.php b/test/Integration/Gateways/GpEcomConnector/Hpp/GpEcomHppClient.php index 9ee42cd6..f9b58a90 100644 --- a/test/Integration/Gateways/GpEcomConnector/Hpp/GpEcomHppClient.php +++ b/test/Integration/Gateways/GpEcomConnector/Hpp/GpEcomHppClient.php @@ -132,7 +132,7 @@ public function sendRequest($jsonData, $hppVersion = '') implode('.', $hashParam), $this->shaHashType ); - if ($newHash != $requestHash) { + if ($newHash !== $requestHash) { throw new ApiException("Incorrect hash. Please check your code and the Developers Documentation."); } diff --git a/test/Integration/Gateways/GpEcomConnector/HppTestCase.php b/test/Integration/Gateways/GpEcomConnector/HppTestCase.php index dfa9b662..336b723a 100644 --- a/test/Integration/Gateways/GpEcomConnector/HppTestCase.php +++ b/test/Integration/Gateways/GpEcomConnector/HppTestCase.php @@ -2,6 +2,7 @@ namespace GlobalPayments\Api\Tests\Integration\Gateways\GpEcomConnector; +use GlobalPayments\Api\Entities\Exceptions\ApiException; use GlobalPayments\Api\Services\HostedService; use GlobalPayments\Api\HostedPaymentConfig; use GlobalPayments\Api\ServiceConfigs\Gateways\GpEcomConfig; @@ -238,4 +239,27 @@ public function testDynamicCurrencyConversionResponse() $this->assertNotEquals(null, $parsedResponse); $this->assertEquals("00", $responseCode); } + + public function testCheckHashVulnerability() + { + $config = new GpEcomConfig(); + $config->merchantId = 'heartlandgpsandbox'; + $config->accountId = 'hpp'; + $config->sharedSecret = 'secret'; + $config->serviceUrl = 'https://pay.sandbox.realexpayments.com/pay'; + + $service = new HostedService($config); + + $responseJson = '{"MERCHANT_ID":"heartlandgpsandbox","ACCOUNT":"hpp","ORDER_ID":"NjMwNkMxMTAtMTA5RUNDRQ","TIMESTAMP":"20180720104340","RESULT":"00","PASREF":"15320798200414985","AUTHCODE":"12345","AVSPOSTCODERESULT":"U","CVNRESULT":"U","HPP_LANG":"GB","SHIPPING_CODE":null,"SHIPPING_CO":null,"BILLING_CODE":"123|56","BILLING_CO":"IRELAND","ECI":null,"CAVV":null,"XID":null,"MERCHANT_RESPONSE_URL":"http:\/\/requestb.in\/10q2bjb1","CARD_PAYMENT_BUTTON":null,"MESSAGE":"[ test system ] Authorised","AMOUNT":"100","SHA1HASH":true,"DCC_INFO":null,"HPP_FRAUDFILTER_MODE":null,"TSS_INFO":null}'; + + $exceptionCaught = false; + try { + $service->parseResponse($responseJson); + } catch (ApiException $e) { + $exceptionCaught = true; + $this->assertEquals('Incorrect hash. Please check your code and the Developers Documentation.', $e->getMessage()); + } finally { + $this->assertTrue($exceptionCaught); + } + } } diff --git a/test/Integration/Gateways/ProPay/ProPayAccountTests.php b/test/Integration/Gateways/ProPay/ProPayAccountTests.php index d8b39e05..dc8068d4 100644 --- a/test/Integration/Gateways/ProPay/ProPayAccountTests.php +++ b/test/Integration/Gateways/ProPay/ProPayAccountTests.php @@ -10,28 +10,27 @@ use GlobalPayments\Api\Entities\PayFac\UploadDocumentData; use GlobalPayments\Api\Entities\PayFac\SingleSignOnData; use GlobalPayments\Api\Tests\Integration\Gateways\ProPay\TestData\TestAccountData; -use GlobalPayments\Api\Entities\Enums\TimeZone; -use GlobalPayments\Api\Entities\PayFac\DeviceDetails; class ProPayAccountTests extends TestCase { - - public function setup() : void + + public function setup(): void { ServicesContainer::configureService($this->getConfig()); } - + protected function getConfig() { $config = new PorticoConfig(); - $config->certificationStr = '5dbacb0fc504dd7bdc2eadeb7039dd'; + $config->certificationStr = '5dbacb0fc504dd7bdc2eadeb7039dd'; $config->terminalId = '7039dd'; $config->environment = Environment::TEST; $config->selfSignedCertLocation = __DIR__ . '/TestData/selfSignedCertificate.crt'; return $config; } - public function testCreateAccount() + + public function test01CreateAccount() { $bankAccountInformation = TestAccountData::getBankAccountData(); $userBusinessInformation = TestAccountData::getBusinessData(); @@ -42,286 +41,372 @@ public function testCreateAccount() $creditCardInformation = TestAccountData::getCreditCardData(); $achInformation = TestAccountData::getACHData(); $secondaryBankInformation = TestAccountData::getSecondaryBankAccountData(); - + $mailingAddressInfo = TestAccountData::getMailingAddress(); + $deviceData = TestAccountData::getDeviceData(1, false); + $response = PayFacService::createAccount() - ->withBankAccountData($bankAccountInformation) - ->withBusinessData($userBusinessInformation) - ->withUserPersonalData($accountPersonalInformation) - ->withThreatRiskData($threatRiskData) - ->withSignificantOwnerData($significantOwnerData) - ->withBeneficialOwnerData($ownersInformation) - ->withCreditCardData($creditCardInformation) - ->withACHData($achInformation) - ->withSecondaryBankAccountData($secondaryBankInformation) - ->execute(); - + ->withBankAccountData($bankAccountInformation) + ->withBusinessData($userBusinessInformation) + ->withUserPersonalData($accountPersonalInformation) + ->withThreatRiskData($threatRiskData) + ->withSignificantOwnerData($significantOwnerData) + ->withBeneficialOwnerData($ownersInformation) + ->withCreditCardData($creditCardInformation) + ->withACHData($achInformation) + ->withDeviceData($deviceData) + ->withMailingAddress($mailingAddressInfo) + ->withTimeZone("ET") // with TimeZone + ->withSecondaryBankAccountData($secondaryBankInformation) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); $this->assertNotNull($response->payFacData->accountNumber); $this->assertNotNull($response->payFacData->password); $this->assertNotNull($response->payFacData->sourceEmail); } - + + public function test02CreateAccountForDeviceOrder() + { + sleep(5); + $bankAccountInformation = TestAccountData::getBankAccountData(); + $userBusinessInformation = TestAccountData::getBusinessData(); + $accountPersonalInformation = TestAccountData::getUserPersonalData(); + $ownersInformation = TestAccountData::getBeneficialOwnerData(); + $mailingAddressInfo = TestAccountData::getMailingAddress(); + $creditCardInformation = TestAccountData::getCreditCardData(); + $deviceData = TestAccountData::getDeviceData(1, false); + + $response = PayFacService::createAccount() + ->withBankAccountData($bankAccountInformation) + ->withBusinessData($userBusinessInformation) + ->withUserPersonalData($accountPersonalInformation) + ->withBeneficialOwnerData($ownersInformation) + ->withCreditCardData($creditCardInformation) + ->withMailingAddress($mailingAddressInfo) + ->withDeviceData($deviceData) + ->withTimeZone("ET") + ->execute(); + + $this->assertNotNull($response); + $this->assertEquals('00', $response->responseCode); + $this->assertNotNull($response->payFacData->accountNumber); + $this->assertNotNull($response->payFacData->password); + $this->assertNotNull($response->payFacData->sourceEmail); + } + + public function test03CreateAccountPhysicalDevice() + { + $bankAccountInformation = TestAccountData::getBankAccountData(); + $userBusinessInformation = TestAccountData::getBusinessData(); + $accountPersonalInformation = TestAccountData::getUserPersonalData(); + $ownersInformation = TestAccountData::getBeneficialOwnerData(); + $creditCardInformation = TestAccountData::getCreditCardData(); + $mailingAddressInfo = TestAccountData::getMailingAddress(); + $deviceData = TestAccountData::getDevicePhysicalData(1, true); + + $response = PayFacService::createAccount() + ->withBankAccountData($bankAccountInformation) + ->withBusinessData($userBusinessInformation) + ->withUserPersonalData($accountPersonalInformation) + ->withBeneficialOwnerData($ownersInformation) + ->withCreditCardData($creditCardInformation) + ->withDeviceData($deviceData) + ->withMailingAddress($mailingAddressInfo) + ->withTimeZone("ET") + ->execute(); + + $this->assertNotNull($response); + $this->assertEquals('00', $response->responseCode); + $this->assertNotNull($response->payFacData->accountNumber); + $this->assertNotNull($response->payFacData->password); + $this->assertNotNull($response->payFacData->sourceEmail); + } + + public function test04CreateAccount() + { + $bankAccountInformation = TestAccountData::getBankAccountData(); + $userBusinessInformation = TestAccountData::getBusinessData(); + $accountPersonalInformation = TestAccountData::getUserPersonalData(); + $threatRiskData = TestAccountData::getThreatRiskData(); + $significantOwnerData = TestAccountData::getSignificantOwnerData(); + $ownersInformation = TestAccountData::getBeneficialOwnerData(); + $creditCardInformation = TestAccountData::getCreditCardData(); + $achInformation = TestAccountData::getACHData(); + $secondaryBankInformation = TestAccountData::getSecondaryBankAccountData(); + $mailingAddressInfo = TestAccountData::getMailingAddress(); + $deviceData = TestAccountData::getDeviceData(1, false); + $accountPersonalInformation->dateOfBirth = "01-01-1971"; + + $response = PayFacService::createAccount() + ->withBankAccountData($bankAccountInformation) + ->withBusinessData($userBusinessInformation) + ->withUserPersonalData($accountPersonalInformation) + ->withThreatRiskData($threatRiskData) + ->withSignificantOwnerData($significantOwnerData) + ->withBeneficialOwnerData($ownersInformation) + ->withCreditCardData($creditCardInformation) + ->withACHData($achInformation) + ->withDeviceData($deviceData) + ->withMailingAddress($mailingAddressInfo) + ->withTimeZone("ET") + ->withSecondaryBankAccountData($secondaryBankInformation) + ->execute(); + + $this->assertNotNull($response); + $this->assertEquals('66', $response->responseCode); // API Boarding Test Failed KYC (Status 66) + } + + public function test05OrderNewDevice() + { + $orderDeviceInfo = TestAccountData::getOrderNewDeviceData(); + $deviceData = TestAccountData::getDeviceDataForOrderDevice(1, false); + + $response = PayFacService::orderDevice() + ->withDeviceDetails($orderDeviceInfo) + ->withDeviceData($deviceData) + ->execute(); + + $this->assertNotNull($response); + $this->assertEquals('00', $response->responseCode); + } + public function testEditAccountInformation() { $response = PayFacService::editAccount() - ->withAccountNumber(718138433) - ->withUserPersonalData(TestAccountData::editUserPersonalData()) - ->execute(); - + ->withAccountNumber(718138433) + ->withUserPersonalData(TestAccountData::editUserPersonalData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditPassword() { $response = PayFacService::editAccount() - ->withAccountNumber(718138433) - ->withPassword('testPwd_'.rand(1, 100)) - ->execute(); - + ->withAccountNumber(718138433) + ->withPassword('testPwd_' . rand(1, 100)) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditAddress() { $response = PayFacService::editAccount() - ->withAccountNumber(718138433) - ->withUserPersonalData(TestAccountData::editAddressData()) - ->execute(); - + ->withAccountNumber(718138433) + ->withUserPersonalData(TestAccountData::editAddressData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditAccountPermissions() { $response = PayFacService::editAccount() - ->withAccountNumber(718136530) - ->withAccountPermissions(TestAccountData::editAccountPermissions()) - ->execute(); - + ->withAccountNumber(718583526) + ->withAccountPermissions(TestAccountData::editAccountPermissions()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditPrimaryBankAccount() { $response = PayFacService::editAccount() - ->withAccountNumber(718150930) - ->withBankAccountData(TestAccountData::editBankData()) - ->execute(); - + ->withAccountNumber(718150930) + ->withBankAccountData(TestAccountData::editBankData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditSecondaryBankAccount() { $response = PayFacService::editAccount() - ->withAccountNumber(718150930) - ->withSecondaryBankAccountData(TestAccountData::editBankData()) - ->execute(); - + ->withAccountNumber(718150930) + ->withSecondaryBankAccountData(TestAccountData::editBankData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditBusinessData() { $response = PayFacService::editAccount() - ->withAccountNumber(718150930) - ->withBusinessData(TestAccountData::getBusinessData()) - ->execute(); - + ->withAccountNumber(718150930) + ->withBusinessData(TestAccountData::getBusinessData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditCreditCard() { $response = PayFacService::editAccount() - ->withAccountNumber(718138433) - ->withCreditCardData(TestAccountData::getCreditCardData()) - ->execute(); - + ->withAccountNumber(718138433) + ->withCreditCardData(TestAccountData::getCreditCardData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditRenewalInformation() { $response = PayFacService::editAccount() - ->withAccountNumber(718138433) - ->withACHData(TestAccountData::editACHData()) - ->execute(); - + ->withAccountNumber(718138433) + ->withACHData(TestAccountData::editACHData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testEditNegativeLimit() { + $this->markTestSkipped('Required additional configurations from Propay'); + // Required additional configurations from Propay $response = PayFacService::editAccount() - ->withAccountNumber(718136530) - ->withNegativeLimit(1) - ->execute(); - + ->withAccountNumber(718583533) + ->withNegativeLimit(1) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testResetPassword() { $response = PayFacService::resetPassword() - ->withAccountNumber(718150930) - ->withNegativeLimit(1) - ->execute(); - + ->withAccountNumber(718150930) + ->withNegativeLimit(1) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); $this->assertNotNull($response->payFacData->password); } - + public function testRenewAccount() { $response = PayFacService::renewAccount() - ->withAccountNumber(718151055) - ->withRenewalAccountData(TestAccountData::getRenewAccountDetails()) - ->execute(); - + ->withAccountNumber(718151055) + ->withRenewalAccountData(TestAccountData::getRenewAccountDetails()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testUpdateBeneficialOwnerData() { - //Owners count shoud not be excedded 6 + $this->markTestSkipped('Required new account number without owners details | and executed once'); + + // Owners count shoud not be excedded 6 + // This account must have been created with a beneficial owner count specified, but no owner details passed $response = PayFacService::updateBeneficialOwnershipInfo() - ->withAccountNumber(718151188) - ->withBeneficialOwnerData(TestAccountData::getBeneficialOwnerData()) - ->execute(); - + ->withAccountNumber(718583641) + ->withBeneficialOwnerData(TestAccountData::getBeneficialOwnerData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); $this->assertNotNull($response->payFacData->beneficialOwnerDataResult); } - + public function testDisownAccount() { //Enter active account number + $this->markTestSkipped('To run this test you need to enter active account number'); $response = PayFacService::disownAccount() - ->withAccountNumber(718150922) - ->execute(); - + ->withAccountNumber(718583546) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testUploadChargebackDocument() { + $this->markTestSkipped('To run this test you need to valid transactionReference number | can be verify on production only'); + // Enter valid transactionReference number $documentDetails = new UploadDocumentData(); - $documentDetails->transactionReference = '123456789'; + $documentDetails->transactionReference = '345'; $documentDetails->documentName = 'ChargebackDispute'; $documentDetails->documentLocation = __DIR__ . '/TestData/ChargebackDispute.jpg'; - + $response = PayFacService::uploadDocumentChargeback() - ->withAccountNumber(718134349) - ->withUploadDocumentData($documentDetails) - ->execute(); - + ->withAccountNumber(718134204) + ->withUploadDocumentData($documentDetails) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testUnderwriteDocument() { $documentDetails = new UploadDocumentData(); $documentDetails->documentCategory = 'Verification'; $documentDetails->documentName = 'ChargebackDispute'; $documentDetails->documentLocation = __DIR__ . '/TestData/ChargebackDispute.jpg'; - + $response = PayFacService::uploadDocument() - ->withAccountNumber(718150930) - ->withUploadDocumentData($documentDetails) - ->execute(); - + ->withAccountNumber(718150930) + ->withUploadDocumentData($documentDetails) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testObtainSSOKey() { $singleSignOnData = new SingleSignOnData(); $singleSignOnData->referrerUrl = 'https://www.globalpaymentsinc.com/'; $singleSignOnData->ipAddress = '40.81.11.219'; $singleSignOnData->ipSubnetMask = '255.255.255.0'; - + $response = PayFacService::obtainSSOKey() - ->withAccountNumber(718150930) - ->withSingleSignOnData($singleSignOnData) - ->execute(); - + ->withAccountNumber(718150930) + ->withSingleSignOnData($singleSignOnData) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); $this->assertNotNull($response->payFacData->authToken); } - + public function testUpdateBankAccountOwnershipInfo() { + // This api request is not in scope for the ProPay/Portico US solution. + $this->markTestSkipped('This api request is not in scope for the ProPay/Portico US solution. '); + $response = PayFacService::updateBankAccountOwnershipInfo() - ->withAccountNumber(718136530) - ->withBeneficialOwnerData(TestAccountData::getBeneficialOwnerData()) - ->execute(); - + ->withAccountNumber(718134204) + ->withBeneficialOwnerData(TestAccountData::getBeneficialOwnerDataCA()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); } - + public function testUpdateGrossBillingInfo() { $response = PayFacService::editAccount() - ->withAccountNumber(718151524) - ->withGrossBillingSettleData(TestAccountData::getGrossBillingSettleData()) - ->execute(); - - $this->assertNotNull($response); - $this->assertEquals('00', $response->responseCode); - } - - public function testCreateAccountWithTimeZone() - { - $bankAccountInformation = TestAccountData::getBankAccountData(); - $userBusinessInformation = TestAccountData::getBusinessData(); - $accountPersonalInformation = TestAccountData::getUserPersonalData(); - $threatRiskData = TestAccountData::getThreatRiskData(); - $significantOwnerData = TestAccountData::getSignificantOwnerData(); - $ownersInformation = TestAccountData::getBeneficialOwnerData(); - $creditCardInformation = TestAccountData::getCreditCardData(); - $achInformation = TestAccountData::getACHData(); - $secondaryBankInformation = TestAccountData::getSecondaryBankAccountData(); - $deviceDetails = new DeviceDetails(); - $deviceDetails->quantity = 2; - $deviceDetails->timezone = TimeZone::ET; - - $response = PayFacService::createAccount() - ->withBankAccountData($bankAccountInformation) - ->withBusinessData($userBusinessInformation) - ->withUserPersonalData($accountPersonalInformation) - ->withThreatRiskData($threatRiskData) - ->withSignificantOwnerData($significantOwnerData) - ->withBeneficialOwnerData($ownersInformation) - ->withCreditCardData($creditCardInformation) - ->withACHData($achInformation) - ->withSecondaryBankAccountData($secondaryBankInformation) - ->withDeviceDetails($deviceDetails) - ->execute(); - + ->withAccountNumber(718151524) + ->withGrossBillingSettleData(TestAccountData::getGrossBillingSettleData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); - $this->assertNotNull($response->payFacData->accountNumber); - $this->assertNotNull($response->payFacData->password); - $this->assertNotNull($response->payFacData->sourceEmail); } } diff --git a/test/Integration/Gateways/ProPay/ProPayFundsTests.php b/test/Integration/Gateways/ProPay/ProPayFundsTests.php index 759ea9ac..e99545dc 100644 --- a/test/Integration/Gateways/ProPay/ProPayFundsTests.php +++ b/test/Integration/Gateways/ProPay/ProPayFundsTests.php @@ -11,63 +11,63 @@ class ProPayFundsTests extends TestCase { - - public function setup() : void + public function setup(): void { ServicesContainer::configureService($this->getConfig()); } - + protected function getConfig() { $config = new PorticoConfig(); - $config->certificationStr = '5dbacb0fc504dd7bdc2eadeb7039dd'; - $config->terminalId = '7039dd'; + $config->certificationStr = '4ee64cbd706400fb4a34e65aab6f48'; + $config->terminalId = 'ab6f48'; $config->environment = Environment::TEST; $config->selfSignedCertLocation = __DIR__ . '/TestData/selfSignedCertificate.crt'; return $config; } - + public function testAddFunds() { $response = PayFacService::addFunds() - ->withAccountNumber("718136438") - ->withAmount("300") - ->execute(); - + ->withAccountNumber("718134204") + ->withAmount("10") + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } - - + public function testSweepFunds() { $response = PayFacService::sweepFunds() - ->withAccountNumber("718136438") - ->withAmount("10") - ->execute(); - + ->withAccountNumber("718570822") + ->withAmount("10") + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } - + public function testAddFlashFundsPaymentCard() { + // It can only be tested in production as required additional configuration from propay $response = PayFacService::addCardFlashFunds() - ->withAccountNumber("718136438") - ->withFlashFundsPaymentCardData(TestFundsData::getFlashFundsData()) - ->execute(); - + ->withAccountNumber("718136438") + ->withFlashFundsPaymentCardData(TestFundsData::getFlashFundsData()) + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } - + public function testPushMoneyToFlashFundsCard() { + // It can only be tested in production as required additional configuration from propay $response = PayFacService::pushMoneyToFlashFundsCard() - ->withAccountNumber("718136438") - ->withAmount("100") - ->execute(); - + ->withAccountNumber("718136438") + ->withAmount("100") + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } diff --git a/test/Integration/Gateways/ProPay/ProPayGetInformationTests.php b/test/Integration/Gateways/ProPay/ProPayGetInformationTests.php index aee07170..6b1a2630 100644 --- a/test/Integration/Gateways/ProPay/ProPayGetInformationTests.php +++ b/test/Integration/Gateways/ProPay/ProPayGetInformationTests.php @@ -10,62 +10,62 @@ class ProPayGetInformationTests extends TestCase { - - public function setup() : void + + public function setup(): void { ServicesContainer::configureService($this->getConfig()); } - + protected function getConfig() { $config = new PorticoConfig(); - $config->certificationStr = '5dbacb0fc504dd7bdc2eadeb7039dd'; - $config->terminalId = '7039dd'; + $config->certificationStr = 'a0287011dbb4181a29a5f07de995b9'; + $config->terminalId = 'e995b9'; $config->environment = Environment::TEST; $config->selfSignedCertLocation = __DIR__ . '/TestData/selfSignedCertificate.crt'; return $config; } - + public function testGetAccountInfo() { $response = PayFacService::getAccountDetails() - ->withAccountNumber("718136438") - ->execute(); - + ->withAccountNumber("718136438") + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } - - + + public function testGetAccountBalance() { $response = PayFacService::getAccountBalance() - ->withAccountNumber("718136438") - ->execute(); + ->withAccountNumber("718136438") + ->execute(); $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); $this->assertNotNull($response->payFacData->flashFunds); $this->assertNotNull($response->payFacData->aCHOut); } - + public function testGetAccountInfoExternalId() { $response = PayFacService::getAccountDetails() - ->withExternalId("1") - ->execute(); - + ->withExternalId("1") + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } - - + + public function testGetAccountInfoSourceEmail() { $response = PayFacService::getAccountDetails() - ->withSourceEmail("user4804@user.com") - ->execute(); - + ->withSourceEmail("user4804@user.com") + ->execute(); + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } diff --git a/test/Integration/Gateways/ProPay/ProPayNetworkTests.php b/test/Integration/Gateways/ProPay/ProPayNetworkTests.php index 598b35e3..0de620c9 100644 --- a/test/Integration/Gateways/ProPay/ProPayNetworkTests.php +++ b/test/Integration/Gateways/ProPay/ProPayNetworkTests.php @@ -10,72 +10,78 @@ class ProPayNetworkTests extends TestCase { - public function setup() : void { ServicesContainer::configureService($this->getConfig()); } - + protected function getConfig() { $config = new PorticoConfig(); - $config->certificationStr = '5dbacb0fc504dd7bdc2eadeb7039dd'; - $config->terminalId = '7039dd'; + $config->certificationStr = 'a0287011dbb4181a29a5f07de995b9'; + $config->terminalId = 'e995b9'; $config->environment = Environment::TEST; $config->selfSignedCertLocation = __DIR__ . '/TestData/selfSignedCertificate.crt'; return $config; } - + public function testDisburseFunds() { + // This transaction required additional configuration needed from ProPay | Fund should be available in account // This method in the ProPay API requires a different, special CertificationStr value from a disbursement account $response = PayFacService::disburseFunds() - ->withReceivingAccountNumber("718136438") - ->withAmount("100") + ->withReceivingAccountNumber("718583641") + ->withAmount("1") ->execute(); $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } + public function testSpendBackTransaction() { $response = PayFacService::spendBack() - ->withAccountNumber("718037672") - ->withReceivingAccountNumber("718136438") + ->withAccountNumber("718581374") + ->withReceivingAccountNumber("718581374") ->withAmount("100") ->withAllowPending(false) ->execute(); - + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } - + public function testReverseSplitPay() { $response = PayFacService::reverseSplitPay() - ->withAccountNumber("718136438") - ->withAmount("3") - ->withCCAmount("1") - ->withRequireCCRefund(false) - ->withTransNum("35") + ->withAccountNumber("718581375") + ->withAmount("10") + ->withCCAmount("0") + ->withRequireCCRefund(true) + ->withTransNum("7") ->execute(); - + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); $this->assertNotNull($response->payFacData->amount); $this->assertNotNull($response->payFacData->recAccountNum); $this->assertNotNull($response->payFacData->transNum); } - + public function testSplitFunds() { + // This transaction required additional configuration needed from ProPay $response = PayFacService::splitFunds() - ->withAccountNumber("718136438") - ->withReceivingAccountNumber("718134204") - ->withAmount("3") - ->withTransNum("35") + ->withAccountNumber("718581374") + ->withReceivingAccountNumber("718581375") + ->withAmount("10") + // ->withTransNum("1") + // ->withGatewayTransactionId("2814958059") + // ->withCardBrandTransactionId("SURN3DP8G1108") + ->withGlobaltransId("719D277C-C36D-4886-B79F-E54BA919CAC4") + ->withGlobalTransSource("portico") ->execute(); - + $this->assertNotNull($response); $this->assertEquals("00", $response->responseCode); } diff --git a/test/Integration/Gateways/ProPay/TestData/TestAccountData.php b/test/Integration/Gateways/ProPay/TestData/TestAccountData.php index 57a6c13f..ead62da4 100644 --- a/test/Integration/Gateways/ProPay/TestData/TestAccountData.php +++ b/test/Integration/Gateways/ProPay/TestData/TestAccountData.php @@ -14,6 +14,7 @@ use GlobalPayments\Api\Entities\PayFac\AccountPermissions; use GlobalPayments\Api\Entities\Enums\ProPayAccountStatus; use GlobalPayments\Api\Entities\PayFac\RenewAccountData; +use GlobalPayments\Api\Entities\PayFac\{DeviceDetails, DeviceOrder}; class TestAccountData { @@ -34,19 +35,20 @@ public static function getBusinessData() $userBusinessInformation = new BusinessData(); $userBusinessInformation->businessLegalName = 'Twain Enterprises'; $userBusinessInformation->doingBusinessAs = 'Twain Enterprises'; - $userBusinessInformation->employerIdentificationNumber = 987654321;//mt_rand(100000000, 999999999); + $userBusinessInformation->employerIdentificationNumber = mt_rand(100000000, 999999999); $userBusinessInformation->businessDescription = 'Accounting Services'; $userBusinessInformation->websiteURL = 'https://www.Propay.com'; $userBusinessInformation->merchantCategoryCode = '5399'; $userBusinessInformation->monthlyBankCardVolume = 50000; $userBusinessInformation->averageTicket = 100; $userBusinessInformation->highestTicket = 300; + $userBusinessInformation->businessType = 'D'; $userBusinessInformation->businessAddress->streetAddress1 = '3400 Ashton Blvd'; $userBusinessInformation->businessAddress->city = 'Lehi'; $userBusinessInformation->businessAddress->state = 'UT'; $userBusinessInformation->businessAddress->postalCode = '84045'; $userBusinessInformation->businessAddress->country = 'USA'; - + return $userBusinessInformation; } public static function getUserPersonalData() @@ -63,13 +65,19 @@ public static function getUserPersonalData() $accountPersonalInformation->ssn = 123456789; $accountPersonalInformation->dateOfBirth = '01-01-1981'; $accountPersonalInformation->tier = 'TestEIN'; - + $accountPersonalInformation->ipSignup = '4.14.150.145'; + $accountPersonalInformation->uSCitizen = true; + $accountPersonalInformation->bOAttestation = true; + $accountPersonalInformation->termsAcceptanceIP = '4.14.150.145'; + $accountPersonalInformation->termsAcceptanceTimeStamp = '2022-10-27 12:57:08.2021237'; + $accountPersonalInformation->termsVersion = 1; + $accountPersonalInformation->userAddress->streetAddress1 = '123 Main St.'; $accountPersonalInformation->userAddress->city = 'Downtown'; $accountPersonalInformation->userAddress->state = 'NJ'; $accountPersonalInformation->userAddress->postalCode = '12345'; $accountPersonalInformation->userAddress->country = 'USA'; - + $accountPersonalInformation->mailingAddress->streetAddress1 = '123 Main St.'; $accountPersonalInformation->mailingAddress->city = 'Downtown'; $accountPersonalInformation->mailingAddress->state = 'NJ'; @@ -104,22 +112,18 @@ public static function getBeneficialOwnerData() { $ownersInformation = new BeneficialOwnerData(); $firstOwnerInformation = new OwnersData(); - $firstOwnerInformation->firstName = 'Scott'; - $firstOwnerInformation->lastName = 'Sterling'; - $firstOwnerInformation->title = 'USA'; - $firstOwnerInformation->email = 'TwainEnterprises@Twain.com'; + $firstOwnerInformation->firstName = 'First1'; + $firstOwnerInformation->lastName = 'Last1'; + $firstOwnerInformation->title = 'CEO'; + $firstOwnerInformation->email = 'abc@qamail.com'; $firstOwnerInformation->dateOfBirth = '11-11-1988'; - $firstOwnerInformation->ssn = 123456789; - $firstOwnerInformation->percentage = 100; - $firstOwnerInformation->ownerAddress->streetAddress1 = '123 Address'; - $firstOwnerInformation->ownerAddress->streetAddress2 = 'Second'; - $firstOwnerInformation->ownerAddress->streetAddress3 = 'Floor'; - $firstOwnerInformation->ownerAddress->city = 'Lehi'; - $firstOwnerInformation->ownerAddress->state = 'UT'; - $firstOwnerInformation->ownerAddress->postalCode = '84045'; + $firstOwnerInformation->ssn = 123545677; + $firstOwnerInformation->ownerAddress->streetAddress1 = '125 Main St.'; + $firstOwnerInformation->ownerAddress->city = 'Downtown'; + $firstOwnerInformation->ownerAddress->state = 'NJ'; + $firstOwnerInformation->ownerAddress->postalCode = '12345'; $firstOwnerInformation->ownerAddress->country = 'USA'; - $firstOwnerInformation->phone = '12233445'; - + $secondOwnerInformation = new OwnersData(); $secondOwnerInformation->firstName = 'First4'; $secondOwnerInformation->lastName = 'Last4'; @@ -128,15 +132,47 @@ public static function getBeneficialOwnerData() $secondOwnerInformation->dateOfBirth = '11-11-1989'; $secondOwnerInformation->ssn = 123545677; $secondOwnerInformation->ownerAddress->streetAddress1 = '125 Main St.'; - $secondOwnerInformation->ownerAddress->streetAddress2 = 'Second'; - $secondOwnerInformation->ownerAddress->streetAddress3 = 'Floor'; $secondOwnerInformation->ownerAddress->city = 'Downtown'; $secondOwnerInformation->ownerAddress->state = 'NJ'; $secondOwnerInformation->ownerAddress->postalCode = '12345'; $secondOwnerInformation->ownerAddress->country = 'USA'; - $secondOwnerInformation->phone = '12233445'; + + $ownersInformation->ownersCount = 2; + $ownersInformation->ownersList = [$firstOwnerInformation, $secondOwnerInformation]; - $ownersInformation->ownersCount = 5; + return $ownersInformation; + } + + public static function getBeneficialOwnerDataCA() + { + $ownersInformation = new BeneficialOwnerData(); + $firstOwnerInformation = new OwnersData(); + $firstOwnerInformation->firstName = 'Style'; + $firstOwnerInformation->lastName = 'Stallone'; + $firstOwnerInformation->title = 'CEO'; + $firstOwnerInformation->email = 'abc@qamail.com'; + $firstOwnerInformation->dateOfBirth = '11-11-1988'; + $firstOwnerInformation->ssn = 123545677; + $firstOwnerInformation->ownerAddress->streetAddress1 = '3400 N Ashton Blvd'; + $firstOwnerInformation->ownerAddress->city = 'Orlando'; + $firstOwnerInformation->ownerAddress->state = 'FL'; + $firstOwnerInformation->ownerAddress->postalCode = 'X0A 0H0'; + $firstOwnerInformation->ownerAddress->country = 'CAN'; + + $secondOwnerInformation = new OwnersData(); + $secondOwnerInformation->firstName = 'Thomas'; + $secondOwnerInformation->lastName = 'Hanks'; + $secondOwnerInformation->title = 'Director'; + $secondOwnerInformation->email = 'abc1@qamail.com'; + $secondOwnerInformation->dateOfBirth = '11-11-1989'; + $secondOwnerInformation->ssn = 123545677; + $secondOwnerInformation->ownerAddress->streetAddress1 = '1970 Diamond Blvd'; + $secondOwnerInformation->ownerAddress->city = 'Orlando'; + $secondOwnerInformation->ownerAddress->state = 'FL'; + $secondOwnerInformation->ownerAddress->postalCode = 'X0A 0H0'; + $secondOwnerInformation->ownerAddress->country = 'CAN'; + + $ownersInformation->ownersCount = 2; $ownersInformation->ownersList = [$firstOwnerInformation, $secondOwnerInformation]; return $ownersInformation; @@ -163,7 +199,18 @@ public static function getACHData() return $bankAccountInformation; } - + + public static function getMailingAddress() + { + $address = new Address(); + $address->streetAddress1 = "123 Main St."; + $address->city = "Downtown"; + $address->state = "NJ"; + $address->postalCode = "12345"; + $address->country = "USA"; + return $address; + } + public static function getSecondaryBankAccountData() { $bankAccountInformation = new BankAccountData(); @@ -173,6 +220,7 @@ public static function getSecondaryBankAccountData() $bankAccountInformation->accountOwnershipType = 'Personal'; $bankAccountInformation->accountType = 'C'; $bankAccountInformation->routingNumber = '102000076'; + $bankAccountInformation->bankName = 'My Bank'; return $bankAccountInformation; } @@ -208,19 +256,8 @@ public static function getGrossBillingSettleData() public static function editAccountPermissions() { $accountPermissions = new AccountPermissions(); - $accountPermissions->achIn = 'Y'; - $accountPermissions->achOut = 'N'; $accountPermissions->ccProcessing = 'Y'; - $accountPermissions->proPayIn = 'Y'; - $accountPermissions->proPayOut = 'N'; - $accountPermissions->creditCardMonthLimit = '10000'; - $accountPermissions->creditCardTransactionLimit = '10000'; - $accountPermissions->merchantOverallStatus = ProPayAccountStatus::READY_TO_PROCESS; - $accountPermissions->softLimitEnabled = 'Y'; - $accountPermissions->achPaymentSoftLimitEnabled = 'N'; - $accountPermissions->softLimitAchOffPercent = '100'; //0-499 - $accountPermissions->achPaymentAchOffPercent = '100'; //0-499 - + return $accountPermissions; } @@ -285,7 +322,100 @@ public static function editACHData() return $bankAccountInformation; } - + + public static function getDeviceData($numOfDeviceTypes = 1, $withAttr = true) + { + $deviceTypes = ["PAX S500", "Secure Submit"]; + $deviceList = new DeviceDetails(); + + for ($i = 0; $i < $numOfDeviceTypes; $i++) { + $deviceData = new DeviceDetails(); + if ($i > count($deviceTypes)) { + break; + } + + $deviceData->name = $deviceTypes[$i]; + $deviceData->quantity = 1; + + if ($withAttr) { + $deviceData->attributes->name = "Heartland.AMD.OfficeKey"; + $deviceData->attributes->value = "123456"; + } + $deviceList->append($deviceData); + } + + return $deviceList; + } + + public static function getDevicePhysicalData($numOfDeviceTypes = 1, $withAttr = true) + { + $deviceTypes = ["PAX S300" ,"TestDevice"]; + $deviceList = new DeviceDetails(); + + for ($i = 0; $i < $numOfDeviceTypes; $i++) { + $deviceData = new DeviceDetails(); + if ($i > count($deviceTypes)) { + break; + } + + $deviceData->name = $deviceTypes[$i]; + $deviceData->quantity = 1; + + if ($withAttr) { + $deviceData->attributes->name = "Canada.CP.Language"; + $deviceData->attributes->value = "en"; + } + $deviceList->append($deviceData); + } + + return $deviceList; + } + + public static function getDeviceDataForOrderDevice($numOfDeviceTypes = 1, $withAttr = true) + { + $deviceTypes = ["Secure Submit"]; + $deviceList = new DeviceDetails(); + + for ($i = 0; $i < $numOfDeviceTypes; $i++) { + $deviceData = new DeviceDetails(); + if ($i > count($deviceTypes)) { + break; + } + + $deviceData->name = $deviceTypes[$i]; + $deviceData->quantity = 1; + + if ($withAttr) { + $deviceData->attributes->name = "Heartland.AMD.OfficeKey"; + $deviceData->attributes->value = "123456"; + } + $deviceList->append($deviceData); + } + + return $deviceList; + } + + public static function getOrderNewDeviceData() + { + $orderDevice = new DeviceOrder(); + $orderDevice->accountNumber = "718581359"; + $orderDevice->shipTo = "Test Company"; + $orderDevice->shipToContact = "John Q. Public"; + $orderDevice->shipToAddress = "2675 W 600 N"; + $orderDevice->shipToAddress2 = "Apt G"; + $orderDevice->shipToCity = "Lindon"; + $orderDevice->shipToState = "UT"; + $orderDevice->shipToZip = "84042"; + $orderDevice->shipToPhone = "801-555-1212"; + $orderDevice->cardholderName = "Johnny Cage"; + $orderDevice->ccNum = "4111111111111111"; + $orderDevice->expDate = "0427"; + $orderDevice->cvv2 = "999"; + $orderDevice->billingZip = "84003"; + + return $orderDevice; + } + public static function getRenewAccountDetails() { $renewAccountData = new RenewAccountData(); diff --git a/test/Integration/Gateways/ProPay/TestData/selfSignedCertificate.crt b/test/Integration/Gateways/ProPay/TestData/selfSignedCertificate.crt index 4e5c4d9b..2afd5ec1 100644 --- a/test/Integration/Gateways/ProPay/TestData/selfSignedCertificate.crt +++ b/test/Integration/Gateways/ProPay/TestData/selfSignedCertificate.crt @@ -1,4 +1,3 @@ ------BEGIN CERTIFICATE----- MIICpDCCAYygAwIBAgIIS7Y5fijJytIwDQYJKoZIhvcNAQENBQAwETEPMA0GA1UE AwwGUFJPUEFZMB4XDTE5MDkxOTAwMDAwMFoXDTI5MDkxOTAwMDAwMFowEzERMA8G A1UEAwwIMTI3LjAuMDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCC @@ -13,6 +12,4 @@ a0RyDTkXMSLqb5FgUseEjmj3ULAvFqLZNW35PY9mmlmCY+S3CC/bQR4iyPLo8lsR q0Nl6hlvB440+9zS8UQjtc2957QgcXfD427UJb698gXzsfQcNeaQWy8pNm7FzDfH TJbo/t6FOpmfR+RMZky9FrlWabInkrkf3w2XJL0uUAYU9jGQa+l/vnZD2KNzs1mO 1EqkS6yB/fsn85mkgGe4Vfbo9GQ/S+KmDujewFA0ma7O03fy1W5v6Amn/nAcFTCd -dVL3BDNEtOM= ------END CERTIFICATE----- - +dVL3BDNEtOM= \ No newline at end of file diff --git a/test/Integration/Gateways/Terminals/PAX/PaxCreditTests.php b/test/Integration/Gateways/Terminals/PAX/PaxCreditTests.php index 4192f6cd..a26678cb 100644 --- a/test/Integration/Gateways/Terminals/PAX/PaxCreditTests.php +++ b/test/Integration/Gateways/Terminals/PAX/PaxCreditTests.php @@ -9,7 +9,9 @@ use GlobalPayments\Api\Terminals\Enums\{ConnectionModes, DeviceType}; use GlobalPayments\Api\Tests\Data\TestCards; use GlobalPayments\Api\Tests\Integration\Gateways\Terminals\RequestIdProvider; +use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\TestCase; +use SebastianBergmann\RecursionContext\InvalidArgumentException; class PaxCreditTests extends TestCase { @@ -41,7 +43,7 @@ public function tearDown(): void protected function getConfig() { $config = new ConnectionConfig(); - $config->ipAddress = '192.168.0.116'; + $config->ipAddress = '192.168.0.130'; $config->port = '10009'; $config->deviceType = DeviceType::PAX_S300; $config->connectionMode = ConnectionModes::TCP_IP; @@ -332,6 +334,14 @@ public function testCreditSaleWithMerchantFee() $this->assertNotNull($response->merchantFee); } + /** + * PAX devices require the tip adjust amount or gratuity amount to be + * the total amount of the sale + tip + * + * @return void + * @throws InvalidArgumentException + * @throws ExpectationFailedException + */ public function testCreditTipAdjust() { $response = $this->device->sale(10) @@ -343,14 +353,14 @@ public function testCreditTipAdjust() $this->assertNotNull($response); $this->assertEquals('00', $response->responseCode); - $tipAdjustResponse = $this->device->tipAdjust() + $tipAdjustResponse = $this->device->tipAdjust("12.50") ->withTransactionId($response->transactionId) - ->withGratuity("2.50") ->execute(); echo $tipAdjustResponse->transactionId; $this->assertNotNull($tipAdjustResponse); $this->assertEquals('00', $response->responseCode); + $this->assertEquals(12.50, $tipAdjustResponse->transactionAmount); } }